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 + -
显示快捷键?