statistics.cpp
来自「Amarok是一款在LINUX或其他类UNIX操作系统中运行的音频播放器软件。 」· C++ 代码 · 共 1,049 行 · 第 1/3 页
CPP
1,049 行
QString rating = locale->formatNumber( fave[i+4].toDouble() / 2.0, 1 ); m_last = new StatisticsDetailedItem( name, subText( score, rating ), item, m_last ); m_last->setItemType( StatisticsDetailedItem::TRACK ); m_last->setUrl( fave[i+2] ); c++; } } else if( item == m_mostplayedItem ) { if( !refresh ) { delete m_newestItem; delete m_genreItem; delete m_albumItem; delete m_artistItem; delete m_trackItem; } qb.addReturnValue( QueryBuilder::tabSong, QueryBuilder::valTitle ); qb.addReturnValue( QueryBuilder::tabArtist, QueryBuilder::valName ); qb.addReturnValue( QueryBuilder::tabSong, QueryBuilder::valURL ); qb.addReturnValue( QueryBuilder::tabStats, QueryBuilder::valPlayCounter ); qb.addNumericFilter( QueryBuilder::tabStats, QueryBuilder::valPlayCounter, "0", QueryBuilder::modeGreater ); qb.setGoogleFilter( QueryBuilder::tabSong | QueryBuilder::tabArtist, m_filter ); qb.sortBy( QueryBuilder::tabStats, QueryBuilder::valPlayCounter, true ); qb.setLimit( 0, 50 ); QStringList fave = qb.run(); for( uint i=0; i < fave.count(); i += qb.countReturnValues() ) { QString name = i18n("%1. %2 - %3").arg( QString::number(c), fave[i].isEmpty() ? i18n( "Unknown" ) : fave[i], fave[i+1].isEmpty() ? i18n( "Unknown" ) : fave[i+1]); double plays = fave[i+3].toDouble(); QString subtext = i18n("%1: %2").arg( i18n( "Playcount" ) ).arg( plays ); m_last = new StatisticsDetailedItem( name, subtext, item, m_last ); m_last->setItemType( StatisticsDetailedItem::TRACK ); m_last->setUrl( fave[i+2] ); c++; } } else if( item == m_artistItem ) { if( !refresh ) { delete m_newestItem; delete m_genreItem; delete m_albumItem; delete m_mostplayedItem; delete m_trackItem; } qb.addReturnValue( QueryBuilder::tabArtist, QueryBuilder::valName ); qb.addReturnFunctionValue( QueryBuilder::funcAvg, QueryBuilder::tabStats, QueryBuilder::valScore ); qb.addReturnFunctionValue( QueryBuilder::funcAvg, QueryBuilder::tabStats, QueryBuilder::valRating ); qb.sortByFavoriteAvg(); // only artists with more than 3 tracks qb.having( QueryBuilder::tabArtist, QueryBuilder::valID, QueryBuilder::funcCount, QueryBuilder::modeGreater, "3" ); qb.setGoogleFilter( QueryBuilder::tabArtist, m_filter ); qb.groupBy( QueryBuilder::tabArtist, QueryBuilder::valName); qb.setLimit( 0, 50 ); QStringList fave = qb.run(); for( uint i=0; i < fave.count(); i += qb.countReturnValues() ) { QString name = i18n("%1. %2").arg( QString::number(c), fave[i].isEmpty() ? i18n( "Unknown" ) : fave[i] ); QString score = locale->formatNumber( fave[i+1].toDouble(), 2 ); QString rating = locale->formatNumber( fave[i+2].toDouble() / 2.0, 2 ); m_last = new StatisticsDetailedItem( name, subText( score, rating ), item, m_last ); m_last->setItemType( StatisticsDetailedItem::ARTIST ); QString url = QString("%1").arg( fave[i] ); m_last->setUrl( url ); c++; } } else if( item == m_albumItem ) { if( !refresh ) { delete m_newestItem; delete m_genreItem; delete m_artistItem; delete m_mostplayedItem; delete m_trackItem; } qb.addReturnValue( QueryBuilder::tabAlbum, QueryBuilder::valName ); qb.addReturnValue( QueryBuilder::tabArtist, QueryBuilder::valName ); qb.addReturnValue( QueryBuilder::tabArtist, QueryBuilder::valID ); qb.addReturnValue( QueryBuilder::tabAlbum, QueryBuilder::valID ); qb.addReturnFunctionValue( QueryBuilder::funcAvg, QueryBuilder::tabStats, QueryBuilder::valScore ); qb.addReturnFunctionValue( QueryBuilder::funcAvg, QueryBuilder::tabStats, QueryBuilder::valRating ); qb.addReturnValue( QueryBuilder::tabSong, QueryBuilder::valIsCompilation ); // only albums with more than 3 tracks qb.having( QueryBuilder::tabAlbum, QueryBuilder::valID, QueryBuilder::funcCount, QueryBuilder::modeGreater, "3" ); qb.setOptions( QueryBuilder::optNoCompilations ); // samplers __need__ to be handled differently qb.setGoogleFilter( QueryBuilder::tabAlbum | QueryBuilder::tabArtist, m_filter ); qb.sortByFavoriteAvg(); qb.excludeMatch( QueryBuilder::tabAlbum, i18n( "Unknown" ) ); qb.groupBy( QueryBuilder::tabAlbum, QueryBuilder::valID ); qb.groupBy( QueryBuilder::tabAlbum, QueryBuilder::valName ); qb.groupBy( QueryBuilder::tabArtist, QueryBuilder::valID ); qb.groupBy( QueryBuilder::tabArtist, QueryBuilder::valName ); qb.groupBy( QueryBuilder::tabSong, QueryBuilder::valIsCompilation ); qb.setLimit( 0, 50 ); QStringList fave = qb.run(); const QString trueValue = CollectionDB::instance()->boolT(); for( uint i=0; i < fave.count(); i += qb.countReturnValues() ) { const bool isSampler = (fave[i+6] == trueValue); QString name = i18n("%1. %2 - %3").arg( QString::number(c), fave[i].isEmpty() ? i18n( "Unknown" ) : fave[i], isSampler ? i18n( "Various Artists" ) : ( fave[i+1].isEmpty() ? i18n( "Unknown" ) : fave[i+1] ) ); QString score = locale->formatNumber( fave[i+4].toDouble(), 2 ); QString rating = locale->formatNumber( fave[i+5].toDouble() / 2.0, 2 ); m_last = new StatisticsDetailedItem( name, subText( score, rating ), item, m_last ); m_last->setItemType( StatisticsDetailedItem::ALBUM ); QString url = QString("%1 @@@ %2").arg( isSampler ? "0" : fave[i+2], fave[i+3] ); m_last->setUrl( url ); c++; } } else if( item == m_genreItem ) { if( !refresh ) { delete m_newestItem; delete m_albumItem; delete m_artistItem; delete m_mostplayedItem; delete m_trackItem; } qb.addReturnValue( QueryBuilder::tabGenre, QueryBuilder::valName ); qb.addReturnFunctionValue( QueryBuilder::funcAvg, QueryBuilder::tabStats, QueryBuilder::valScore ); qb.addReturnFunctionValue( QueryBuilder::funcAvg, QueryBuilder::tabStats, QueryBuilder::valRating ); // only genres with more than 3 tracks qb.having( QueryBuilder::tabGenre, QueryBuilder::valID, QueryBuilder::funcCount, QueryBuilder::modeGreater, "3" ); // only genres which have been played/rated qb.setGoogleFilter( QueryBuilder::tabGenre, m_filter ); qb.sortByFavoriteAvg(); qb.groupBy( QueryBuilder::tabGenre, QueryBuilder::valName); qb.setLimit( 0, 50 ); QStringList fave = qb.run(); for( uint i=0; i < fave.count(); i += qb.countReturnValues() ) { QString name = i18n("%1. %2").arg( QString::number(c), fave[i].isEmpty() ? i18n( "Unknown" ) : fave[i] ); QString score = locale->formatNumber( fave[i+1].toDouble(), 2 ); QString rating = locale->formatNumber( fave[i+2].toDouble() / 2.0, 2 ); m_last = new StatisticsDetailedItem( name, subText( score, rating ), item, m_last ); m_last->setItemType( StatisticsDetailedItem::GENRE ); QString url = QString("%1").arg( fave[i] ); m_last->setUrl( url ); c++; } } else if( item == m_newestItem ) { if( !refresh ) { delete m_genreItem; delete m_albumItem; delete m_artistItem; delete m_mostplayedItem; delete m_trackItem; } qb.addReturnValue( QueryBuilder::tabAlbum, QueryBuilder::valName ); qb.addReturnValue( QueryBuilder::tabArtist, QueryBuilder::valName ); qb.addReturnValue( QueryBuilder::tabArtist, QueryBuilder::valID ); qb.addReturnValue( QueryBuilder::tabAlbum, QueryBuilder::valID ); qb.addReturnFunctionValue( QueryBuilder::funcMax, QueryBuilder::tabSong, QueryBuilder::valCreateDate ); qb.sortByFunction( QueryBuilder::funcMax, QueryBuilder::tabSong, QueryBuilder::valCreateDate, true ); qb.excludeMatch( QueryBuilder::tabAlbum, i18n( "Unknown" ) ); qb.setGoogleFilter( QueryBuilder::tabAlbum | QueryBuilder::tabArtist, m_filter ); qb.groupBy( QueryBuilder::tabAlbum, QueryBuilder::valName); qb.groupBy( QueryBuilder::tabAlbum, QueryBuilder::valID); qb.groupBy( QueryBuilder::tabArtist, QueryBuilder::valName); qb.groupBy( QueryBuilder::tabArtist, QueryBuilder::valID); qb.setOptions( QueryBuilder::optNoCompilations ); // samplers __need__ to be handled differently qb.setLimit( 0, 50 ); QStringList newest = qb.run(); for( uint i=0; i < newest.count(); i += qb.countReturnValues() ) { QString name = i18n("%1. %2 - %3").arg( QString::number(c), newest[i].isEmpty() ? i18n( "Unknown" ) : newest[i], newest[i+1].isEmpty() ? i18n( "Unknown" ) : newest[i+1] ); QDateTime added = QDateTime(); added.setTime_t( newest[i+4].toUInt() ); QString subtext = i18n("Added: %1").arg( Amarok::verboseTimeSince( added ) ); m_last = new StatisticsDetailedItem( name, subtext, item, m_last ); m_last->setItemType( StatisticsDetailedItem::HISTORY ); QString url = QString("%1 @@@ %2").arg( newest[i+2] ).arg( newest[i+3] ); m_last->setUrl( url ); c++; } } item->setExpanded( true ); repaintItem( item ); // Better than ::repaint(), flickers less delete locale;}QString StatisticsList::subText( const QString &score, const QString &rating ) //static{ if( AmarokConfig::useScores() && AmarokConfig::useRatings() ) return i18n( "Score: %1 Rating: %2" ).arg( score ).arg( rating ); else if( AmarokConfig::useScores() ) return i18n( "Score: %1" ).arg( score ); else if( AmarokConfig::useRatings() ) return i18n( "Rating: %1" ).arg( rating ); else return QString();}voidStatisticsList::startHover( QListViewItem *item ) //SLOT{ if( m_currentItem && item != m_currentItem ) static_cast<StatisticsItem*>(m_currentItem)->leaveHover(); if( item->depth() != 0 ) { m_currentItem = 0; return; } static_cast<StatisticsItem*>(item)->enterHover(); m_currentItem = item;}voidStatisticsList::clearHover() //SLOT{ if( m_currentItem ) static_cast<StatisticsItem*>(m_currentItem)->leaveHover(); m_currentItem = 0;}voidStatisticsList::viewportPaintEvent( QPaintEvent *e ){ if( e ) KListView::viewportPaintEvent( e ); if( CollectionDB::instance()->isEmpty() && e ) { QPainter p( viewport() ); QString minimumText(i18n( "<div align=center>" "<h3>Statistics</h3>" "You need a collection to use statistics! " "Create a collection and then start playing " "tracks to accumulate data on your play habits!" "</div>" ) ); QSimpleRichText t( minimumText, QApplication::font() ); if ( t.width()+30 >= viewport()->width() || t.height()+30 >= viewport()->height() ) //too big, giving up return; const uint w = t.width(); const uint h = t.height(); const uint x = (viewport()->width() - w - 30) / 2 ; const uint y = (viewport()->height() - h - 30) / 2 ; p.setBrush( colorGroup().background() ); p.drawRoundRect( x, y, w+30, h+30, (8*200)/w, (8*200)/h ); t.draw( &p, x+15, y+15, QRect(), colorGroup() ); }}voidStatisticsList::showContextMenu( QListViewItem *item, const QPoint &p, int ) //SLOT{ if( !item || item->rtti() == StatisticsItem::RTTI ) return;#define item static_cast<StatisticsDetailedItem*>(item) bool hasSQL = !( item->itemType() == StatisticsDetailedItem::TRACK ); //track is url KPopupMenu menu( this ); enum Actions { APPEND, QUEUE, INFO }; menu.insertItem( SmallIconSet( Amarok::icon( "add_playlist" ) ), i18n( "&Append to Playlist" ), APPEND ); menu.insertItem( SmallIconSet( Amarok::icon( "queue_track" ) ), i18n( "&Queue Track" ), QUEUE ); menu.insertSeparator(); menu.insertItem( SmallIconSet( Amarok::icon( "info" ) ), i18n( "Edit Track &Information..." ), INFO ); switch( menu.exec( p ) ) { case APPEND: hasSQL ? Playlist::instance()->insertMediaSql( item->getSQL() ): Playlist::instance()->insertMedia( KURL::fromPathOrURL( item->url() ) ); break; case QUEUE: hasSQL ? Playlist::instance()->insertMediaSql( item->getSQL(), Playlist::Queue ): Playlist::instance()->insertMedia( KURL::fromPathOrURL( item->url() ), Playlist::Queue ); break; case INFO: if( hasSQL ) { TagDialog* dialog = new TagDialog( item->getURLs(), Statistics::instance() ); dialog->show(); } else { TagDialog* dialog = new TagDialog( KURL::fromPathOrURL( item->url() ), Statistics::instance() ); dialog->show(); } }#undef item}///////////////////////////////////////////////////////////////////////////////////////////// CLASS StatisticsItem//////////////////////////////////////////////////////////////////////////////////////////StatisticsItem::StatisticsItem( QString text, StatisticsList *parent, KListViewItem *after, const char *name ) : KListViewItem( static_cast<KListView*>(parent), after, name ) , m_animTimer( new QTimer( this ) ) , m_animCount( 0 ) , m_isActive( false ) , m_isExpanded( false ){ setDragEnabled( false ); setDropEnabled( false ); setSelectable( false ); setText( 0, text ); connect( m_animTimer, SIGNAL( timeout() ), this, SLOT( slotAnimTimer() ) );}void
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?