statistics.cpp

来自「Amarok是一款在LINUX或其他类UNIX操作系统中运行的音频播放器软件。 」· C++ 代码 · 共 1,049 行 · 第 1/3 页

CPP
1,049
字号
/*************************************************************************** * copyright            : (C) 2005-2006 Seb Ruiz <me@sebruiz.net>          * **************************************************************************//*************************************************************************** *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU General Public License as published by  * *   the Free Software Foundation; either version 2 of the License, or     * *   (at your option) any later version.                                   * *                                                                         * ***************************************************************************/#include "amarok.h"             //foreach macro#include "browserToolBar.h"     //search toolbar#include "clicklineedit.h"#include "collectiondb.h"#include "debug.h"#include "playlist.h"#include "statistics.h"#include "tagdialog.h"         //showContextMenu()#include <kapplication.h>#include <kdeversion.h>        //KDE_VERSION ifndefs.  Remove this once we reach a kde 4 dep#include <kiconloader.h>#include <klocale.h>#include <kmultipledrag.h>     //startDrag()#include <kpopupmenu.h>#include <kstringhandler.h>    //paintCell#include <ktoolbarbutton.h>    //ctor#include <kurldrag.h>          //startDrag()#include <kwin.h>#include <qcolor.h>#include <qdatetime.h>#include <qheader.h>#include <qpainter.h>#include <qpen.h>#include <qpixmap.h>#include <qsimplerichtext.h>#include <qtimer.h>#include <qtooltip.h>#include <qvbox.h>///////////////////////////////////////////////////////////////////////////////////////////// CLASS Statistics//////////////////////////////////////////////////////////////////////////////////////////Statistics *Statistics::s_instance = 0;Statistics::Statistics( QWidget *parent, const char *name )    : KDialogBase( KDialogBase::Swallow, 0, parent, name, false, 0, Close )    , m_timer( new QTimer( this ) ){    s_instance = this;    // Gives the window a small title bar, and skips a taskbar entry    KWin::setType( winId(), NET::Utility );    KWin::setState( winId(), NET::SkipTaskbar );    kapp->setTopWidget( this );    setCaption( kapp->makeStdCaption( i18n("Collection Statistics") ) );    setInitialSize( QSize( 400, 550 ) );    QVBox *mainBox = new QVBox( this );    setMainWidget( mainBox );    QVBox *box = new QVBox( mainWidget() );    box->setSpacing( 5 );    { //<Search LineEdit>        KToolBar *bar = new Browser::ToolBar( box );        bar->setIconSize( 22, false ); //looks more sensible        bar->setFlat( true ); //removes the ugly frame        bar->setMovingEnabled( false ); //removes the ugly frame        QWidget *button = new KToolBarButton( "locationbar_erase", 1, bar );        m_lineEdit = new ClickLineEdit( i18n( "Enter search terms here" ), bar );        bar->setStretchableWidget( m_lineEdit );        m_lineEdit->setFrame( QFrame::Sunken );        m_lineEdit->installEventFilter( this ); //we intercept keyEvents        connect( button,     SIGNAL( clicked() )      , m_lineEdit  , SLOT( clear() ) );        connect( m_timer,    SIGNAL( timeout() )                    , SLOT( slotSetFilter() ) );        connect( m_lineEdit, SIGNAL( textChanged( const QString& ) ), SLOT( slotSetFilterTimeout() ) );        connect( m_lineEdit, SIGNAL( returnPressed() )              , SLOT( slotSetFilter() ) );        QToolTip::add( button, i18n( "Clear search field" ) );    } //</Search LineEdit>    m_listView = new StatisticsList( box );}Statistics::~Statistics(){    s_instance = 0;}voidStatistics::slotSetFilterTimeout() //SLOT{    m_timer->start( 280, true ); //stops the timer for us first}voidStatistics::slotSetFilter() //SLOT{    m_timer->stop();    m_listView->setFilter( m_lineEdit->text() );    if( m_listView->childCount() > 1 )        m_listView->renderView();    else        m_listView->refreshView();}///////////////////////////////////////////////////////////////////////////////////////////// CLASS StatisticsList//////////////////////////////////////////////////////////////////////////////////////////StatisticsList::StatisticsList( QWidget *parent, const char *name )    : KListView( parent, name )    , m_currentItem( 0 )    , m_expanded( false ){    header()->hide();    addColumn( i18n("Name") );    setResizeMode( QListView::LastColumn );    setSelectionMode( QListView::Extended );    setSorting( -1 );    setAcceptDrops( false );    setDragEnabled( true );    connect( this, SIGNAL( onItem( QListViewItem*) ),  SLOT( startHover( QListViewItem* ) ) );    connect( this, SIGNAL( onViewport() ),             SLOT( clearHover() ) );    connect( this, SIGNAL( clicked( QListViewItem*) ), SLOT( itemClicked( QListViewItem* ) ) );    connect( this, SIGNAL( contextMenuRequested( QListViewItem *, const QPoint &, int ) ),             this,   SLOT( showContextMenu( QListViewItem *, const QPoint &, int )  ) );    if( CollectionDB::instance()->isEmpty() )        return;    renderView();}voidStatisticsList::startDrag(){    // there is only one item ever selected in this tool.  maybe this needs to change    DEBUG_FUNC_INFO    KURL::List list;    KMultipleDrag *drag = new KMultipleDrag( this );    QListViewItemIterator it( this, QListViewItemIterator::Selected );    StatisticsDetailedItem *item = dynamic_cast<StatisticsDetailedItem*>(*it);    if ( !item )        return;    if( item->itemType() == StatisticsDetailedItem::TRACK )    {        list += KURL::fromPathOrURL( item->url() );        drag->addDragObject( new KURLDrag( list, viewport() ) );        drag->setPixmap( CollectionDB::createDragPixmap(list),                         QPoint( CollectionDB::DRAGPIXMAP_OFFSET_X,                                 CollectionDB::DRAGPIXMAP_OFFSET_Y ) );    }    else    {        QTextDrag *textdrag = new QTextDrag( '\n' + item->getSQL(), 0 );        textdrag->setSubtype( "amarok-sql" );        drag->addDragObject( textdrag );        drag->setPixmap( CollectionDB::createDragPixmapFromSQL( item->getSQL() ),                         QPoint( CollectionDB::DRAGPIXMAP_OFFSET_X,                                 CollectionDB::DRAGPIXMAP_OFFSET_Y ) );    }    clearSelection();    drag->dragCopy();}voidStatisticsList::refreshView(){    if( m_expanded )    {        if( !firstChild() )        {            error() << "Statistics: uh oh, no first child!" << endl;            return;        }        while( firstChild()->firstChild() )            delete firstChild()->firstChild();        expandInformation( static_cast<StatisticsItem*>(firstChild()), true /*refresh*/ );    }    else        renderView();}voidStatisticsList::renderView(){    m_expanded = false;    //ensure cleanliness - this function is not just called from the ctor, but also when returning to the initial display    while( firstChild() )        delete firstChild();    m_currentItem = 0;    QueryBuilder qb;    QStringList a;    qb.clear();    qb.addReturnFunctionValue( QueryBuilder::funcCount, QueryBuilder::tabSong, QueryBuilder::valURL );    qb.setOptions( QueryBuilder::optRemoveDuplicates );    a = qb.run();    m_trackItem = new StatisticsItem( i18n("Favorite Tracks"), this, 0 );    m_trackItem->setSubtext( i18n("%n track", "%n tracks", a[0].toInt()) );    qb.clear();    qb.addReturnFunctionValue( QueryBuilder::funcSum, QueryBuilder::tabStats, QueryBuilder::valPlayCounter );    a = qb.run();    m_mostplayedItem = new StatisticsItem( i18n("Most Played Tracks"), this, m_trackItem );    m_mostplayedItem->setSubtext( i18n("%n play", "%n plays", a[0].toInt()) );    qb.clear();    //qb.addReturnFunctionValue( QueryBuilder::funcCount, QueryBuilder::tabArtist, QueryBuilder::valID );    //qb.setOptions( QueryBuilder::optRemoveDuplicates );    //a = qb.run();    qb.setOptions( QueryBuilder::optRemoveDuplicates );    qb.addReturnValue( QueryBuilder::tabSong, QueryBuilder::valArtistID );    //I can't get the correct value w/o using a subquery, and querybuilder doesn't support those    a = QString::number( qb.run().count() );    m_artistItem = new StatisticsItem( i18n("Favorite Artists"), this, m_mostplayedItem );    m_artistItem->setSubtext( i18n("%n artist", "%n artists", a[0].toInt()) );    qb.clear();    //qb.addReturnFunctionValue( QueryBuilder::funcCount, QueryBuilder::tabAlbum, QueryBuilder::valID );    //qb.setOptions( QueryBuilder::optRemoveDuplicates );    //a = qb.run();    qb.setOptions( QueryBuilder::optRemoveDuplicates );    qb.addReturnValue( QueryBuilder::tabSong, QueryBuilder::valAlbumID );    //I can't get the correct value w/o using a subquery, and querybuilder doesn't support those    a = QString::number( qb.run().count() );    m_albumItem = new StatisticsItem( i18n("Favorite Albums"), this, m_artistItem );    m_albumItem->setSubtext( i18n("%n album", "%n albums", a[0].toInt()) );    qb.clear();    //qb.addReturnFunctionValue( QueryBuilder::funcCount, QueryBuilder::tabGenre, QueryBuilder::valID );    //qb.setOptions( QueryBuilder::optRemoveDuplicates );    //a = qb.run();    qb.setOptions( QueryBuilder::optRemoveDuplicates );    qb.addReturnValue( QueryBuilder::tabSong, QueryBuilder::valGenreID );    //I can't get the correct value w/o using a subquery, and querybuilder doesn't support those    a = QString::number( qb.run().count() );    m_genreItem = new StatisticsItem( i18n("Favorite Genres"), this, m_albumItem );    m_genreItem->setSubtext( i18n("%n genre", "%n genres", a[0].toInt()) );    qb.clear();    qb.addReturnFunctionValue( QueryBuilder::funcMin, QueryBuilder::tabStats, QueryBuilder::valCreateDate );    qb.setOptions( QueryBuilder::optRemoveDuplicates );    a = qb.run();    QDateTime firstPlay = QDateTime::currentDateTime();    if ( a[0].toUInt() )        firstPlay.setTime_t( a[0].toUInt() );    m_newestItem = new StatisticsItem( i18n("Newest Items"), this, m_genreItem );    m_newestItem->setSubtext( i18n("First played %1").arg( Amarok::verboseTimeSince( firstPlay ) ) );    m_trackItem     ->setIcon( Amarok::icon("track") );    m_mostplayedItem->setIcon( Amarok::icon("mostplayed") );    m_artistItem    ->setIcon( Amarok::icon("artist") );    m_albumItem     ->setIcon( Amarok::icon("album") );    m_genreItem     ->setIcon( Amarok::icon("favourite_genres") );    m_newestItem    ->setIcon( Amarok::icon("clock") );}voidStatisticsList::itemClicked( QListViewItem *item ) //SLOT{    if( !item )        return;    if( item->depth() != 0 ) //not very flexible, *shrug*        return;    #define item static_cast<StatisticsItem*>(item)    if( item->isExpanded() )    {        renderView();        return;    }    expandInformation( item );    item->setOpen( true );    #undef item}voidStatisticsList::expandInformation( StatisticsItem *item, bool refresh ){    m_expanded = true;    KLocale *locale = new KLocale( "locale" );    QueryBuilder qb;    StatisticsDetailedItem *m_last = 0;    uint c = 1;    if( item == m_trackItem )    {        if( !refresh ) {            delete m_newestItem;            delete m_genreItem;            delete m_albumItem;            delete m_artistItem;            delete m_mostplayedItem;        }        qb.addReturnValue( QueryBuilder::tabSong, QueryBuilder::valTitle );        qb.addReturnValue( QueryBuilder::tabArtist, QueryBuilder::valName );        qb.addReturnValue( QueryBuilder::tabSong, QueryBuilder::valURL );        qb.addReturnValue( QueryBuilder::tabStats, QueryBuilder::valScore );        qb.addReturnValue( QueryBuilder::tabStats, QueryBuilder::valRating );        qb.addNumericFilter( QueryBuilder::tabStats, QueryBuilder::valForFavoriteSorting(), "0", QueryBuilder::modeGreater );        qb.setGoogleFilter( QueryBuilder::tabSong | QueryBuilder::tabArtist, m_filter );        qb.sortByFavorite();        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]);            QString score = locale->formatNumber( fave[i+3].toDouble(), 0 );

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?