playlistbrowser.cpp

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

CPP
1,990
字号
/*************************************************************************** * copyright            : (c) 2004 Pierpaolo Di Panfilo                    * *                        (c) 2004 Mark Kretschmann <markey@web.de>        * *                        (c) 2005-2006 Seb Ruiz <me@sebruiz.net>          * *                        (c) 2005 Gábor Lehel <illissius@gmail.com>       * *                        (c) 2005 Christian Muehlhaeuser <chris@chris.de> * *                        (c) 2006 Alexandre Oliveira <aleprj@gmail.com>   * *                        (c) 2006 Adam Pigg <adam@piggz.co.uk>            * * See COPYING file for licensing information                              * ***************************************************************************/#define DEBUG_PREFIX "PlaylistBrowser"#include "amarok.h"            //actionCollection()#include "browserToolBar.h"#include "collectiondb.h"      //smart playlists#include "debug.h"#include "htmlview.h"#include "k3bexporter.h"#include "mediabrowser.h"#include "dynamicmode.h"#include "lastfm.h"#include "playlist.h"#include "playlistbrowser.h"#include "playlistbrowseritem.h"#include "playlistselection.h"#include "podcastbundle.h"#include "podcastsettings.h"#include "scancontroller.h"#include "smartplaylisteditor.h"#include "tagdialog.h"         //showContextMenu()#include "threadmanager.h"#include "statusbar.h"#include "contextbrowser.h"#include "xspfplaylist.h"#include <qevent.h>            //customEvent()#include <qheader.h>           //mousePressed()#include <qlabel.h>#include <qpainter.h>          //paintCell()#include <qpixmap.h>           //paintCell()#include <qtextstream.h>       //loadPlaylists(), saveM3U(), savePLS()#include <kaction.h>#include <kactionclasses.h>#include <kactioncollection.h>#include <kapplication.h>#include <kfiledialog.h>       //openPlaylist()#include <kio/job.h>           //deleteSelectedPlaylists()#include <kiconloader.h>       //smallIcon#include <kinputdialog.h>#include <klineedit.h>         //rename()#include <klocale.h>#include <kmessagebox.h>       //renamePlaylist(), deleteSelectedPlaylist()#include <kmimetype.h>#include <kmultipledrag.h>     //dragObject()#include <kpopupmenu.h>#include <kpushbutton.h>#include <kstandarddirs.h>     //KGlobal::dirs()#include <kurldrag.h>          //dragObject()#include <cstdio>              //rename() in renamePlaylist()namespace Amarok {    QListViewItem*    findItemByPath( QListView *view, QString name )    {        const static QString escaped( "\\/" );        const static QChar sep( '/' );        debug() << "Searching " << name << endl;        QStringList path = splitPath( name );        QListViewItem *prox = view->firstChild();        QListViewItem *item = 0;        foreach( path ) {            item = prox;            QString text( *it );            text.replace( escaped, sep );            for ( ; item; item = item->nextSibling() ) {                if ( text == item->text(0) ) {                    break;                }            }            if ( !item )                return 0;            prox = item->firstChild();        }        return item;    }    QStringList    splitPath( QString path ) {        QStringList list;        const static QChar sep( '/' );        int bOffset = 0, sOffset = 0;        int pos = path.find( sep, bOffset );        while ( pos != -1 ) {            if ( pos > sOffset && pos <= (int)path.length() ) {                if ( pos > 0 && path[pos-1] != '\\' ) {                    list << path.mid( sOffset, pos - sOffset );                    sOffset = pos + 1;                }            }            bOffset = pos + 1;            pos = path.find( sep, bOffset );        }        int length = path.length() - 1;        if ( path.mid( sOffset, length - sOffset + 1 ).length() > 0 )            list << path.mid( sOffset, length - sOffset + 1 );        return list;    }}inline QStringfileExtension( const QString &fileName ){    return Amarok::extension( fileName );}PlaylistBrowser *PlaylistBrowser::s_instance = 0;PlaylistBrowser::PlaylistBrowser( const char *name )        : QVBox( 0, name )        , m_polished( false )        , m_playlistCategory( 0 )        , m_streamsCategory( 0 )        , m_smartCategory( 0 )        , m_dynamicCategory( 0 )        , m_podcastCategory( 0 )        , m_coolStreams( 0 )        , m_smartDefaults( 0 )        , m_lastfmCategory( 0 )        , m_shoutcastCategory( 0 )        , m_lastPlaylist( 0 )        , m_coolStreamsOpen( false )        , m_smartDefaultsOpen( false )        , m_lastfmOpen( false )        , m_ac( new KActionCollection( this ) )        , m_podcastTimer( new QTimer( this ) ){    s_instance = this;    QVBox *browserBox = new QVBox( this );    browserBox->setSpacing( 3 );    //<Toolbar>    addMenuButton  = new KActionMenu( i18n("Add"), Amarok::icon( "add_playlist" ), m_ac );    addMenuButton->setDelayed( false );    KPopupMenu *playlistMenu = new KPopupMenu( this );    playlistMenu->insertItem( i18n("New..."), PLAYLIST );    playlistMenu->insertItem( i18n("Import Existing..."), PLAYLIST_IMPORT );    connect( playlistMenu, SIGNAL( activated(int) ), SLOT( slotAddPlaylistMenu(int) ) );    KPopupMenu *addMenu  = addMenuButton->popupMenu();    addMenu->insertItem( i18n("Playlist"), playlistMenu );    addMenu->insertItem( i18n("Smart Playlist..."), SMARTPLAYLIST );    addMenu->insertItem( i18n("Dynamic Playlist..."), ADDDYNAMIC);    addMenu->insertItem( i18n("Radio Stream..."), STREAM );    addMenu->insertItem( i18n("Podcast..."), PODCAST );    connect( addMenu, SIGNAL( activated(int) ), SLOT( slotAddMenu(int) ) );    renameButton   = new KAction( i18n("Rename"), "editclear", 0, this, SLOT( renameSelectedItem() ), m_ac );    removeButton   = new KAction( i18n("Delete"), Amarok::icon( "remove" ), 0, this, SLOT( removeSelectedItems() ), m_ac );    m_toolbar = new Browser::ToolBar( browserBox );    m_toolbar->setIconText( KToolBar::IconTextRight, false ); //we want the open button to have text on right    addMenuButton->plug( m_toolbar );    m_toolbar->setIconText( KToolBar::IconOnly, false );      //default appearance    m_toolbar->insertLineSeparator();    renameButton->plug( m_toolbar);    removeButton->plug( m_toolbar );    renameButton->setEnabled( false );    removeButton->setEnabled( false );    //</Toolbar>    m_splitter = new QSplitter( Qt::Vertical, browserBox );    m_splitter->setChildrenCollapsible( false ); // hiding the InfoPane entirely can only be confusing    m_listview = new PlaylistBrowserView( m_splitter );    int sort = Amarok::config( "PlaylistBrowser" )->readNumEntry( "Sorting", Qt::Ascending );    m_listview->setSorting( 0, sort == Qt::Ascending ? true : false );    m_podcastTimerInterval = Amarok::config( "PlaylistBrowser" )->readNumEntry( "Podcast Interval", 14400000 );    connect( m_podcastTimer, SIGNAL(timeout()), this, SLOT(scanPodcasts()) );    // signals and slots connections    connect( m_listview, SIGNAL( contextMenuRequested( QListViewItem *, const QPoint &, int ) ),             this,         SLOT( showContextMenu( QListViewItem *, const QPoint &, int ) ) );    connect( m_listview, SIGNAL( doubleClicked( QListViewItem *, const QPoint &, int ) ),             this,         SLOT( invokeItem( QListViewItem *, const QPoint &, int ) ) );    connect( m_listview, SIGNAL( itemRenamed( QListViewItem*, const QString&, int ) ),             this,         SLOT( renamePlaylist( QListViewItem*, const QString&, int ) ) );    connect( m_listview, SIGNAL( currentChanged( QListViewItem * ) ),             this,         SLOT( currentItemChanged( QListViewItem * ) ) );    connect( CollectionDB::instance(), SIGNAL( scanDone( bool ) ), SLOT( collectionScanDone() ) );    setMinimumWidth( m_toolbar->sizeHint().width() );    m_infoPane = new InfoPane( m_splitter );    m_podcastCategory = loadPodcasts();    setSpacing( 4 );    setFocusProxy( m_listview );}voidPlaylistBrowser::polish(){    // we make startup faster by doing the slow bits for this    // only when we are shown on screen    DEBUG_FUNC_INFO    Amarok::OverrideCursor cursor;//     blockSignals( true );//     BrowserBar::instance()->restoreWidth();//     blockSignals( false );    QVBox::polish();    /// Podcasting is always initialised in the ctor because of autoscanning    m_polished = true;    m_playlistCategory = loadPlaylists();    if( !CollectionDB::instance()->isEmpty() )    {        m_smartCategory = loadSmartPlaylists();        loadDefaultSmartPlaylists();    }#define config Amarok::config( "PlaylistBrowser" )    m_dynamicCategory = loadDynamics();    m_randomDynamic   = new DynamicEntry( m_dynamicCategory, 0, i18n("Random Mix") );    m_randomDynamic->setKept( false ); //don't save it    m_randomDynamic->setCycleTracks(   config->readBoolEntry( "Dynamic Random Remove Played", true ) );    m_randomDynamic->setUpcomingCount( config->readNumEntry ( "Dynamic Random Upcoming Count", 15 ) );    m_randomDynamic->setPreviousCount( config->readNumEntry ( "Dynamic Random Previous Count", 5 ) );    m_suggestedDynamic = new DynamicEntry( m_dynamicCategory, m_randomDynamic, i18n("Suggested Songs" ) );    m_suggestedDynamic->setKept( false ); //don't save it    m_suggestedDynamic->setAppendType( DynamicMode::SUGGESTION );    m_suggestedDynamic->setCycleTracks(   config->readBoolEntry( "Dynamic Suggest Remove Played", true ) );    m_suggestedDynamic->setUpcomingCount( config->readNumEntry ( "Dynamic Suggest Upcoming Count", 15 ) );    m_suggestedDynamic->setPreviousCount( config->readNumEntry ( "Dynamic Suggest Previous Count", 5 ) );#undef config    m_streamsCategory  = loadStreams();    loadCoolStreams();    m_shoutcastCategory = new ShoutcastBrowser( m_streamsCategory );    if( !AmarokConfig::scrobblerUsername().isEmpty() )    {        const bool subscriber = Amarok::config( "Scrobbler" )->readBoolEntry( "Subscriber", false );        loadLastfmStreams( subscriber );    }    markDynamicEntries();    // ListView item state restoration:    // First we check if the number of items in the listview is the same as it was on last    // application exit. If true, we iterate over all items and restore their open/closed state.    // Note: We ignore podcast items, because they are added dynamically added to the ListView.    QValueList<int> stateList = Amarok::config( "PlaylistBrowser" )->readIntListEntry( "Item State" );    QListViewItemIterator it( m_listview );    uint count = 0;    while ( it.current() ) {        if( !isPodcastEpisode( it.current() ) )            ++count;        ++it;    }    if ( count == stateList.count() ) {        uint index = 0;        it = QListViewItemIterator( m_listview );        while ( it.current() ) {            if( !isPodcastEpisode( it.current() ) ) {                it.current()->setOpen( stateList[index] );                ++index;            }            ++it;        }    }    // Set height of InfoPane    m_infoPane->setStoredHeight( Amarok::config( "PlaylistBrowser" )->readNumEntry( "InfoPane Height", 200 ) );}PlaylistBrowser::~PlaylistBrowser(){    DEBUG_BLOCK    s_instance = 0;    if( m_polished )    {        savePlaylists();        saveSmartPlaylists();        saveDynamics();        saveStreams();        saveLastFm();        savePodcastFolderStates( m_podcastCategory );        QStringList list;        for( uint i=0; i < m_dynamicEntries.count(); i++ )        {            QListViewItem *item = m_dynamicEntries.at( i );            list.append( item->text(0) );        }        Amarok::config( "PlaylistBrowser" )->writeEntry( "Sorting", m_listview->sortOrder() );        Amarok::config( "PlaylistBrowser" )->writeEntry( "Podcast Interval", m_podcastTimerInterval );        Amarok::config( "PlaylistBrowser" )->writeEntry( "Podcast Folder Open", m_podcastCategory->isOpen() );        Amarok::config( "PlaylistBrowser" )->writeEntry( "InfoPane Height", m_infoPane->getHeight() );    }}voidPlaylistBrowser::setInfo( const QString &title, const QString &info ){    m_infoPane->setInfo( title, info );}voidPlaylistBrowser::resizeEvent( QResizeEvent * ){    if( static_cast<QWidget*>( m_infoPane->child( "container" ) )->isShown() )        m_infoPane->setMaximumHeight( ( int )( m_splitter->height() / 1.5 ) );}voidPlaylistBrowser::markDynamicEntries(){    if( Amarok::dynamicMode() )    {        QStringList playlists = Amarok::dynamicMode()->items();        for( uint i=0; i < playlists.count(); i++ )        {            PlaylistBrowserEntry *item = dynamic_cast<PlaylistBrowserEntry*>( Amarok::findItemByPath( m_listview, playlists[i]  ) );            if( item )            {                m_dynamicEntries.append( item );                if( item->rtti() == PlaylistEntry::RTTI )                     static_cast<PlaylistEntry*>( item )->setDynamic( true );                if( item->rtti() == SmartPlaylist::RTTI )                     static_cast<SmartPlaylist*>( item )->setDynamic( true );            }        }    }}/** ************************************************************************* *  STREAMS ************************************************************************* **/QString PlaylistBrowser::streamBrowserCache() const{    return Amarok::saveLocation() + "streambrowser_save.xml";}PlaylistCategory* PlaylistBrowser::loadStreams(){    QFile file( streamBrowserCache() );    QTextStream stream( &file );    stream.setEncoding( QTextStream::UnicodeUTF8 );

⌨️ 快捷键说明

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