Пример #1
0
void
AccountsToolButton::paintEvent( QPaintEvent* event )
{
    QToolButton::paintEvent( event );

    QPainter painter( this );
    painter.initFrom( this );

    if ( m_proxy->rowCount() == 0 )
    {
        QRect pixmapRect( QPoint( width() / 2 - iconSize().width() / 2,
                                  height() / 2 - iconSize().height() / 2 ),
                          iconSize() );
        painter.drawPixmap( pixmapRect, m_defaultPixmap );
    }
    else
    {
        for ( int i = 0; i < m_factoryPixmaps.count(); ++i )
        {
            int diff = height() - iconSize().height();
            int pixmapRectX = diff / 2
                            + i * ( iconSize().width() + diff );
            QRect pixmapRect( QPoint( pixmapRectX, height() / 2 - iconSize().height() / 2 ),
                              iconSize() );
            painter.drawPixmap( pixmapRect, m_factoryPixmaps.at( i ) );
        }
    }

    painter.end();
}
Пример #2
0
void SlideShow::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing, false);

    if (d->imagePaths.size() > 0) {
        QPixmap slide = QPixmap(d->imagePaths[d->currentSlide]);
        QSize slideSize = slide.size();
        QSize scaledSize = QSize(qMin(slideSize.width(), size().width()),
            qMin(slideSize.height(), size().height()));
        if (slideSize != scaledSize)
            slide = slide.scaled(scaledSize, Qt::KeepAspectRatio);

        QRect pixmapRect(qMax( (size().width() - slide.width())/2, 0),
                         qMax( (size().height() - slide.height())/2, 0),
                         slide.width(),
                         slide.height());

        if (pixmapRect.top() > 0) {
            // Fill in top & bottom rectangles:
            painter.fillRect(0, 0, size().width(), pixmapRect.top(), Qt::black);
            painter.fillRect(0, pixmapRect.bottom(), size().width(), size().height(), Qt::black);
        }

        if (pixmapRect.left() > 0) {
            // Fill in left & right rectangles:
            painter.fillRect(0, 0, pixmapRect.left(), size().height(), Qt::black);
            painter.fillRect(pixmapRect.right(), 0, size().width(), size().height(), Qt::black);
        }

        painter.drawPixmap(pixmapRect, slide);

    } else
        painter.fillRect(event->rect(), Qt::black);
}
Пример #3
0
Thumbnail::Thumbnail(const QPixmap &originalPixmap)
{
	QPixmap pixmap = originalPixmap.scaled(PixmapSize, PixmapSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
	QPixmap shadow;
	QRect pixmapRect(Margin + PixmapSize / 2 - pixmap.size().width() / 2, Margin + PixmapSize / 2 - pixmap.size().height() / 2, pixmap.size().width(), pixmap.size().height());
	
	if (_shadowCache.contains(pixmap.size()))
	{
		shadow = _shadowCache.value(pixmap.size());
	}
	else
	{
		shadow = QPixmap(thumbnailSize());
		shadow.fill(Qt::transparent);
		
		QGraphicsScene scene(shadow.rect());
		auto rectItem = scene.addRect(pixmapRect, Qt::NoPen, Qt::white);
		QGraphicsDropShadowEffect effect(0);
		effect.setBlurRadius(6);
		effect.setOffset(0);
		rectItem->setGraphicsEffect(&effect);
		
		QPainter painter(&shadow);
		scene.render(&painter);
		painter.end();
		
		_shadowCache.insert(pixmap.size(), shadow);
	}
	
	_thumbnail = shadow;
	QPainter painter(&_thumbnail);
	painter.drawPixmap(pixmapRect.topLeft(), pixmap);
}
Пример #4
0
bool IconDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
{

    QRect rect = option.rect;
    QRect pixmapRect(rect.left() + rect.width()/2 - x,
                 rect.top() + rect.height()/2 - y,
                 2*x, 2*y);

    QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
    if (event->type() == QEvent::MouseButtonRelease && pixmapRect.contains(mouseEvent->pos()))
    {
        int row = index.row();
        int status = iconStatus.value(index);
        if (status == icon_normal){
            iconStatus.insert(index, icon_pressed);
            emit currentRow(row, true);
        }else if(status == icon_pressed){
            iconStatus.insert(index, icon_normal);
            emit currentRow(row, false);
        }

        if(_Play){
//            QString _path = paths.value(index);
//            qDebug() << "path : " << _path;
//            emit currentRow(_path);
        }

        return true;
    }
}
Пример #5
0
void IconDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
//    QString path = index.data().toString();
//    if(_Play)
//        (const_cast<IconDelegate *>(this))->paths.insert(index, path);

    ///显示元单元格内容
//    QStyleOptionViewItem  viewOption(option);
//    if (viewOption.state & QStyle::State_HasFocus)
//    {
//        viewOption.state = viewOption.state ^ QStyle::State_HasFocus;
//    }

//    QItemDelegate::paint(painter, viewOption, index);

    int status = -1;
    QPixmap image;
    status = iconStatus.value(index);
    if(status != icon_normal && status != icon_pressed){
        (const_cast<IconDelegate *>(this))->iconStatus.insert(index, icon_normal);
        image = _pixmap_normal;
    }

    if(status == icon_normal)
        image = _pixmap_normal;
    else if(status == icon_pressed){
        image = _pixmap_pressed;
    }

    QRect rect = option.rect;
    QRect pixmapRect(rect.left() + rect.width()/2 - x,
                 rect.top() + rect.height()/2 - y,
                 2*x, 2*y);
    painter->drawPixmap(pixmapRect, image);
}
Пример #6
0
void ImageView::paintEvent(QPaintEvent *event)
{
    //QItemSelectionModel *selections = selectionModel();
    QStyleOptionViewItem option = viewOptions();
    //QStyle::State state = option.state;
    //QBrush background = option.palette.base();
    QPen foreground(option.palette.color(QPalette::WindowText));
    //QBrush highlight(option.palette.color(QPalette::Highlight));

    //p.fillRect(event->rect(),background);

    if (!model())
        return;

    QPainter p(viewport());

    int n = model()->rowCount();

    p.translate(-horizontalOffset(),-verticalOffset());

    for (int i=0;i<n;i++)
    {
        QModelIndex index = model()->index(i,0);

        QRect rect = itemRect(index);
        p.setPen(foreground);
        //p.drawRect(rect);

        QVariant decoration = model()->data(index,Qt::DecorationRole);
        if (decoration.type() == QVariant::Pixmap)
        {
            QPixmap pixmap = qvariant_cast<QPixmap>(decoration);
            if (!pixmap.isNull())
            {
                QSize pixmapSize = pixmap.size();
                QSize itemSize = rect.size();
                pixmapSize.scale(itemSize,Qt::KeepAspectRatio);
                QSize rest = (itemSize - pixmapSize)/2;
                QRect pixmapRect(QPoint(rest.width(),rest.height()),pixmapSize);
                pixmapRect.translate(rect.topLeft());
                p.drawPixmap(pixmapRect,pixmap);
            }

        }

        if (index == currentIndex())
        {
            QColor color(option.palette.color(QPalette::Highlight));
            color.setAlpha(100);
            p.fillRect(rect,color);
        }

        //qDebug() << rect << foreground.color() << background.color();
        //p.drawText(rect,Qt::AlignCenter,QString::number(i));
    }

    event->accept();
}
Пример #7
0
void IconViewItemExt::paintItem(QPainter* p,const QColorGroup& cg)
{
  if(isSelected())
  {
    p->setBrush(cg.highlight());
    p->drawRect(textRect(false));
    p->setPen(QPen(cg.highlightedText()));
    p->setBackgroundColor(cg.highlight());
    p->setBackgroundMode(Qt::OpaqueMode);
    p->drawText(textRect(false),Qt::AlignHCenter|Qt::WordBreak,text());
    p->setPen(QPen(cg.dark(),4));
    p->drawRect(pixmapRect(false));
    p->drawPixmap(pixmapRect(false).x(),pixmapRect(false).y(),*pixmap());
  }
  else
  {
    QIconViewItem::paintItem ( p,cg);
  }
}
Пример #8
0
void ImageDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QPixmap pixmap(index.data().toString());
    QStyleOptionViewItem  viewOption(option);
    if (viewOption.state & QStyle::State_HasFocus)
    {
        viewOption.state = viewOption.state ^ QStyle::State_HasFocus;
    }

