void DynamicWidget::steeringChanged() { // When steering changes, toss all the tracks that are upcoming, and re-fetch. // We have to find the currently playing item QModelIndex playing; for ( int i = 0; i < m_view->proxyModel()->rowCount( QModelIndex() ); ++i ) { const QModelIndex cur = m_view->proxyModel()->index( i, 0, QModelIndex() ); TrackModelItem* item = m_view->proxyModel()->itemFromIndex( m_view->proxyModel()->mapToSource( cur ) ); if ( item && item->isPlaying() ) { playing = cur; break; } } if ( !playing.isValid() ) return; const int upcoming = m_view->proxyModel()->rowCount( QModelIndex() ) - 1 - playing.row(); tDebug() << "Removing tracks after current in station, found" << upcoming; QModelIndexList toRemove; for ( int i = playing.row() + 1; i < m_view->proxyModel()->rowCount( QModelIndex() ); i++ ) { toRemove << m_view->proxyModel()->index( i, 0, QModelIndex() ); } m_view->proxyModel()->remove( toRemove ); m_playlist->generator()->fetchNext(); }
void PlaylistItemDelegate::paintDetailed( 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->hoveredIndex().row() == index.row() && m_view->hoveredIndex().column() == index.column() && ( index.column() == TrackModel::Artist || index.column() == TrackModel::Album ) ) { opt.rect.setWidth( opt.rect.width() - 16 ); QRect arrowRect( opt.rect.x() + opt.rect.width(), opt.rect.y() + 1, opt.rect.height() - 2, opt.rect.height() - 2 ); if ( m_arrowIcon.height() != arrowRect.height() ) m_arrowIcon = m_arrowIcon.scaled( arrowRect.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation ); painter->drawPixmap( arrowRect, m_arrowIcon ); } painter->save(); if ( index.column() == TrackModel::Score ) { QColor barColor( 167, 183, 211 ); // This matches the sidebar (sourcetreeview.cpp:672) if ( opt.state & QStyle::State_Selected ) painter->setPen( opt.palette.brightText().color() ); else painter->setPen( barColor ); QRect r = opt.rect.adjusted( 3, 3, -6, -4 ); painter->drawRect( r ); QRect fillR = r; int fillerWidth = (int)( index.data().toFloat() * (float)fillR.width() ); fillR.adjust( 0, 0, -( fillR.width() - fillerWidth ), 0 ); if ( opt.state & QStyle::State_Selected ) painter->setBrush( opt.palette.brightText().color() ); else painter->setBrush( barColor ); painter->drawRect( fillR ); } else if ( item->isPlaying() ) { { QRect r = opt.rect.adjusted( 3, 0, 0, 0 ); // Paint Now Playing Speaker Icon if ( m_view->header()->visualIndex( index.column() ) == 0 ) { r.adjust( 0, 0, 0, -3 ); painter->drawPixmap( r.adjusted( 3, 1, 18 - r.width(), 1 ), m_nowPlayingIcon ); r.adjust( 25, 0, 0, 3 ); } painter->setPen( opt.palette.text().color() ); QString text = painter->fontMetrics().elidedText( index.data().toString(), Qt::ElideRight, r.width() - 3 ); painter->drawText( r.adjusted( 0, 1, 0, 0 ), text, m_centerOption ); } } else { painter->setPen( opt.palette.text().color() ); QString text = painter->fontMetrics().elidedText( index.data().toString(), Qt::ElideRight, opt.rect.width() - 3 ); painter->drawText( opt.rect.adjusted( 3, 1, 0, 0 ), text, m_centerOption ); } painter->restore(); }
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(); }
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(); }