ktrm.cpp

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

CPP
893
字号
/***************************************************************************    copyright            : (C) 2004 by Scott Wheeler    email                : wheeler@kde.org ***************************************************************************//*************************************************************************** *   This library is free software; you can redistribute it and/or modify  * *   it  under the terms of the GNU Lesser General Public License version  * *   2.1 as published by the Free Software Foundation.                     * *                                                                         * *   This library is distributed in the hope that it will be useful, but   * *   WITHOUT ANY WARRANTY; without even the implied warranty of            * *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     * *   Lesser General Public License for more details.                       * *                                                                         * *   You should have received a copy of the GNU Lesser General Public      * *   License along with this library; if not, write to the Free Software   * *   Foundation, Inc., 51 Franklin Steet, Fifth Floor, Boston, MA  02111-1307  * *   USA                                                                   * ***************************************************************************/#include "config.h"#include "debug.h"#include "statusbar.h"#define DEBUG_PREFIX "KTRM"#include "ktrm.h"#include <kapplication.h>#include <kio/job.h>#include <kio/jobclasses.h>#include <kprotocolmanager.h>#include <kurl.h>#include <kresolver.h>#include <qdom.h>#include <qmutex.h>#include <qevent.h>#include <qobject.h>#include <qfile.h>#include <qregexp.h>#if HAVE_TUNEPIMP#if HAVE_TUNEPIMP >= 5#include <tunepimp-0.5/tp_c.h>#else#include <tunepimp/tp_c.h>#endifclass KTRMLookup;extern "C"{#if HAVE_TUNEPIMP >= 4    static void TRMNotifyCallback(tunepimp_t pimp, void *data, TPCallbackEnum type, int fileId, TPFileStatus status);#else    static void TRMNotifyCallback(tunepimp_t pimp, void *data, TPCallbackEnum type, int fileId);#endif}/** * This represents the main TunePimp instance and handles incoming requests. */class KTRMRequestHandler{public:    static KTRMRequestHandler *instance()    {        static QMutex mutex;        mutex.lock();        static KTRMRequestHandler handler;        mutex.unlock();        return &handler;    }    int startLookup(KTRMLookup *lookup)    {        int id;        if(!m_fileMap.contains(lookup->file())) {#if HAVE_TUNEPIMP >= 4            id = tp_AddFile(m_pimp, QFile::encodeName(lookup->file()), 0);#else            id = tp_AddFile(m_pimp, QFile::encodeName(lookup->file()));#endif            m_fileMap.insert(lookup->file(), id);        }        else {            id = m_fileMap[lookup->file()];            tp_IdentifyAgain(m_pimp, id);        }        m_lookupMap[id] = lookup;        return id;    }    void endLookup(KTRMLookup *lookup)    {        tp_ReleaseTrack(m_pimp, tp_GetTrack(m_pimp, lookup->fileId()));        tp_Remove(m_pimp, lookup->fileId());        m_lookupMapMutex.lock();        m_lookupMap.remove(lookup->fileId());        m_fileMap.remove( lookup->file() );        m_lookupMapMutex.unlock();    }    bool lookupMapContains(int fileId) const    {        m_lookupMapMutex.lock();        bool contains = m_lookupMap.contains(fileId);        m_lookupMapMutex.unlock();        return contains;    }    KTRMLookup *lookup(int fileId) const    {        m_lookupMapMutex.lock();        KTRMLookup *l = m_lookupMap[fileId];        m_lookupMapMutex.unlock();        return l;    }    void removeFromLookupMap(int fileId)    {        m_lookupMapMutex.lock();        m_lookupMap.remove(fileId);        m_lookupMapMutex.unlock();    }    const tunepimp_t &tunePimp() const    {        return m_pimp;    }protected:    KTRMRequestHandler()    {        m_pimp = tp_New("KTRM", "0.1");        //tp_SetDebug(m_pimp, true);#if HAVE_TUNEPIMP < 5        tp_SetTRMCollisionThreshold(m_pimp, 100);        tp_SetAutoFileLookup(m_pimp,true);#endif        tp_SetAutoSaveThreshold(m_pimp, -1);        tp_SetMoveFiles(m_pimp, false);        tp_SetRenameFiles(m_pimp, false);#if HAVE_TUNEPIMP >= 4        tp_SetFileNameEncoding(m_pimp, "UTF-8");#else        tp_SetUseUTF8(m_pimp, true);#endif        tp_SetNotifyCallback(m_pimp, TRMNotifyCallback, 0);#if HAVE_TUNEPIMP < 5        KProtocolManager::reparseConfiguration();        if(KProtocolManager::useProxy()) {            QString noProxiesFor = KProtocolManager::noProxyFor();            QStringList noProxies = QStringList::split(QRegExp("[',''\t'' ']"), noProxiesFor);            bool useProxy = true;            char server[255];            short port;            tp_GetServer(m_pimp, server, 255, &port);            QString tunepimpHost = QString(server);            QString tunepimpHostWithPort = (tunepimpHost + ":%1").arg(port);            for(QStringList::ConstIterator it = noProxies.constBegin(); it != noProxies.constEnd(); ++it) {                QString normalizedHost = KNetwork::KResolver::normalizeDomain(*it);                if(normalizedHost == tunepimpHost ||                    tunepimpHost.endsWith('.' + normalizedHost)) {                    useProxy = false;                    break;                }                if(normalizedHost == tunepimpHostWithPort ||                    tunepimpHostWithPort.endsWith('.' + normalizedHost)) {                    useProxy = false;                    break;                }            }            if(KProtocolManager::useReverseProxy())                useProxy = !useProxy;            if(useProxy) {                KURL proxy = KProtocolManager::proxyFor("http");                tp_SetProxy(m_pimp, proxy.host().latin1(), short(proxy.port()));            }        }#else        tp_SetMusicDNSClientId(m_pimp, "0c6019606b1d8a54d0985e448f3603ca");#endif    }    ~KTRMRequestHandler()    {        tp_Delete(m_pimp);    }private:    tunepimp_t m_pimp;    QMap<int, KTRMLookup *> m_lookupMap;    QMap<QString, int> m_fileMap;    mutable QMutex m_lookupMapMutex;};/** * A custom event type used for signalling that a TRM lookup is finished. */class KTRMEvent : public QCustomEvent{public:    enum Status {        Recognized,        Unrecognized,        Collision,        PuidGenerated,        Error    };    KTRMEvent(int fileId, Status status) :        QCustomEvent(id),        m_fileId(fileId),        m_status(status) {}    int fileId() const    {        return m_fileId;    }    Status status() const    {        return m_status;    }    static const int id = User + 1984; // random, unique, event idprivate:    int m_fileId;    Status m_status;};/** * A helper class to intercept KTRMQueryEvents and call recognized() (from the GUI * thread) for the lookup. */class KTRMEventHandler : public QObject{public:    static void send(int fileId, KTRMEvent::Status status)    {        KApplication::postEvent(instance(), new KTRMEvent(fileId, status));    }protected:    KTRMEventHandler() : QObject() {}    static KTRMEventHandler *instance()    {        static QMutex mutex;        mutex.lock();        static KTRMEventHandler handler;        mutex.unlock();        return &handler;    }    virtual void customEvent(QCustomEvent *event)    {        if(!event->type() == KTRMEvent::id)            return;        KTRMEvent *e = static_cast<KTRMEvent *>(event);        static QMutex mutex;        mutex.lock();        if(!KTRMRequestHandler::instance()->lookupMapContains(e->fileId())) {            mutex.unlock();            return;        }        KTRMLookup *lookup = KTRMRequestHandler::instance()->lookup(e->fileId());#if HAVE_TUNEPIMP >= 4        if ( e->status() != KTRMEvent::Unrecognized)#endif            KTRMRequestHandler::instance()->removeFromLookupMap(e->fileId());        mutex.unlock();        switch(e->status()) {        case KTRMEvent::Recognized:            lookup->recognized();            break;        case KTRMEvent::Unrecognized:            lookup->unrecognized();            break;        case KTRMEvent::Collision:            lookup->collision();            break;        case KTRMEvent::PuidGenerated:            lookup->puidGenerated();            break;        case KTRMEvent::Error:            lookup->error();            break;        }    }};/** * Callback function for TunePimp lookup events. */#if HAVE_TUNEPIMP >= 4static void TRMNotifyCallback(tunepimp_t /*pimp*/, void */*data*/, TPCallbackEnum type, int fileId, TPFileStatus status)#elsestatic void TRMNotifyCallback(tunepimp_t pimp, void */*data*/, TPCallbackEnum type, int fileId)#endif{    if(type != tpFileChanged)        return;#if HAVE_TUNEPIMP < 4    track_t track = tp_GetTrack(pimp, fileId);    TPFileStatus status = tr_GetStatus(track);#endif    //debug() << "Status is: " << status << endl;    switch(status) {    case eRecognized:        KTRMEventHandler::send(fileId, KTRMEvent::Recognized);        break;    case eUnrecognized:        KTRMEventHandler::send(fileId, KTRMEvent::Unrecognized);        break;#if HAVE_TUNEPIMP >= 5    case ePUIDLookup:    case ePUIDCollision:    case eFileLookup:        KTRMEventHandler::send(fileId, KTRMEvent::PuidGenerated);        break;#else    case eTRMCollision:#if HAVE_TUNEPIMP >= 4    case eUserSelection:#endif        KTRMEventHandler::send(fileId, KTRMEvent::Collision);        break;#endif    case eError:        KTRMEventHandler::send(fileId, KTRMEvent::Error);        break;    default:        break;    }#if HAVE_TUNEPIMP < 4    tp_ReleaseTrack(pimp, track);#endif}////////////////////////////////////////////////////////////////////////////////// KTRMResult implementation////////////////////////////////////////////////////////////////////////////////class KTRMResult::KTRMResultPrivate{public:    KTRMResultPrivate() : track(0), year(0), relevance(0) {}    QString title;    QString artist;    QString album;    int track;    int year;    double relevance;    bool operator== (const KTRMResultPrivate &r) const;};bool KTRMResult::KTRMResultPrivate::operator==(const KTRMResultPrivate &r) const{	return (			title == r.title &&			artist == r.artist &&			album == r.album &&			track == r.track &&			year == r.year &&			relevance == r.relevance	       );}////////////////////////////////////////////////////////////////////////////////// KTRMResult public methods////////////////////////////////////////////////////////////////////////////////#endifKTRMResult::KTRMResult(){#if HAVE_TUNEPIMP    d = new KTRMResultPrivate;#endif}KTRMResult::KTRMResult(const KTRMResult &result){#if HAVE_TUNEPIMP    d = new KTRMResultPrivate(*result.d);#else    Q_UNUSED(result);#endif}KTRMResult::~KTRMResult(){#if HAVE_TUNEPIMP    delete d;#endif}QString KTRMResult::title() const{#if HAVE_TUNEPIMP    return d->title;#else    return QString();#endif}QString KTRMResult::artist() const{#if HAVE_TUNEPIMP    return d->artist;#else    return QString();#endif}QString KTRMResult::album() const{#if HAVE_TUNEPIMP    return d->album;#else    return QString();#endif}int KTRMResult::track() const

⌨️ 快捷键说明

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