//    QItemDelegate::paint(painter, viewOption, index);

    QRect rect = option.rect;
    QRect pixmapRect(rect.left() + rect.width()/2 - 33,
                 rect.top() + rect.height()/2 - 33,
                 66, 66);
    painter->drawPixmap(pixmapRect, pixmap);
}
Пример #9
0
bool CheckBoxDelegate::editorEvent(QEvent *event, QAbstractItemModel *, const QStyleOptionViewItem &option, const QModelIndex &index)
{
    QRect rect = option.rect;
    QRect pixmapRect(rect.left() + rect.width()*1/4 - 8,
                 rect.top() + rect.height()/2 - 8,
                 16, 16);

    QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
    if (event->type() == QEvent::MouseButtonRelease && pixmapRect.contains(mouseEvent->pos()))
    {
        int status = checkBoxStatus.value(index);
        if (status == checkBox_normal)
            checkBoxStatus.insert(index, checkBox_select);
        else if(status == checkBox_select)
            checkBoxStatus.insert(index, checkBox_normal);
    }

    return true;
}
Пример #10
0
void XProcessTablePrivate::drawIcon(QPainter *painter, qreal initX, qreal initY, XProcessItem *item)
{
    qreal iconX = initX + XPT::Constant::ExtraSpace;
    qreal iconY = initY + XPT::Constant::RowHeight/2 - XPT::Constant::IconSize.height()/2;

    if(item->hasChild())
    {
        iconX += XPT::Constant::ExpandBoxSize.width();
    }
    else
    {
        iconX + XPT::Constant::BoxExtraSpace;
    }

    QPointF topLeft(iconX + XPT::Constant::IconExtraSpace,initY + XPT::Constant::IconExtraSpace);
    QPointF bottomRight(iconX + XPT::Constant::IconSize.width() - XPT::Constant::IconExtraSpace,initY + XPT::Constant::IconSize.height() - XPT::Constant::IconExtraSpace);
    QRect pixmapRect(topLeft.toPoint(),bottomRight.toPoint());
    painter->drawPixmap(pixmapRect,item->icon().pixmap(pixmapRect.size()));
}
Пример #11
0
void CheckBoxDelegate::paint(QPainter *painter,
                             const QStyleOptionViewItem &option,
                             const QModelIndex &index) const
{
    QStyleOptionViewItem  viewOption(option);
    if (viewOption.state & QStyle::State_HasFocus)
    {
        viewOption.state = viewOption.state ^ QStyle::State_HasFocus;
    }

    QItemDelegate::paint(painter, viewOption, index);

    int status = -1;
    QPixmap image;
    status = checkBoxStatus.value(index);
    if(status != checkBox_normal
       && status != checkBox_select
       && status != checkBox_disabled){
        (const_cast<CheckBoxDelegate *>(this))->checkBoxStatus.insert(index, checkBox_normal);
        image = _pixmap_normal;
    }

    if(status == checkBox_normal)
        image = _pixmap_normal;
    else if(status == checkBox_select){
        image = _pixmap_select;
    }
    else if(status == checkBox_disabled)
        image = _pixmap_disabled;
    else
        return;

    painter->save();
    QRect rect = option.rect;
    QRect pixmapRect(rect.left() + rect.width()*1/4 - 8,
                 rect.top() + rect.height()/2 - 8,
                 16, 16);
    painter->drawPixmap(pixmapRect, image);
    painter->restore();
}
Пример #12
0
static void qt_plastique_draw_gradient(QPainter *painter, const QRect &rect, const QColor &gradientStart,
                                       const QColor &gradientStop)
{
    QString gradientName;
    gradientName.sprintf("%dx%d-%x-%x", rect.width(), rect.height(), gradientStart.rgba(), gradientStop.rgba());
    QPixmap cache;
    if (!UsePixmapCache || !QPixmapCache::find(gradientName, cache)) {
        cache = QPixmap(rect.size());
        cache.fill(Qt::white);
        QPainter cachePainter(&cache);
        QRect pixmapRect(0, 0, rect.width(), rect.height());
        int x = pixmapRect.center().x();
        QLinearGradient gradient(x, pixmapRect.top(), x, pixmapRect.bottom());
        gradient.setColorAt(0, gradientStart);
        gradient.setColorAt(1, gradientStop);
        cachePainter.fillRect(pixmapRect, gradient);
        cachePainter.end();
        if (UsePixmapCache)
            QPixmapCache::insert(gradientName, cache);
    }
    painter->drawPixmap(rect, cache);
}
Пример #13
0
void QLabelPrivate::_q_movieUpdated(const QRect& rect)
{
    Q_Q(QLabel);
    if (movie && movie->isValid()) {
        QRect r;
        if (scaledcontents) {
            QRect cr = q->contentsRect();
            QRect pixmapRect(cr.topLeft(), movie->currentPixmap().size());
            if (pixmapRect.isEmpty())
                return;
            r.setRect(cr.left(), cr.top(),
                      (rect.width() * cr.width()) / pixmapRect.width(),
                      (rect.height() * cr.height()) / pixmapRect.height());
        } else {
            r = q->style()->itemPixmapRect(q->contentsRect(), align, movie->currentPixmap());
            r.translate(rect.x(), rect.y());
            r.setWidth(qMin(r.width(), rect.width()));
            r.setHeight(qMin(r.height(), rect.height()));
        }
        q->update(r);
    }
}
Пример #14
0
QPixmap DItemDelegate::makeDragPixmap(const QStyleOptionViewItem& option,
                                      const QList<QModelIndex>& indexes,
                                      const QPixmap& suggestedPixmap)
{
    QPixmap icon = suggestedPixmap;

    if (icon.isNull())
    {
        icon = QPixmap(DesktopIcon("image-jp2", KIconLoader::SizeMedium));
    }

    if (qMax(icon.width(), icon.height()) > KIconLoader::SizeHuge)
    {
        icon = icon.scaled(KIconLoader::SizeHuge, KIconLoader::SizeHuge,
                           Qt::KeepAspectRatio, Qt::SmoothTransformation);
    }

    int w                 = icon.width();
    int h                 = icon.height();
    const int borderWidth = 6;

    QRect   rect(0, 0, w + borderWidth*2, h + borderWidth*2);
    QRect   pixmapRect(borderWidth, borderWidth, w, h);

    QPixmap pix(rect.size());
    QPainter p(&pix);

/* 
    // border
    p.fillRect(0, 0, pix.width()-1, pix.height()-1, QColor(Qt::white));
    p.setPen(QPen(Qt::black, 1));
    p.drawRect(0, 0, pix.width()-1, pix.height()-1);
*/

    QStyleOption opt(option);
    opt.rect = rect;
    qApp->style()->drawPrimitive(QStyle::PE_PanelTipLabel, &opt, &p);

    p.drawPixmap(pixmapRect.topLeft(), icon);

    QFont f(option.font);
    f.setBold(true);
    p.setFont(f);

    if (indexes.size() > 1)
    {
        QRect   textRect;
        QString text;

        QString text2(i18np("1 Image", "%1 Images", indexes.count()));
        QString text1 = QString::number(indexes.count());
        QRect r1      = p.boundingRect(pixmapRect, Qt::AlignLeft|Qt::AlignTop, text1).adjusted(0,0,1,1);
        QRect r2      = p.boundingRect(pixmapRect, Qt::AlignLeft|Qt::AlignTop, text2).adjusted(0,0,1,1);

        if (r2.width() > pixmapRect.width() || r2.height() > pixmapRect.height())
        {
//            textRect     = r1;
            text         = text1;
            int rectSize = qMax(r1.width(), r1.height());
            textRect     = QRect(0, 0, rectSize, rectSize);
        }
        else
        {
            textRect = QRect(0, 0, r2.width(), r2.height());
            text     = text2;
        }

        textRect.moveLeft((pixmapRect.width() - textRect.width()) / 2 + pixmapRect.x());
        textRect.moveTop((pixmapRect.height() - textRect.height()) * 4 / 5);
        p.fillRect(textRect, QColor(0, 0, 0, 128));
        p.setPen(Qt::white);
        p.drawText(textRect, Qt::AlignCenter, text);
    }

    return pix;
}
Пример #15
0
void
GetNewStuffDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const
{
    QStyleOptionViewItemV4 opt = option;
    initStyleOption( &opt, index );

    QApplication::style()->drawPrimitive( QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget );

    painter->setRenderHint( QPainter::Antialiasing );

    QFont titleFont = opt.font;
    titleFont.setBold( true );
    titleFont.setPointSize( titleFont.pointSize() + 2 );
    QFontMetrics titleMetrics( titleFont );

    QFont authorFont = opt.font;
    authorFont.setItalic( true );
    authorFont.setPointSize( authorFont.pointSize() - 1 );
    QFontMetrics authorMetrics( authorFont );

    QFont descFont = authorFont;
    descFont.setItalic( false );
    QFontMetrics descMetrics( descFont );

    QFont installFont = opt.font;
    installFont.setPointSize( installFont.pointSize() - 1 );
    QFontMetrics installMetrics( descFont );

    const int height = opt.rect.height();
    const int center = height / 2 + opt.rect.top();

    // Pixmap
    QPixmap p = index.data( Qt::DecorationRole ).value< QPixmap >();
    const int pixmapWidth = height - 2*PADDING;
    QRect pixmapRect( PADDING, PADDING + opt.rect.top(), pixmapWidth, pixmapWidth );
    if ( p.isNull() ) // default image... TODO
        p = m_defaultCover;
    else
        p = p.scaled( pixmapRect.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation );

    painter->drawPixmap( pixmapRect, p );

    // Go from right edge now, stars, install button, and downloaded info

    // install / status button
    AtticaManager::ResolverState state = static_cast< AtticaManager::ResolverState >( index.data( GetNewStuffModel::StateRole ).toInt() );
    QString actionText;
    switch( state )
    {
        case AtticaManager::Uninstalled:
            actionText = tr( "Install" );
            break;
        case AtticaManager::Installing:
            actionText = tr( "Installing" );
            break;
        case AtticaManager::Upgrading:
            actionText = tr( "Upgrading" );
            break;
        case AtticaManager::Failed:
            actionText = tr( "Failed" );
            break;
        case AtticaManager::Installed:
            actionText = tr( "Uninstall" );
            break;
        case AtticaManager::NeedsUpgrade:
            actionText = tr( "Upgrade" );
            break;
    }

    const int btnWidth = m_widestTextWidth + 7;
    const int leftEdge = opt.rect.width() - PADDING - btnWidth - 3;
    const QRect btnRect( leftEdge, center - ( installMetrics.height() + 4 ) / 2, btnWidth, installMetrics.height() + 4 );
    m_cachedButtonRects[ QPair<int, int>(index.row(), index.column()) ] = btnRect;

    QPen saved = painter->pen();
    painter->setPen( opt.palette.color( QPalette::Active, QPalette::AlternateBase ) );

    QPainterPath btnPath;
    const int radius = 3;
    //btnPath.addRoundedRect( btnRect, 3, 3 );
    // draw top half gradient
    const int btnCenter = btnRect.bottom() - ( btnRect.height() / 2 );
    btnPath.moveTo( btnRect.left(), btnCenter );
    btnPath.lineTo( btnRect.left(), btnRect.top() + radius );
    btnPath.quadTo( QPoint( btnRect.topLeft() ), QPoint( btnRect.left() + radius, btnRect.top() ) );
    btnPath.lineTo( btnRect.right() - radius, btnRect.top() );
    btnPath.quadTo( QPoint( btnRect.topRight() ), QPoint( btnRect.right(), btnRect.top() + radius ) );
    btnPath.lineTo( btnRect.right(),btnCenter );
    btnPath.lineTo( btnRect.left(), btnCenter );

    QLinearGradient g;
    g.setColorAt( 0, QColor(54, 127, 211) );
    g.setColorAt( 0.5, QColor(43, 104, 182) );
    //painter->setPen( bg.darker() );
    painter->fillPath( btnPath, g );
    //painter->drawPath( btnPath );

    btnPath = QPainterPath();
    btnPath.moveTo( btnRect.left(), btnCenter );
    btnPath.lineTo( btnRect.left(), btnRect.bottom() - radius );
    btnPath.quadTo( QPoint( btnRect.bottomLeft() ), QPoint( btnRect.left() + radius, btnRect.bottom() ) );
    btnPath.lineTo( btnRect.right() - radius, btnRect.bottom() );
    btnPath.quadTo( QPoint( btnRect.bottomRight() ), QPoint( btnRect.right(), btnRect.bottom() - radius ) );
    btnPath.lineTo( btnRect.right(), btnCenter );
    btnPath.lineTo( btnRect.left(), btnCenter );

    g.setColorAt( 0, QColor(34, 85, 159) );
    g.setColorAt( 0.5, QColor(35, 79, 147) );
    painter->fillPath( btnPath, g );

    painter->setFont( installFont );
    painter->drawText( btnRect, Qt::AlignCenter, actionText );

    painter->setPen( saved );

    // rating stars
    int rating = index.data( GetNewStuffModel::RatingRole ).toInt();
    const int ratingWidth = 5 * ( m_ratingStarPositive.width() + PADDING_BETWEEN_STARS );
    int runningEdge = ( btnRect.right() - btnRect.width() / 2 ) - ratingWidth / 2;
    for ( int i = 1; i < 6; i++ )
    {
        QRect r( runningEdge, btnRect.top() - m_ratingStarPositive.height() - PADDING, m_ratingStarPositive.width(), m_ratingStarPositive.height() );
        if ( i == 1 )
            m_cachedStarRects[ QPair<int, int>(index.row(), index.column()) ] = r;

        const bool userHasRated = index.data( GetNewStuffModel::UserHasRatedRole ).toBool();
        if ( !userHasRated && // Show on-hover animation if the user hasn't rated it yet, and is hovering over it
             m_hoveringOver > -1 &&
             m_hoveringItem == index )
        {
            if ( i <= m_hoveringOver ) // positive star
                painter->drawPixmap( r, m_onHoverStar );
            else
                painter->drawPixmap( r, m_ratingStarNegative );
        }
        else
        {
            if ( i <= rating ) // positive or rated star
            {
                if ( userHasRated )
                    painter->drawPixmap( r, m_onHoverStar );
                else
                    painter->drawPixmap( r, m_ratingStarPositive );
            }
            else
                painter->drawPixmap( r, m_ratingStarNegative );
        }
        runningEdge += m_ratingStarPositive.width() + PADDING_BETWEEN_STARS;
    }

    // downloaded num times, underneath button
    QString count = tr( "%1 downloads" ).arg( index.data( GetNewStuffModel::DownloadCounterRole ).toInt() );
    const QRect countRect( btnRect.left(), btnRect.bottom() + PADDING, btnRect.width(), opt.rect.bottom() - PADDING - btnRect.bottom() );
    QFont countFont = descFont;
    countFont.setPointSize( countFont.pointSize() - 2 );
    countFont.setBold( true );
    painter->setFont( countFont );
    painter->drawText( countRect, Qt::AlignCenter | Qt::TextWordWrap, count );

    // author and version
    QString author = index.data( GetNewStuffModel::AuthorRole ).toString();
    const int authorWidth = authorMetrics.width( author );
    const int topTextLine = opt.rect.top() + PADDING;
    const QRect authorRect( btnRect.x() - 3*PADDING - authorWidth, topTextLine, authorWidth + 6, authorMetrics.height() );
    painter->setFont( authorFont );
    painter->drawText( authorRect, Qt::AlignCenter, author );

    const QRect versionRect = authorRect.translated( 0, authorRect.height() );
    QString version = index.data( GetNewStuffModel::VersionRole ).toString();
    painter->drawText( versionRect, Qt::AlignCenter, version );

    // title
    QString title = index.data( Qt::DisplayRole ).toString();
    const int rightTitleEdge = authorRect.left() - PADDING;
    const int leftTitleEdge = pixmapRect.right() + PADDING;
    const QRect textRect( leftTitleEdge, topTextLine, rightTitleEdge - leftTitleEdge, versionRect.bottom() - opt.rect.top() - PADDING );
    painter->setFont( titleFont );
    painter->drawText( textRect, Qt::AlignVCenter | Qt::AlignLeft, title );

    // description
    QString desc = index.data( GetNewStuffModel::DescriptionRole ).toString();
    const int descWidth = btnRect.left() - leftTitleEdge - PADDING;
    const QRect descRect( leftTitleEdge, versionRect.bottom(), descWidth, opt.rect.bottom() - versionRect.bottom() + PADDING );
    painter->setFont( descFont );
    painter->drawText( descRect, Qt::AlignLeft | Qt::TextWordWrap, desc );
}