void TrackView::onCustomContextMenu( const QPoint& pos ) { m_contextMenu->clear(); QModelIndex idx = indexAt( pos ); idx = idx.sibling( idx.row(), 0 ); setContextMenuIndex( idx ); if ( !idx.isValid() ) return; if ( model() && !model()->isReadOnly() ) m_contextMenu->setSupportedActions( m_contextMenu->supportedActions() | ContextMenu::ActionDelete ); QList<query_ptr> queries; foreach ( const QModelIndex& index, selectedIndexes() ) { if ( index.column() ) continue; TrackModelItem* item = proxyModel()->itemFromIndex( proxyModel()->mapToSource( index ) ); if ( item && !item->query().isNull() ) queries << item->query(); } m_contextMenu->setQueries( queries ); m_contextMenu->exec( mapToGlobal( pos ) ); }
Tomahawk::result_ptr TrackProxyModel::currentItem() const { TrackModelItem* item = itemFromIndex( mapToSource( currentIndex() ) ); if ( item && !item->query().isNull() && item->query()->playable() ) return item->query()->results().at( 0 ); return Tomahawk::result_ptr(); }
Tomahawk::result_ptr TrackProxyModelPlaylistInterface::currentItem() const { if ( m_proxyModel.isNull() ) return Tomahawk::result_ptr(); TrackProxyModel* proxyModel = m_proxyModel.data(); TrackModelItem* item = proxyModel->itemFromIndex( proxyModel->mapToSource( proxyModel->currentIndex() ) ); if ( item && !item->query().isNull() && item->query()->playable() ) return item->query()->results().at( 0 ); return Tomahawk::result_ptr(); }
void TrackView::startAutoPlay( const QModelIndex& index ) { if ( tryToPlayItem( index ) ) return; // item isn't playable but still resolving TrackModelItem* item = m_model->itemFromIndex( m_proxyModel->mapToSource( index ) ); if ( item && !item->query().isNull() && !item->query()->resolvingFinished() ) { m_autoPlaying = item->query(); // So we can kill it if user starts autoplaying this playlist again NewClosure( item->query().data(), SIGNAL( resolvingFinished( bool ) ), this, SLOT( autoPlayResolveFinished( Tomahawk::query_ptr, int ) ), item->query(), index.row() ); return; }
QMimeData* TrackModel::mimeData( const QModelIndexList &indexes ) const { qDebug() << Q_FUNC_INFO; QByteArray queryData; QDataStream queryStream( &queryData, QIODevice::WriteOnly ); foreach ( const QModelIndex& i, indexes ) { if ( i.column() > 0 ) continue; QModelIndex idx = index( i.row(), 0, i.parent() ); TrackModelItem* item = itemFromIndex( idx ); if ( item ) { const query_ptr& query = item->query(); queryStream << qlonglong( &query ); } } QMimeData* mimeData = new QMimeData(); mimeData->setData( "application/tomahawk.query.list", queryData ); return mimeData; }
void TrackView::onItemActivated( const QModelIndex& index ) { if ( !index.isValid() ) return; TrackModelItem* item = m_model->itemFromIndex( m_proxyModel->mapToSource( index ) ); if ( item && !item->query().isNull() && item->query()->numResults() ) { tDebug() << "Result activated:" << item->query()->toString() << item->query()->results().first()->url(); m_proxyModel->setCurrentIndex( index ); AudioEngine::instance()->playItem( m_proxyModel->getPlaylistInterface(), item->query()->results().first() ); } emit itemActivated( index ); }
QVariant CollectionModel::data( const QModelIndex& index, int role ) const { if ( role != Qt::DisplayRole ) return QVariant(); TrackModelItem* entry = itemFromIndex( index ); if ( !entry ) return QVariant(); const query_ptr& query = entry->query(); if ( query.isNull() ) { if ( !index.column() ) { return entry->caption.isEmpty() ? "Unknown" : entry->caption; } if ( index.column() == 1 ) { return entry->childCount; } return QVariant( "" ); } if ( !query->numResults() ) { switch( index.column() ) { case 0: return query->track(); break; } } else { switch( index.column() ) { case 0: return query->results().first()->track(); break; case 1: return QVariant(); break; case 2: return TomahawkUtils::timeToString( query->results().first()->duration() ); break; case 3: return query->results().first()->collection()->source()->friendlyName(); break; } } return QVariant(); }
void WelcomeWidget::onPlaybackFinished( const Tomahawk::query_ptr& query ) { int count = m_tracksModel->trackCount(); unsigned int playtime = query->playedBy().second; if ( count ) { TrackModelItem* oldestItem = m_tracksModel->itemFromIndex( m_tracksModel->index( count - 1, 0, QModelIndex() ) ); if ( oldestItem->query()->playedBy().second >= playtime ) return; TrackModelItem* youngestItem = m_tracksModel->itemFromIndex( m_tracksModel->index( 0, 0, QModelIndex() ) ); if ( youngestItem->query()->playedBy().second <= playtime ) m_tracksModel->insert( query, 0 ); else { for ( int i = 0; i < count - 1; i++ ) { TrackModelItem* item1 = m_tracksModel->itemFromIndex( m_tracksModel->index( i, 0, QModelIndex() ) ); TrackModelItem* item2 = m_tracksModel->itemFromIndex( m_tracksModel->index( i + 1, 0, QModelIndex() ) ); if ( item1->query()->playedBy().second >= playtime && item2->query()->playedBy().second <= playtime ) { m_tracksModel->insert( query, i + 1 ); break; } } } } else m_tracksModel->insert( query, 0 ); if ( m_tracksModel->trackCount() > HISTORY_TRACK_ITEMS ) m_tracksModel->remove( HISTORY_TRACK_ITEMS ); if ( m_timer->isActive() ) m_timer->stop(); m_timer->start( HISTORY_RESOLVING_TIMEOUT ); }
void TrackModel::setCurrentItem( const QModelIndex& index ) { TrackModelItem* oldEntry = itemFromIndex( m_currentIndex ); if ( oldEntry ) { oldEntry->setIsPlaying( false ); } TrackModelItem* entry = itemFromIndex( index ); if ( index.isValid() && entry && !entry->query().isNull() ) { m_currentIndex = index; m_currentUuid = entry->query()->id(); entry->setIsPlaying( true ); } else { m_currentIndex = QModelIndex(); m_currentUuid = QString(); } }
void RecentlyPlayedModel::onPlaybackFinished( const Tomahawk::query_ptr& query ) { int count = trackCount(); unsigned int playtime = query->playedBy().second; if ( count ) { TrackModelItem* oldestItem = itemFromIndex( index( count - 1, 0, QModelIndex() ) ); if ( oldestItem->query()->playedBy().second >= playtime ) return; TrackModelItem* youngestItem = itemFromIndex( index( 0, 0, QModelIndex() ) ); if ( youngestItem->query()->playedBy().second <= playtime ) insert( query, 0 ); else { for ( int i = 0; i < count - 1; i++ ) { TrackModelItem* item1 = itemFromIndex( index( i, 0, QModelIndex() ) ); TrackModelItem* item2 = itemFromIndex( index( i + 1, 0, QModelIndex() ) ); if ( item1->query()->playedBy().second >= playtime && item2->query()->playedBy().second <= playtime ) { insert( query, i + 1 ); break; } } } } else insert( query, 0 ); if ( trackCount() > (int)m_limit ) remove( m_limit ); ensureResolved(); }
QList< Tomahawk::query_ptr > TrackProxyModel::tracks() { QList<Tomahawk::query_ptr> queries; for ( int i = 0; i < rowCount( QModelIndex() ); i++ ) { TrackModelItem* item = itemFromIndex( mapToSource( index( i, 0 ) ) ); if ( item ) queries << item->query(); } return queries; }
void TrackView::currentChanged( const QModelIndex& current, const QModelIndex& previous ) { QTreeView::currentChanged( current, previous ); if ( !m_updateContextView ) return; TrackModelItem* item = m_model->itemFromIndex( m_proxyModel->mapToSource( current ) ); if ( item ) { ViewManager::instance()->context()->setQuery( item->query() ); } }
QList< Tomahawk::query_ptr > TrackProxyModelPlaylistInterface::tracks() { if ( m_proxyModel.isNull() ) return QList< Tomahawk::query_ptr >(); TrackProxyModel* proxyModel = m_proxyModel.data(); QList<Tomahawk::query_ptr> queries; for ( int i = 0; i < proxyModel->rowCount( QModelIndex() ); i++ ) { TrackModelItem* item = proxyModel->itemFromIndex( proxyModel->mapToSource( proxyModel->index( i, 0 ) ) ); if ( item ) queries << item->query(); } return queries; }
void TrackView::mousePressEvent( QMouseEvent* event ) { QTreeView::mousePressEvent( event ); if ( !m_model || m_model->style() != TrackModel::Detailed ) return; QModelIndex idx = indexAt( event->pos() ); if ( event->pos().x() > header()->sectionViewportPosition( idx.column() ) + header()->sectionSize( idx.column() ) - 16 && event->pos().x() < header()->sectionViewportPosition( idx.column() ) + header()->sectionSize( idx.column() ) ) { TrackModelItem* item = proxyModel()->itemFromIndex( proxyModel()->mapToSource( idx ) ); switch ( idx.column() ) { case TrackModel::Artist: { if ( item->query()->results().count() ) { ViewManager::instance()->show( item->query()->results().first()->artist() ); } else { ViewManager::instance()->show( Artist::get( item->query()->artist() ) ); } break; } case TrackModel::Album: { if ( item->query()->results().count() ) { ViewManager::instance()->show( item->query()->results().first()->album() ); } else { artist_ptr artist = Artist::get( item->query()->artist() ); ViewManager::instance()->show( Album::get( artist, item->query()->album() ) ); } break; } default: break; } } }
bool TrackProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex& sourceParent ) const { TrackModelItem* pi = itemFromIndex( sourceModel()->index( sourceRow, 0, sourceParent ) ); if ( !pi ) return false; const Tomahawk::query_ptr& q = pi->query(); if( q.isNull() ) // uh oh? filter out invalid queries i guess return false; Tomahawk::result_ptr r; if ( q->numResults() ) r = q->results().first(); if ( !m_showOfflineResults && !r.isNull() && !r->collection()->source()->isOnline() ) return false; if ( filterRegExp().isEmpty() ) return true; QStringList sl = filterRegExp().pattern().split( " ", QString::SkipEmptyParts ); foreach( QString s, sl ) { s = s.toLower(); if ( !r.isNull() ) { if ( !r->artist()->name().toLower().contains( s ) && !r->album()->name().toLower().contains( s ) && !r->track().toLower().contains( s ) ) { return false; } } else { if ( !q->artist().toLower().contains( s ) && !q->album().toLower().contains( s ) && !q->track().toLower().contains( s ) ) { return false; } } }
void PlaylistItemDelegate::paintShort( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index, bool useAvatars ) const { TrackModelItem* item = m_model->itemFromIndex( m_model->mapToSource( index ) ); Q_ASSERT( item ); QStyleOptionViewItemV4 opt = option; prepareStyleOption( &opt, index, item ); opt.text.clear(); qApp->style()->drawControl( QStyle::CE_ItemViewItem, &opt, painter ); if ( m_view->header()->visualIndex( index.column() ) > 0 ) return; QPixmap pixmap; QString artist, track, upperText, lowerText; source_ptr source = item->query()->playedBy().first; if ( item->query()->results().count() ) { artist = item->query()->results().first()->artist()->name(); track = item->query()->results().first()->track(); } else { artist = item->query()->artist(); track = item->query()->track(); } if ( source.isNull() ) { upperText = artist; lowerText = track; } else { upperText = QString( "%1 - %2" ).arg( artist ).arg( track ); QString playtime = TomahawkUtils::ageToString( QDateTime::fromTime_t( item->query()->playedBy().second ) ); if ( source == SourceList::instance()->getLocal() ) lowerText = QString( "played %1 ago by you" ).arg( playtime ); else lowerText = QString( "played %1 ago by %2" ).arg( playtime ).arg( source->friendlyName() ); if ( useAvatars ) pixmap = source->avatar( Source::FancyStyle ); } if ( pixmap.isNull() && !useAvatars ) pixmap = QPixmap( RESPATH "images/track-placeholder.png" ); else if ( pixmap.isNull() && useAvatars ) pixmap = m_defaultAvatar; painter->save(); { QRect r = opt.rect.adjusted( 3, 6, 0, -6 ); // Paint Now Playing Speaker Icon if ( item->isPlaying() ) { r.adjust( 0, 0, 0, 0 ); QRect npr = r.adjusted( 3, r.height() / 2 - m_nowPlayingIcon.height() / 2, 18 - r.width(), -r.height() / 2 + m_nowPlayingIcon.height() / 2 ); painter->drawPixmap( npr, m_nowPlayingIcon ); r.adjust( 22, 0, 0, 0 ); } painter->setPen( opt.palette.text().color() ); QRect ir = r.adjusted( 4, 0, -option.rect.width() + option.rect.height() - 8 + r.left(), 0 ); QPixmap scover; if ( m_cache.contains( pixmap.cacheKey() ) ) { scover = m_cache.value( pixmap.cacheKey() ); } else { scover = pixmap.scaled( ir.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation ); m_cache.insert( pixmap.cacheKey(), scover ); } painter->drawPixmap( ir, scover ); QFont boldFont = opt.font; boldFont.setBold( true ); r.adjust( ir.width() + 12, 0, -12, 0 ); painter->setFont( boldFont ); QString text = painter->fontMetrics().elidedText( upperText, Qt::ElideRight, r.width() ); painter->drawText( r.adjusted( 0, 1, 0, 0 ), text, m_topOption ); painter->setFont( opt.font); text = painter->fontMetrics().elidedText( lowerText, Qt::ElideRight, r.width() ); painter->drawText( r.adjusted( 0, 1, 0, 0 ), text, m_bottomOption ); } painter->restore(); }
void PlaylistChartItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const { TrackModelItem* item = m_model->itemFromIndex( m_model->mapToSource( index ) ); Q_ASSERT( item ); QStyleOptionViewItemV4 opt = option; prepareStyleOption( &opt, index, item ); opt.text.clear(); qApp->style()->drawControl( QStyle::CE_ItemViewItem, &opt, painter ); if ( m_view->header()->visualIndex( index.column() ) > 0 ) return; QPixmap pixmap, avatar; QString artist, track, upperText, lowerText; unsigned int duration = 0; if ( item->query()->results().count() ) { artist = item->query()->results().first()->artist()->name(); track = item->query()->results().first()->track(); duration = item->query()->results().first()->duration(); } else { artist = item->query()->artist(); track = item->query()->track(); } painter->save(); { QRect r = opt.rect.adjusted( 3, 6, 0, -6 ); // Paint Now Playing Speaker Icon if ( item->isPlaying() ) { QPixmap nowPlayingIcon = TomahawkUtils::defaultPixmap( TomahawkUtils::NowPlayingSpeaker ); QRect npr = r.adjusted( 3, r.height() / 2 - nowPlayingIcon.height() / 2, 18 - r.width(), -r.height() / 2 + nowPlayingIcon.height() / 2 ); nowPlayingIcon = TomahawkUtils::defaultPixmap( TomahawkUtils::NowPlayingSpeaker, TomahawkUtils::Original, npr.size() ); painter->drawPixmap( npr, nowPlayingIcon ); r.adjust( 22, 0, 0, 0 ); } QFont figureFont = opt.font; figureFont.setPixelSize( 18 ); figureFont.setWeight( 99 ); QFont boldFont = opt.font; boldFont.setPixelSize( 15 ); boldFont.setWeight( 99 ); QFont smallBoldFont = opt.font; smallBoldFont.setPixelSize( 12 ); smallBoldFont.setWeight( 80 ); QFont durationFont = opt.font; durationFont.setPixelSize( 12 ); durationFont.setWeight( 80 ); if ( index.row() == 0 ) { figureFont.setPixelSize( 36 ); boldFont.setPixelSize( 26 ); smallBoldFont.setPixelSize( 22 ); } else if ( index.row() == 1 ) { figureFont.setPixelSize( 30 ); boldFont.setPixelSize( 22 ); smallBoldFont.setPixelSize( 18 ); } else if ( index.row() == 2 ) { figureFont.setPixelSize( 24 ); boldFont.setPixelSize( 18 ); smallBoldFont.setPixelSize( 14 ); } else if ( index.row() >= 10 ) { boldFont.setPixelSize( 12 ); smallBoldFont.setPixelSize( 11 ); } QRect figureRect = r.adjusted( 0, 0, -option.rect.width() + 60 - 6 + r.left(), 0 ); painter->setFont( figureFont ); painter->setPen( option.palette.text().color().lighter( 450 ) ); painter->drawText( figureRect, QString::number( index.row() + 1 ), m_centerOption ); painter->setPen( opt.palette.text().color() ); QRect pixmapRect = r.adjusted( figureRect.width() + 6, 0, -option.rect.width() + figureRect.width() + option.rect.height() - 6 + r.left(), 0 ); pixmap = item->query()->cover( pixmapRect.size(), false ); if ( !pixmap ) { pixmap = TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultTrackImage, TomahawkUtils::ScaledCover, pixmapRect.size() ); } painter->drawPixmap( pixmapRect, pixmap ); r.adjust( pixmapRect.width() + figureRect.width() + 18, 1, -28, 0 ); QRect leftRect = r.adjusted( 0, 0, -48, 0 ); QRect rightRect = r.adjusted( r.width() - 40, 0, 0, 0 ); painter->setFont( boldFont ); QString text = painter->fontMetrics().elidedText( artist, Qt::ElideRight, leftRect.width() ); painter->drawText( leftRect, text, m_topOption ); painter->setFont( smallBoldFont ); text = painter->fontMetrics().elidedText( track, Qt::ElideRight, leftRect.width() ); painter->drawText( index.row() >= 10 ? leftRect : leftRect.adjusted( 0, painter->fontMetrics().height() + 6, 0, 0 ), text, index.row() >= 10 ? m_bottomOption : m_topOption ); if ( duration > 0 ) { painter->setFont( durationFont ); text = painter->fontMetrics().elidedText( TomahawkUtils::timeToString( duration ), Qt::ElideRight, rightRect.width() ); painter->drawText( rightRect, text, m_centerRightOption ); } } painter->restore(); }
QVariant TrackModel::data( const QModelIndex& index, int role ) const { TrackModelItem* entry = itemFromIndex( index ); if ( !entry ) return QVariant(); if ( role == Qt::DecorationRole ) { return QVariant(); } if ( role == Qt::SizeHintRole ) { return QSize( 0, 18 ); } if ( role == StyleRole ) { return m_style; } if ( role != Qt::DisplayRole ) // && role != Qt::ToolTipRole ) return QVariant(); const query_ptr& query = entry->query(); if ( !query->numResults() ) { switch( index.column() ) { case Artist: return query->artist(); break; case Track: return query->track(); break; case Album: return query->album(); break; } } else { switch( index.column() ) { case Artist: return query->results().first()->artist()->name(); break; case Track: return query->results().first()->track(); break; case Album: return query->results().first()->album()->name(); break; case Duration: return TomahawkUtils::timeToString( query->results().first()->duration() ); break; case Bitrate: if ( query->results().first()->bitrate() == 0 ) return QString(); else return query->results().first()->bitrate(); break; case Age: return TomahawkUtils::ageToString( QDateTime::fromTime_t( query->results().first()->modificationTime() ) ); break; case Year: if ( query->results().first()->year() == 0 ) return QString(); else return query->results().first()->year(); break; case Filesize: return TomahawkUtils::filesizeToString( query->results().first()->size() ); break; case Origin: return query->results().first()->friendlySource(); break; case Score: return query->results().first()->score(); break; case AlbumPos: if ( query->results().first()->albumpos() == 0 ) return QString(); return QString::number( query->results().first()->albumpos() ); break; } } return QVariant(); }
QVariant TrackModel::data( const QModelIndex& index, int role ) const { TrackModelItem* entry = itemFromIndex( index ); if ( !entry ) return QVariant(); if ( role == Qt::DecorationRole ) { return QVariant(); } if ( role == Qt::SizeHintRole ) { return QSize( 0, 18 ); } if ( role != Qt::DisplayRole ) // && role != Qt::ToolTipRole ) return QVariant(); const query_ptr& query = entry->query(); if ( query.isNull() ) { if ( !index.column() ) { return entry->caption.isEmpty() ? "Unknown" : entry->caption; } if ( index.column() == 1 ) { return entry->childCount; } return QVariant( "" ); } if ( !query->numResults() ) { switch( index.column() ) { case Artist: return query->artist(); break; case Track: return query->track(); break; case Album: return query->album(); break; } } else { switch( index.column() ) { case Artist: return query->results().first()->artist()->name(); break; case Track: return query->results().first()->track(); break; case Album: return query->results().first()->album()->name(); break; case Duration: return TomahawkUtils::timeToString( query->results().first()->duration() ); break; case Bitrate: return query->results().first()->bitrate(); break; case Age: return TomahawkUtils::ageToString( QDateTime::fromTime_t( query->results().first()->modificationTime() ) ); break; case Year: return query->results().first()->year(); break; case Filesize: return TomahawkUtils::filesizeToString( query->results().first()->size() ); break; case Origin: return query->results().first()->friendlySource(); break; } } return QVariant(); }
Tomahawk::result_ptr TrackProxyModel::siblingItem( int itemsAway ) { qDebug() << Q_FUNC_INFO; QModelIndex idx = index( 0, 0 ); if( rowCount() ) { if ( m_shuffled ) { // random mode is enabled // TODO come up with a clever random logic, that keeps track of previously played items idx = index( qrand() % rowCount(), 0 ); } else if ( currentItem().isValid() ) { idx = currentItem(); // random mode is disabled if ( m_repeatMode == PlaylistInterface::RepeatOne ) { // repeat one track idx = index( idx.row(), 0 ); } else { // keep progressing through the playlist normally idx = index( idx.row() + itemsAway, 0 ); } } } if ( !idx.isValid() && m_repeatMode == PlaylistInterface::RepeatAll ) { // repeat all tracks if ( itemsAway > 0 ) { // reset to first item idx = index( 0, 0 ); } else { // reset to last item idx = index( rowCount() - 1, 0 ); } } // Try to find the next available PlaylistItem (with results) if ( idx.isValid() ) do { TrackModelItem* item = itemFromIndex( mapToSource( idx ) ); qDebug() << item->query()->toString(); if ( item && item->query()->playable() ) { qDebug() << "Next PlaylistItem found:" << item->query()->toString() << item->query()->results().at( 0 )->url(); setCurrentItem( idx ); return item->query()->results().at( 0 ); } idx = index( idx.row() + ( itemsAway > 0 ? 1 : -1 ), 0 ); } while ( idx.isValid() ); setCurrentItem( QModelIndex() ); return Tomahawk::result_ptr(); }
void PlaylistLargeItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const { TrackModelItem* item = m_model->itemFromIndex( m_model->mapToSource( index ) ); Q_ASSERT( item ); QStyleOptionViewItemV4 opt = option; prepareStyleOption( &opt, index, item ); opt.text.clear(); qApp->style()->drawControl( QStyle::CE_ItemViewItem, &opt, painter ); if ( m_view->header()->visualIndex( index.column() ) > 0 ) return; QPixmap pixmap, avatar; QString artist, track, lowerText; unsigned int duration = 0; if ( item->query()->results().count() ) { artist = item->query()->results().first()->artist()->name(); track = item->query()->results().first()->track(); duration = item->query()->results().first()->duration(); } else { artist = item->query()->artist(); track = item->query()->track(); } QSize avatarSize( 32, 32 ); source_ptr source = item->query()->playedBy().first; if ( m_mode == RecentlyPlayed && !source.isNull() ) { avatar = source->avatar( Source::FancyStyle, avatarSize ); QString playtime = TomahawkUtils::ageToString( QDateTime::fromTime_t( item->query()->playedBy().second ), true ); if ( source == SourceList::instance()->getLocal() ) lowerText = QString( tr( "played %1 by you" ) ).arg( playtime ); else lowerText = QString( tr( "played %1 by %2" ) ).arg( playtime ).arg( source->friendlyName() ); } if ( m_mode == LatestAdditions && item->query()->numResults() ) { QString playtime = TomahawkUtils::ageToString( QDateTime::fromTime_t( item->query()->results().first()->modificationTime() ), true ); lowerText = QString( tr( "added %1" ) ).arg( playtime ); } if ( m_mode == LovedTracks ) lowerText = item->query()->socialActionDescription( "Love", Query::Detailed ); painter->save(); { QRect r = opt.rect.adjusted( 3, 6, 0, -6 ); // Paint Now Playing Speaker Icon if ( item->isPlaying() ) { QPixmap nowPlayingIcon = TomahawkUtils::defaultPixmap( TomahawkUtils::NowPlayingSpeaker ); QRect npr = r.adjusted( 3, r.height() / 2 - nowPlayingIcon.height() / 2, 18 - r.width(), -r.height() / 2 + nowPlayingIcon.height() / 2 ); nowPlayingIcon = TomahawkUtils::defaultPixmap( TomahawkUtils::NowPlayingSpeaker, TomahawkUtils::Original, npr.size() ); painter->drawPixmap( npr, nowPlayingIcon ); r.adjust( 22, 0, 0, 0 ); } painter->setPen( opt.palette.text().color() ); QRect pixmapRect = r.adjusted( 6, 0, -option.rect.width() + option.rect.height() - 6 + r.left(), 0 ); QRect avatarRect = r.adjusted( option.rect.width() - r.left() - 12 - avatarSize.width(), ( option.rect.height() - avatarSize.height() ) / 2 - 5, 0, 0 ); avatarRect.setSize( avatarSize ); pixmap = item->query()->cover( pixmapRect.size(), false ); if ( !pixmap ) { pixmap = TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultTrackImage, TomahawkUtils::ScaledCover, pixmapRect.size() ); } painter->drawPixmap( pixmapRect, pixmap ); if ( !avatar.isNull() ) painter->drawPixmap( avatarRect, avatar ); QFont boldFont = opt.font; boldFont.setPixelSize( 15 ); boldFont.setWeight( 99 ); QFont smallBoldFont = opt.font; smallBoldFont.setPixelSize( 12 ); smallBoldFont.setBold( true ); smallBoldFont.setWeight( 60 ); QFont smallFont = opt.font; smallFont.setPixelSize( 10 ); r.adjust( pixmapRect.width() + 12, 1, -28 - avatar.width(), 0 ); QRect leftRect = r.adjusted( 0, 0, -48, 0 ); QRect rightRect = r.adjusted( r.width() - 40, 0, 0, 0 ); painter->setFont( boldFont ); QString text = painter->fontMetrics().elidedText( track, Qt::ElideRight, leftRect.width() ); painter->drawText( leftRect, text, m_topOption ); painter->setFont( smallBoldFont ); text = painter->fontMetrics().elidedText( artist, Qt::ElideRight, leftRect.width() ); painter->drawText( leftRect.adjusted( 0, 19, 0, 0 ), text, m_topOption ); painter->setFont( smallFont ); painter->setPen( Qt::gray ); QTextDocument textDoc; textDoc.setHtml( lowerText ); textDoc.setDocumentMargin( 0 ); textDoc.setDefaultFont( painter->font() ); textDoc.setDefaultTextOption( m_bottomOption ); if ( textDoc.idealWidth() > leftRect.width() ) textDoc.setHtml( item->query()->socialActionDescription( "Love", Query::Short ) ); drawRichText( painter, leftRect, Qt::AlignBottom, textDoc ); if ( duration > 0 ) { painter->setFont( smallBoldFont ); text = painter->fontMetrics().elidedText( TomahawkUtils::timeToString( duration ), Qt::ElideRight, rightRect.width() ); painter->drawText( rightRect, text, m_centerRightOption ); } } painter->restore(); }