daapclient.cpp

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

CPP
881
字号
/*************************************************************************** * copyright: (C) 2006, 2007 Ian Monroe <ian@monroe.nu>                    * *            (C) 2006 Seb Ruiz <me@sebruiz.net>                           * *            (C) 2007 Maximilian Kossick <maximilian.kossick@googlemail.com> ***************************************************************************//*************************************************************************** *                                                                         * *   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.                                   * *                                                                         * ***************************************************************************/#ifndef AMAROK_DAAPCLIENT_CPP#define AMAROK_DAAPCLIENT_CPP#include "addhostbase.h"#include "collectiondb.h"#include "collectionbrowser.h"#include "daapreader/reader.h"#include "daapreader/authentication/contentfetcher.h"#include "daapclient.h"#include "daapserver.h"#include "debug.h"#include "mediabrowser.h"#include "playlist.h"#include "proxy.h"#include "statusbar/statusbar.h"#include "tagdialog.h"#include <qcheckbox.h>#include <qmetaobject.h>#include <qobjectlist.h>#include <qlabel.h>#include <qpixmap.h>#include <qtimer.h>#include <qtooltip.h>#include <kiconloader.h>#include <klineedit.h>#include <knuminput.h>#include <kpassdlg.h>#include <kpopupmenu.h>#include <kresolver.h>#include <kstandarddirs.h>     //loading icons#include <ktempfile.h>#include <ktoolbar.h>#include <ktoolbarbutton.h>#if DNSSD_SUPPORT    #include <dnssd/remoteservice.h>    #include <dnssd/servicebase.h>    #include <dnssd/servicebrowser.h>#endifAMAROK_EXPORT_PLUGIN( DaapClient )DaapClient::DaapClient()    : MediaDevice()#if DNSSD_SUPPORT    , m_browser( 0 )#endif    , m_connected( false )    , m_sharingServer( 0 )    , m_broadcastServerCheckBox( 0 )    , m_broadcastServer( false ) // to abide by "all ports closed" policy, we default to not broadcasting music{DEBUG_BLOCK    setName( "daapclient" );    m_name = i18n( "Shared Music" );    m_hasMountPoint      = false;    m_autoDeletePodcasts = false;    m_syncStats          = false;    m_transcode          = false;    m_transcodeAlways    = false;    m_transcodeRemove    = false;    m_configure          = false;    m_customButton       = true;    m_transfer           = false;    KToolBar       *toolbar         = MediaBrowser::instance()->getToolBar();    KToolBarButton *customButton    = toolbar->getButton( MediaBrowser::CUSTOM );    customButton->setText( i18n("Add computer") );    toolbar = CollectionBrowser::instance()->getToolBar();    toolbar->setIconText( KToolBar::IconTextRight, false );    m_broadcastButton = new KToolBarButton( "connect_creating", 0, toolbar, "broadcast_button",                                                          i18n("Share My Music") );    m_broadcastButton->setToggle( true );    QToolTip::add( customButton,      i18n( "List music from a remote host" ) );    QToolTip::add( m_broadcastButton, i18n( "If this button is checked, then your music will be exported to the network" ) );    connect( m_broadcastButton, SIGNAL( toggled(int) ), SLOT( broadcastButtonToggled() ) );    MediaBrowser::instance()->insertChild( this );}DaapClient::~DaapClient(){#if DNSSD_SUPPORT    delete m_browser;#endif}boolDaapClient::isConnected(){    return m_connected;}boolDaapClient::getCapacity(  KIO::filesize_t* /* total */, KIO::filesize_t* /* available */ ){    return false;}boolDaapClient::lockDevice(bool /*tryOnly = false*/ ){    return true;}voidDaapClient::unlockDevice(){    return;}boolDaapClient::openDevice(bool /* silent=false */){    DEBUG_BLOCK    m_connected = true;#if DNSSD_SUPPORT    if ( !m_browser )    {        m_browser = new DNSSD::ServiceBrowser("_daap._tcp");        m_browser->setName("daapServiceBrowser");        connect( m_browser, SIGNAL( serviceAdded( DNSSD::RemoteService::Ptr ) ),                      this,   SLOT( foundDaap   ( DNSSD::RemoteService::Ptr ) ) );        connect( m_browser, SIGNAL( serviceRemoved( DNSSD::RemoteService::Ptr ) ),                      this,   SLOT( serverOffline ( DNSSD::RemoteService::Ptr ) ) );        m_browser->startBrowse();    }#endif    QStringList sl = AmarokConfig::manuallyAddedServers();    foreach( sl )    {        QStringList current = QStringList::split(":", (*it) );        QString host = current.first();        Q_UINT16 port = current.last().toInt();        QString ip = resolve( host );        if( ip != "0" )        {             newHost( host, host, ip, port );        }    }    if( m_broadcastServer )        m_sharingServer = new DaapServer( this, "DaapServer" );    return true;}boolDaapClient::closeDevice(){    m_view->clear();    QObjectList* readers =  queryList( "Daap::Reader");    QObject* itRead;    for( itRead = readers->first(); itRead; itRead = readers->next() )    {        static_cast<Daap::Reader*>(itRead)->logoutRequest();        delete m_servers[ itRead->name() ];        m_servers.remove( itRead->name() );    }    m_connected = false;    m_servers.clear();#if DNSSD_SUPPORT    m_serverItemMap.clear();    delete m_browser;    m_browser = 0;#endif    delete m_sharingServer;    m_sharingServer = 0;    return true;}KURLDaapClient::getProxyUrl( const KURL& url ){    DEBUG_BLOCK    Daap::Proxy* daapProxy = new Daap::Proxy( url, this, "daapProxy" );    return daapProxy->proxyUrl();}voidDaapClient::synchronizeDevice(){    return;}MediaItem*DaapClient::copyTrackToDevice(const MetaBundle& /* bundle */){    return 0;}MediaItem*DaapClient::trackExists( const MetaBundle& ){    return 0;}intDaapClient::deleteItemFromDevice( MediaItem* /*item*/, int /*flags*/ ){    return 0;}voidDaapClient::rmbPressed( QListViewItem* qitem, const QPoint& point, int ){    DEBUG_BLOCK    enum Actions { APPEND, LOAD, QUEUE, INFO, CONNECT, REMOVE, DOWNLOAD };    MediaItem *item = dynamic_cast<MediaItem *>(qitem);    ServerItem* sitem = dynamic_cast<ServerItem *>(qitem);    if( !item )        return;    KURL::List urls;    KPopupMenu menu( m_view );    switch( item->type() )    {        case MediaItem::DIRECTORY:            menu.insertItem( SmallIconSet( "connect_creating" ), i18n( "&Connect" ), CONNECT );            if( sitem && !m_serverItemMap.contains( sitem->key() ) )            {                menu.insertItem( SmallIconSet( "remove" ), i18n("&Remove Computer"), REMOVE );            }            {                QStringList sl = m_serverItemMap.keys();                foreach( sl )                {                    debug() << (*it) << endl;                }                debug() << sitem->key() << endl;            }            break;        default:            urls = m_view->nodeBuildDragList( 0 );            menu.insertItem( SmallIconSet( Amarok::icon( "playlist" ) ), i18n( "&Load" ), LOAD );            menu.insertItem( SmallIconSet( Amarok::icon( "add_playlist" ) ), i18n( "&Append to Playlist" ), APPEND );            menu.insertItem( SmallIconSet( Amarok::icon( "fastforward" ) ), i18n( "&Queue Tracks" ), QUEUE );            menu.insertSeparator();            menu.insertItem( SmallIconSet( Amarok::icon( "playlist" ) ), i18n( "&Copy Files to Collection..." ), DOWNLOAD );            // albums and artists don't have bundles, so they crash... :(            if( item->bundle() )            {                menu.insertItem( SmallIconSet( Amarok::icon( "info" ) ), i18n( "Track &Information..." ), INFO );            }            break;    }    int id =  menu.exec( point );    switch( id )    {        case CONNECT:            if( ServerItem *s = dynamic_cast<ServerItem *>(item) )            {                s->reset();            }            item->setOpen( true );            break;        case LOAD:            Playlist::instance()->insertMedia( urls, Playlist::Replace );            break;        case APPEND:            Playlist::instance()->insertMedia( urls, Playlist::Append );            break;        case QUEUE:            Playlist::instance()->insertMedia( urls, Playlist::Queue );            break;        case INFO:            {                // The tag dialog automatically disables the widgets if the file is not local, which it is not.                TagDialog *dialog = new TagDialog( *item->bundle(), 0 );                dialog->show();            }            break;        case REMOVE:            if( sitem )            {                QStringList mas = AmarokConfig::manuallyAddedServers();                mas.remove( sitem->key() );                AmarokConfig::setManuallyAddedServers( mas );                delete sitem;            }            break;        case DOWNLOAD:            downloadSongs( urls );            break;    }}voidDaapClient::downloadSongs( KURL::List urls ){    DEBUG_BLOCK    KURL::List realStreamUrls;    KURL::List::Iterator it;    for( it = urls.begin(); it != urls.end(); ++it )        realStreamUrls << Daap::Proxy::realStreamUrl( (*it), getSession( (*it).host() + ':' + QString::number( (*it).port() ) ) );    ThreadManager::instance()->queueJob( new DaapDownloader( realStreamUrls ) );}voidDaapClient::serverOffline( DNSSD::RemoteService::Ptr service ){#if DNSSD_SUPPORT    DEBUG_BLOCK    QString key =  serverKey( service.data() );    if( m_serverItemMap.contains( key ) )    {        ServerItem* removeMe = m_serverItemMap[ key ];        if( removeMe )        {            delete removeMe;            removeMe = 0;        }        else            warning() << "root item already null" << endl;        m_serverItemMap.remove( key );    }    else        warning() << "removing non-existant service" << endl;#endif}#if DNSSD_SUPPORTQStringDaapClient::serverKey( const DNSSD::RemoteService* service ) const{    return ServerItem::key( service->hostName(), service->port() );}#endifvoidDaapClient::foundDaap( DNSSD::RemoteService::Ptr service ){#if DNSSD_SUPPORT    DEBUG_BLOCK    connect( service, SIGNAL( resolved( bool ) ), this, SLOT( resolvedDaap( bool ) ) );    service->resolveAsync();#endif}voidDaapClient::resolvedDaap( bool success ){#if DNSSD_SUPPORT    DEBUG_BLOCK    const DNSSD::RemoteService* service =  dynamic_cast<const DNSSD::RemoteService*>(sender());    if( !success || !service ) return;    debug() << service->serviceName() << ' ' << service->hostName() << ' ' << service->domain() << ' ' << service->type() << endl;    QString ip = resolve( service->hostName() );    if( ip == "0" || m_serverItemMap.contains(serverKey( service )) ) //same server from multiple interfaces        return;    m_serverItemMap[ serverKey( service ) ] = newHost( service->serviceName(), service->hostName(), ip, service->port() );#endif}voidDaapClient::createTree( const QString& /*host*/, Daap::SongList bundles ){    DEBUG_BLOCK    const Daap::Reader* callback = dynamic_cast<const Daap::Reader*>(sender());    if( !callback )    {        debug() << "No callback!" << endl;        return;    }    {        const QString hostKey = callback->name();        ServerInfo* si = new ServerInfo();        si->sessionId = callback->sessionId();        m_servers[ hostKey ] = si;    }    ServerItem* root = callback->rootMediaItem();    QStringList artists = bundles.keys();    foreach( artists )    {        MediaItem* parentArtist =  new MediaItem( root );        parentArtist->setType( MediaItem::ARTIST );        Daap::AlbumList albumMap = *( bundles.find(*it) );        parentArtist->setText( 0, (*albumMap.begin()).getFirst()->artist() ); //map was made case insensitively                                                                              //just get the displayed-case from                                                                              //the first track        QStringList albums = albumMap.keys();        for ( QStringList::Iterator itAlbum = albums.begin(); itAlbum != albums.end(); ++itAlbum )        {            MediaItem* parentAlbum = new MediaItem( parentArtist );            parentAlbum->setType( MediaItem::ALBUM );            MetaBundle* track;            Daap::TrackList trackList = *albumMap.find(*itAlbum);            parentAlbum->setText( 0, trackList.getFirst()->album() );            for( track = trackList.first(); track; track = trackList.next() )            {                if( m_removeDuplicates && trackExistsInCollection( track ) )                    continue;                MediaItem* childTrack = new MediaItem( parentAlbum );                childTrack->setText( 0, track->title() );                childTrack->setType( MediaItem::TRACK );                childTrack->setBundle( track );                childTrack->m_order = track->track();            }            if( !parentAlbum->childCount() )                delete parentAlbum;        }        if( !parentArtist->childCount() )            delete parentArtist;    }    root->resetTitle();    root->stopAnimation();    root->setOpen( true );}

⌨️ 快捷键说明

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