From ed0574f6b72de70d69e1422ac049ffbdebe4bfbb Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Wed, 6 Apr 2011 17:20:31 -0400 Subject: [PATCH 01/75] fix epic fail of boolean condition --- src/libtomahawk/playlist/playlistmodel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libtomahawk/playlist/playlistmodel.cpp b/src/libtomahawk/playlist/playlistmodel.cpp index 9f95c554b..46ebf4a35 100644 --- a/src/libtomahawk/playlist/playlistmodel.cpp +++ b/src/libtomahawk/playlist/playlistmodel.cpp @@ -110,7 +110,7 @@ PlaylistModel::loadPlaylist( const Tomahawk::playlist_ptr& playlist, bool loadEn connect( plitem, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) ); - if( !entry->query()->resolvingFinished() && entry->query()->playable() ) { + if( !entry->query()->resolvingFinished() && !entry->query()->playable() ) { m_waitingForResolved.append( entry->query().data() ); connect( entry->query().data(), SIGNAL( resolvingFinished( bool ) ), this, SLOT( trackResolved( bool ) ) ); } From db7b2d2523b364cc5d212776547205b93f4f54e9 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Wed, 6 Apr 2011 21:34:59 -0400 Subject: [PATCH 02/75] don't assume that exit() will clean up the stack --- .../kdsingleapplicationguard.cpp | 231 +++++++++--------- 1 file changed, 118 insertions(+), 113 deletions(-) diff --git a/src/libtomahawk/kdsingleapplicationguard/kdsingleapplicationguard.cpp b/src/libtomahawk/kdsingleapplicationguard/kdsingleapplicationguard.cpp index 63893dbde..6ccfe4e39 100644 --- a/src/libtomahawk/kdsingleapplicationguard/kdsingleapplicationguard.cpp +++ b/src/libtomahawk/kdsingleapplicationguard/kdsingleapplicationguard.cpp @@ -8,11 +8,11 @@ #define KDSINGLEAPPLICATIONGUARD_MAX_COMMAND_LINE 1024 #endif - + KDSingleApplicationGuard::Instance::Instance( const QStringList& args, qint64 p ) - : arguments( args ), - pid( p ) +: arguments( args ), +pid( p ) { } @@ -61,31 +61,31 @@ void KDSingleApplicationGuard::timerEvent( QTimerEvent* ) using namespace kdtools; /*! - \class KDSingleApplicationGuard KDSingleApplicationGuard - \brief A guard to protect an application from having several instances. - - KDSingleApplicationGuard can be used to make sure only one instance of an - application is running at the same time. - - \note As KDSingleApplicationGuard uses QSharedMemory Qt 4.4 or later is required + * \class KDSingleApplicationGuard KDSingleApplicationGuard + * \brief A guard to protect an application from having several instances. + * + * KDSingleApplicationGuard can be used to make sure only one instance of an + * application is running at the same time. + * + * \note As KDSingleApplicationGuard uses QSharedMemory Qt 4.4 or later is required */ /*! - \fn void KDSingleApplicationGuard::instanceStarted() - This signal is emitted by the primary instance when ever one other - instance was started. + * \fn void KDSingleApplicationGuard::instanceStarted() + * This signal is emitted by the primary instance when ever one other + * instance was started. */ /*! - \fn void KDSingleApplicationGuard::instanceExited() - This signal is emitted by the primary instance when ever one other - instance was exited. + * \fn void KDSingleApplicationGuard::instanceExited() + * This signal is emitted by the primary instance when ever one other + * instance was exited. */ - + /*! - \fn void KDSingleApplicationGuard::becamePrimaryInstance() - This signal is emitted, when the current running application gets the new - primary application. The old primary application has quit. + * \fn void KDSingleApplicationGuard::becamePrimaryInstance() + * This signal is emitted, when the current running application gets the new + * primary application. The old primary application has quit. */ enum Command @@ -105,8 +105,8 @@ Q_DECLARE_OPERATORS_FOR_FLAGS( Commands ) struct ProcessInfo { explicit ProcessInfo( Command c = FreeInstance, const QStringList& arguments = QStringList(), qint64 p = -1 ) - : command( c ), - pid( p ) + : command( c ), + pid( p ) { std::fill_n( commandline, KDSINGLEAPPLICATIONGUARD_MAX_COMMAND_LINE, '\0' ); @@ -149,7 +149,7 @@ struct ProcessInfo bool operator==( const ProcessInfo& lhs, const ProcessInfo& rhs ) { return lhs.command == rhs.command && - ::memcmp( lhs.commandline, rhs.commandline, KDSINGLEAPPLICATIONGUARD_MAX_COMMAND_LINE ) == 0; + ::memcmp( lhs.commandline, rhs.commandline, KDSINGLEAPPLICATIONGUARD_MAX_COMMAND_LINE ) == 0; } bool operator!=( const ProcessInfo& lhs, const ProcessInfo& rhs ) @@ -158,21 +158,21 @@ bool operator!=( const ProcessInfo& lhs, const ProcessInfo& rhs ) } /*! - This struct contains information about the managed process system. - \internal + * This struct contains information about the managed process system. + * \internal */ struct InstanceRegister { InstanceRegister( KDSingleApplicationGuard::Policy policy = KDSingleApplicationGuard::NoPolicy ) - : policy( policy ) + : policy( policy ) { std::fill_n( info, KDSINGLEAPPLICATIONGUARD_NUMBER_OF_PROCESSES, ProcessInfo() ); ::memcpy( magicCookie, "kdsingleapp", 12 ); } /*! - Returns wheter this register was properly initialized by the first instance. - */ + * Returns wheter this register was properly initialized by the first instance. + */ bool isValid() const { return ::strcmp( magicCookie, "kdsingleapp" ) == 0; @@ -192,18 +192,18 @@ bool operator==( const InstanceRegister& lhs, const InstanceRegister& rhs ) if( lhs.info[ i ] != rhs.info[ i ] ) return false; - return true; + return true; } /*! - \internal + * \internal */ class KDSingleApplicationGuard::Private { public: Private( KDSingleApplicationGuard* qq ) - : q( qq ), - id( -1 ) + : q( qq ), + id( -1 ) { if( primaryInstance == 0 ) primaryInstance = q; @@ -258,28 +258,28 @@ void SIGINT_handler( int sig ) #endif /*! - Creates a new KDSingleApplicationGuard guarding \a parent from mulitply instances. - If \a policy is AutoKillOtherInstances (the default), all instances, which try to start, - are killed automatically and instanceStarted() is emitted. - If \a policy is NoPolicy, the other instance will run and instanceStarted() is emitted. + * Creates a new KDSingleApplicationGuard guarding \a parent from mulitply instances. + * If \a policy is AutoKillOtherInstances (the default), all instances, which try to start, + * are killed automatically and instanceStarted() is emitted. + * If \a policy is NoPolicy, the other instance will run and instanceStarted() is emitted. */ KDSingleApplicationGuard::KDSingleApplicationGuard( QCoreApplication* parent, Policy policy ) - : QObject( parent ), - d( new Private( this ) ) +: QObject( parent ), +d( new Private( this ) ) { const QString name = parent->applicationName(); Q_ASSERT_X( !name.isEmpty(), "KDSingleApplicationGuard::KDSingleApplicationGuard", "applicationName must not be emty" ); d->mem.setKey( name ); - + // if another instance crashed, the shared memory segment is still there on Unix // the following lines trigger deletion in that case -#ifndef Q_WS_WIN + #ifndef Q_WS_WIN d->mem.attach(); d->mem.detach(); -#endif - + #endif + d->policy = policy; - + const bool created = d->mem.create( sizeof( InstanceRegister ) ); if( !created ) { @@ -288,7 +288,7 @@ KDSingleApplicationGuard::KDSingleApplicationGuard( QCoreApplication* parent, Po qWarning( "KDSingleApplicationGuard: Could neither create nor attach to shared memory segment." ); return; } - + // lets wait till the other instance initialized the register bool initialized = false; while( !initialized ) @@ -298,52 +298,57 @@ KDSingleApplicationGuard::KDSingleApplicationGuard( QCoreApplication* parent, Po } } - - KDLockedSharedMemoryPointer< InstanceRegister > instances( &d->mem ); - - if( !created ) + bool killMyself = false; { - // we're _not_ the first instance - // but the - bool killOurSelf = false; - - // find a new slot... - d->id = std::find( instances->info, instances->info + KDSINGLEAPPLICATIONGUARD_NUMBER_OF_PROCESSES, ProcessInfo() ) - instances->info; - ProcessInfo& info = instances->info[ d->id ]; - info = ProcessInfo( NewInstance, parent->arguments(), QCoreApplication::applicationPid() ); - killOurSelf = instances->policy == AutoKillOtherInstances; - d->policy = instances->policy; + KDLockedSharedMemoryPointer< InstanceRegister > instances( &d->mem ); - // but the signal that we tried to start was sent to the primary application - if( killOurSelf ) + if( !created ) { - info.command |= ExitedInstance; - exit( 1 ); + // we're _not_ the first instance + // but the + bool killOurSelf = false; + + // find a new slot... + d->id = std::find( instances->info, instances->info + KDSINGLEAPPLICATIONGUARD_NUMBER_OF_PROCESSES, ProcessInfo() ) - instances->info; + ProcessInfo& info = instances->info[ d->id ]; + info = ProcessInfo( NewInstance, parent->arguments(), QCoreApplication::applicationPid() ); + killOurSelf = instances->policy == AutoKillOtherInstances; + d->policy = instances->policy; + + // but the signal that we tried to start was sent to the primary application + if( killOurSelf ) + { + info.command |= ExitedInstance; + killMyself = true; + } + } + else + { + // ok.... we are the first instance + InstanceRegister reg( policy ); // create a new list + d->id = 0; // our id = 0 + // and we've no command + reg.info[ 0 ] = ProcessInfo( NoCommand, parent->arguments(), QCoreApplication::applicationPid() ); + *instances = reg; // push this is the process list into shared memory } } - else - { - // ok.... we are the first instance - InstanceRegister reg( policy ); // create a new list - d->id = 0; // our id = 0 - // and we've no command - reg.info[ 0 ] = ProcessInfo( NoCommand, parent->arguments(), QCoreApplication::applicationPid() ); - *instances = reg; // push this is the process list into shared memory - } + // call exit after we let the locker release our memory, as exit() is not guaranteed to clean up objects on the stack + if ( killMyself ) + exit( 1 ); -#ifndef Q_WS_WIN - ::signal( SIGINT, SIGINT_handler ); -#endif + #ifndef Q_WS_WIN + ::signal( SIGINT, SIGINT_handler ); + #endif - // now listen for commands - startTimer( 250 ); + // now listen for commands + startTimer( 250 ); } /*! - Destroys this SingleApplicationGuard. - If this instance has been the primary instance and no other instance is existing anymore, - the application is shut down completely. Otherwise the destructor selects another instance to - be the primary instances. + * Destroys this SingleApplicationGuard. + * If this instance has been the primary instance and no other instance is existing anymore, + * the application is shut down completely. Otherwise the destructor selects another instance to + * be the primary instances. */ KDSingleApplicationGuard::~KDSingleApplicationGuard() { @@ -352,16 +357,16 @@ KDSingleApplicationGuard::~KDSingleApplicationGuard() d->shutdownInstance(); } - -/*! - \property KDSingleApplicationGuard::primaryInstance - Determines wheter this instance is the primary instance. - The primary instance is the first instance which was started or an instance which - got selected by KDSingleApplicationGuard's destructor, when the primary instance was - shut down. - Get this property's value using %isPrimaryInstance(), and monitor changes to it - using becamePrimaryInstance(). +/*! + * \property KDSingleApplicationGuard::primaryInstance + * Determines wheter this instance is the primary instance. + * The primary instance is the first instance which was started or an instance which + * got selected by KDSingleApplicationGuard's destructor, when the primary instance was + * shut down. + * + * Get this property's value using %isPrimaryInstance(), and monitor changes to it + * using becamePrimaryInstance(). */ bool KDSingleApplicationGuard::isPrimaryInstance() const { @@ -369,12 +374,12 @@ bool KDSingleApplicationGuard::isPrimaryInstance() const } /*! - \property KDSingleApplicationGuard::Policy - Specifies the policy KDSingleApplicationGuard is using when new instances are started. - This can only be set in the primary instance. - - Get this property's value using %policy(), set it using %setPolicy(), and monitor changes - to it using policyChanged(). + * \property KDSingleApplicationGuard::Policy + * Specifies the policy KDSingleApplicationGuard is using when new instances are started. + * This can only be set in the primary instance. + * + * Get this property's value using %policy(), set it using %setPolicy(), and monitor changes + * to it using policyChanged(). */ KDSingleApplicationGuard::Policy KDSingleApplicationGuard::policy() const { @@ -394,7 +399,7 @@ void KDSingleApplicationGuard::setPolicy( Policy policy ) } /*! - Returns a list of all currently running instances. + * Returns a list of all currently running instances. */ QList< KDSingleApplicationGuard::Instance > KDSingleApplicationGuard::instances() const { @@ -409,10 +414,10 @@ QList< KDSingleApplicationGuard::Instance > KDSingleApplicationGuard::instances( return result; } -/*! - Shuts down all other instances. This can only be called from the - the primary instance. - Shut down is done gracefully via QCoreApplication::quit(). +/*! + * Shuts down all other instances. This can only be called from the + * the primary instance. + * Shut down is done gracefully via QCoreApplication::quit(). */ void KDSingleApplicationGuard::shutdownOtherInstances() { @@ -426,9 +431,9 @@ void KDSingleApplicationGuard::shutdownOtherInstances() } /*! - Kills all other instances. This can only be called from the - the primary instance. - Killing is done via exit(1) + * Kills all other instances. This can only be called from the + * the primary instance. + * Killing is done via exit(1) */ void KDSingleApplicationGuard::killOtherInstances() { @@ -442,7 +447,7 @@ void KDSingleApplicationGuard::killOtherInstances() } /*! - \reimp + * \reimp */ void KDSingleApplicationGuard::timerEvent( QTimerEvent* event ) { @@ -456,11 +461,11 @@ void KDSingleApplicationGuard::timerEvent( QTimerEvent* event ) { KDLockedSharedMemoryPointer< InstanceRegister > instances( &d->mem ); - + for( int i = 1; i < KDSINGLEAPPLICATIONGUARD_NUMBER_OF_PROCESSES; ++i ) { ProcessInfo& info = instances->info[ i ]; - if( info.command & NewInstance ) + if( info.command & NewInstance ) { startedInstances.push_back( Instance( info.arguments(), info.pid ) ); info.command &= ~NewInstance; // clear NewInstance flag @@ -472,7 +477,7 @@ void KDSingleApplicationGuard::timerEvent( QTimerEvent* event ) } } } - + // one signal for every new instance - _after_ the memory segment was unlocked again for( QList< Instance >::const_iterator it = startedInstances.begin(); it != startedInstances.end(); ++it ) emit instanceStarted( *it ); @@ -495,7 +500,7 @@ void KDSingleApplicationGuard::timerEvent( QTimerEvent* event ) if( instances->info[ d->id ].command & BecomePrimaryCommand ) { // we became primary! - instances->info[ 0 ] = instances->info[ d->id ]; + instances->info[ 0 ] = instances->info[ d->id ]; instances->info[ d->id ] = ProcessInfo(); // change our id to 0 and declare the old slot as free d->id = 0; emit becamePrimaryInstance(); @@ -510,7 +515,7 @@ void KDSingleApplicationGuard::timerEvent( QTimerEvent* event ) d->id = -1; // becauso our d'tor won't be called anymore } } - + if( killOurSelf ) // kill our self takes precedence exit( 1 ); else if( shutDownOurSelf ) @@ -590,14 +595,14 @@ KDAB_UNITTEST_SIMPLE( KDSingleApplicationGuard, "kdcoretools" ) { spy3 = new QSignalSpy( guard3, SIGNAL( becamePrimaryInstance() ) ); assertFalse( guard3->isPrimaryInstance() ); } - + wait( 1000 ); assertEqual( spy3->count(), 1 ); assertEqual( guard3->instances().count(), 1 ); assertTrue( guard3->isPrimaryInstance() ); assertEqual( guard3->instances().first().arguments, qApp->arguments() ); - + QSignalSpy spyStarted( guard3, SIGNAL( instanceStarted( KDSingleApplicationGuard::Instance ) ) ); QSignalSpy spyExited( guard3, SIGNAL( instanceExited( KDSingleApplicationGuard::Instance ) ) ); @@ -609,13 +614,13 @@ KDAB_UNITTEST_SIMPLE( KDSingleApplicationGuard, "kdcoretools" ) { assertEqual( spyStarted.count(), 2 ); } - + wait( 1000 ); assertEqual( spyExited.count(), 2 ); delete spy3; delete guard3; - } +} #endif // KDTOOLSCORE_UNITTESTS From f6d4e0c63af9476f3d508ecb9d5760a3e9df6a5b Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Fri, 25 Mar 2011 13:55:28 +0000 Subject: [PATCH 03/75] * Re-added launch page to installer. --- admin/win/nsi/revision.txt | 2 +- admin/win/nsi/tomahawk.nsi | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/admin/win/nsi/revision.txt b/admin/win/nsi/revision.txt index 105d7d9ad..0fd0714a5 100644 --- a/admin/win/nsi/revision.txt +++ b/admin/win/nsi/revision.txt @@ -1 +1 @@ -100 \ No newline at end of file +103 \ No newline at end of file diff --git a/admin/win/nsi/tomahawk.nsi b/admin/win/nsi/tomahawk.nsi index 416944114..11c2469ba 100644 --- a/admin/win/nsi/tomahawk.nsi +++ b/admin/win/nsi/tomahawk.nsi @@ -9,7 +9,7 @@ !define OPTION_SECTION_SC_DESKTOP !define OPTION_SECTION_SC_QUICK_LAUNCH !define OPTION_FINISHPAGE -;!define OPTION_FINISHPAGE_LAUNCHER +!define OPTION_FINISHPAGE_LAUNCHER !define OPTION_FINISHPAGE_RELEASE_NOTES ;----------------------------------------------------------------------------- From 0c52b37bb25f0921e4f4f9311f76f7cd2a81308b Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Wed, 6 Apr 2011 19:42:50 -0400 Subject: [PATCH 04/75] InfoSystemCache saving and loading from disk works. We might have to tweak exactly how it's stored on disk at some point, depending on efficiency, but this works. --- src/infosystem/infosystemcache.cpp | 68 +++++++++++++++++++++--------- src/infosystem/infosystemcache.h | 4 +- 2 files changed, 49 insertions(+), 23 deletions(-) diff --git a/src/infosystem/infosystemcache.cpp b/src/infosystem/infosystemcache.cpp index 3a86c5634..7d73c6ade 100644 --- a/src/infosystem/infosystemcache.cpp +++ b/src/infosystem/infosystemcache.cpp @@ -39,13 +39,11 @@ InfoSystemCache::InfoSystemCache( QObject* parent ) for( int i = 0; i <= InfoNoInfo; i++ ) { InfoType type = (InfoType)(i); - if( m_dirtySet.contains( type ) && m_dataCache.contains( type ) ) - { - QString cacheDir = cacheBaseDir + QString::number( i ); - QDir dir( cacheDir ); - if( dir.exists() && QFile::exists( QString( cacheDir + '/' + QString::number( i ) ) ) ) - loadCache( type, QString( cacheDir + '/' + QString::number( i ) ) ); - } + QString cacheDir = cacheBaseDir + "/InfoSystemCache/" + QString::number( i ); + QString cacheFile = cacheDir + '/' + QString::number( i ); + QDir dir( cacheDir ); + if( dir.exists() && QFile::exists( cacheFile ) ) + loadCache( type, cacheFile ); } } @@ -60,7 +58,7 @@ InfoSystemCache::~InfoSystemCache() InfoType type = (InfoType)(i); if( m_dirtySet.contains( type ) && m_dataCache.contains( type ) ) { - QString cacheDir = cacheBaseDir + QString::number( i ); + QString cacheDir = cacheBaseDir + "/InfoSystemCache/" + QString::number( i ); saveCache( type, cacheDir ); } } @@ -85,8 +83,8 @@ void InfoSystemCache::updateCacheSlot( Tomahawk::InfoSystem::InfoCacheCriteria criteria, Tomahawk::InfoSystem::InfoType type, QVariant output ) { qDebug() << Q_FUNC_INFO; - QHash< InfoCacheCriteria, QVariant > typedatacache; - QHash< InfoCacheCriteria, QDateTime > typetimecache; + QHash< InfoCacheCriteria, QVariant > typedatacache = m_dataCache[type]; + QHash< InfoCacheCriteria, QDateTime > typetimecache = m_timeCache[type]; typedatacache[criteria] = output; typetimecache[criteria] = QDateTime::currentDateTimeUtc(); m_dataCache[type] = typedatacache; @@ -96,9 +94,32 @@ InfoSystemCache::updateCacheSlot( Tomahawk::InfoSystem::InfoCacheCriteria criter void -InfoSystemCache::loadCache( InfoType type, const QString &cacheDir ) +InfoSystemCache::loadCache( InfoType type, const QString &cacheFile ) { qDebug() << Q_FUNC_INFO; + QSettings cachedSettings( cacheFile, QSettings::IniFormat ); + + foreach( QString group, cachedSettings.childGroups() ) + { + QHash< InfoCacheCriteria, QVariant > dataHash = m_dataCache[type]; + QHash< InfoCacheCriteria, QDateTime > dateHash = m_timeCache[type]; + InfoCacheCriteria criteria; + cachedSettings.beginGroup( group ); + int numCriteria = cachedSettings.beginReadArray( "criteria" ); + for( int i = 0; i < numCriteria; i++ ) + { + cachedSettings.setArrayIndex( i ); + QStringList criteriaValues = cachedSettings.value( QString::number( i ) ).toStringList(); + for( int j = 0; j < criteriaValues.length(); j += 2 ) + criteria[criteriaValues.at( j )] = criteriaValues.at( j + 1 ); + } + cachedSettings.endArray(); + dataHash[criteria] = cachedSettings.value( "data" ); + dateHash[criteria] = cachedSettings.value( "time" ).toDateTime(); + cachedSettings.endGroup(); + m_dataCache[type] = dataHash; + m_timeCache[type] = dateHash; + } } @@ -117,22 +138,27 @@ InfoSystemCache::saveCache( InfoType type, const QString &cacheDir ) } } - QSettings cacheFile( QString( cacheDir + '/' + QString::number( (int)type ) ), QSettings::IniFormat ); - + QSettings cachedSettings( QString( cacheDir + '/' + QString::number( (int)type ) ), QSettings::IniFormat ); + + int criteriaNumber = 0; + foreach( InfoCacheCriteria criteria, m_dataCache[type].keys() ) { - cacheFile.beginGroup( "type_" + QString::number( type ) ); - cacheFile.beginWriteArray( "criteria" ); + cachedSettings.beginGroup( "group_" + QString::number( criteriaNumber ) ); + cachedSettings.beginWriteArray( "criteria" ); QStringList keys = criteria.keys(); for( int i = 0; i < criteria.size(); i++ ) { - cacheFile.setArrayIndex( i ); - cacheFile.setValue( keys.at( i ), criteria[keys.at( i )] ); + cachedSettings.setArrayIndex( i ); + QStringList critVal; + critVal << keys.at( i ) << criteria[keys.at( i )]; + cachedSettings.setValue( QString::number( i ), critVal ); } - cacheFile.endArray(); - cacheFile.setValue( "data", m_dataCache[type][criteria] ); - cacheFile.setValue( "time", m_timeCache[type][criteria] ); - cacheFile.endGroup(); + cachedSettings.endArray(); + cachedSettings.setValue( "data", m_dataCache[type][criteria] ); + cachedSettings.setValue( "time", m_timeCache[type][criteria] ); + cachedSettings.endGroup(); + ++criteriaNumber; } m_dirtySet.remove( type ); diff --git a/src/infosystem/infosystemcache.h b/src/infosystem/infosystemcache.h index b74cf8a40..ca347f7bc 100644 --- a/src/infosystem/infosystemcache.h +++ b/src/infosystem/infosystemcache.h @@ -49,8 +49,8 @@ public slots: void updateCacheSlot( Tomahawk::InfoSystem::InfoCacheCriteria criteria, Tomahawk::InfoSystem::InfoType type, QVariant output ); private: - void loadCache( InfoType type, const QString &cache ); - void saveCache( InfoType type, const QString &cache ); + void loadCache( InfoType type, const QString &cacheFile ); + void saveCache( InfoType type, const QString &cacheDir ); QHash< InfoType, QHash< InfoCacheCriteria, QVariant > > m_dataCache; QHash< InfoType, QHash< InfoCacheCriteria, QDateTime > > m_timeCache; From 8690a76df70598af60539bada28649f43b12231b Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Wed, 6 Apr 2011 19:51:58 -0400 Subject: [PATCH 05/75] Fix hang-on-exit in ScanManager. Turns out all it needed was to be explicitly deleted; I guess the parenting wasn't working right, or something? --- include/tomahawk/tomahawkapp.h | 2 ++ src/scanmanager.cpp | 2 +- src/tomahawkapp.cpp | 5 +++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/include/tomahawk/tomahawkapp.h b/include/tomahawk/tomahawkapp.h index 7775a6528..5919a4496 100644 --- a/include/tomahawk/tomahawkapp.h +++ b/include/tomahawk/tomahawkapp.h @@ -44,6 +44,7 @@ class AudioEngine; class Database; +class ScanManager; class SipHandler; class TomahawkSettings; class XMPPBot; @@ -118,6 +119,7 @@ private: QList m_scriptResolvers; Database* m_database; + ScanManager *m_scanManager; AudioEngine* m_audioEngine; SipHandler* m_sipHandler; Servent* m_servent; diff --git a/src/scanmanager.cpp b/src/scanmanager.cpp index 0073c73b9..dba8ffcc3 100644 --- a/src/scanmanager.cpp +++ b/src/scanmanager.cpp @@ -88,7 +88,7 @@ ScanManager::~ScanManager() QCoreApplication::processEvents( QEventLoop::AllEvents, 200 ); TomahawkUtils::Sleep::msleep( 100 ); } - + if( m_scanner ) { delete m_scanner; diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index 95fbfb05c..31630965e 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -145,6 +145,7 @@ using namespace Tomahawk; TomahawkApp::TomahawkApp( int& argc, char *argv[] ) : TOMAHAWK_APPLICATION( argc, argv ) , m_database( 0 ) + , m_scanManager( 0 ) , m_audioEngine( 0 ) , m_sipHandler( 0 ) , m_servent( 0 ) @@ -173,7 +174,7 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] ) new TomahawkSettings( this ); m_audioEngine = new AudioEngine; - new ScanManager( this ); + m_scanManager = new ScanManager( this ); new Pipeline( this ); m_servent = new Servent( this ); @@ -294,7 +295,7 @@ TomahawkApp::~TomahawkApp() delete m_sipHandler; delete m_servent; - + delete m_scanManager; #ifndef TOMAHAWK_HEADLESS delete m_mainwindow; delete m_audioEngine; From 83909e53f90a4520b941f953d297789477d18717 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Wed, 6 Apr 2011 19:58:24 -0400 Subject: [PATCH 06/75] Don't unconditionally scan for changes on startup --- src/scanmanager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scanmanager.cpp b/src/scanmanager.cpp index dba8ffcc3..f28cf0f82 100644 --- a/src/scanmanager.cpp +++ b/src/scanmanager.cpp @@ -146,7 +146,7 @@ ScanManager::setInitialPaths( QMap< QString, unsigned int > pathMap ) qDebug() << "Adding " << path << " to watcher"; m_dirWatcher->addPath( path ); } - if( TomahawkSettings::instance()->hasScannerPaths() ) + if( TomahawkSettings::instance()->hasScannerPaths() && TomahawkSettings::instance()->watchForChanges() ) runManualScan( TomahawkSettings::instance()->scannerPaths() ); } From 87c554c6f0fc71d46f2bc001c89897b3d54b9983 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Thu, 7 Apr 2011 04:47:31 +0200 Subject: [PATCH 07/75] * Fixed TomahawkApp CTOR for secondary instances. --- include/tomahawk/tomahawkapp.h | 11 ++-- src/main.cpp | 16 +++--- src/tomahawkapp.cpp | 94 ++++++++++++++++++---------------- 3 files changed, 66 insertions(+), 55 deletions(-) diff --git a/include/tomahawk/tomahawkapp.h b/include/tomahawk/tomahawkapp.h index 7775a6528..fe8648ad5 100644 --- a/include/tomahawk/tomahawkapp.h +++ b/include/tomahawk/tomahawkapp.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -78,6 +78,7 @@ public: TomahawkApp( int& argc, char *argv[] ); virtual ~TomahawkApp(); + void init(); static TomahawkApp* instance(); SipHandler* sipHandler() { return m_sipHandler; } @@ -98,10 +99,10 @@ public: // because QApplication::arguments() is expensive bool scrubFriendlyName() const { return m_scrubFriendlyName; } - + public slots: void instanceStarted( KDSingleApplicationGuard::Instance ); - + private slots: void setupSIP(); @@ -124,14 +125,14 @@ private: XMPPBot* m_xmppBot; Tomahawk::ShortcutHandler* m_shortcutHandler; bool m_scrubFriendlyName; - + #ifdef LIBLASTFM_FOUND Scrobbler* m_scrobbler; #endif #ifndef TOMAHAWK_HEADLESS TomahawkWindow* m_mainwindow; -#endif +#endif bool m_headless; diff --git a/src/main.cpp b/src/main.cpp index 3a6d6936e..f213d74de 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -18,15 +18,15 @@ #include "tomahawk/tomahawkapp.h" +#include "kdsingleapplicationguard/kdsingleapplicationguard.h" + #ifdef Q_WS_MAC #include "tomahawkapp_mac.h" #include static pascal OSErr appleEventHandler( const AppleEvent*, AppleEvent*, long ); #endif -#include - -#include "kdsingleapplicationguard/kdsingleapplicationguard.h" + int main( int argc, char *argv[] ) { @@ -42,11 +42,15 @@ main( int argc, char *argv[] ) TomahawkApp a( argc, argv ); KDSingleApplicationGuard guard( &a, KDSingleApplicationGuard::AutoKillOtherInstances ); - QObject::connect( &guard, SIGNAL( instanceStarted( KDSingleApplicationGuard::Instance ) ), &a, SLOT( instanceStarted( KDSingleApplicationGuard::Instance ) ) ); - + QObject::connect( &guard, SIGNAL( instanceStarted( KDSingleApplicationGuard::Instance ) ), &a, SLOT( instanceStarted( KDSingleApplicationGuard::Instance ) ) ); + + if ( guard.isPrimaryInstance() ) + a.init(); + return a.exec(); } + #ifdef Q_WS_MAC static pascal OSErr appleEventHandler( const AppleEvent* e, AppleEvent*, long ) diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index e4198383f..826887587 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -152,31 +152,53 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] ) , m_mainwindow( 0 ) , m_infoSystem( 0 ) { - qsrand( QTime( 0, 0, 0 ).secsTo( QTime::currentTime() ) ); - -#ifdef TOMAHAWK_HEADLESS - m_headless = true; -#else - m_mainwindow = 0; - m_headless = arguments().contains( "--headless" ); - setWindowIcon( QIcon( RESPATH "icons/tomahawk-icon-128x128.png" ) ); -#endif - qDebug() << "TomahawkApp thread:" << this->thread(); setOrganizationName( QLatin1String( ORGANIZATION_NAME ) ); setOrganizationDomain( QLatin1String( ORGANIZATION_DOMAIN ) ); setApplicationName( QLatin1String( APPLICATION_NAME ) ); setApplicationVersion( QLatin1String( VERSION ) ); - registerMetaTypes(); setupLogfile(); - +} + + +TomahawkApp::~TomahawkApp() +{ + qDebug() << Q_FUNC_INFO; + + delete m_sipHandler; + delete m_servent; + +#ifndef TOMAHAWK_HEADLESS + delete m_mainwindow; + delete m_audioEngine; +#endif + + delete m_database; +} + + +void +TomahawkApp::init() +{ + qsrand( QTime( 0, 0, 0 ).secsTo( QTime::currentTime() ) ); + + #ifdef TOMAHAWK_HEADLESS + m_headless = true; + #else + m_mainwindow = 0; + m_headless = arguments().contains( "--headless" ); + setWindowIcon( QIcon( RESPATH "icons/tomahawk-icon-128x128.png" ) ); + #endif + + registerMetaTypes(); + Echonest::Config::instance()->setAPIKey( "JRIHWEP6GPOER2QQ6" ); - + new TomahawkSettings( this ); m_audioEngine = new AudioEngine; new ScanManager( this ); new Pipeline( this ); - + m_servent = new Servent( this ); connect( m_servent, SIGNAL( ready() ), SLOT( setupSIP() ) ); @@ -185,15 +207,15 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] ) qDebug() << "Init Echonest Factory."; GeneratorFactory::registerFactory( "echonest", new EchonestFactory ); - + m_scrubFriendlyName = arguments().contains( "--demo" ); // Register shortcut handler for this platform -#ifdef Q_WS_MAC + #ifdef Q_WS_MAC m_shortcutHandler = new MacShortcutHandler( this ); Tomahawk::setShortcutHandler( static_cast( m_shortcutHandler) ); Tomahawk::setApplicationHandler( this ); -#endif + #endif // Connect up shortcuts if ( m_shortcutHandler ) @@ -208,7 +230,7 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] ) connect( m_shortcutHandler, SIGNAL( mute() ), m_audioEngine, SLOT( mute() ) ); } -#ifdef LIBLASTFM_FOUND + #ifdef LIBLASTFM_FOUND qDebug() << "Init Scrobbler."; m_scrobbler = new Scrobbler( this ); qDebug() << "Setting NAM."; @@ -225,10 +247,10 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] ) connect( m_audioEngine, SIGNAL( stopped() ), m_scrobbler, SLOT( trackStopped() ), Qt::QueuedConnection ); -#else + #else qDebug() << "Setting NAM."; TomahawkUtils::setNam( new QNetworkAccessManager ); -#endif + #endif // Set up proxy if( TomahawkSettings::instance()->proxyType() != QNetworkProxy::NoProxy && @@ -258,7 +280,7 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] ) m_mainwindow->setWindowTitle( "Tomahawk" ); m_mainwindow->show(); } -#endif + #endif qDebug() << "Init Local Collection."; initLocalCollection(); @@ -273,28 +295,12 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] ) startHTTP(); } -#ifndef TOMAHAWK_HEADLESS + #ifndef TOMAHAWK_HEADLESS if ( !TomahawkSettings::instance()->hasScannerPath() ) { m_mainwindow->showSettingsDialog(); } -#endif -} - - -TomahawkApp::~TomahawkApp() -{ - qDebug() << Q_FUNC_INFO; - - delete m_sipHandler; - delete m_servent; - -#ifndef TOMAHAWK_HEADLESS - delete m_mainwindow; - delete m_audioEngine; -#endif - - delete m_database; + #endif } @@ -332,7 +338,7 @@ TomahawkApp::registerMetaTypes() qRegisterMetaType< QMap >("QMap"); qRegisterMetaType< QMap< QString, plentry_ptr > >("QMap< QString, plentry_ptr >"); qRegisterMetaType< QHash< QString, QMap > >("QHash< QString, QMap >"); - + qRegisterMetaType< GeneratorMode>("GeneratorMode"); qRegisterMetaType("Tomahawk::GeneratorMode"); // Extra definition for namespaced-versions of signals/slots required @@ -525,16 +531,16 @@ TomahawkApp::loadUrl( const QString& url ) } -void +void TomahawkApp::instanceStarted( KDSingleApplicationGuard::Instance instance ) { qDebug() << "INSTANCE STARTED!" << instance.pid << instance.arguments; - - if( instance.arguments.size() < 2 ) + + if( instance.arguments.size() < 2 ) { return; } - + loadUrl( instance.arguments.at( 1 ) ); } From 3b3ff063dc26ed291c6396ba1f2ed141aa2d0eeb Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Thu, 7 Apr 2011 05:07:14 +0200 Subject: [PATCH 08/75] * Updated Changelog. --- ChangeLog | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 88ee61dd1..75917dc87 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,9 +9,10 @@ Version 0.0.3: * Don't automatically try to resolve all incoming playback logs. This speeds up importing sources a lot. * Faster painting of playlists with lots of unresolved tracks. - * The tomahawk:// protocol handler works on Windows now. - * Fixed launching Tomahawk from Windows installer with admin privileges. * Prefer local results when results' score is equal. + * (Windows) The tomahawk:// protocol handler works on Windows now. + * (Windows) Fixed launching Tomahawk from Windows installer with admin privileges. + * (Windows) Prevent launching a second instance on Windows. Version 0.0.2: * Don't reconnect to Jabber if the settings dialog is closed successfully @@ -27,7 +28,6 @@ Version 0.0.2: the Tomahawk XMPP presence. * Incompatible change: Twitter SIP protocol has changed slightly. 0.0.1 clients will not be able to talk to newer clients. - * Hopefully fixed crashes during Twitter authentication. * Don't let long playlist or summary names force a large Tomahawk window. * Tomahawk now asks you to authorize new contacts. From c6442e4dfda10a4ca72a4bc489bf3467f0355e34 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Wed, 6 Apr 2011 23:15:16 -0400 Subject: [PATCH 09/75] changelog++ --- ChangeLog | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ChangeLog b/ChangeLog index 75917dc87..2db4e9bd0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,8 @@ Version 0.0.3: + * Show spinner while resolving playlists. + * Go back to previous page visible when deleting a playlist. + * Fixed issue where automatic playlists and station summaries were not + updated in the playlist header. * Fixed an issue which caused duplicate items when rescanning. * Revert change introduced in 0.0.2 causing Twitter protocol to not try to reconnect to a peer if it couldn't connect the first time the plugin From 196397f210edea4b36b8054fe5421f333deafaff Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Thu, 7 Apr 2011 09:16:21 -0400 Subject: [PATCH 10/75] fix build --- src/tomahawkapp.cpp | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index d0c444164..e7ae74a45 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -162,23 +162,6 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] ) setupLogfile(); } - -TomahawkApp::~TomahawkApp() -{ - qDebug() << Q_FUNC_INFO; - - delete m_sipHandler; - delete m_servent; - -#ifndef TOMAHAWK_HEADLESS - delete m_mainwindow; - delete m_audioEngine; -#endif - - delete m_database; -} - - void TomahawkApp::init() { From db6a93e55c7d7cdbdfc77b5316a83e7e7f47a709 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Thu, 7 Apr 2011 10:35:29 -0400 Subject: [PATCH 11/75] Now when inserting into the cache a max age time is specified. It can be refreshed by issuing a new max age time when doing a getCachedInfo call (optional). --- include/tomahawk/infosystem.h | 2 +- src/infosystem/infoplugins/lastfmplugin.cpp | 2 +- src/infosystem/infosystemcache.cpp | 53 ++++++++++++++++----- src/infosystem/infosystemcache.h | 7 +-- 4 files changed, 47 insertions(+), 17 deletions(-) diff --git a/include/tomahawk/infosystem.h b/include/tomahawk/infosystem.h index 1409dabf9..e36af20d3 100644 --- a/include/tomahawk/infosystem.h +++ b/include/tomahawk/infosystem.h @@ -112,7 +112,7 @@ public: virtual void getInfo( const QString &caller, const InfoType type, const QVariant &data, InfoCustomData customData ) = 0; signals: - void getCachedInfo( Tomahawk::InfoSystem::InfoCacheCriteria criteria, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, Tomahawk::InfoSystem::InfoCustomData customData ); + void getCachedInfo( Tomahawk::InfoSystem::InfoCacheCriteria criteria, qint64 newMaxAge, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, Tomahawk::InfoSystem::InfoCustomData customData ); void updateCache( Tomahawk::InfoSystem::InfoCacheCriteria criteria, Tomahawk::InfoSystem::InfoType type, QVariant output ); void info( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ); void finished( QString, Tomahawk::InfoSystem::InfoType ); diff --git a/src/infosystem/infoplugins/lastfmplugin.cpp b/src/infosystem/infoplugins/lastfmplugin.cpp index 652d87414..fcff625bf 100644 --- a/src/infosystem/infoplugins/lastfmplugin.cpp +++ b/src/infosystem/infoplugins/lastfmplugin.cpp @@ -178,7 +178,7 @@ LastFmPlugin::fetchCoverArt( const QString &caller, const InfoType type, const Q criteria["artist"] = hash["artist"].toString(); criteria["album"] = hash["album"].toString(); - emit getCachedInfo( criteria, caller, type, data, customData ); + emit getCachedInfo( criteria, 2419200000, caller, type, data, customData ); } void diff --git a/src/infosystem/infosystemcache.cpp b/src/infosystem/infosystemcache.cpp index 7d73c6ade..e6e7b04f5 100644 --- a/src/infosystem/infosystemcache.cpp +++ b/src/infosystem/infosystemcache.cpp @@ -53,10 +53,10 @@ InfoSystemCache::~InfoSystemCache() qDebug() << Q_FUNC_INFO; qDebug() << "Saving infosystemcache to disk"; QString cacheBaseDir = QDesktopServices::storageLocation( QDesktopServices::CacheLocation ); - for( int i = 0; i <= InfoNoInfo; i++ ) + for ( int i = 0; i <= InfoNoInfo; i++ ) { InfoType type = (InfoType)(i); - if( m_dirtySet.contains( type ) && m_dataCache.contains( type ) ) + if ( m_dirtySet.contains( type ) && m_dataCache.contains( type ) ) { QString cacheDir = cacheBaseDir + "/InfoSystemCache/" + QString::number( i ); saveCache( type, cacheDir ); @@ -66,29 +66,54 @@ InfoSystemCache::~InfoSystemCache() void -InfoSystemCache::getCachedInfoSlot( Tomahawk::InfoSystem::InfoCacheCriteria criteria, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, Tomahawk::InfoSystem::InfoCustomData customData ) +InfoSystemCache::getCachedInfoSlot( Tomahawk::InfoSystem::InfoCacheCriteria criteria, qint64 newMaxAge, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, Tomahawk::InfoSystem::InfoCustomData customData ) { qDebug() << Q_FUNC_INFO; - if( !m_dataCache.contains( type ) || !m_dataCache[type].contains( criteria ) ) + if ( !m_dataCache.contains( type ) || !m_dataCache[type].contains( criteria ) ) { emit notInCache( criteria, caller, type, input, customData ); return; } + QHash< InfoCacheCriteria, QDateTime > typemaxtimecache = m_maxTimeCache[type]; + + if ( typemaxtimecache[criteria].toMSecsSinceEpoch() < QDateTime::currentMSecsSinceEpoch() ) + { + QHash< InfoCacheCriteria, QVariant > typedatacache = m_dataCache[type]; + QHash< InfoCacheCriteria, QDateTime > typeinserttimecache = m_insertTimeCache[type]; + typemaxtimecache.remove( criteria ); + typedatacache.remove( criteria ); + typeinserttimecache.remove( criteria ); + m_dirtySet.insert( type ); + emit notInCache( criteria, caller, type, input, customData ); + return; + } + + if ( newMaxAge > 0 ) + { + QHash< InfoCacheCriteria, QDateTime > typemaxtimecache = m_maxTimeCache[type]; + typemaxtimecache[criteria] = QDateTime::fromMSecsSinceEpoch( QDateTime::currentMSecsSinceEpoch() + newMaxAge ); + m_maxTimeCache[type] = typemaxtimecache; + m_dirtySet.insert( type ); + } + emit info( caller, type, input, m_dataCache[type][criteria], customData ); } void -InfoSystemCache::updateCacheSlot( Tomahawk::InfoSystem::InfoCacheCriteria criteria, Tomahawk::InfoSystem::InfoType type, QVariant output ) +InfoSystemCache::updateCacheSlot( Tomahawk::InfoSystem::InfoCacheCriteria criteria, qint64 maxAge, Tomahawk::InfoSystem::InfoType type, QVariant output ) { qDebug() << Q_FUNC_INFO; QHash< InfoCacheCriteria, QVariant > typedatacache = m_dataCache[type]; - QHash< InfoCacheCriteria, QDateTime > typetimecache = m_timeCache[type]; + QHash< InfoCacheCriteria, QDateTime > typeinserttimecache = m_insertTimeCache[type]; + QHash< InfoCacheCriteria, QDateTime > typemaxtimecache = m_maxTimeCache[type]; typedatacache[criteria] = output; - typetimecache[criteria] = QDateTime::currentDateTimeUtc(); + typeinserttimecache[criteria] = QDateTime::currentDateTimeUtc(); + typemaxtimecache[criteria] = QDateTime::fromMSecsSinceEpoch( QDateTime::currentMSecsSinceEpoch() + maxAge ); m_dataCache[type] = typedatacache; - m_timeCache[type] = typetimecache; + m_insertTimeCache[type] = typeinserttimecache; + m_maxTimeCache[type] = typemaxtimecache; m_dirtySet.insert( type ); } @@ -102,7 +127,8 @@ InfoSystemCache::loadCache( InfoType type, const QString &cacheFile ) foreach( QString group, cachedSettings.childGroups() ) { QHash< InfoCacheCriteria, QVariant > dataHash = m_dataCache[type]; - QHash< InfoCacheCriteria, QDateTime > dateHash = m_timeCache[type]; + QHash< InfoCacheCriteria, QDateTime > insertDateHash = m_insertTimeCache[type]; + QHash< InfoCacheCriteria, QDateTime > maxDateHash = m_maxTimeCache[type]; InfoCacheCriteria criteria; cachedSettings.beginGroup( group ); int numCriteria = cachedSettings.beginReadArray( "criteria" ); @@ -115,10 +141,12 @@ InfoSystemCache::loadCache( InfoType type, const QString &cacheFile ) } cachedSettings.endArray(); dataHash[criteria] = cachedSettings.value( "data" ); - dateHash[criteria] = cachedSettings.value( "time" ).toDateTime(); + insertDateHash[criteria] = cachedSettings.value( "inserttime" ).toDateTime(); + maxDateHash[criteria] = cachedSettings.value( "maxtime" ).toDateTime(); cachedSettings.endGroup(); m_dataCache[type] = dataHash; - m_timeCache[type] = dateHash; + m_insertTimeCache[type] = insertDateHash; + m_maxTimeCache[type] = maxDateHash; } } @@ -156,7 +184,8 @@ InfoSystemCache::saveCache( InfoType type, const QString &cacheDir ) } cachedSettings.endArray(); cachedSettings.setValue( "data", m_dataCache[type][criteria] ); - cachedSettings.setValue( "time", m_timeCache[type][criteria] ); + cachedSettings.setValue( "inserttime", m_insertTimeCache[type][criteria] ); + cachedSettings.setValue( "maxtime", m_maxTimeCache[type][criteria] ); cachedSettings.endGroup(); ++criteriaNumber; } diff --git a/src/infosystem/infosystemcache.h b/src/infosystem/infosystemcache.h index ca347f7bc..0ccad6d19 100644 --- a/src/infosystem/infosystemcache.h +++ b/src/infosystem/infosystemcache.h @@ -45,15 +45,16 @@ signals: void info( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ); public slots: - void getCachedInfoSlot( Tomahawk::InfoSystem::InfoCacheCriteria criteria, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, Tomahawk::InfoSystem::InfoCustomData customData ); - void updateCacheSlot( Tomahawk::InfoSystem::InfoCacheCriteria criteria, Tomahawk::InfoSystem::InfoType type, QVariant output ); + void getCachedInfoSlot( Tomahawk::InfoSystem::InfoCacheCriteria criteria, qint64 newMaxAge, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, Tomahawk::InfoSystem::InfoCustomData customData ); + void updateCacheSlot( Tomahawk::InfoSystem::InfoCacheCriteria criteria, qint64 maxAge, Tomahawk::InfoSystem::InfoType type, QVariant output ); private: void loadCache( InfoType type, const QString &cacheFile ); void saveCache( InfoType type, const QString &cacheDir ); QHash< InfoType, QHash< InfoCacheCriteria, QVariant > > m_dataCache; - QHash< InfoType, QHash< InfoCacheCriteria, QDateTime > > m_timeCache; + QHash< InfoType, QHash< InfoCacheCriteria, QDateTime > > m_insertTimeCache; + QHash< InfoType, QHash< InfoCacheCriteria, QDateTime > > m_maxTimeCache; QSet< InfoType > m_dirtySet; }; From bf744ac8bb1a323103e16950fa3228cca033f6cc Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Thu, 7 Apr 2011 10:41:08 -0400 Subject: [PATCH 12/75] Ah-whoops, knew I forgot something in my previous commit --- src/infosystem/infosystemcache.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/infosystem/infosystemcache.cpp b/src/infosystem/infosystemcache.cpp index e6e7b04f5..67bdea896 100644 --- a/src/infosystem/infosystemcache.cpp +++ b/src/infosystem/infosystemcache.cpp @@ -82,8 +82,11 @@ InfoSystemCache::getCachedInfoSlot( Tomahawk::InfoSystem::InfoCacheCriteria crit QHash< InfoCacheCriteria, QVariant > typedatacache = m_dataCache[type]; QHash< InfoCacheCriteria, QDateTime > typeinserttimecache = m_insertTimeCache[type]; typemaxtimecache.remove( criteria ); + m_maxTimeCache[type] = typemaxtimecache; typedatacache.remove( criteria ); + m_dataCache[type] = typedatacache; typeinserttimecache.remove( criteria ); + m_insertTimeCache[type] = typeinserttimecache; m_dirtySet.insert( type ); emit notInCache( criteria, caller, type, input, customData ); return; From a13388f2c4635499a13854c32452bd34351006de Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Thu, 7 Apr 2011 11:19:20 -0400 Subject: [PATCH 13/75] Rejig Jreen/Gloox cmake stuff to report correct status --- CMakeLists.txt | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a4a65c53..c96d97ea9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,31 +53,32 @@ include( CheckTagLibFileName ) check_taglib_filename( COMPLEX_TAGLIB_FILENAME ) # optional -macro_optional_find_package(Jreen) -IF( ENABLE_JREEN AND NOT LIBJREEN_FOUND ) +IF( ENABLE_JREEN ) + macro_optional_find_package(Jreen) + IF( LIBJREEN_FOUND ) + macro_log_feature(JREEN_FOUND "Jreen" "Qt XMPP library" "http://gitorious.org/jreen" FALSE "" "Jreen is needed for the alternative/new Jabber SIP plugin. Built automatically inside Tomahawk, if not installed systemwide and ENABLE_JREEN is true") + ELSE( LIBJREEN_FOUND ) ADD_SUBDIRECTORY( thirdparty/jreen ) SET( LIBJREEN_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/thirdparty/jreen/include ) IF( UNIX AND NOT APPLE ) SET( LIBJREEN_LIBRARY ${CMAKE_CURRENT_BINARY_DIR}/thirdparty/jreen/libjreen.so ) ENDIF( UNIX AND NOT APPLE ) IF( WIN32 ) - SET( LIBJREEN_LIBRARY ${CMAKE_CURRENT_BINARY_DIR}/thirdparty/jreen/libjreen.dll ) + SET( LIBJREEN_LIBRARY ${CMAKE_CURRENT_BINARY_DIR}/thirdparty/jreen/libjreen.dll ) ENDIF( WIN32 ) SET( LIBJREEN_FOUND true ) MESSAGE(STATUS "Internal libjreen: ${LIBJREEN_INCLUDE_DIR}, ${LIBJREEN_LIBRARY}") -ENDIF( ENABLE_JREEN AND NOT LIBJREEN_FOUND ) + ENDIF( LIBJREEN_FOUND ) +ELSE( LIBJREEN_FOUND ) + macro_optional_find_package(Gloox 1.0) + macro_log_feature(GLOOX_FOUND "Gloox" "A portable high-level Jabber/XMPP library for C++" "http://camaya.net/gloox" FALSE "" "Gloox is needed for the Jabber SIP plugin and the XMPP-Bot") + +ENDIF( ENABLE_JREEN ) IF( WIN32 ) find_library(QTSPARKLE_LIBRARIES qtsparkle) ENDIF( WIN32 ) -macro_log_feature(JREEN_FOUND "Jreen" "Qt XMPP library" "http://gitorious.org/jreen" FALSE "" "Jreen is needed for the alternative/new Jabber SIP plugin. Built automatically inside Tomahawk, if not installed systemwide and ENABLE_JREEN is true") - -macro_optional_find_package(Gloox 1.0) -IF( ENABLE_JREEN ) - set( GLOOX_FOUND false ) -ENDIF( ENABLE_JREEN) -macro_log_feature(GLOOX_FOUND "Gloox" "A portable high-level Jabber/XMPP library for C++" "http://camaya.net/gloox" FALSE "" "Gloox is needed for the Jabber SIP plugin and the XMPP-Bot") #show dep log macro_display_feature_log() MESSAGE("WARNING!") From 7639d8da9e4cc594337385f2d2beb1c6c8dcfd60 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Thu, 7 Apr 2011 17:58:45 -0400 Subject: [PATCH 14/75] Happy Birthday, muesli --- src/infosystem/infosystemcache.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/infosystem/infosystemcache.cpp b/src/infosystem/infosystemcache.cpp index 67bdea896..9ecdc7435 100644 --- a/src/infosystem/infosystemcache.cpp +++ b/src/infosystem/infosystemcache.cpp @@ -127,19 +127,21 @@ InfoSystemCache::loadCache( InfoType type, const QString &cacheFile ) qDebug() << Q_FUNC_INFO; QSettings cachedSettings( cacheFile, QSettings::IniFormat ); - foreach( QString group, cachedSettings.childGroups() ) + foreach ( QString group, cachedSettings.childGroups() ) { + cachedSettings.beginGroup( group ); + if ( cachedSettings.value( "maxtime" ).toDateTime().toMSecsSinceEpoch() < QDateTime::currentMSecsSinceEpoch() ) + continue; QHash< InfoCacheCriteria, QVariant > dataHash = m_dataCache[type]; QHash< InfoCacheCriteria, QDateTime > insertDateHash = m_insertTimeCache[type]; QHash< InfoCacheCriteria, QDateTime > maxDateHash = m_maxTimeCache[type]; InfoCacheCriteria criteria; - cachedSettings.beginGroup( group ); int numCriteria = cachedSettings.beginReadArray( "criteria" ); - for( int i = 0; i < numCriteria; i++ ) + for ( int i = 0; i < numCriteria; i++ ) { cachedSettings.setArrayIndex( i ); QStringList criteriaValues = cachedSettings.value( QString::number( i ) ).toStringList(); - for( int j = 0; j < criteriaValues.length(); j += 2 ) + for ( int j = 0; j < criteriaValues.length(); j += 2 ) criteria[criteriaValues.at( j )] = criteriaValues.at( j + 1 ); } cachedSettings.endArray(); From c0994e3c248dcd80f9d7282b935501ad271785af Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sat, 9 Apr 2011 11:03:52 +0200 Subject: [PATCH 15/75] * Fixed crash bug caused by multiple sources going on- and offline at a time. --- ChangeLog | 3 +++ src/libtomahawk/query.cpp | 49 ++++++++++++++++++++++----------------- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2db4e9bd0..be69b1974 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +Version 0.0.4: + * Fixed a crash situation caused by sources going on- or offline. + Version 0.0.3: * Show spinner while resolving playlists. * Go back to previous page visible when deleting a playlist. diff --git a/src/libtomahawk/query.cpp b/src/libtomahawk/query.cpp index f07025411..413ab4c96 100644 --- a/src/libtomahawk/query.cpp +++ b/src/libtomahawk/query.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -89,10 +89,13 @@ Query::refreshResults() void Query::onResultStatusChanged() { - if ( m_results.count() ) - qStableSort( m_results.begin(), m_results.end(), Query::resultSorter ); - checkResults(); + { + QMutexLocker lock( &m_mutex ); + if ( m_results.count() ) + qStableSort( m_results.begin(), m_results.end(), Query::resultSorter ); + } + checkResults(); emit resultsChanged(); } @@ -180,27 +183,31 @@ Query::checkResults() { bool becameSolved = false; bool becameUnsolved = true; - m_playable = false; - - // hook up signals, and check solved status - foreach( const result_ptr& rp, m_results ) { - if ( rp->score() > 0.0 && rp->collection().isNull() ) - { - m_playable = true; - } - if ( !rp->collection().isNull() && rp->collection()->source()->isOnline() ) - { - m_playable = true; + QMutexLocker lock( &m_mutex ); - if ( rp->score() > 0.99 ) + m_playable = false; + + // hook up signals, and check solved status + foreach( const result_ptr& rp, m_results ) + { + if ( rp->score() > 0.0 && rp->collection().isNull() ) { - becameUnsolved = false; + m_playable = true; + } + if ( !rp->collection().isNull() && rp->collection()->source()->isOnline() ) + { + m_playable = true; - if ( !m_solved ) + if ( rp->score() > 0.99 ) { - m_solved = true; - becameSolved = true; + becameUnsolved = false; + + if ( !m_solved ) + { + m_solved = true; + becameSolved = true; + } } } } @@ -226,7 +233,7 @@ Query::toVariant() const m.insert( "track", track() ); m.insert( "duration", duration() ); m.insert( "qid", id() ); - + return m; } From 5ae0a7138c8eec388f76257fdd01d96c1b0f18ca Mon Sep 17 00:00:00 2001 From: Alejandro Wainzinger Date: Sun, 10 Apr 2011 02:24:32 -0700 Subject: [PATCH 16/75] Make compile on OS X. (liblastfm2) --- src/libtomahawk/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index 188f6c1b3..6d2e7dc3b 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -329,6 +329,7 @@ include_directories( . ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/. ${THIRDPARTY_DIR}/jdns/jdns ${THIRDPARTY_DIR}/jdns/jdnsshared ${THIRDPARTY_DIR}/qtweetlib/qtweetlib/src + ${CMAKE_BINARY_DIR}/thirdparty/liblastfm2/src ) From 252a48196ca598faf9fac1b0804122249159923b Mon Sep 17 00:00:00 2001 From: Alejandro Wainzinger Date: Sun, 10 Apr 2011 16:46:35 -0700 Subject: [PATCH 17/75] Move signal connections of scrobbler into scrobbler, easier to read. --- src/scrobbler.cpp | 14 +++++++++++++- src/tomahawkapp.cpp | 11 ----------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/scrobbler.cpp b/src/scrobbler.cpp index ef599db76..bbdb0e26f 100644 --- a/src/scrobbler.cpp +++ b/src/scrobbler.cpp @@ -43,6 +43,18 @@ Scrobbler::Scrobbler( QObject* parent ) SLOT( infoSystemInfo( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ) ); connect( TomahawkApp::instance()->infoSystem(), SIGNAL( finished( QString ) ), SLOT( infoSystemFinished( QString ) ) ); + + connect( AudioEngine::instance(), SIGNAL( started( const Tomahawk::result_ptr& ) ), + SLOT( trackStarted( const Tomahawk::result_ptr& ) ), Qt::QueuedConnection ); + + connect( AudioEngine::instance(), SIGNAL( paused() ), + SLOT( trackPaused() ), Qt::QueuedConnection ); + + connect( AudioEngine::instance(), SIGNAL( resumed() ), + SLOT( trackResumed() ), Qt::QueuedConnection ); + + connect( AudioEngine::instance(), SIGNAL( stopped() ), + SLOT( trackStopped() ), Qt::QueuedConnection ); } @@ -143,4 +155,4 @@ Scrobbler::infoSystemFinished( QString target ) qDebug() << Q_FUNC_INFO; qDebug() << "Scrobbler received done signal from InfoSystem"; } -} \ No newline at end of file +} diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index e7ae74a45..11fa147c2 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -225,17 +225,6 @@ TomahawkApp::init() qDebug() << "Setting NAM."; TomahawkUtils::setNam( new lastfm::NetworkAccessManager( this ) ); - connect( m_audioEngine, SIGNAL( started( const Tomahawk::result_ptr& ) ), - m_scrobbler, SLOT( trackStarted( const Tomahawk::result_ptr& ) ), Qt::QueuedConnection ); - - connect( m_audioEngine, SIGNAL( paused() ), - m_scrobbler, SLOT( trackPaused() ), Qt::QueuedConnection ); - - connect( m_audioEngine, SIGNAL( resumed() ), - m_scrobbler, SLOT( trackResumed() ), Qt::QueuedConnection ); - - connect( m_audioEngine, SIGNAL( stopped() ), - m_scrobbler, SLOT( trackStopped() ), Qt::QueuedConnection ); #else qDebug() << "Setting NAM."; TomahawkUtils::setNam( new QNetworkAccessManager ); From a9a9ffa40fb9e9bb353572b959f17481dcc89d58 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sun, 10 Apr 2011 17:03:16 -0400 Subject: [PATCH 18/75] Changes to make Spotify resolver work --- CMakeLists.txt | 23 ++++--- include/tomahawk/infosystem.h | 2 +- src/audiocontrols.cpp | 22 +++---- src/infosystem/infoplugins/lastfmplugin.cpp | 2 +- src/infosystem/infosystemcache.cpp | 66 +++++--------------- src/infosystem/infosystemcache.h | 7 +-- src/libtomahawk/CMakeLists.txt | 12 ++-- src/libtomahawk/audio/audioengine.cpp | 38 +++++++---- src/libtomahawk/audio/dummytranscode.cpp | 62 ++++++++++++++++++ src/libtomahawk/audio/dummytranscode.h | 63 +++++++++++++++++++ src/libtomahawk/network/servent.cpp | 29 +++++---- src/libtomahawk/network/streamconnection.cpp | 6 +- src/resolvers/scriptresolver.cpp | 9 ++- src/resolvers/scriptresolver.h | 2 +- src/tomahawkapp.cpp | 9 ++- 15 files changed, 233 insertions(+), 119 deletions(-) create mode 100644 src/libtomahawk/audio/dummytranscode.cpp create mode 100644 src/libtomahawk/audio/dummytranscode.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c96d97ea9..2a4a65c53 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,32 +53,31 @@ include( CheckTagLibFileName ) check_taglib_filename( COMPLEX_TAGLIB_FILENAME ) # optional -IF( ENABLE_JREEN ) - macro_optional_find_package(Jreen) - IF( LIBJREEN_FOUND ) - macro_log_feature(JREEN_FOUND "Jreen" "Qt XMPP library" "http://gitorious.org/jreen" FALSE "" "Jreen is needed for the alternative/new Jabber SIP plugin. Built automatically inside Tomahawk, if not installed systemwide and ENABLE_JREEN is true") - ELSE( LIBJREEN_FOUND ) +macro_optional_find_package(Jreen) +IF( ENABLE_JREEN AND NOT LIBJREEN_FOUND ) ADD_SUBDIRECTORY( thirdparty/jreen ) SET( LIBJREEN_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/thirdparty/jreen/include ) IF( UNIX AND NOT APPLE ) SET( LIBJREEN_LIBRARY ${CMAKE_CURRENT_BINARY_DIR}/thirdparty/jreen/libjreen.so ) ENDIF( UNIX AND NOT APPLE ) IF( WIN32 ) - SET( LIBJREEN_LIBRARY ${CMAKE_CURRENT_BINARY_DIR}/thirdparty/jreen/libjreen.dll ) + SET( LIBJREEN_LIBRARY ${CMAKE_CURRENT_BINARY_DIR}/thirdparty/jreen/libjreen.dll ) ENDIF( WIN32 ) SET( LIBJREEN_FOUND true ) MESSAGE(STATUS "Internal libjreen: ${LIBJREEN_INCLUDE_DIR}, ${LIBJREEN_LIBRARY}") - ENDIF( LIBJREEN_FOUND ) -ELSE( LIBJREEN_FOUND ) - macro_optional_find_package(Gloox 1.0) - macro_log_feature(GLOOX_FOUND "Gloox" "A portable high-level Jabber/XMPP library for C++" "http://camaya.net/gloox" FALSE "" "Gloox is needed for the Jabber SIP plugin and the XMPP-Bot") - -ENDIF( ENABLE_JREEN ) +ENDIF( ENABLE_JREEN AND NOT LIBJREEN_FOUND ) IF( WIN32 ) find_library(QTSPARKLE_LIBRARIES qtsparkle) ENDIF( WIN32 ) +macro_log_feature(JREEN_FOUND "Jreen" "Qt XMPP library" "http://gitorious.org/jreen" FALSE "" "Jreen is needed for the alternative/new Jabber SIP plugin. Built automatically inside Tomahawk, if not installed systemwide and ENABLE_JREEN is true") + +macro_optional_find_package(Gloox 1.0) +IF( ENABLE_JREEN ) + set( GLOOX_FOUND false ) +ENDIF( ENABLE_JREEN) +macro_log_feature(GLOOX_FOUND "Gloox" "A portable high-level Jabber/XMPP library for C++" "http://camaya.net/gloox" FALSE "" "Gloox is needed for the Jabber SIP plugin and the XMPP-Bot") #show dep log macro_display_feature_log() MESSAGE("WARNING!") diff --git a/include/tomahawk/infosystem.h b/include/tomahawk/infosystem.h index e36af20d3..1409dabf9 100644 --- a/include/tomahawk/infosystem.h +++ b/include/tomahawk/infosystem.h @@ -112,7 +112,7 @@ public: virtual void getInfo( const QString &caller, const InfoType type, const QVariant &data, InfoCustomData customData ) = 0; signals: - void getCachedInfo( Tomahawk::InfoSystem::InfoCacheCriteria criteria, qint64 newMaxAge, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, Tomahawk::InfoSystem::InfoCustomData customData ); + void getCachedInfo( Tomahawk::InfoSystem::InfoCacheCriteria criteria, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, Tomahawk::InfoSystem::InfoCustomData customData ); void updateCache( Tomahawk::InfoSystem::InfoCacheCriteria criteria, Tomahawk::InfoSystem::InfoType type, QVariant output ); void info( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ); void finished( QString, Tomahawk::InfoSystem::InfoType ); diff --git a/src/audiocontrols.cpp b/src/audiocontrols.cpp index 8f4214ed8..1138826ee 100644 --- a/src/audiocontrols.cpp +++ b/src/audiocontrols.cpp @@ -45,11 +45,11 @@ AudioControls::AudioControls( QWidget* parent ) QFont font( ui->artistTrackLabel->font() ); font.setPixelSize( 12 ); - + #ifdef Q_WS_MAC font.setPointSize( font.pointSize() - 2 ); #endif - + ui->artistTrackLabel->setFont( font ); ui->artistTrackLabel->setElideMode( Qt::ElideMiddle ); ui->artistTrackLabel->setType( QueryLabel::ArtistAndTrack ); @@ -144,10 +144,10 @@ AudioControls::AudioControls( QWidget* parent ) connect( ui->volumeLowButton, SIGNAL( clicked() ), AudioEngine::instance(), SLOT( lowerVolume() ) ); connect( ui->volumeHighButton, SIGNAL( clicked() ), AudioEngine::instance(), SLOT( raiseVolume() ) ); - + connect( ui->playPauseButton, SIGNAL( clicked() ), this, SIGNAL( playPressed() ) ); connect( ui->pauseButton, SIGNAL( clicked() ), this, SIGNAL( pausePressed() ) ); - + connect( ui->repeatButton, SIGNAL( clicked() ), SLOT( onRepeatClicked() ) ); connect( ui->shuffleButton, SIGNAL( clicked() ), SLOT( onShuffleClicked() ) ); @@ -170,7 +170,7 @@ AudioControls::AudioControls( QWidget* parent ) connect( TomahawkApp::instance()->infoSystem(), SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ), SLOT( infoSystemInfo( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ) ); - + connect( TomahawkApp::instance()->infoSystem(), SIGNAL( finished( QString ) ), SLOT( infoSystemFinished( QString ) ) ); onPlaybackStopped(); // initial state @@ -251,9 +251,9 @@ AudioControls::onPlaybackStarted( const Tomahawk::result_ptr& result ) QString artistName = result->artist()->name(); QString albumName = result->album()->name(); - + Tomahawk::InfoSystem::InfoCustomData trackInfo; - + trackInfo["artist"] = QVariant::fromValue< QString >( result->artist()->name() ); trackInfo["album"] = QVariant::fromValue< QString >( result->album()->name() ); TomahawkApp::instance()->infoSystem()->getInfo( @@ -270,7 +270,7 @@ AudioControls::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType ty qDebug() << "info of wrong type or not with our identifier"; return; } - + if ( m_currentTrack.isNull() ) { qDebug() << "Current track is null when trying to apply fetched cover art"; @@ -281,7 +281,7 @@ AudioControls::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType ty { qDebug() << "Cannot convert fetched art from a QByteArray"; return; - } + } Tomahawk::InfoSystem::InfoCustomData returnedData = output.value< Tomahawk::InfoSystem::InfoCustomData >(); const QByteArray ba = returnedData["imgbytes"].toByteArray(); @@ -296,7 +296,7 @@ AudioControls::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType ty ui->coverImage->setPixmap( pm.scaled( ui->coverImage->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation ) ); } } - + void AudioControls::infoSystemFinished( QString target ) { @@ -356,7 +356,7 @@ AudioControls::onPlaybackResumed() ui->pauseButton->setVisible( true ); ui->pauseButton->setEnabled( true ); ui->playPauseButton->setVisible( false ); - ui->playPauseButton->setEnabled( false ); + ui->playPauseButton->setEnabled( false ); } diff --git a/src/infosystem/infoplugins/lastfmplugin.cpp b/src/infosystem/infoplugins/lastfmplugin.cpp index fcff625bf..652d87414 100644 --- a/src/infosystem/infoplugins/lastfmplugin.cpp +++ b/src/infosystem/infoplugins/lastfmplugin.cpp @@ -178,7 +178,7 @@ LastFmPlugin::fetchCoverArt( const QString &caller, const InfoType type, const Q criteria["artist"] = hash["artist"].toString(); criteria["album"] = hash["album"].toString(); - emit getCachedInfo( criteria, 2419200000, caller, type, data, customData ); + emit getCachedInfo( criteria, caller, type, data, customData ); } void diff --git a/src/infosystem/infosystemcache.cpp b/src/infosystem/infosystemcache.cpp index 9ecdc7435..7d73c6ade 100644 --- a/src/infosystem/infosystemcache.cpp +++ b/src/infosystem/infosystemcache.cpp @@ -53,10 +53,10 @@ InfoSystemCache::~InfoSystemCache() qDebug() << Q_FUNC_INFO; qDebug() << "Saving infosystemcache to disk"; QString cacheBaseDir = QDesktopServices::storageLocation( QDesktopServices::CacheLocation ); - for ( int i = 0; i <= InfoNoInfo; i++ ) + for( int i = 0; i <= InfoNoInfo; i++ ) { InfoType type = (InfoType)(i); - if ( m_dirtySet.contains( type ) && m_dataCache.contains( type ) ) + if( m_dirtySet.contains( type ) && m_dataCache.contains( type ) ) { QString cacheDir = cacheBaseDir + "/InfoSystemCache/" + QString::number( i ); saveCache( type, cacheDir ); @@ -66,57 +66,29 @@ InfoSystemCache::~InfoSystemCache() void -InfoSystemCache::getCachedInfoSlot( Tomahawk::InfoSystem::InfoCacheCriteria criteria, qint64 newMaxAge, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, Tomahawk::InfoSystem::InfoCustomData customData ) +InfoSystemCache::getCachedInfoSlot( Tomahawk::InfoSystem::InfoCacheCriteria criteria, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, Tomahawk::InfoSystem::InfoCustomData customData ) { qDebug() << Q_FUNC_INFO; - if ( !m_dataCache.contains( type ) || !m_dataCache[type].contains( criteria ) ) + if( !m_dataCache.contains( type ) || !m_dataCache[type].contains( criteria ) ) { emit notInCache( criteria, caller, type, input, customData ); return; } - QHash< InfoCacheCriteria, QDateTime > typemaxtimecache = m_maxTimeCache[type]; - - if ( typemaxtimecache[criteria].toMSecsSinceEpoch() < QDateTime::currentMSecsSinceEpoch() ) - { - QHash< InfoCacheCriteria, QVariant > typedatacache = m_dataCache[type]; - QHash< InfoCacheCriteria, QDateTime > typeinserttimecache = m_insertTimeCache[type]; - typemaxtimecache.remove( criteria ); - m_maxTimeCache[type] = typemaxtimecache; - typedatacache.remove( criteria ); - m_dataCache[type] = typedatacache; - typeinserttimecache.remove( criteria ); - m_insertTimeCache[type] = typeinserttimecache; - m_dirtySet.insert( type ); - emit notInCache( criteria, caller, type, input, customData ); - return; - } - - if ( newMaxAge > 0 ) - { - QHash< InfoCacheCriteria, QDateTime > typemaxtimecache = m_maxTimeCache[type]; - typemaxtimecache[criteria] = QDateTime::fromMSecsSinceEpoch( QDateTime::currentMSecsSinceEpoch() + newMaxAge ); - m_maxTimeCache[type] = typemaxtimecache; - m_dirtySet.insert( type ); - } - emit info( caller, type, input, m_dataCache[type][criteria], customData ); } void -InfoSystemCache::updateCacheSlot( Tomahawk::InfoSystem::InfoCacheCriteria criteria, qint64 maxAge, Tomahawk::InfoSystem::InfoType type, QVariant output ) +InfoSystemCache::updateCacheSlot( Tomahawk::InfoSystem::InfoCacheCriteria criteria, Tomahawk::InfoSystem::InfoType type, QVariant output ) { qDebug() << Q_FUNC_INFO; QHash< InfoCacheCriteria, QVariant > typedatacache = m_dataCache[type]; - QHash< InfoCacheCriteria, QDateTime > typeinserttimecache = m_insertTimeCache[type]; - QHash< InfoCacheCriteria, QDateTime > typemaxtimecache = m_maxTimeCache[type]; + QHash< InfoCacheCriteria, QDateTime > typetimecache = m_timeCache[type]; typedatacache[criteria] = output; - typeinserttimecache[criteria] = QDateTime::currentDateTimeUtc(); - typemaxtimecache[criteria] = QDateTime::fromMSecsSinceEpoch( QDateTime::currentMSecsSinceEpoch() + maxAge ); + typetimecache[criteria] = QDateTime::currentDateTimeUtc(); m_dataCache[type] = typedatacache; - m_insertTimeCache[type] = typeinserttimecache; - m_maxTimeCache[type] = typemaxtimecache; + m_timeCache[type] = typetimecache; m_dirtySet.insert( type ); } @@ -127,31 +99,26 @@ InfoSystemCache::loadCache( InfoType type, const QString &cacheFile ) qDebug() << Q_FUNC_INFO; QSettings cachedSettings( cacheFile, QSettings::IniFormat ); - foreach ( QString group, cachedSettings.childGroups() ) + foreach( QString group, cachedSettings.childGroups() ) { - cachedSettings.beginGroup( group ); - if ( cachedSettings.value( "maxtime" ).toDateTime().toMSecsSinceEpoch() < QDateTime::currentMSecsSinceEpoch() ) - continue; QHash< InfoCacheCriteria, QVariant > dataHash = m_dataCache[type]; - QHash< InfoCacheCriteria, QDateTime > insertDateHash = m_insertTimeCache[type]; - QHash< InfoCacheCriteria, QDateTime > maxDateHash = m_maxTimeCache[type]; + QHash< InfoCacheCriteria, QDateTime > dateHash = m_timeCache[type]; InfoCacheCriteria criteria; + cachedSettings.beginGroup( group ); int numCriteria = cachedSettings.beginReadArray( "criteria" ); - for ( int i = 0; i < numCriteria; i++ ) + for( int i = 0; i < numCriteria; i++ ) { cachedSettings.setArrayIndex( i ); QStringList criteriaValues = cachedSettings.value( QString::number( i ) ).toStringList(); - for ( int j = 0; j < criteriaValues.length(); j += 2 ) + for( int j = 0; j < criteriaValues.length(); j += 2 ) criteria[criteriaValues.at( j )] = criteriaValues.at( j + 1 ); } cachedSettings.endArray(); dataHash[criteria] = cachedSettings.value( "data" ); - insertDateHash[criteria] = cachedSettings.value( "inserttime" ).toDateTime(); - maxDateHash[criteria] = cachedSettings.value( "maxtime" ).toDateTime(); + dateHash[criteria] = cachedSettings.value( "time" ).toDateTime(); cachedSettings.endGroup(); m_dataCache[type] = dataHash; - m_insertTimeCache[type] = insertDateHash; - m_maxTimeCache[type] = maxDateHash; + m_timeCache[type] = dateHash; } } @@ -189,8 +156,7 @@ InfoSystemCache::saveCache( InfoType type, const QString &cacheDir ) } cachedSettings.endArray(); cachedSettings.setValue( "data", m_dataCache[type][criteria] ); - cachedSettings.setValue( "inserttime", m_insertTimeCache[type][criteria] ); - cachedSettings.setValue( "maxtime", m_maxTimeCache[type][criteria] ); + cachedSettings.setValue( "time", m_timeCache[type][criteria] ); cachedSettings.endGroup(); ++criteriaNumber; } diff --git a/src/infosystem/infosystemcache.h b/src/infosystem/infosystemcache.h index 0ccad6d19..ca347f7bc 100644 --- a/src/infosystem/infosystemcache.h +++ b/src/infosystem/infosystemcache.h @@ -45,16 +45,15 @@ signals: void info( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ); public slots: - void getCachedInfoSlot( Tomahawk::InfoSystem::InfoCacheCriteria criteria, qint64 newMaxAge, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, Tomahawk::InfoSystem::InfoCustomData customData ); - void updateCacheSlot( Tomahawk::InfoSystem::InfoCacheCriteria criteria, qint64 maxAge, Tomahawk::InfoSystem::InfoType type, QVariant output ); + void getCachedInfoSlot( Tomahawk::InfoSystem::InfoCacheCriteria criteria, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, Tomahawk::InfoSystem::InfoCustomData customData ); + void updateCacheSlot( Tomahawk::InfoSystem::InfoCacheCriteria criteria, Tomahawk::InfoSystem::InfoType type, QVariant output ); private: void loadCache( InfoType type, const QString &cacheFile ); void saveCache( InfoType type, const QString &cacheDir ); QHash< InfoType, QHash< InfoCacheCriteria, QVariant > > m_dataCache; - QHash< InfoType, QHash< InfoCacheCriteria, QDateTime > > m_insertTimeCache; - QHash< InfoType, QHash< InfoCacheCriteria, QDateTime > > m_maxTimeCache; + QHash< InfoType, QHash< InfoCacheCriteria, QDateTime > > m_timeCache; QSet< InfoType > m_dirtySet; }; diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index 6d2e7dc3b..cdc92f878 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -29,6 +29,7 @@ set( libSources sip/SipPlugin.cpp audio/madtranscode.cpp + audio/dummytranscode.cpp audio/vorbistranscode.cpp audio/flactranscode.cpp audio/audioengine.cpp @@ -96,8 +97,8 @@ set( libSources playlist/albumview.cpp playlist/topbar/topbar.cpp - playlist/topbar/clearbutton.cpp - playlist/topbar/searchlineedit.cpp + playlist/topbar/clearbutton.cpp + playlist/topbar/searchlineedit.cpp playlist/topbar/lineedit.cpp playlist/topbar/searchbutton.cpp @@ -175,6 +176,7 @@ set( libHeaders audio/transcodeinterface.h audio/madtranscode.h + audio/dummytranscode.h audio/vorbistranscode.h audio/flactranscode.h audio/audioengine.h @@ -251,7 +253,7 @@ set( libHeaders playlist/topbar/topbar.h playlist/topbar/clearbutton.h - playlist/topbar/searchlineedit.h + playlist/topbar/searchlineedit.h playlist/topbar/lineedit.h playlist/topbar/lineedit_p.h playlist/topbar/searchbutton.h @@ -297,8 +299,8 @@ set( libHeaders kdsingleapplicationguard/kdlockedsharedmemorypointer.h ) -set( libHeaders_NoMOC - playlist/dynamic/GeneratorInterface.h +set( libHeaders_NoMOC + playlist/dynamic/GeneratorInterface.h ) set( libUI ${libUI} widgets/newplaylistwidget.ui diff --git a/src/libtomahawk/audio/audioengine.cpp b/src/libtomahawk/audio/audioengine.cpp index 07c5c3cc1..e7e931cf7 100644 --- a/src/libtomahawk/audio/audioengine.cpp +++ b/src/libtomahawk/audio/audioengine.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -28,6 +28,7 @@ #include "network/servent.h" #include "madtranscode.h" +#include "dummytranscode.h" #ifndef NO_OGG #include "vorbistranscode.h" #endif @@ -205,7 +206,9 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result ) else { setCurrentTrack( result ); + qDebug() << "Getting IODEVICE, on thread:" << QThread::currentThread() << QThread::currentThreadId(); io = Servent::instance()->getIODeviceForUrl( m_currentTrack ); + qDebug() << "GOT IODEVICE:" << io.data(); if ( m_currentTrack->url().startsWith( "http://" ) ) { m_readReady = false; @@ -228,12 +231,15 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result ) qDebug() << "Starting new song from url:" << m_currentTrack->url(); emit loading( m_currentTrack ); + qDebug() << "input is:" << m_input.isNull(); if ( !m_input.isNull() ) { m_input->close(); m_input.clear(); } + if( !m_lastTrack.isNull() ) qDebug() << "LAST TRACK:" << m_lastTrack->mimetype(); + qDebug() << "LOADING SONG:" << m_currentTrack->mimetype(); if ( m_lastTrack.isNull() || ( m_currentTrack->mimetype() != m_lastTrack->mimetype() ) ) { if ( !m_transcode.isNull() ) @@ -241,7 +247,10 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result ) m_transcode.clear(); } - if ( m_currentTrack->mimetype() == "audio/mpeg" ) + if ( m_currentTrack->mimetype() == "audio/basic" ) + { + m_transcode = QSharedPointer(new DummyTranscode()); + } else if ( m_currentTrack->mimetype() == "audio/mpeg" ) { m_transcode = QSharedPointer(new MADTranscode()); } @@ -428,8 +437,10 @@ AudioEngine::setCurrentTrack( const Tomahawk::result_ptr& result ) void AudioEngine::onDownloadProgress( qint64 recv, qint64 total ) { - if ( ( recv > 1024 * 32 ) || recv > total ) + if ( ( recv > 1024 * 32 ) || recv > total ) m_readReady = true; + +// qDebug() << "Got onDownloadProgress from reading http stream, received enough?" << m_readReady << "(" << recv << "> 1024 * 32 and" << recv << "<" << total << ")"; } @@ -454,28 +465,30 @@ void AudioEngine::loop() { m_i++; - //if( m_i % 500 == 0 ) qDebug() << Q_FUNC_INFO << thread(); +// if( m_i % 500 == 0 ) qDebug() << Q_FUNC_INFO << thread(); { QMutexLocker lock( &m_mutex ); -/* if ( m_i % 200 == 0 ) - { - if ( !m_input.isNull() ) - qDebug() << "Outer audio loop" << m_input->bytesAvailable() << m_audio->needData(); - }*/ +// if ( m_i % 200 == 0 ) +// { +// if ( !m_input.isNull() ) +// qDebug() << "Outer audio loop" << m_input->bytesAvailable() << m_audio->needData(); +// } if ( m_i % 10 == 0 && m_audio->isPlaying() ) m_audio->triggerTimers(); +// qDebug() << !m_transcode.isNull() << !m_input.isNull() << m_audio->needData() << !m_audio->isPaused(); +// if( !m_input.isNull() ) qDebug() << "INPUT has bytes:" << m_input->bytesAvailable(); if( !m_transcode.isNull() && !m_input.isNull() && m_input->bytesAvailable() && m_audio->needData() && !m_audio->isPaused() ) { - //if ( m_i % 50 == 0 ) - // qDebug() << "Inner audio loop"; +// if ( m_i % 50 == 0 ) +// qDebug() << "Inner audio loop"; if ( m_transcode->needData() > 0 ) { @@ -498,11 +511,12 @@ AudioEngine::loop() // are we cleanly at the end of a track, and ready for the next one? if ( !m_input.isNull() && m_input->atEnd() && - m_readReady && + m_readReady && !m_input->bytesAvailable() && !m_audio->haveData() && !m_audio->isPaused() ) { + qDebug() << !m_input.isNull() << m_input->atEnd() << m_readReady << !m_input->bytesAvailable() << !m_audio->haveData() << !m_audio->isPaused(); qDebug() << "Starting next track then"; loadNextTrack(); // will need data immediately: diff --git a/src/libtomahawk/audio/dummytranscode.cpp b/src/libtomahawk/audio/dummytranscode.cpp new file mode 100644 index 000000000..1ab245d86 --- /dev/null +++ b/src/libtomahawk/audio/dummytranscode.cpp @@ -0,0 +1,62 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Christian Muehlhaeuser + * + * Tomahawk 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 3 of the License, or + * (at your option) any later version. + * + * Tomahawk 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#include "dummytranscode.h" + +#include + +DummyTranscode::DummyTranscode() + : m_init( false ) +{ + qDebug() << Q_FUNC_INFO; +} + + +DummyTranscode::~DummyTranscode() +{ + qDebug() << Q_FUNC_INFO; +} + + +void +DummyTranscode::processData( const QByteArray &buffer, bool finish ) +{ + m_buffer.append( buffer ); +// qDebug() << "DUMMYTRANSCODING:" << buffer.size(); + + if( !m_init && m_buffer.size() >= 16364 ) { + m_init = true; + emit streamInitialized( 44100, 2 ); + } +} + + +void +DummyTranscode::onSeek( int seconds ) +{ + m_buffer.clear(); +} + + +void +DummyTranscode::clearBuffers() +{ + m_buffer.clear(); + m_init = false; +} + diff --git a/src/libtomahawk/audio/dummytranscode.h b/src/libtomahawk/audio/dummytranscode.h new file mode 100644 index 000000000..d38774ffd --- /dev/null +++ b/src/libtomahawk/audio/dummytranscode.h @@ -0,0 +1,63 @@ +/* + + Copyright (C) 2011 Leo Franchi + + 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 3 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + + +#ifndef DUMMYTRANSCODE_H +#define DUMMYTRANSCODE_H + +#include "audio/transcodeinterface.h" +#include "dllmacro.h" + +#define _BUFFER_PREFERRED 32768 + +class DLLEXPORT DummyTranscode : public TranscodeInterface +{ + Q_OBJECT + +public: + DummyTranscode(); + virtual ~DummyTranscode(); + + const QStringList supportedTypes() const { QStringList l; l << "audio/basic"; return l; } + + int needData() { return true; } // always eats data + bool haveData() { return !m_buffer.isEmpty(); } + + unsigned int preferredDataSize() { return _BUFFER_PREFERRED; } + + QByteArray data() { QByteArray b = m_buffer; m_buffer.clear(); return b; } + + virtual void setBufferCapacity( int bytes ) { m_bufferCapacity = bytes; } + int bufferSize() { return m_buffer.size(); } + +public slots: + virtual void clearBuffers(); + virtual void onSeek( int seconds ); + virtual void processData( const QByteArray& data, bool finish ); + +signals: + void streamInitialized( long sampleRate, int channels ); + void timeChanged( int seconds ); + +private: + QByteArray m_buffer; + int m_bufferCapacity; + bool m_init; +}; + +#endif // DUMMYTRANSCODE_H diff --git a/src/libtomahawk/network/servent.cpp b/src/libtomahawk/network/servent.cpp index 083e67d92..4b9a88358 100644 --- a/src/libtomahawk/network/servent.cpp +++ b/src/libtomahawk/network/servent.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -62,7 +62,7 @@ Servent::Servent( QObject* parent ) , m_portfwd( 0 ) { s_instance = this; - + new ACLSystem( this ); setProxy( QNetworkProxy::NoProxy ); @@ -126,7 +126,7 @@ Servent::startListening( QHostAddress ha, bool upnp, int port ) // --lanhack means to advertise your LAN IP over jabber as if it were externallyVisible qDebug() << "Address mode = " << (int)(TomahawkSettings::instance()->externalAddressMode()); qDebug() << "Static host/port preferred ? = " << ( TomahawkSettings::instance()->preferStaticHostPort() ? "true" : "false" ); - + if( TomahawkSettings::instance()->preferStaticHostPort() ) { qDebug() << "Forcing static preferred host and port"; @@ -136,7 +136,7 @@ Servent::startListening( QHostAddress ha, bool upnp, int port ) emit ready(); return true; } - + switch( TomahawkSettings::instance()->externalAddressMode() ) { case TomahawkSettings::Lan: @@ -318,7 +318,7 @@ Servent::readyRead() pport = m.value( "port" ).toInt(); nodeid = m.value( "nodeid" ).toString(); controlid = m.value( "controlid" ).toString(); - + qDebug() << "Incoming connection details: " << m; if( !nodeid.isEmpty() ) // only control connections send nodeid @@ -367,7 +367,7 @@ Servent::readyRead() { qDebug() << "Invalid or unhandled conntype"; } - + // fallthru to cleanup: closeconnection: qDebug() << "Closing incoming connection, something was wrong."; @@ -562,7 +562,7 @@ Connection* Servent::claimOffer( ControlConnection* cc, const QString &nodeid, const QString &key, const QHostAddress peer ) { qDebug() << Q_FUNC_INFO; - + bool noauth = qApp->arguments().contains( "--noauth" ); // magic key for stream connections: @@ -629,9 +629,9 @@ Servent::claimOffer( ControlConnection* cc, const QString &nodeid, const QString return NULL; } } - + qDebug() << "ACL has allowed the connection"; - + if( conn->onceOnly() ) { m_offers.remove( key ); @@ -672,7 +672,7 @@ Servent::checkACL( const Connection* conn, const QString &nodeid, bool showDialo { if( !showDialog ) return false; - + qDebug() << "ACL for this node not found"; QMessageBox msgBox; msgBox.setIcon( QMessageBox::Question ); @@ -682,7 +682,7 @@ Servent::checkACL( const Connection* conn, const QString &nodeid, bool showDialo QPushButton *alwaysDenyButton = msgBox.addButton( tr( "Always Deny" ), QMessageBox::YesRole ); QPushButton *allowButton = msgBox.addButton( tr( "Allow" ), QMessageBox::NoRole ); QPushButton *alwaysAllowButton = msgBox.addButton( tr( "Always Allow" ), QMessageBox::ActionRole ); - + msgBox.setDefaultButton( denyButton ); msgBox.setEscapeButton( denyButton ); @@ -701,7 +701,7 @@ Servent::checkACL( const Connection* conn, const QString &nodeid, bool showDialo #endif return true; -} +} QSharedPointer Servent::remoteIODeviceFactory( const result_ptr& result ) @@ -832,7 +832,6 @@ Servent::registerIODeviceFactory( const QString &proto, boost::function Servent::getIODeviceForUrl( const Tomahawk::result_ptr& result ) { @@ -845,9 +844,9 @@ Servent::getIODeviceForUrl( const Tomahawk::result_ptr& result ) const QString proto = rx.cap( 1 ); //const QString urlpart = rx.cap( 2 ); + qDebug() << "Getting IODevice for URL:" << proto << m_iofactories.contains( proto ); if ( !m_iofactories.contains( proto ) ) return sp; - return m_iofactories.value( proto )( result ); } @@ -870,5 +869,5 @@ Servent::httpIODeviceFactory( const Tomahawk::result_ptr& result ) qDebug() << Q_FUNC_INFO << result->url(); QNetworkRequest req( result->url() ); QNetworkReply* reply = TomahawkUtils::nam()->get( req ); - return QSharedPointer( reply ); + return QSharedPointer( reply, &QObject::deleteLater ); } diff --git a/src/libtomahawk/network/streamconnection.cpp b/src/libtomahawk/network/streamconnection.cpp index 224ab7d7f..e33ed6196 100644 --- a/src/libtomahawk/network/streamconnection.cpp +++ b/src/libtomahawk/network/streamconnection.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -46,7 +46,7 @@ StreamConnection::StreamConnection( Servent* s, ControlConnection* cc, QString f qDebug() << Q_FUNC_INFO; BufferIODevice* bio = new BufferIODevice( result->size() ); - m_iodev = QSharedPointer( bio ); // device audio data gets written to + m_iodev = QSharedPointer( bio, &QObject::deleteLater ); // device audio data gets written to m_iodev->open( QIODevice::ReadWrite ); Servent::instance()->registerStreamConnection( this ); @@ -108,7 +108,7 @@ StreamConnection::id() const } -Tomahawk::source_ptr +Tomahawk::source_ptr StreamConnection::source() const { return m_source; diff --git a/src/resolvers/scriptresolver.cpp b/src/resolvers/scriptresolver.cpp index 913588663..f84acf492 100644 --- a/src/resolvers/scriptresolver.cpp +++ b/src/resolvers/scriptresolver.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -46,6 +46,8 @@ ScriptResolver::ScriptResolver( const QString& exe ) ScriptResolver::~ScriptResolver() { + stop(); + Tomahawk::Pipeline::instance()->removeResolver( this ); } @@ -175,7 +177,7 @@ ScriptResolver::cmdExited( int code, QProcess::ExitStatus status ) qDebug() << Q_FUNC_INFO << "SCRIPT EXITED, code" << code << "status" << status << filePath(); Tomahawk::Pipeline::instance()->removeResolver( this ); - if( m_stopped ) + if( m_stopped ) { qDebug() << "*** Script resolver stopped "; emit finished(); @@ -233,10 +235,11 @@ ScriptResolver::doSetup( const QVariantMap& m ) } -void +void ScriptResolver::stop() { m_stopped = true; + qDebug() << "KILLING PROCESS!"; m_proc.kill(); } diff --git a/src/resolvers/scriptresolver.h b/src/resolvers/scriptresolver.h index dcd5eeed6..60d636352 100644 --- a/src/resolvers/scriptresolver.h +++ b/src/resolvers/scriptresolver.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index 11fa147c2..82e614800 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -223,7 +223,7 @@ TomahawkApp::init() qDebug() << "Init Scrobbler."; m_scrobbler = new Scrobbler( this ); qDebug() << "Setting NAM."; - TomahawkUtils::setNam( new lastfm::NetworkAccessManager( this ) ); + TomahawkUtils::setNam( lastfm::nam() ); #else qDebug() << "Setting NAM."; @@ -290,6 +290,13 @@ TomahawkApp::~TomahawkApp() { qDebug() << Q_FUNC_INFO; + // stop script resolvers + foreach( Tomahawk::ExternalResolver* r, m_scriptResolvers ) + { + delete r; + } + m_scriptResolvers.clear(); + delete m_sipHandler; delete m_servent; delete m_scanManager; From 41c553fac7ba09ec1f778030f6075bbbefc1c574 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sun, 10 Apr 2011 21:03:21 -0400 Subject: [PATCH 19/75] undo oops --- CMakeLists.txt | 23 +++---- include/tomahawk/infosystem.h | 2 +- src/infosystem/infoplugins/lastfmplugin.cpp | 2 +- src/infosystem/infosystemcache.cpp | 68 +++++++++++++++------ src/infosystem/infosystemcache.h | 7 ++- 5 files changed, 69 insertions(+), 33 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a4a65c53..c96d97ea9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,31 +53,32 @@ include( CheckTagLibFileName ) check_taglib_filename( COMPLEX_TAGLIB_FILENAME ) # optional -macro_optional_find_package(Jreen) -IF( ENABLE_JREEN AND NOT LIBJREEN_FOUND ) +IF( ENABLE_JREEN ) + macro_optional_find_package(Jreen) + IF( LIBJREEN_FOUND ) + macro_log_feature(JREEN_FOUND "Jreen" "Qt XMPP library" "http://gitorious.org/jreen" FALSE "" "Jreen is needed for the alternative/new Jabber SIP plugin. Built automatically inside Tomahawk, if not installed systemwide and ENABLE_JREEN is true") + ELSE( LIBJREEN_FOUND ) ADD_SUBDIRECTORY( thirdparty/jreen ) SET( LIBJREEN_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/thirdparty/jreen/include ) IF( UNIX AND NOT APPLE ) SET( LIBJREEN_LIBRARY ${CMAKE_CURRENT_BINARY_DIR}/thirdparty/jreen/libjreen.so ) ENDIF( UNIX AND NOT APPLE ) IF( WIN32 ) - SET( LIBJREEN_LIBRARY ${CMAKE_CURRENT_BINARY_DIR}/thirdparty/jreen/libjreen.dll ) + SET( LIBJREEN_LIBRARY ${CMAKE_CURRENT_BINARY_DIR}/thirdparty/jreen/libjreen.dll ) ENDIF( WIN32 ) SET( LIBJREEN_FOUND true ) MESSAGE(STATUS "Internal libjreen: ${LIBJREEN_INCLUDE_DIR}, ${LIBJREEN_LIBRARY}") -ENDIF( ENABLE_JREEN AND NOT LIBJREEN_FOUND ) + ENDIF( LIBJREEN_FOUND ) +ELSE( LIBJREEN_FOUND ) + macro_optional_find_package(Gloox 1.0) + macro_log_feature(GLOOX_FOUND "Gloox" "A portable high-level Jabber/XMPP library for C++" "http://camaya.net/gloox" FALSE "" "Gloox is needed for the Jabber SIP plugin and the XMPP-Bot") + +ENDIF( ENABLE_JREEN ) IF( WIN32 ) find_library(QTSPARKLE_LIBRARIES qtsparkle) ENDIF( WIN32 ) -macro_log_feature(JREEN_FOUND "Jreen" "Qt XMPP library" "http://gitorious.org/jreen" FALSE "" "Jreen is needed for the alternative/new Jabber SIP plugin. Built automatically inside Tomahawk, if not installed systemwide and ENABLE_JREEN is true") - -macro_optional_find_package(Gloox 1.0) -IF( ENABLE_JREEN ) - set( GLOOX_FOUND false ) -ENDIF( ENABLE_JREEN) -macro_log_feature(GLOOX_FOUND "Gloox" "A portable high-level Jabber/XMPP library for C++" "http://camaya.net/gloox" FALSE "" "Gloox is needed for the Jabber SIP plugin and the XMPP-Bot") #show dep log macro_display_feature_log() MESSAGE("WARNING!") diff --git a/include/tomahawk/infosystem.h b/include/tomahawk/infosystem.h index 1409dabf9..e36af20d3 100644 --- a/include/tomahawk/infosystem.h +++ b/include/tomahawk/infosystem.h @@ -112,7 +112,7 @@ public: virtual void getInfo( const QString &caller, const InfoType type, const QVariant &data, InfoCustomData customData ) = 0; signals: - void getCachedInfo( Tomahawk::InfoSystem::InfoCacheCriteria criteria, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, Tomahawk::InfoSystem::InfoCustomData customData ); + void getCachedInfo( Tomahawk::InfoSystem::InfoCacheCriteria criteria, qint64 newMaxAge, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, Tomahawk::InfoSystem::InfoCustomData customData ); void updateCache( Tomahawk::InfoSystem::InfoCacheCriteria criteria, Tomahawk::InfoSystem::InfoType type, QVariant output ); void info( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ); void finished( QString, Tomahawk::InfoSystem::InfoType ); diff --git a/src/infosystem/infoplugins/lastfmplugin.cpp b/src/infosystem/infoplugins/lastfmplugin.cpp index 652d87414..fcff625bf 100644 --- a/src/infosystem/infoplugins/lastfmplugin.cpp +++ b/src/infosystem/infoplugins/lastfmplugin.cpp @@ -178,7 +178,7 @@ LastFmPlugin::fetchCoverArt( const QString &caller, const InfoType type, const Q criteria["artist"] = hash["artist"].toString(); criteria["album"] = hash["album"].toString(); - emit getCachedInfo( criteria, caller, type, data, customData ); + emit getCachedInfo( criteria, 2419200000, caller, type, data, customData ); } void diff --git a/src/infosystem/infosystemcache.cpp b/src/infosystem/infosystemcache.cpp index 7d73c6ade..9ecdc7435 100644 --- a/src/infosystem/infosystemcache.cpp +++ b/src/infosystem/infosystemcache.cpp @@ -53,10 +53,10 @@ InfoSystemCache::~InfoSystemCache() qDebug() << Q_FUNC_INFO; qDebug() << "Saving infosystemcache to disk"; QString cacheBaseDir = QDesktopServices::storageLocation( QDesktopServices::CacheLocation ); - for( int i = 0; i <= InfoNoInfo; i++ ) + for ( int i = 0; i <= InfoNoInfo; i++ ) { InfoType type = (InfoType)(i); - if( m_dirtySet.contains( type ) && m_dataCache.contains( type ) ) + if ( m_dirtySet.contains( type ) && m_dataCache.contains( type ) ) { QString cacheDir = cacheBaseDir + "/InfoSystemCache/" + QString::number( i ); saveCache( type, cacheDir ); @@ -66,29 +66,57 @@ InfoSystemCache::~InfoSystemCache() void -InfoSystemCache::getCachedInfoSlot( Tomahawk::InfoSystem::InfoCacheCriteria criteria, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, Tomahawk::InfoSystem::InfoCustomData customData ) +InfoSystemCache::getCachedInfoSlot( Tomahawk::InfoSystem::InfoCacheCriteria criteria, qint64 newMaxAge, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, Tomahawk::InfoSystem::InfoCustomData customData ) { qDebug() << Q_FUNC_INFO; - if( !m_dataCache.contains( type ) || !m_dataCache[type].contains( criteria ) ) + if ( !m_dataCache.contains( type ) || !m_dataCache[type].contains( criteria ) ) { emit notInCache( criteria, caller, type, input, customData ); return; } + QHash< InfoCacheCriteria, QDateTime > typemaxtimecache = m_maxTimeCache[type]; + + if ( typemaxtimecache[criteria].toMSecsSinceEpoch() < QDateTime::currentMSecsSinceEpoch() ) + { + QHash< InfoCacheCriteria, QVariant > typedatacache = m_dataCache[type]; + QHash< InfoCacheCriteria, QDateTime > typeinserttimecache = m_insertTimeCache[type]; + typemaxtimecache.remove( criteria ); + m_maxTimeCache[type] = typemaxtimecache; + typedatacache.remove( criteria ); + m_dataCache[type] = typedatacache; + typeinserttimecache.remove( criteria ); + m_insertTimeCache[type] = typeinserttimecache; + m_dirtySet.insert( type ); + emit notInCache( criteria, caller, type, input, customData ); + return; + } + + if ( newMaxAge > 0 ) + { + QHash< InfoCacheCriteria, QDateTime > typemaxtimecache = m_maxTimeCache[type]; + typemaxtimecache[criteria] = QDateTime::fromMSecsSinceEpoch( QDateTime::currentMSecsSinceEpoch() + newMaxAge ); + m_maxTimeCache[type] = typemaxtimecache; + m_dirtySet.insert( type ); + } + emit info( caller, type, input, m_dataCache[type][criteria], customData ); } void -InfoSystemCache::updateCacheSlot( Tomahawk::InfoSystem::InfoCacheCriteria criteria, Tomahawk::InfoSystem::InfoType type, QVariant output ) +InfoSystemCache::updateCacheSlot( Tomahawk::InfoSystem::InfoCacheCriteria criteria, qint64 maxAge, Tomahawk::InfoSystem::InfoType type, QVariant output ) { qDebug() << Q_FUNC_INFO; QHash< InfoCacheCriteria, QVariant > typedatacache = m_dataCache[type]; - QHash< InfoCacheCriteria, QDateTime > typetimecache = m_timeCache[type]; + QHash< InfoCacheCriteria, QDateTime > typeinserttimecache = m_insertTimeCache[type]; + QHash< InfoCacheCriteria, QDateTime > typemaxtimecache = m_maxTimeCache[type]; typedatacache[criteria] = output; - typetimecache[criteria] = QDateTime::currentDateTimeUtc(); + typeinserttimecache[criteria] = QDateTime::currentDateTimeUtc(); + typemaxtimecache[criteria] = QDateTime::fromMSecsSinceEpoch( QDateTime::currentMSecsSinceEpoch() + maxAge ); m_dataCache[type] = typedatacache; - m_timeCache[type] = typetimecache; + m_insertTimeCache[type] = typeinserttimecache; + m_maxTimeCache[type] = typemaxtimecache; m_dirtySet.insert( type ); } @@ -99,26 +127,31 @@ InfoSystemCache::loadCache( InfoType type, const QString &cacheFile ) qDebug() << Q_FUNC_INFO; QSettings cachedSettings( cacheFile, QSettings::IniFormat ); - foreach( QString group, cachedSettings.childGroups() ) + foreach ( QString group, cachedSettings.childGroups() ) { - QHash< InfoCacheCriteria, QVariant > dataHash = m_dataCache[type]; - QHash< InfoCacheCriteria, QDateTime > dateHash = m_timeCache[type]; - InfoCacheCriteria criteria; cachedSettings.beginGroup( group ); + if ( cachedSettings.value( "maxtime" ).toDateTime().toMSecsSinceEpoch() < QDateTime::currentMSecsSinceEpoch() ) + continue; + QHash< InfoCacheCriteria, QVariant > dataHash = m_dataCache[type]; + QHash< InfoCacheCriteria, QDateTime > insertDateHash = m_insertTimeCache[type]; + QHash< InfoCacheCriteria, QDateTime > maxDateHash = m_maxTimeCache[type]; + InfoCacheCriteria criteria; int numCriteria = cachedSettings.beginReadArray( "criteria" ); - for( int i = 0; i < numCriteria; i++ ) + for ( int i = 0; i < numCriteria; i++ ) { cachedSettings.setArrayIndex( i ); QStringList criteriaValues = cachedSettings.value( QString::number( i ) ).toStringList(); - for( int j = 0; j < criteriaValues.length(); j += 2 ) + for ( int j = 0; j < criteriaValues.length(); j += 2 ) criteria[criteriaValues.at( j )] = criteriaValues.at( j + 1 ); } cachedSettings.endArray(); dataHash[criteria] = cachedSettings.value( "data" ); - dateHash[criteria] = cachedSettings.value( "time" ).toDateTime(); + insertDateHash[criteria] = cachedSettings.value( "inserttime" ).toDateTime(); + maxDateHash[criteria] = cachedSettings.value( "maxtime" ).toDateTime(); cachedSettings.endGroup(); m_dataCache[type] = dataHash; - m_timeCache[type] = dateHash; + m_insertTimeCache[type] = insertDateHash; + m_maxTimeCache[type] = maxDateHash; } } @@ -156,7 +189,8 @@ InfoSystemCache::saveCache( InfoType type, const QString &cacheDir ) } cachedSettings.endArray(); cachedSettings.setValue( "data", m_dataCache[type][criteria] ); - cachedSettings.setValue( "time", m_timeCache[type][criteria] ); + cachedSettings.setValue( "inserttime", m_insertTimeCache[type][criteria] ); + cachedSettings.setValue( "maxtime", m_maxTimeCache[type][criteria] ); cachedSettings.endGroup(); ++criteriaNumber; } diff --git a/src/infosystem/infosystemcache.h b/src/infosystem/infosystemcache.h index ca347f7bc..0ccad6d19 100644 --- a/src/infosystem/infosystemcache.h +++ b/src/infosystem/infosystemcache.h @@ -45,15 +45,16 @@ signals: void info( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ); public slots: - void getCachedInfoSlot( Tomahawk::InfoSystem::InfoCacheCriteria criteria, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, Tomahawk::InfoSystem::InfoCustomData customData ); - void updateCacheSlot( Tomahawk::InfoSystem::InfoCacheCriteria criteria, Tomahawk::InfoSystem::InfoType type, QVariant output ); + void getCachedInfoSlot( Tomahawk::InfoSystem::InfoCacheCriteria criteria, qint64 newMaxAge, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, Tomahawk::InfoSystem::InfoCustomData customData ); + void updateCacheSlot( Tomahawk::InfoSystem::InfoCacheCriteria criteria, qint64 maxAge, Tomahawk::InfoSystem::InfoType type, QVariant output ); private: void loadCache( InfoType type, const QString &cacheFile ); void saveCache( InfoType type, const QString &cacheDir ); QHash< InfoType, QHash< InfoCacheCriteria, QVariant > > m_dataCache; - QHash< InfoType, QHash< InfoCacheCriteria, QDateTime > > m_timeCache; + QHash< InfoType, QHash< InfoCacheCriteria, QDateTime > > m_insertTimeCache; + QHash< InfoType, QHash< InfoCacheCriteria, QDateTime > > m_maxTimeCache; QSet< InfoType > m_dirtySet; }; From 5235cc9093c6557b02a82b55c43e88dc59b11a5e Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sun, 10 Apr 2011 21:04:18 -0400 Subject: [PATCH 20/75] less debug --- src/libtomahawk/audio/audioengine.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libtomahawk/audio/audioengine.cpp b/src/libtomahawk/audio/audioengine.cpp index e7e931cf7..8b2987149 100644 --- a/src/libtomahawk/audio/audioengine.cpp +++ b/src/libtomahawk/audio/audioengine.cpp @@ -206,9 +206,7 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result ) else { setCurrentTrack( result ); - qDebug() << "Getting IODEVICE, on thread:" << QThread::currentThread() << QThread::currentThreadId(); io = Servent::instance()->getIODeviceForUrl( m_currentTrack ); - qDebug() << "GOT IODEVICE:" << io.data(); if ( m_currentTrack->url().startsWith( "http://" ) ) { m_readReady = false; From 4095f4b5aac8a1f292788d617458ae7cd49177fe Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Mon, 11 Apr 2011 10:11:40 -0400 Subject: [PATCH 21/75] support loading local .xspfs from files --- src/libtomahawk/utils/xspfloader.cpp | 4 ++-- src/libtomahawk/utils/xspfloader.h | 2 +- src/tomahawkwindow.cpp | 30 +++++++++++++++++----------- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/libtomahawk/utils/xspfloader.cpp b/src/libtomahawk/utils/xspfloader.cpp index 5b1899300..d8b31d40d 100644 --- a/src/libtomahawk/utils/xspfloader.cpp +++ b/src/libtomahawk/utils/xspfloader.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -137,7 +137,7 @@ XSPFLoader::gotBody() track = n.text(); } } - + if( artist.isEmpty() || track.isEmpty() ) { if( !shownError ) { QMessageBox::warning( 0, tr( "Failed to save tracks" ), tr( "Some tracks in the playlist do not contain an artist and a title. They will be ignored." ), QMessageBox::Ok ); diff --git a/src/libtomahawk/utils/xspfloader.h b/src/libtomahawk/utils/xspfloader.h index d541293cf..39e5088f7 100644 --- a/src/libtomahawk/utils/xspfloader.h +++ b/src/libtomahawk/utils/xspfloader.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify diff --git a/src/tomahawkwindow.cpp b/src/tomahawkwindow.cpp index 15b355d28..08d7dd504 100644 --- a/src/tomahawkwindow.cpp +++ b/src/tomahawkwindow.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -108,7 +108,7 @@ TomahawkWindow::TomahawkWindow( QWidget* parent ) connect( ui->actionHideOfflineSources, SIGNAL( triggered() ), stv, SLOT( hideOfflineSources() ) ); connect( ui->actionShowOfflineSources, SIGNAL( triggered() ), stv, SLOT( showOfflineSources() ) ); - + sidebar->addWidget( stv ); sidebar->addWidget( transferView ); sidebar->hide( 1, false ); @@ -145,7 +145,7 @@ TomahawkWindow::TomahawkWindow( QWidget* parent ) toolbar->setIconSize( QSize( 32, 32 ) ); toolbar->setToolButtonStyle( Qt::ToolButtonFollowStyle ); toolbar->installEventFilter( new WidgetDragFilter( toolbar ) ); - + #if defined( Q_OS_DARWIN ) && defined( HAVE_SPARKLE ) QAction* checkForUpdates = ui->menu_Help->addAction( tr( "Check For Updates...") ); checkForUpdates->setMenuRole( QAction::ApplicationSpecificRole ); @@ -161,7 +161,7 @@ TomahawkWindow::TomahawkWindow( QWidget* parent ) qtsparkle::Updater* updater = new qtsparkle::Updater( updaterUrl, this ); updater->SetNetworkAccessManager( TomahawkUtils::nam() ); updater->SetVersion( VERSION ); - + ui->menu_Help->addSeparator(); QAction* checkForUpdates = ui->menu_Help->addAction( tr( "Check For Updates...") ); connect( checkForUpdates, SIGNAL( triggered() ), updater, SLOT( CheckNow() ) ); @@ -355,14 +355,14 @@ TomahawkWindow::addPeerManually() } -void +void TomahawkWindow::pluginMenuAdded( QMenu* menu ) { ui->menuNetwork->addMenu( menu ); } -void +void TomahawkWindow::pluginMenuRemoved( QMenu* menu ) { foreach( QAction* action, ui->menuNetwork->actions() ) @@ -384,21 +384,27 @@ TomahawkWindow::loadSpiff() if ( !ok || urlstr.isEmpty() ) return; - QUrl url( urlstr ); - XSPFLoader* loader = new XSPFLoader; - loader->load( url ); + QFileInfo info( urlstr ); + if( info.isFile() ) + { + QFile f( urlstr ); + loader->load( f ); + } else + { + loader->load( QUrl( urlstr ) ); + } } -void +void TomahawkWindow::createAutomaticPlaylist() { bool ok; QString name = QInputDialog::getText( this, tr( "Create New Automatic Playlist" ), tr( "Name:" ), QLineEdit::Normal, tr( "New Automatic Playlist" ), &ok ); if ( !ok || name.isEmpty() ) return; - + source_ptr author = SourceList::instance()->getLocal(); QString id = uuid(); QString info = ""; // FIXME @@ -417,7 +423,7 @@ TomahawkWindow::createStation() QString name = QInputDialog::getText( this, tr( "Create New Station" ), tr( "Name:" ), QLineEdit::Normal, tr( "New Station" ), &ok ); if ( !ok || name.isEmpty() ) return; - + source_ptr author = SourceList::instance()->getLocal(); QString id = uuid(); QString info = ""; // FIXME From c24a95e49f4138802e93aa12c2d0ffbdc71a9376 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Mon, 11 Apr 2011 10:11:40 -0400 Subject: [PATCH 22/75] support loading local .xspfs from files (cherry picked from commit 4095f4b5aac8a1f292788d617458ae7cd49177fe) --- src/libtomahawk/utils/xspfloader.cpp | 4 ++-- src/libtomahawk/utils/xspfloader.h | 2 +- src/tomahawkwindow.cpp | 30 +++++++++++++++++----------- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/libtomahawk/utils/xspfloader.cpp b/src/libtomahawk/utils/xspfloader.cpp index 5b1899300..d8b31d40d 100644 --- a/src/libtomahawk/utils/xspfloader.cpp +++ b/src/libtomahawk/utils/xspfloader.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -137,7 +137,7 @@ XSPFLoader::gotBody() track = n.text(); } } - + if( artist.isEmpty() || track.isEmpty() ) { if( !shownError ) { QMessageBox::warning( 0, tr( "Failed to save tracks" ), tr( "Some tracks in the playlist do not contain an artist and a title. They will be ignored." ), QMessageBox::Ok ); diff --git a/src/libtomahawk/utils/xspfloader.h b/src/libtomahawk/utils/xspfloader.h index d541293cf..39e5088f7 100644 --- a/src/libtomahawk/utils/xspfloader.h +++ b/src/libtomahawk/utils/xspfloader.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify diff --git a/src/tomahawkwindow.cpp b/src/tomahawkwindow.cpp index 868f1609b..97adfb7ca 100644 --- a/src/tomahawkwindow.cpp +++ b/src/tomahawkwindow.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -108,7 +108,7 @@ TomahawkWindow::TomahawkWindow( QWidget* parent ) connect( ui->actionHideOfflineSources, SIGNAL( triggered() ), stv, SLOT( hideOfflineSources() ) ); connect( ui->actionShowOfflineSources, SIGNAL( triggered() ), stv, SLOT( showOfflineSources() ) ); - + sidebar->addWidget( stv ); sidebar->addWidget( transferView ); sidebar->hide( 1, false ); @@ -145,7 +145,7 @@ TomahawkWindow::TomahawkWindow( QWidget* parent ) toolbar->setIconSize( QSize( 32, 32 ) ); toolbar->setToolButtonStyle( Qt::ToolButtonFollowStyle ); toolbar->installEventFilter( new WidgetDragFilter( toolbar ) ); - + #if defined( Q_OS_DARWIN ) && defined( HAVE_SPARKLE ) QAction* checkForUpdates = ui->menu_Help->addAction( tr( "Check for updates...") ); checkForUpdates->setMenuRole( QAction::ApplicationSpecificRole ); @@ -161,7 +161,7 @@ TomahawkWindow::TomahawkWindow( QWidget* parent ) qtsparkle::Updater* updater = new qtsparkle::Updater( updaterUrl, this ); updater->SetNetworkAccessManager( TomahawkUtils::nam() ); updater->SetVersion( VERSION ); - + ui->menu_Help->addSeparator(); QAction* checkForUpdates = ui->menu_Help->addAction( tr( "Check for updates...") ); connect( checkForUpdates, SIGNAL( triggered() ), updater, SLOT( CheckNow() ) ); @@ -355,14 +355,14 @@ TomahawkWindow::addPeerManually() } -void +void TomahawkWindow::pluginMenuAdded( QMenu* menu ) { ui->menuNetwork->addMenu( menu ); } -void +void TomahawkWindow::pluginMenuRemoved( QMenu* menu ) { foreach( QAction* action, ui->menuNetwork->actions() ) @@ -384,21 +384,27 @@ TomahawkWindow::loadSpiff() if ( !ok || urlstr.isEmpty() ) return; - QUrl url( urlstr ); - XSPFLoader* loader = new XSPFLoader; - loader->load( url ); + QFileInfo info( urlstr ); + if( info.isFile() ) + { + QFile f( urlstr ); + loader->load( f ); + } else + { + loader->load( QUrl( urlstr ) ); + } } -void +void TomahawkWindow::createAutomaticPlaylist() { bool ok; QString name = QInputDialog::getText( this, "Create New Automatic Playlist", "Name:", QLineEdit::Normal, "New Automatic Playlist", &ok ); if ( !ok || name.isEmpty() ) return; - + source_ptr author = SourceList::instance()->getLocal(); QString id = uuid(); QString info = ""; // FIXME @@ -417,7 +423,7 @@ TomahawkWindow::createStation() QString name = QInputDialog::getText( this, "Create New Station", "Name:", QLineEdit::Normal, "New Station", &ok ); if ( !ok || name.isEmpty() ) return; - + source_ptr author = SourceList::instance()->getLocal(); QString id = uuid(); QString info = ""; // FIXME From 1cb3516dc69bd3c9ade3d08751635ba7b4a39950 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Mon, 11 Apr 2011 11:01:26 -0400 Subject: [PATCH 23/75] As per domme's suggestion, use ::fromUserInput to make loading xspfs work everywhere --- src/tomahawkapp.cpp | 2 +- src/tomahawkwindow.cpp | 10 +--------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index 826887587..4c10d987d 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -524,7 +524,7 @@ TomahawkApp::loadUrl( const QString& url ) if( f.exists() && info.suffix() == "xspf" ) { XSPFLoader* l = new XSPFLoader( true, this ); qDebug() << "Loading spiff:" << url; - l->load( QUrl( url ) ); + l->load( QUrl::fromUserInput( url ) ); } } return true; diff --git a/src/tomahawkwindow.cpp b/src/tomahawkwindow.cpp index 97adfb7ca..20de04fa1 100644 --- a/src/tomahawkwindow.cpp +++ b/src/tomahawkwindow.cpp @@ -385,15 +385,7 @@ TomahawkWindow::loadSpiff() return; XSPFLoader* loader = new XSPFLoader; - QFileInfo info( urlstr ); - if( info.isFile() ) - { - QFile f( urlstr ); - loader->load( f ); - } else - { - loader->load( QUrl( urlstr ) ); - } + loader->load( QUrl::fromUserInput( urlstr ) ); } From 24d9cce3a8562d694b9cb08da19c19a347a380d5 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Mon, 11 Apr 2011 15:36:29 -0400 Subject: [PATCH 24/75] Install a .protocol file on KDE so tomahawk:// links work there too --- CMakeLists.txt | 17 ++++++++++++++--- admin/unix/tomahawk.protocol | 2 +- src/CMakeLists.txt | 12 +++++++++++- thirdparty/alsa-playback/CMakeLists.txt | 2 ++ thirdparty/jdns/CMakeLists.txt | 2 ++ thirdparty/libportfwd/CMakeLists.txt | 2 ++ 6 files changed, 32 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dde40af13..b69c77148 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,12 +47,22 @@ macro_log_feature(TAGLIB_FOUND "TagLib" "Audio Meta-Data Library" "http://develo # we need pthreads too find_package(Threads) +find_package(KDE4) +IF(KDE4_FOUND) + #KDE4 adds and removes some compiler flags that we don't like + STRING( REPLACE "-std=iso9899:1990" "" CLEAN_C_FLAGS ${CMAKE_C_FLAGS} ) + SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexceptions" ) +ELSE() + SET( CLEAN_C_FLAGS ${CMAKE_C_FLAGS} ) +ENDIF() + include( CheckTagLibFileName ) check_taglib_filename( COMPLEX_TAGLIB_FILENAME ) # optional macro_optional_find_package(Jreen) IF( ENABLE_JREEN AND NOT LIBJREEN_FOUND ) + ADD_SUBDIRECTORY( thirdparty/jreen ) SET( LIBJREEN_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/thirdparty/jreen/include ) IF( UNIX AND NOT APPLE ) @@ -92,9 +102,10 @@ CONFIGURE_FILE( "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY) -ADD_CUSTOM_TARGET(uninstall - "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake") - +# KDE4 defines an uninstall target for us automatically +IF( NOT KDE4_FOUND ) + ADD_CUSTOM_TARGET(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake") +ENDIF() IF( NOT APPLE ) # Make linking as strict on linux as it is on osx. Then we don't break linking on mac so often diff --git a/admin/unix/tomahawk.protocol b/admin/unix/tomahawk.protocol index 3a393aa61..f342fb39c 100644 --- a/admin/unix/tomahawk.protocol +++ b/admin/unix/tomahawk.protocol @@ -1,5 +1,5 @@ [Protocol] -exec=/home/leo/kde/tomahawk/build/tomahawk "%u" +exec=/path/to/binary "%u" protocol=tomahawk input=none output=none diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a28f4d97b..8bc02ece4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -120,7 +120,7 @@ SET( tomahawkUI ${tomahawkUI} ) INCLUDE_DIRECTORIES( - . + . ${TOMAHAWK_INC_DIR} ${CMAKE_CURRENT_BINARY_DIR} @@ -237,4 +237,14 @@ ENDIF( APPLE ) INSTALL( TARGETS tomahawk BUNDLE DESTINATION . RUNTIME DESTINATION bin ) +IF(KDE4_FOUND) #install protocol file + FILE(READ ${CMAKE_SOURCE_DIR}/admin/unix/tomahawk.protocol protocol) + STRING( REPLACE "/path/to/binary" # match this + "${CMAKE_INSTALL_PREFIX}/bin/tomahawk" # this is linux (kde) so pretty safe I think + edited_protocol # save in this variable + "${protocol}" # from the contents of this var + ) + FILE( WRITE ${CMAKE_BINARY_DIR}/tomahawk.protocol "${edited_protocol}" ) + INSTALL( FILES ${CMAKE_BINARY_DIR}/tomahawk.protocol DESTINATION ${SERVICES_INSTALL_DIR} ) +ENDIF() #INCLUDE( "CPack.txt" ) diff --git a/thirdparty/alsa-playback/CMakeLists.txt b/thirdparty/alsa-playback/CMakeLists.txt index 4a4e98d99..b8fe19f7f 100644 --- a/thirdparty/alsa-playback/CMakeLists.txt +++ b/thirdparty/alsa-playback/CMakeLists.txt @@ -12,6 +12,8 @@ SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}") SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}") SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}") +SET( CMAKE_C_FLAGS ${CLEAN_C_FLAGS} ) + #ADD_DEFINITIONS(-Wall -O2 -DNDEBUG) ADD_DEFINITIONS(-fPIC) diff --git a/thirdparty/jdns/CMakeLists.txt b/thirdparty/jdns/CMakeLists.txt index 85667cb7e..70df58ed4 100644 --- a/thirdparty/jdns/CMakeLists.txt +++ b/thirdparty/jdns/CMakeLists.txt @@ -9,6 +9,8 @@ INCLUDE( ${QT_USE_FILE} ) add_definitions( ${QT_DEFINITIONS} ) add_definitions( -DQT_SHARED ) +SET( CMAKE_C_FLAGS ${CLEAN_C_FLAGS} ) + if(WIN32) set(PLATFORM_SPECIFIC_LIBS "ws2_32.dll" "advapi32.dll" ) endif(WIN32) diff --git a/thirdparty/libportfwd/CMakeLists.txt b/thirdparty/libportfwd/CMakeLists.txt index c301bf95b..e19485414 100644 --- a/thirdparty/libportfwd/CMakeLists.txt +++ b/thirdparty/libportfwd/CMakeLists.txt @@ -17,6 +17,8 @@ ELSE() ENDIF() INCLUDE_DIRECTORIES(${MINIUPNP_DIR} include) +SET( CMAKE_C_FLAGS ${CLEAN_C_FLAGS} ) + ADD_LIBRARY(portfwd STATIC # the needed bits of miniupnpc (no python module, no tests, no cli) From f5f16b6b2693186a79adf141e139362879a570cc Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Mon, 11 Apr 2011 17:10:31 -0400 Subject: [PATCH 25/75] update the Info.plist version as a part of cmake so we don't forget next time :) --- admin/mac/Info.plist | 4 ++-- src/CMakeLists.osx.txt | 17 ++++++++++------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/admin/mac/Info.plist b/admin/mac/Info.plist index 9acc67a0c..f4fd83c88 100644 --- a/admin/mac/Info.plist +++ b/admin/mac/Info.plist @@ -13,9 +13,9 @@ CFBundlePackageType APPL CFBundleVersion - 0.0.2.0 + TOMAHAWK_VERSION CFBundleShortVersionString - 0.0.2 + TOMAHAWK_VERSION CFBundleSignature tomahawk CFBundleIconFile diff --git a/src/CMakeLists.osx.txt b/src/CMakeLists.osx.txt index 6d3ded108..0488b2f71 100644 --- a/src/CMakeLists.osx.txt +++ b/src/CMakeLists.osx.txt @@ -35,15 +35,18 @@ if (APPLE) # Use two different sparkle update tracks for debug and release # We have to change the URL in the Info.plist file :-/ - IF( NOT CMAKE_BUILD_TYPE STREQUAL "Release" ) - FILE(READ ${CMAKE_SOURCE_DIR}/admin/mac/Info.plist plist) - STRING( REPLACE "http://download.tomahawk-player.org/sparkle" # match this - "http://download.tomahawk-player.org/sparkle-debug" #replace with debug url + FILE(READ ${CMAKE_SOURCE_DIR}/admin/mac/Info.plist plist) + STRING( REPLACE "TOMAHAWK_VERSION" + ${VERSION} edited_plist # save in this variable "${plist}" # from the contents of this var ) - FILE( WRITE ${CMAKE_BINARY_DIR}/Info.plist "${edited_plist}" ) - ELSE() # Just copy the release one - FILE( COPY ${CMAKE_SOURCE_DIR}/admin/mac/Info.plist DESTINATION ${CMAKE_BINARY_DIR} ) + IF( NOT CMAKE_BUILD_TYPE STREQUAL "Release" ) + STRING( REPLACE "http://download.tomahawk-player.org/sparkle" # match this + "http://download.tomahawk-player.org/sparkle-debug" #replace with debug url + edited_plist # save in this variable + "${edited_plist}" # from the contents of this var + ) ENDIF() + FILE( WRITE ${CMAKE_BINARY_DIR}/Info.plist "${edited_plist}" ) endif (APPLE) From 0d6c335e45e3d4b11918656bd8f05fed48631360 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Tue, 12 Apr 2011 10:53:32 -0400 Subject: [PATCH 26/75] Suppress warning with newer cmake --- CMakeLists.txt | 2 ++ thirdparty/qxt/qxtweb-standalone/CMakeLists.txt | 1 + 2 files changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 97fa506d8..22af95c72 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,8 @@ PROJECT( tomahawk ) CMAKE_MINIMUM_REQUIRED( VERSION 2.8 ) +CMAKE_POLICY(SET CMP0017 NEW) + ### ### Tomahawk application info ### diff --git a/thirdparty/qxt/qxtweb-standalone/CMakeLists.txt b/thirdparty/qxt/qxtweb-standalone/CMakeLists.txt index ec81d04cb..c0a453e40 100644 --- a/thirdparty/qxt/qxtweb-standalone/CMakeLists.txt +++ b/thirdparty/qxt/qxtweb-standalone/CMakeLists.txt @@ -2,6 +2,7 @@ PROJECT(libqxtweb-standalone) CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR) SET(CMAKE_VERBOSE_MAKEFILE ON) SET(CMAKE_INSTALL_PREFIX ".") +CMAKE_POLICY(SET CMP0017 NEW) FIND_PACKAGE( Qt4 4.6.0 COMPONENTS QtCore QtNetwork REQUIRED ) set(QT_USE_QTNETWORK TRUE) From 3b873dfedac2c36652f9e78c6105d33b608d3ced Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Tue, 12 Apr 2011 11:00:07 -0400 Subject: [PATCH 27/75] Limit policy setting to 2.8.4 or higher --- CMakeLists.txt | 4 +++- thirdparty/qxt/qxtweb-standalone/CMakeLists.txt | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 22af95c72..e08ee0e3b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,9 @@ PROJECT( tomahawk ) CMAKE_MINIMUM_REQUIRED( VERSION 2.8 ) -CMAKE_POLICY(SET CMP0017 NEW) +IF( ${CMAKE_VERSION} VERSION_GREATER 2.8.3 ) + CMAKE_POLICY(SET CMP0017 NEW) +ENDIF( ${CMAKE_VERSION} VERSION_GREATER 2.8.3 ) ### ### Tomahawk application info diff --git a/thirdparty/qxt/qxtweb-standalone/CMakeLists.txt b/thirdparty/qxt/qxtweb-standalone/CMakeLists.txt index c0a453e40..d29e7b989 100644 --- a/thirdparty/qxt/qxtweb-standalone/CMakeLists.txt +++ b/thirdparty/qxt/qxtweb-standalone/CMakeLists.txt @@ -2,7 +2,10 @@ PROJECT(libqxtweb-standalone) CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR) SET(CMAKE_VERBOSE_MAKEFILE ON) SET(CMAKE_INSTALL_PREFIX ".") -CMAKE_POLICY(SET CMP0017 NEW) + +IF( ${CMAKE_VERSION} VERSION_GREATER 2.8.3 ) + CMAKE_POLICY(SET CMP0017 NEW) +ENDIF( ${CMAKE_VERSION} VERSION_GREATER 2.8.3 ) FIND_PACKAGE( Qt4 4.6.0 COMPONENTS QtCore QtNetwork REQUIRED ) set(QT_USE_QTNETWORK TRUE) From 0c3ec4a6cf7ec5e3ec450db80089b603449da087 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Tue, 12 Apr 2011 11:24:54 -0400 Subject: [PATCH 28/75] Fix Jreen compilation when KDE4 is found --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index e08ee0e3b..71c62fdea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,6 +71,8 @@ IF( ENABLE_JREEN ) IF( LIBJREEN_FOUND ) macro_log_feature(JREEN_FOUND "Jreen" "Qt XMPP library" "http://gitorious.org/jreen" FALSE "" "Jreen is needed for the alternative/new Jabber SIP plugin. Built automatically inside Tomahawk, if not installed systemwide and ENABLE_JREEN is true") ELSE( LIBJREEN_FOUND ) + SET( OLD_C_FLAGS ${CMAKE_C_FLAGS} ) + SET( CMAKE_C_FLAGS ${CLEAN_C_FLAGS} ) ADD_SUBDIRECTORY( thirdparty/jreen ) SET( LIBJREEN_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/thirdparty/jreen/include ) IF( UNIX AND NOT APPLE ) @@ -81,6 +83,7 @@ IF( ENABLE_JREEN ) ENDIF( WIN32 ) SET( LIBJREEN_FOUND true ) MESSAGE(STATUS "Internal libjreen: ${LIBJREEN_INCLUDE_DIR}, ${LIBJREEN_LIBRARY}") + SET( CMAKE_C_FLAGS ${OLD_C_FLAGS} ) ENDIF( LIBJREEN_FOUND ) ELSE( LIBJREEN_FOUND ) macro_optional_find_package(Gloox 1.0) From 4a6bc942fa4df746f29438389c1615ecd44df584 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Tue, 12 Apr 2011 12:21:03 -0400 Subject: [PATCH 29/75] First round of warning cleanups. Leo, please look at the changes in the playlist stuff, make sure I didn't screw anything up --- include/tomahawk/infosystem.h | 5 +++++ src/audiocontrols.cpp | 4 ++++ src/libtomahawk/album.h | 2 +- src/libtomahawk/artist.h | 2 +- src/libtomahawk/database/database.h | 2 +- src/libtomahawk/database/databasecommand.h | 3 ++- .../database/databasecommand_alltracks.cpp | 1 - .../database/databasecommand_loadops.h | 4 +++- .../databasecommand_loadplaylistentries.h | 2 +- .../database/databasecommand_modifyplaylist.cpp | 1 + src/libtomahawk/database/databaseimpl.cpp | 1 + src/libtomahawk/database/databaseworker.cpp | 3 +++ src/libtomahawk/network/remotecollection.cpp | 2 ++ src/libtomahawk/network/servent.cpp | 15 ++++++++++++++- src/libtomahawk/playlist.cpp | 1 + src/libtomahawk/playlist.h | 4 ++-- src/libtomahawk/playlist/albummodel.cpp | 2 ++ src/libtomahawk/playlist/albummodel.h | 4 ++-- src/libtomahawk/playlist/albumproxymodel.cpp | 9 +++++++-- src/libtomahawk/playlist/albumproxymodel.h | 2 +- src/libtomahawk/playlist/albumview.cpp | 9 +++++++-- src/libtomahawk/playlist/albumview.h | 2 +- src/libtomahawk/playlist/collectionflatmodel.h | 2 +- src/libtomahawk/playlist/collectionmodel.h | 4 ++-- src/libtomahawk/playlist/collectionview.cpp | 10 +++++++--- src/libtomahawk/playlist/collectionview.h | 2 +- .../playlist/dynamic/DynamicControl.h | 4 ++-- .../playlist/dynamic/DynamicModel.cpp | 6 +++++- src/libtomahawk/playlist/dynamic/DynamicModel.h | 2 +- .../playlist/dynamic/DynamicPlaylist.h | 4 ++-- .../playlist/dynamic/GeneratorFactory.h | 2 ++ .../playlist/dynamic/GeneratorInterface.h | 4 ++-- .../playlist/dynamic/widgets/DynamicWidget.cpp | 2 ++ .../playlist/playlistitemdelegate.cpp | 3 +++ src/libtomahawk/playlist/playlistmodel.cpp | 1 + src/libtomahawk/playlist/playlistview.cpp | 17 +++++++++++------ src/libtomahawk/playlist/playlistview.h | 2 +- src/libtomahawk/playlist/trackmodel.cpp | 2 ++ src/libtomahawk/playlist/trackmodel.h | 4 ++-- src/libtomahawk/playlist/trackproxymodel.cpp | 14 +++++++++----- src/libtomahawk/playlist/trackproxymodel.h | 2 +- src/libtomahawk/playlist/trackview.cpp | 9 +++++++-- src/libtomahawk/playlist/trackview.h | 4 ++-- src/libtomahawk/source.cpp | 2 ++ src/libtomahawk/tomahawksettings.cpp | 2 +- src/libtomahawk/viewpage.h | 2 ++ src/libtomahawk/widgets/welcomewidget.cpp | 2 ++ src/scrobbler.cpp | 3 +++ src/sourcetree/sourcesmodel.cpp | 1 + src/sourcetree/sourcetreeview.cpp | 1 + src/sourcetree/sourcetreeview.h | 2 +- 51 files changed, 141 insertions(+), 54 deletions(-) diff --git a/include/tomahawk/infosystem.h b/include/tomahawk/infosystem.h index e36af20d3..e1f0017c5 100644 --- a/include/tomahawk/infosystem.h +++ b/include/tomahawk/infosystem.h @@ -121,6 +121,11 @@ public slots: //FIXME: Make pure virtual when everything supports it virtual void notInCacheSlot( Tomahawk::InfoSystem::InfoCacheCriteria criteria, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, Tomahawk::InfoSystem::InfoCustomData customData ) { + Q_UNUSED( criteria ); + Q_UNUSED( caller ); + Q_UNUSED( type ); + Q_UNUSED( input ); + Q_UNUSED( customData ); } protected: diff --git a/src/audiocontrols.cpp b/src/audiocontrols.cpp index 1138826ee..e7b0e8739 100644 --- a/src/audiocontrols.cpp +++ b/src/audiocontrols.cpp @@ -264,6 +264,9 @@ AudioControls::onPlaybackStarted( const Tomahawk::result_ptr& result ) void AudioControls::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ) { + Q_UNUSED( input ); + Q_UNUSED( customData ); + qDebug() << Q_FUNC_INFO; if ( caller != s_infoIdentifier || type != Tomahawk::InfoSystem::InfoAlbumCoverArt ) { @@ -300,6 +303,7 @@ AudioControls::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType ty void AudioControls::infoSystemFinished( QString target ) { + Q_UNUSED( target ); qDebug() << Q_FUNC_INFO; } diff --git a/src/libtomahawk/album.h b/src/libtomahawk/album.h index df8009b27..a1497f490 100644 --- a/src/libtomahawk/album.h +++ b/src/libtomahawk/album.h @@ -58,7 +58,7 @@ public: virtual void setRepeatMode( PlaylistInterface::RepeatMode ) {} virtual void setShuffled( bool ) {} - virtual void setFilter( const QString& pattern ) {} + virtual void setFilter( const QString& /*pattern*/ ) {} signals: void repeatModeChanged( PlaylistInterface::RepeatMode mode ); diff --git a/src/libtomahawk/artist.h b/src/libtomahawk/artist.h index d7f5ac7ef..200e29c48 100644 --- a/src/libtomahawk/artist.h +++ b/src/libtomahawk/artist.h @@ -58,7 +58,7 @@ public: virtual void setRepeatMode( PlaylistInterface::RepeatMode ) {} virtual void setShuffled( bool ) {} - virtual void setFilter( const QString& pattern ) {} + virtual void setFilter( const QString& /*pattern*/ ) {} signals: void repeatModeChanged( PlaylistInterface::RepeatMode mode ); diff --git a/src/libtomahawk/database/database.h b/src/libtomahawk/database/database.h index a6890fbb6..df02ce2a0 100644 --- a/src/libtomahawk/database/database.h +++ b/src/libtomahawk/database/database.h @@ -49,7 +49,7 @@ public: ~Database(); QString dbid() const; - const bool indexReady() const { return m_indexReady; } + bool indexReady() const { return m_indexReady; } void loadIndex(); diff --git a/src/libtomahawk/database/databasecommand.h b/src/libtomahawk/database/databasecommand.h index f18440ca7..35fff3dfc 100644 --- a/src/libtomahawk/database/databasecommand.h +++ b/src/libtomahawk/database/databasecommand.h @@ -48,6 +48,7 @@ public: explicit DatabaseCommand( const Tomahawk::source_ptr& src, QObject* parent = 0 ); DatabaseCommand( const DatabaseCommand &other ) + : QObject( other.parent() ) { } @@ -59,7 +60,7 @@ public: // if i make this pure virtual, i get compile errors in qmetatype.h. // we need Q_DECLARE_METATYPE to use in queued sig/slot connections. - virtual void exec( DatabaseImpl* lib ) { Q_ASSERT( false ); } + virtual void exec( DatabaseImpl* /*lib*/ ) { Q_ASSERT( false ); } void _exec( DatabaseImpl* lib ); diff --git a/src/libtomahawk/database/databasecommand_alltracks.cpp b/src/libtomahawk/database/databasecommand_alltracks.cpp index 07072db4b..8e2548a3c 100644 --- a/src/libtomahawk/database/databasecommand_alltracks.cpp +++ b/src/libtomahawk/database/databasecommand_alltracks.cpp @@ -77,7 +77,6 @@ DatabaseCommand_AllTracks::exec( DatabaseImpl* dbi ) query.prepare( sql ); query.exec(); - int i = 0; while( query.next() ) { Tomahawk::result_ptr result = Tomahawk::result_ptr( new Tomahawk::Result() ); diff --git a/src/libtomahawk/database/databasecommand_loadops.h b/src/libtomahawk/database/databasecommand_loadops.h index 6a3580f42..06c8cb56f 100644 --- a/src/libtomahawk/database/databasecommand_loadops.h +++ b/src/libtomahawk/database/databasecommand_loadops.h @@ -32,7 +32,9 @@ Q_OBJECT public: explicit DatabaseCommand_loadOps( const Tomahawk::source_ptr& src, QString since, QObject* parent = 0 ) : DatabaseCommand( src ), m_since( since ) - {} + { + Q_UNUSED( parent ); + } virtual void exec( DatabaseImpl* db ); virtual bool doesMutates() const { return false; } diff --git a/src/libtomahawk/database/databasecommand_loadplaylistentries.h b/src/libtomahawk/database/databasecommand_loadplaylistentries.h index ec597ef67..255c9a017 100644 --- a/src/libtomahawk/database/databasecommand_loadplaylistentries.h +++ b/src/libtomahawk/database/databasecommand_loadplaylistentries.h @@ -33,7 +33,7 @@ Q_OBJECT public: explicit DatabaseCommand_LoadPlaylistEntries( QString revision_guid, QObject* parent = 0 ) - : DatabaseCommand( parent ), m_revguid( revision_guid ), m_islatest( true ) + : DatabaseCommand( parent ), m_islatest( true ), m_revguid( revision_guid ) {} virtual void exec( DatabaseImpl* ); diff --git a/src/libtomahawk/database/databasecommand_modifyplaylist.cpp b/src/libtomahawk/database/databasecommand_modifyplaylist.cpp index 640fe8a3c..1d60da687 100644 --- a/src/libtomahawk/database/databasecommand_modifyplaylist.cpp +++ b/src/libtomahawk/database/databasecommand_modifyplaylist.cpp @@ -32,4 +32,5 @@ DatabaseCommand_ModifyPlaylist::DatabaseCommand_ModifyPlaylist( Playlist* playli void DatabaseCommand_ModifyPlaylist::exec( DatabaseImpl* lib ) { + Q_UNUSED( lib ); } diff --git a/src/libtomahawk/database/databaseimpl.cpp b/src/libtomahawk/database/databaseimpl.cpp index ff96c3d7d..85615f00e 100644 --- a/src/libtomahawk/database/databaseimpl.cpp +++ b/src/libtomahawk/database/databaseimpl.cpp @@ -369,6 +369,7 @@ DatabaseImpl::albumId( int artistid, const QString& name_orig, bool& isnew ) QList< int > DatabaseImpl::searchTable( const QString& table, const QString& name, uint limit ) { + Q_UNUSED( limit ); QList< int > results; if( table != "artist" && table != "track" && table != "album" ) return results; diff --git a/src/libtomahawk/database/databaseworker.cpp b/src/libtomahawk/database/databaseworker.cpp index 791888e80..e0d1f7be7 100644 --- a/src/libtomahawk/database/databaseworker.cpp +++ b/src/libtomahawk/database/databaseworker.cpp @@ -32,6 +32,9 @@ DatabaseWorker::DatabaseWorker( DatabaseImpl* lib, Database* db, bool mutates ) , m_abort( false ) , m_outstanding( 0 ) { + Q_UNUSED( db ); + Q_UNUSED( mutates ); + moveToThread( this ); qDebug() << "CTOR DatabaseWorker" << this->thread(); diff --git a/src/libtomahawk/network/remotecollection.cpp b/src/libtomahawk/network/remotecollection.cpp index 8bfdfd3a2..e73966cac 100644 --- a/src/libtomahawk/network/remotecollection.cpp +++ b/src/libtomahawk/network/remotecollection.cpp @@ -31,6 +31,7 @@ RemoteCollection::RemoteCollection( source_ptr source, QObject* parent ) // the database will make us emit the appropriate signals (tracksAdded etc.) void RemoteCollection::addTracks( const QList& newitems ) { + Q_UNUSED( newitems ); qDebug() << Q_FUNC_INFO; Q_ASSERT( false ); } @@ -38,6 +39,7 @@ void RemoteCollection::addTracks( const QList& newitems ) void RemoteCollection::removeTracks( const QDir& dir ) { + Q_UNUSED( dir ); qDebug() << Q_FUNC_INFO; Q_ASSERT( false ); } diff --git a/src/libtomahawk/network/servent.cpp b/src/libtomahawk/network/servent.cpp index 4b9a88358..16f46d428 100644 --- a/src/libtomahawk/network/servent.cpp +++ b/src/libtomahawk/network/servent.cpp @@ -137,7 +137,11 @@ Servent::startListening( QHostAddress ha, bool upnp, int port ) return true; } - switch( TomahawkSettings::instance()->externalAddressMode() ) + TomahawkSettings::ExternalAddressMode mode = TomahawkSettings::instance()->externalAddressMode(); + if ( mode == TomahawkSettings::Upnp && !upnp ) + mode = TomahawkSettings::Lan; + + switch( mode ) { case TomahawkSettings::Lan: foreach( QHostAddress ha, QNetworkInterface::allAddresses() ) @@ -696,7 +700,16 @@ Servent::checkACL( const Connection* conn, const QString &nodeid, bool showDialo return false; } else if( msgBox.clickedButton() == alwaysAllowButton ) + { aclSystem->authorizeUser( nodeid, ACLSystem::Allow ); + return true; + } + else if( msgBox.clickedButton() == allowButton ) + return true; + + //How could we get here? + qDebug() << "Somehow no button matched"; + return false; } #endif diff --git a/src/libtomahawk/playlist.cpp b/src/libtomahawk/playlist.cpp index 9d35c0fe6..bf65556da 100644 --- a/src/libtomahawk/playlist.cpp +++ b/src/libtomahawk/playlist.cpp @@ -431,6 +431,7 @@ Playlist::resolve() void Playlist::onResultsFound( const QList& results ) { + Q_UNUSED( results ); m_locallyChanged = true; } diff --git a/src/libtomahawk/playlist.h b/src/libtomahawk/playlist.h index d0a4ee490..5147a3d9b 100644 --- a/src/libtomahawk/playlist.h +++ b/src/libtomahawk/playlist.h @@ -162,7 +162,7 @@ public: virtual int unfilteredTrackCount() const { return m_entries.count(); } virtual int trackCount() const { return m_entries.count(); } - virtual Tomahawk::result_ptr siblingItem( int itemsAway ) { return result_ptr(); } + virtual Tomahawk::result_ptr siblingItem( int /*itemsAway*/ ) { return result_ptr(); } virtual PlaylistInterface::RepeatMode repeatMode() const { return PlaylistInterface::NoRepeat; } virtual bool shuffled() const { return false; } @@ -170,7 +170,7 @@ public: virtual void setRepeatMode( PlaylistInterface::RepeatMode ) {} virtual void setShuffled( bool ) {} - virtual void setFilter( const QString& pattern ) {} + virtual void setFilter( const QString& /*pattern*/ ) {} signals: /// emitted when the playlist revision changes (whenever the playlist changes) diff --git a/src/libtomahawk/playlist/albummodel.cpp b/src/libtomahawk/playlist/albummodel.cpp index a60610e36..6be94ee1a 100644 --- a/src/libtomahawk/playlist/albummodel.cpp +++ b/src/libtomahawk/playlist/albummodel.cpp @@ -81,6 +81,7 @@ AlbumModel::rowCount( const QModelIndex& parent ) const int AlbumModel::columnCount( const QModelIndex& parent ) const { + Q_UNUSED( parent ); return 1; } @@ -273,6 +274,7 @@ AlbumModel::addFilteredCollection( const collection_ptr& collection, unsigned in void AlbumModel::onAlbumsAdded( const QList& albums, const Tomahawk::collection_ptr& collection ) { + Q_UNUSED( collection ); if ( !albums.count() ) return; diff --git a/src/libtomahawk/playlist/albummodel.h b/src/libtomahawk/playlist/albummodel.h index dc080a84c..fd9361b60 100644 --- a/src/libtomahawk/playlist/albummodel.h +++ b/src/libtomahawk/playlist/albummodel.h @@ -81,8 +81,8 @@ public: } public slots: - virtual void setRepeatMode( PlaylistInterface::RepeatMode mode ) {} - virtual void setShuffled( bool shuffled ) {} + virtual void setRepeatMode( PlaylistInterface::RepeatMode /*mode*/ ) {} + virtual void setShuffled( bool /*shuffled*/ ) {} signals: void repeatModeChanged( PlaylistInterface::RepeatMode mode ); diff --git a/src/libtomahawk/playlist/albumproxymodel.cpp b/src/libtomahawk/playlist/albumproxymodel.cpp index 8a9f66493..97f2130c7 100644 --- a/src/libtomahawk/playlist/albumproxymodel.cpp +++ b/src/libtomahawk/playlist/albumproxymodel.cpp @@ -43,9 +43,13 @@ AlbumProxyModel::AlbumProxyModel( QObject* parent ) void -AlbumProxyModel::setSourceModel( AlbumModel* sourceModel ) +AlbumProxyModel::setSourceModel( QAbstractItemModel* sourceModel ) { - m_model = sourceModel; + AlbumModel* amodel = static_cast< AlbumModel* >( sourceModel ); + if( !amodel ) + return; + else + m_model = amodel; connect( m_model, SIGNAL( trackCountChanged( unsigned int ) ), SIGNAL( sourceTrackCountChanged( unsigned int ) ) ); @@ -141,6 +145,7 @@ AlbumProxyModel::removeIndexes( const QList& indexes ) Tomahawk::result_ptr AlbumProxyModel::siblingItem( int itemsAway ) { + Q_UNUSED( itemsAway ); qDebug() << Q_FUNC_INFO; return Tomahawk::result_ptr( 0 ); } diff --git a/src/libtomahawk/playlist/albumproxymodel.h b/src/libtomahawk/playlist/albumproxymodel.h index 151ba51c8..87535bbb1 100644 --- a/src/libtomahawk/playlist/albumproxymodel.h +++ b/src/libtomahawk/playlist/albumproxymodel.h @@ -34,7 +34,7 @@ public: explicit AlbumProxyModel( QObject* parent = 0 ); virtual AlbumModel* sourceModel() const { return m_model; } - virtual void setSourceModel( AlbumModel* sourceModel ); + virtual void setSourceModel( QAbstractItemModel* sourceModel ); virtual QList tracks() { Q_ASSERT( FALSE ); QList queries; return queries; } diff --git a/src/libtomahawk/playlist/albumview.cpp b/src/libtomahawk/playlist/albumview.cpp index 1f8affea7..4d652d1f4 100644 --- a/src/libtomahawk/playlist/albumview.cpp +++ b/src/libtomahawk/playlist/albumview.cpp @@ -72,9 +72,14 @@ AlbumView::setProxyModel( AlbumProxyModel* model ) void -AlbumView::setModel( AlbumModel* model ) +AlbumView::setModel( QAbstractItemModel* model ) { - m_model = model; + AlbumModel *amodel = static_cast< AlbumModel* >( model ); + + if ( !amodel ) + return; + else + m_model = amodel; if ( m_proxyModel ) { diff --git a/src/libtomahawk/playlist/albumview.h b/src/libtomahawk/playlist/albumview.h index 953863ab2..013cb349a 100644 --- a/src/libtomahawk/playlist/albumview.h +++ b/src/libtomahawk/playlist/albumview.h @@ -42,7 +42,7 @@ public: AlbumProxyModel* proxyModel() const { return m_proxyModel; } // PlaylistItemDelegate* delegate() { return m_delegate; } - void setModel( AlbumModel* model ); + void setModel( QAbstractItemModel* model ); virtual QWidget* widget() { return this; } virtual PlaylistInterface* playlistInterface() const { return proxyModel(); } diff --git a/src/libtomahawk/playlist/collectionflatmodel.h b/src/libtomahawk/playlist/collectionflatmodel.h index fee195376..65e1489a0 100644 --- a/src/libtomahawk/playlist/collectionflatmodel.h +++ b/src/libtomahawk/playlist/collectionflatmodel.h @@ -54,7 +54,7 @@ public: void addFilteredCollection( const Tomahawk::collection_ptr& collection, unsigned int amount, DatabaseCommand_AllTracks::SortOrder order ); - virtual void append( const Tomahawk::query_ptr& query ) {} + virtual void append( const Tomahawk::query_ptr& /*query*/ ) {} signals: void repeatModeChanged( PlaylistInterface::RepeatMode mode ); diff --git a/src/libtomahawk/playlist/collectionmodel.h b/src/libtomahawk/playlist/collectionmodel.h index d6563922f..2ba760743 100644 --- a/src/libtomahawk/playlist/collectionmodel.h +++ b/src/libtomahawk/playlist/collectionmodel.h @@ -59,8 +59,8 @@ public: virtual PlaylistInterface::RepeatMode repeatMode() const { return PlaylistInterface::NoRepeat; } virtual bool shuffled() const { return false; } - virtual void setRepeatMode( PlaylistInterface::RepeatMode mode ) {} - virtual void setShuffled( bool shuffled ) {} + virtual void setRepeatMode( PlaylistInterface::RepeatMode /*mode*/ ) {} + virtual void setShuffled( bool /*shuffled*/ ) {} TrackModelItem* itemFromIndex( const QModelIndex& index ) const; diff --git a/src/libtomahawk/playlist/collectionview.cpp b/src/libtomahawk/playlist/collectionview.cpp index d67b02535..e5a72cd19 100644 --- a/src/libtomahawk/playlist/collectionview.cpp +++ b/src/libtomahawk/playlist/collectionview.cpp @@ -51,12 +51,16 @@ CollectionView::~CollectionView() void -CollectionView::setModel( TrackModel* model ) +CollectionView::setModel( QAbstractItemModel* model ) { - TrackView::setModel( model ); + TrackModel *tmodel = static_cast< TrackModel* >( model ); + if ( !tmodel ) + return; + + TrackView::setModel( tmodel ); setGuid( "collectionview" ); - connect( model, SIGNAL( trackCountChanged( unsigned int ) ), SLOT( onTrackCountChanged( unsigned int ) ) ); + connect( tmodel, SIGNAL( trackCountChanged( unsigned int ) ), SLOT( onTrackCountChanged( unsigned int ) ) ); } diff --git a/src/libtomahawk/playlist/collectionview.h b/src/libtomahawk/playlist/collectionview.h index ea26fc5af..54fa0b47a 100644 --- a/src/libtomahawk/playlist/collectionview.h +++ b/src/libtomahawk/playlist/collectionview.h @@ -36,7 +36,7 @@ public: explicit CollectionView( QWidget* parent = 0 ); ~CollectionView(); - virtual void setModel( TrackModel* model ); + virtual void setModel( QAbstractItemModel* model ); virtual QWidget* widget() { return this; } virtual PlaylistInterface* playlistInterface() const { return proxyModel(); } diff --git a/src/libtomahawk/playlist/dynamic/DynamicControl.h b/src/libtomahawk/playlist/dynamic/DynamicControl.h index 42b62d07d..c03d386fd 100644 --- a/src/libtomahawk/playlist/dynamic/DynamicControl.h +++ b/src/libtomahawk/playlist/dynamic/DynamicControl.h @@ -79,8 +79,8 @@ public: virtual QString summary() const { Q_ASSERT( false ); return QString(); } // used by JSON serialization - virtual void setMatch( const QString& match ) { Q_ASSERT( false ); } - virtual void setInput( const QString& input ) { Q_ASSERT( false ); } + virtual void setMatch( const QString& /*match*/ ) { Q_ASSERT( false ); } + virtual void setInput( const QString& /*input*/ ) { Q_ASSERT( false ); } /// All the potential type selectors for this control QStringList typeSelectors() const { return m_typeSelectors; } diff --git a/src/libtomahawk/playlist/dynamic/DynamicModel.cpp b/src/libtomahawk/playlist/dynamic/DynamicModel.cpp index 43fceeaac..689af3bca 100644 --- a/src/libtomahawk/playlist/dynamic/DynamicModel.cpp +++ b/src/libtomahawk/playlist/dynamic/DynamicModel.cpp @@ -42,8 +42,10 @@ DynamicModel::~DynamicModel() } void -DynamicModel::loadPlaylist( const Tomahawk::dynplaylist_ptr& playlist ) +DynamicModel::loadPlaylist( const Tomahawk::dynplaylist_ptr& playlist, bool loadEntries ) { + Q_UNUSED( loadEntries ); + if( !m_playlist.isNull() ) { disconnect( m_playlist->generator().data(), SIGNAL( nextTrackGenerated( Tomahawk::query_ptr ) ), this, SLOT( newTrackGenerated( Tomahawk::query_ptr ) ) ); } @@ -108,6 +110,8 @@ DynamicModel::changeStation() void DynamicModel::trackResolveFinished( bool success ) { + Q_UNUSED( success ); + Query* q = qobject_cast(sender()); if( !q->playable() ) { diff --git a/src/libtomahawk/playlist/dynamic/DynamicModel.h b/src/libtomahawk/playlist/dynamic/DynamicModel.h index a3cdc5f65..23aa93e68 100644 --- a/src/libtomahawk/playlist/dynamic/DynamicModel.h +++ b/src/libtomahawk/playlist/dynamic/DynamicModel.h @@ -44,7 +44,7 @@ public: virtual QString description() const; - void loadPlaylist( const dynplaylist_ptr& playlist ); + void loadPlaylist( const dynplaylist_ptr& playlist, bool loadEntries = true ); virtual void removeIndex( const QModelIndex& index, bool moreToCome = false ); diff --git a/src/libtomahawk/playlist/dynamic/DynamicPlaylist.h b/src/libtomahawk/playlist/dynamic/DynamicPlaylist.h index bee37900a..04cd2119e 100644 --- a/src/libtomahawk/playlist/dynamic/DynamicPlaylist.h +++ b/src/libtomahawk/playlist/dynamic/DynamicPlaylist.h @@ -105,7 +105,7 @@ public: // maybe friend QObjectHelper and make them private? explicit DynamicPlaylist( const source_ptr& author, const QString& type ); void setMode( int mode ); - void setType( const QString& type ) { /** TODO */; } + void setType( const QString& /*type*/ ) { /** TODO */; } void setGenerator( const geninterface_ptr& gen_ptr ); // @@ -189,4 +189,4 @@ private: }; // namespace -#endif \ No newline at end of file +#endif diff --git a/src/libtomahawk/playlist/dynamic/GeneratorFactory.h b/src/libtomahawk/playlist/dynamic/GeneratorFactory.h index 5687dbb91..56a131cd1 100644 --- a/src/libtomahawk/playlist/dynamic/GeneratorFactory.h +++ b/src/libtomahawk/playlist/dynamic/GeneratorFactory.h @@ -36,6 +36,8 @@ class DLLEXPORT GeneratorFactoryInterface { public: GeneratorFactoryInterface() {} + + virtual ~GeneratorFactoryInterface() {} virtual GeneratorInterface* create() = 0; /** diff --git a/src/libtomahawk/playlist/dynamic/GeneratorInterface.h b/src/libtomahawk/playlist/dynamic/GeneratorInterface.h index b08634104..238c14ff6 100644 --- a/src/libtomahawk/playlist/dynamic/GeneratorInterface.h +++ b/src/libtomahawk/playlist/dynamic/GeneratorInterface.h @@ -70,7 +70,7 @@ public: * Connect to the generated() signal for the results. * */ - virtual void generate( int number = -1 ) {} + virtual void generate( int number = -1 ) { Q_UNUSED( number ); } /** * Starts an on demand session for this generator. Listen to the nextTrack() signal to get @@ -82,7 +82,7 @@ public: * Get the next on demand track. * \param rating Rating from 1-5, -1 for none */ - virtual void fetchNext( int rating = -1 ) {} + virtual void fetchNext( int rating = -1 ) { Q_UNUSED( rating ) } /** * Return a sentence that describes this generator's controls. TODO english only ATM diff --git a/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.cpp b/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.cpp index bd76b5683..0aa65d3bc 100644 --- a/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.cpp +++ b/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.cpp @@ -171,6 +171,7 @@ DynamicWidget::loadDynamicPlaylist( const Tomahawk::dynplaylist_ptr& playlist ) void DynamicWidget::onRevisionLoaded( const Tomahawk::DynamicPlaylistRevision& rev ) { + Q_UNUSED( rev ); qDebug() << "DynamicWidget::onRevisionLoaded"; loadDynamicPlaylist( m_playlist ); if( m_resolveOnNextLoad || !m_playlist->author()->isLocal() ) @@ -354,6 +355,7 @@ DynamicWidget::controlsChanged() void DynamicWidget::controlChanged( const Tomahawk::dyncontrol_ptr& control ) { + Q_UNUSED( control ); if( !m_playlist->author()->isLocal() ) return; m_playlist->createNewRevision(); diff --git a/src/libtomahawk/playlist/playlistitemdelegate.cpp b/src/libtomahawk/playlist/playlistitemdelegate.cpp index 8e9adb3a7..174001fc7 100644 --- a/src/libtomahawk/playlist/playlistitemdelegate.cpp +++ b/src/libtomahawk/playlist/playlistitemdelegate.cpp @@ -61,6 +61,9 @@ PlaylistItemDelegate::sizeHint( const QStyleOptionViewItem& option, const QModel QWidget* PlaylistItemDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const { + Q_UNUSED( parent ); + Q_UNUSED( option ); + Q_UNUSED( index ); return 0; } diff --git a/src/libtomahawk/playlist/playlistmodel.cpp b/src/libtomahawk/playlist/playlistmodel.cpp index 22e863457..c171f2cb1 100644 --- a/src/libtomahawk/playlist/playlistmodel.cpp +++ b/src/libtomahawk/playlist/playlistmodel.cpp @@ -298,6 +298,7 @@ PlaylistModel::onRevisionLoaded( Tomahawk::PlaylistRevision revision ) bool PlaylistModel::dropMimeData( const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent ) { + Q_UNUSED( column ); if ( action == Qt::IgnoreAction || isReadOnly() ) return true; diff --git a/src/libtomahawk/playlist/playlistview.cpp b/src/libtomahawk/playlist/playlistview.cpp index 79026e872..e6a06ea0c 100644 --- a/src/libtomahawk/playlist/playlistview.cpp +++ b/src/libtomahawk/playlist/playlistview.cpp @@ -45,20 +45,25 @@ PlaylistView::~PlaylistView() void -PlaylistView::setModel( PlaylistModel* model ) +PlaylistView::setModel( QAbstractItemModel* model ) { - m_model = model; + PlaylistModel* pmodel = static_cast< PlaylistModel* >( model ); + + if ( !pmodel ) + return; + else + m_model = pmodel; TrackView::setModel( model ); setColumnHidden( 5, true ); // Hide age column per default - if ( !model->playlist().isNull() ) - setGuid( QString( "playlistview/%1" ).arg( model->playlist()->guid() ) ); + if ( !m_model->playlist().isNull() ) + setGuid( QString( "playlistview/%1" ).arg( m_model->playlist()->guid() ) ); else setGuid( "playlistview" ); - connect( model, SIGNAL( trackCountChanged( unsigned int ) ), SLOT( onTrackCountChanged( unsigned int ) ) ); - connect( model, SIGNAL( playlistDeleted() ), SLOT( onDeleted() ) ); + connect( m_model, SIGNAL( trackCountChanged( unsigned int ) ), SLOT( onTrackCountChanged( unsigned int ) ) ); + connect( m_model, SIGNAL( playlistDeleted() ), SLOT( onDeleted() ) ); } diff --git a/src/libtomahawk/playlist/playlistview.h b/src/libtomahawk/playlist/playlistview.h index 5fa0d3a51..dbf653625 100644 --- a/src/libtomahawk/playlist/playlistview.h +++ b/src/libtomahawk/playlist/playlistview.h @@ -39,7 +39,7 @@ public: ~PlaylistView(); PlaylistModel* playlistModel() const { return m_model; } - virtual void setModel( PlaylistModel* model ); + virtual void setModel( QAbstractItemModel* model ); virtual QWidget* widget() { return this; } virtual PlaylistInterface* playlistInterface() const { return proxyModel(); } diff --git a/src/libtomahawk/playlist/trackmodel.cpp b/src/libtomahawk/playlist/trackmodel.cpp index 6bcb438a8..0249aa1d1 100644 --- a/src/libtomahawk/playlist/trackmodel.cpp +++ b/src/libtomahawk/playlist/trackmodel.cpp @@ -81,6 +81,7 @@ TrackModel::rowCount( const QModelIndex& parent ) const int TrackModel::columnCount( const QModelIndex& parent ) const { + Q_UNUSED( parent ); return 9; } @@ -207,6 +208,7 @@ TrackModel::data( const QModelIndex& index, int role ) const QVariant TrackModel::headerData( int section, Qt::Orientation orientation, int role ) const { + Q_UNUSED( orientation ); QStringList headers; headers << tr( "Artist" ) << tr( "Track" ) << tr( "Album" ) << tr( "Duration" ) << tr( "Bitrate" ) << tr( "Age" ) << tr( "Year" ) << tr( "Size" ) << tr( "Origin" ); if ( role == Qt::DisplayRole && section >= 0 ) diff --git a/src/libtomahawk/playlist/trackmodel.h b/src/libtomahawk/playlist/trackmodel.h index 3fbb1e868..843e8f72a 100644 --- a/src/libtomahawk/playlist/trackmodel.h +++ b/src/libtomahawk/playlist/trackmodel.h @@ -99,8 +99,8 @@ public slots: virtual void removeIndex( const QModelIndex& index, bool moreToCome = false ); virtual void removeIndexes( const QList& indexes ); - virtual void setRepeatMode( PlaylistInterface::RepeatMode mode ) {} - virtual void setShuffled( bool shuffled ) {} + virtual void setRepeatMode( PlaylistInterface::RepeatMode /*mode*/ ) {} + virtual void setShuffled( bool /*shuffled*/ ) {} protected: virtual void setReadOnly( bool b ) { m_readOnly = b; } diff --git a/src/libtomahawk/playlist/trackproxymodel.cpp b/src/libtomahawk/playlist/trackproxymodel.cpp index 6fa2ac3f6..f69670057 100644 --- a/src/libtomahawk/playlist/trackproxymodel.cpp +++ b/src/libtomahawk/playlist/trackproxymodel.cpp @@ -45,13 +45,17 @@ TrackProxyModel::TrackProxyModel( QObject* parent ) void -TrackProxyModel::setSourceModel( TrackModel* sourceModel ) +TrackProxyModel::setSourceModel( QAbstractItemModel* sourceModel ) { - m_model = sourceModel; + TrackModel* tmodel = static_cast< TrackModel* >( sourceModel ); - if ( m_model ) - connect( m_model, SIGNAL( trackCountChanged( unsigned int ) ), - SIGNAL( sourceTrackCountChanged( unsigned int ) ) ); + if ( !tmodel ) + return; + else + m_model = tmodel; + + connect( m_model, SIGNAL( trackCountChanged( unsigned int ) ), + SIGNAL( sourceTrackCountChanged( unsigned int ) ) ); QSortFilterProxyModel::setSourceModel( sourceModel ); } diff --git a/src/libtomahawk/playlist/trackproxymodel.h b/src/libtomahawk/playlist/trackproxymodel.h index fa68b8c4b..ac626f0a5 100644 --- a/src/libtomahawk/playlist/trackproxymodel.h +++ b/src/libtomahawk/playlist/trackproxymodel.h @@ -34,7 +34,7 @@ public: explicit TrackProxyModel ( QObject* parent = 0 ); virtual TrackModel* sourceModel() const { return m_model; } - virtual void setSourceModel( TrackModel* sourceModel ); + virtual void setSourceModel( QAbstractItemModel* sourceModel ); virtual QPersistentModelIndex currentItem() const { return mapFromSource( m_model->currentItem() ); } virtual void setCurrentItem( const QModelIndex& index ) { m_model->setCurrentItem( mapToSource( index ) ); } diff --git a/src/libtomahawk/playlist/trackview.cpp b/src/libtomahawk/playlist/trackview.cpp index 3ec4ce4c7..8b851ba33 100644 --- a/src/libtomahawk/playlist/trackview.cpp +++ b/src/libtomahawk/playlist/trackview.cpp @@ -107,9 +107,14 @@ TrackView::setProxyModel( TrackProxyModel* model ) void -TrackView::setModel( TrackModel* model ) +TrackView::setModel( QAbstractItemModel* model ) { - m_model = model; + TrackModel* tmodel = static_cast< TrackModel* >( model ); + + if ( !tmodel ) + return; + else + m_model = tmodel; if ( m_proxyModel ) { diff --git a/src/libtomahawk/playlist/trackview.h b/src/libtomahawk/playlist/trackview.h index 7777e24a3..2d9707f26 100644 --- a/src/libtomahawk/playlist/trackview.h +++ b/src/libtomahawk/playlist/trackview.h @@ -44,7 +44,7 @@ public: virtual QString guid() const { return m_guid; } virtual void setGuid( const QString& guid ); - virtual void setModel( TrackModel* model ); + virtual void setModel( QAbstractItemModel* model ); void setProxyModel( TrackProxyModel* model ); virtual TrackModel* model() const { return m_model; } @@ -67,7 +67,7 @@ protected: virtual void startDrag( Qt::DropActions supportedActions ); virtual void dragEnterEvent( QDragEnterEvent* event ); - virtual void dragLeaveEvent( QDragLeaveEvent* event ) { m_dragging = false; setDirtyRegion( m_dropRect ); } + virtual void dragLeaveEvent( QDragLeaveEvent* /*event*/ ) { m_dragging = false; setDirtyRegion( m_dropRect ); } virtual void dragMoveEvent( QDragMoveEvent* event ); virtual void dropEvent( QDropEvent* event ); diff --git a/src/libtomahawk/source.cpp b/src/libtomahawk/source.cpp index 54c4394b3..29715c966 100644 --- a/src/libtomahawk/source.cpp +++ b/src/libtomahawk/source.cpp @@ -181,6 +181,7 @@ Source::scanningProgress( unsigned int files ) void Source::scanningFinished( unsigned int files ) { + Q_UNUSED( files ); m_textStatus = QString(); emit stateChanged(); } @@ -189,6 +190,7 @@ Source::scanningFinished( unsigned int files ) void Source::onStateChanged( DBSyncConnection::State newstate, DBSyncConnection::State oldstate, const QString& info ) { + Q_UNUSED( oldstate ); QString msg; switch( newstate ) { diff --git a/src/libtomahawk/tomahawksettings.cpp b/src/libtomahawk/tomahawksettings.cpp index bdbe3c171..37a905cad 100644 --- a/src/libtomahawk/tomahawksettings.cpp +++ b/src/libtomahawk/tomahawksettings.cpp @@ -624,7 +624,7 @@ TomahawkSettings::xmppBotPort() const void TomahawkSettings::setXmppBotPort( const int port ) { - setValue( "xmppBot/port", -1 ); + setValue( "xmppBot/port", port ); } void diff --git a/src/libtomahawk/viewpage.h b/src/libtomahawk/viewpage.h index a515c47e6..356fabcf8 100644 --- a/src/libtomahawk/viewpage.h +++ b/src/libtomahawk/viewpage.h @@ -35,6 +35,8 @@ class DLLEXPORT ViewPage public: ViewPage() {} + virtual ~ViewPage() {} + virtual QWidget* widget() = 0; virtual PlaylistInterface* playlistInterface() const = 0; diff --git a/src/libtomahawk/widgets/welcomewidget.cpp b/src/libtomahawk/widgets/welcomewidget.cpp index d7ad62938..55154e32f 100644 --- a/src/libtomahawk/widgets/welcomewidget.cpp +++ b/src/libtomahawk/widgets/welcomewidget.cpp @@ -190,6 +190,8 @@ PlaylistWidgetItem::data( int role ) const QSize PlaylistDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const { + Q_UNUSED( option ); + Q_UNUSED( index ); return QSize( 0, 64 ); } diff --git a/src/scrobbler.cpp b/src/scrobbler.cpp index bbdb0e26f..2968d5196 100644 --- a/src/scrobbler.cpp +++ b/src/scrobbler.cpp @@ -137,6 +137,9 @@ Scrobbler::scrobble() void Scrobbler::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ) { + Q_UNUSED( input ); + Q_UNUSED( output ); + Q_UNUSED( customData ); if ( caller == s_infoIdentifier ) { qDebug() << Q_FUNC_INFO; diff --git a/src/sourcetree/sourcesmodel.cpp b/src/sourcetree/sourcesmodel.cpp index bee554830..76f1d233d 100644 --- a/src/sourcetree/sourcesmodel.cpp +++ b/src/sourcetree/sourcesmodel.cpp @@ -352,6 +352,7 @@ SourcesModel::collectionToIndex( const Tomahawk::collection_ptr& collection ) bool SourcesModel::setData( const QModelIndex& index, const QVariant& value, int role ) { + Q_UNUSED( role ); qDebug() << Q_FUNC_INFO; if ( !index.isValid() ) diff --git a/src/sourcetree/sourcetreeview.cpp b/src/sourcetree/sourcetreeview.cpp index 050f895db..4ceccd2c1 100644 --- a/src/sourcetree/sourcetreeview.cpp +++ b/src/sourcetree/sourcetreeview.cpp @@ -168,6 +168,7 @@ SourceTreeView::hideOfflineSources() void SourceTreeView::onSourceOffline( Tomahawk::source_ptr src ) { + Q_UNUSED( src ); qDebug() << Q_FUNC_INFO; } diff --git a/src/sourcetree/sourcetreeview.h b/src/sourcetree/sourcetreeview.h index 710c609cb..e9cbe51b0 100644 --- a/src/sourcetree/sourcetreeview.h +++ b/src/sourcetree/sourcetreeview.h @@ -68,7 +68,7 @@ protected: virtual void paintEvent( QPaintEvent* event ); virtual void dragEnterEvent( QDragEnterEvent* event ); - virtual void dragLeaveEvent( QDragLeaveEvent* event ) { m_dragging = false; setDirtyRegion( m_dropRect ); } + virtual void dragLeaveEvent( QDragLeaveEvent* event ) { Q_UNUSED( event ); m_dragging = false; setDirtyRegion( m_dropRect ); } virtual void dragMoveEvent( QDragMoveEvent* event ); virtual void dropEvent( QDropEvent* event ); From e2a3c48e6e318f6fa00b3e999b89ce786891d1c8 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Tue, 12 Apr 2011 15:21:05 -0400 Subject: [PATCH 30/75] Rejig the parameters and add QASSERTs. Chris, I decided to take your advice about the asserts -- it will help in the future to make sure people don't mistakenly use the wrong function in new code either. --- src/libtomahawk/playlist/albumproxymodel.cpp | 15 +++++++++------ src/libtomahawk/playlist/albumproxymodel.h | 1 + src/libtomahawk/playlist/albumview.cpp | 18 ++++++++++++------ src/libtomahawk/playlist/albumview.h | 1 + src/libtomahawk/playlist/collectionview.cpp | 14 +++++++++----- src/libtomahawk/playlist/collectionview.h | 1 + .../playlist/dynamic/DynamicView.cpp | 8 ++++---- src/libtomahawk/playlist/dynamic/DynamicView.h | 2 +- src/libtomahawk/playlist/playlistview.cpp | 16 ++++++++++------ src/libtomahawk/playlist/playlistview.h | 1 + src/libtomahawk/playlist/trackproxymodel.cpp | 18 +++++++++++------- src/libtomahawk/playlist/trackproxymodel.h | 3 ++- src/libtomahawk/playlist/trackview.cpp | 17 +++++++++++------ src/libtomahawk/playlist/trackview.h | 1 + 14 files changed, 74 insertions(+), 42 deletions(-) diff --git a/src/libtomahawk/playlist/albumproxymodel.cpp b/src/libtomahawk/playlist/albumproxymodel.cpp index 97f2130c7..c3b3fe29c 100644 --- a/src/libtomahawk/playlist/albumproxymodel.cpp +++ b/src/libtomahawk/playlist/albumproxymodel.cpp @@ -41,15 +41,18 @@ AlbumProxyModel::AlbumProxyModel( QObject* parent ) setSourceModel( 0 ); } - void AlbumProxyModel::setSourceModel( QAbstractItemModel* sourceModel ) { - AlbumModel* amodel = static_cast< AlbumModel* >( sourceModel ); - if( !amodel ) - return; - else - m_model = amodel; + Q_UNUSED( sourceModel ); + qDebug() << "Explicitly use setSourceAlbumModel instead"; + Q_ASSERT( false ); +} + +void +AlbumProxyModel::setSourceAlbumModel( AlbumModel* sourceModel ) +{ + m_model = sourceModel; connect( m_model, SIGNAL( trackCountChanged( unsigned int ) ), SIGNAL( sourceTrackCountChanged( unsigned int ) ) ); diff --git a/src/libtomahawk/playlist/albumproxymodel.h b/src/libtomahawk/playlist/albumproxymodel.h index 87535bbb1..7427cc85f 100644 --- a/src/libtomahawk/playlist/albumproxymodel.h +++ b/src/libtomahawk/playlist/albumproxymodel.h @@ -34,6 +34,7 @@ public: explicit AlbumProxyModel( QObject* parent = 0 ); virtual AlbumModel* sourceModel() const { return m_model; } + virtual void setSourceAlbumModel( AlbumModel* sourceModel ); virtual void setSourceModel( QAbstractItemModel* sourceModel ); virtual QList tracks() { Q_ASSERT( FALSE ); QList queries; return queries; } diff --git a/src/libtomahawk/playlist/albumview.cpp b/src/libtomahawk/playlist/albumview.cpp index 4d652d1f4..9f6ad1a57 100644 --- a/src/libtomahawk/playlist/albumview.cpp +++ b/src/libtomahawk/playlist/albumview.cpp @@ -74,16 +74,20 @@ AlbumView::setProxyModel( AlbumProxyModel* model ) void AlbumView::setModel( QAbstractItemModel* model ) { - AlbumModel *amodel = static_cast< AlbumModel* >( model ); + Q_UNUSED( model ); + qDebug() << "Explicitly use setAlbumModel instead"; + Q_ASSERT( false ); +} - if ( !amodel ) - return; - else - m_model = amodel; + +void +AlbumView::setAlbumModel( AlbumModel* model ) +{ + m_model = model; if ( m_proxyModel ) { - m_proxyModel->setSourceModel( model ); + m_proxyModel->setSourceModel( m_model ); m_proxyModel->sort( 0 ); } @@ -147,6 +151,7 @@ AlbumView::onFilterChanged( const QString& ) void AlbumView::startDrag( Qt::DropActions supportedActions ) { + Q_UNUSED( supportedActions ); } @@ -154,5 +159,6 @@ AlbumView::startDrag( Qt::DropActions supportedActions ) QPixmap AlbumView::createDragPixmap( int itemCount ) const { + Q_UNUSED( itemCount ); return QPixmap(); } diff --git a/src/libtomahawk/playlist/albumview.h b/src/libtomahawk/playlist/albumview.h index 013cb349a..194eab8d7 100644 --- a/src/libtomahawk/playlist/albumview.h +++ b/src/libtomahawk/playlist/albumview.h @@ -42,6 +42,7 @@ public: AlbumProxyModel* proxyModel() const { return m_proxyModel; } // PlaylistItemDelegate* delegate() { return m_delegate; } + void setAlbumModel( AlbumModel* model ); void setModel( QAbstractItemModel* model ); virtual QWidget* widget() { return this; } diff --git a/src/libtomahawk/playlist/collectionview.cpp b/src/libtomahawk/playlist/collectionview.cpp index e5a72cd19..9f3b439ef 100644 --- a/src/libtomahawk/playlist/collectionview.cpp +++ b/src/libtomahawk/playlist/collectionview.cpp @@ -53,14 +53,18 @@ CollectionView::~CollectionView() void CollectionView::setModel( QAbstractItemModel* model ) { - TrackModel *tmodel = static_cast< TrackModel* >( model ); - if ( !tmodel ) - return; + qDebug() << "Explicitly use setTrackModel instead"; + Q_ASSERT( false ); +} - TrackView::setModel( tmodel ); + +void +CollectionView::setTrackModel( TrackModel* model ) +{ + TrackView::setModel( model ); setGuid( "collectionview" ); - connect( tmodel, SIGNAL( trackCountChanged( unsigned int ) ), SLOT( onTrackCountChanged( unsigned int ) ) ); + connect( model, SIGNAL( trackCountChanged( unsigned int ) ), SLOT( onTrackCountChanged( unsigned int ) ) ); } diff --git a/src/libtomahawk/playlist/collectionview.h b/src/libtomahawk/playlist/collectionview.h index 54fa0b47a..1fe261646 100644 --- a/src/libtomahawk/playlist/collectionview.h +++ b/src/libtomahawk/playlist/collectionview.h @@ -36,6 +36,7 @@ public: explicit CollectionView( QWidget* parent = 0 ); ~CollectionView(); + virtual void setTrackModel( TrackModel* model ); virtual void setModel( QAbstractItemModel* model ); virtual QWidget* widget() { return this; } diff --git a/src/libtomahawk/playlist/dynamic/DynamicView.cpp b/src/libtomahawk/playlist/dynamic/DynamicView.cpp index 05b2c9c9d..85b87aa53 100644 --- a/src/libtomahawk/playlist/dynamic/DynamicView.cpp +++ b/src/libtomahawk/playlist/dynamic/DynamicView.cpp @@ -71,13 +71,13 @@ DynamicView::~DynamicView() } void -DynamicView::setModel( DynamicModel* model) +DynamicView::setDynamicModel( DynamicModel* model) { m_model = model; - PlaylistView::setModel( model ); + PlaylistView::setModel( m_model ); - connect( model, SIGNAL( trackCountChanged( unsigned int ) ), SLOT( onTrackCountChanged( unsigned int ) ) ); - connect( model, SIGNAL( checkForOverflow() ), this, SLOT( checkForOverflow() ) ); + connect( m_model, SIGNAL( trackCountChanged( unsigned int ) ), SLOT( onTrackCountChanged( unsigned int ) ) ); + connect( m_model, SIGNAL( checkForOverflow() ), this, SLOT( checkForOverflow() ) ); } void diff --git a/src/libtomahawk/playlist/dynamic/DynamicView.h b/src/libtomahawk/playlist/dynamic/DynamicView.h index 3ea371d3a..39826fe97 100644 --- a/src/libtomahawk/playlist/dynamic/DynamicView.h +++ b/src/libtomahawk/playlist/dynamic/DynamicView.h @@ -40,7 +40,7 @@ public: explicit DynamicView( QWidget* parent = 0 ); virtual ~DynamicView(); - virtual void setModel( DynamicModel* model ); + virtual void setDynamicModel( DynamicModel* model ); void setOnDemand( bool onDemand ); void setReadOnly( bool readOnly ); diff --git a/src/libtomahawk/playlist/playlistview.cpp b/src/libtomahawk/playlist/playlistview.cpp index e6a06ea0c..0ba3373db 100644 --- a/src/libtomahawk/playlist/playlistview.cpp +++ b/src/libtomahawk/playlist/playlistview.cpp @@ -47,14 +47,18 @@ PlaylistView::~PlaylistView() void PlaylistView::setModel( QAbstractItemModel* model ) { - PlaylistModel* pmodel = static_cast< PlaylistModel* >( model ); + Q_UNUSED( model ); + qDebug() << "Explicitly use setPlaylistModel instead"; + Q_ASSERT( false ); +} - if ( !pmodel ) - return; - else - m_model = pmodel; - TrackView::setModel( model ); +void +PlaylistView::setPlaylistModel( PlaylistModel* model ) +{ + m_model = model; + + TrackView::setModel( m_model ); setColumnHidden( 5, true ); // Hide age column per default if ( !m_model->playlist().isNull() ) diff --git a/src/libtomahawk/playlist/playlistview.h b/src/libtomahawk/playlist/playlistview.h index dbf653625..84df64805 100644 --- a/src/libtomahawk/playlist/playlistview.h +++ b/src/libtomahawk/playlist/playlistview.h @@ -39,6 +39,7 @@ public: ~PlaylistView(); PlaylistModel* playlistModel() const { return m_model; } + virtual void setPlaylistModel( PlaylistModel* model ); virtual void setModel( QAbstractItemModel* model ); virtual QWidget* widget() { return this; } diff --git a/src/libtomahawk/playlist/trackproxymodel.cpp b/src/libtomahawk/playlist/trackproxymodel.cpp index f69670057..2c11bcd6d 100644 --- a/src/libtomahawk/playlist/trackproxymodel.cpp +++ b/src/libtomahawk/playlist/trackproxymodel.cpp @@ -45,19 +45,23 @@ TrackProxyModel::TrackProxyModel( QObject* parent ) void -TrackProxyModel::setSourceModel( QAbstractItemModel* sourceModel ) +TrackProxyModel::setSourceModel( QAbstractItemModel* model ) { - TrackModel* tmodel = static_cast< TrackModel* >( sourceModel ); + Q_UNUSED( model ); + qDebug() << "Explicitly use setSourceTrackModel instead"; + Q_ASSERT( false ); +} - if ( !tmodel ) - return; - else - m_model = tmodel; + +void +TrackProxyModel::setSourceTrackModel( TrackModel* sourceModel ) +{ + m_model = sourceModel; connect( m_model, SIGNAL( trackCountChanged( unsigned int ) ), SIGNAL( sourceTrackCountChanged( unsigned int ) ) ); - QSortFilterProxyModel::setSourceModel( sourceModel ); + QSortFilterProxyModel::setSourceModel( m_model ); } diff --git a/src/libtomahawk/playlist/trackproxymodel.h b/src/libtomahawk/playlist/trackproxymodel.h index ac626f0a5..853a512d8 100644 --- a/src/libtomahawk/playlist/trackproxymodel.h +++ b/src/libtomahawk/playlist/trackproxymodel.h @@ -34,7 +34,8 @@ public: explicit TrackProxyModel ( QObject* parent = 0 ); virtual TrackModel* sourceModel() const { return m_model; } - virtual void setSourceModel( QAbstractItemModel* sourceModel ); + virtual void setSourceTrackModel( TrackModel* sourceModel ); + virtual void setSourceModel( QAbstractItemModel* model ); virtual QPersistentModelIndex currentItem() const { return mapFromSource( m_model->currentItem() ); } virtual void setCurrentItem( const QModelIndex& index ) { m_model->setCurrentItem( mapToSource( index ) ); } diff --git a/src/libtomahawk/playlist/trackview.cpp b/src/libtomahawk/playlist/trackview.cpp index 8b851ba33..3e7b11bef 100644 --- a/src/libtomahawk/playlist/trackview.cpp +++ b/src/libtomahawk/playlist/trackview.cpp @@ -33,6 +33,7 @@ #include "queueview.h" #include "trackmodel.h" #include "trackproxymodel.h" +#include using namespace Tomahawk; @@ -109,16 +110,20 @@ TrackView::setProxyModel( TrackProxyModel* model ) void TrackView::setModel( QAbstractItemModel* model ) { - TrackModel* tmodel = static_cast< TrackModel* >( model ); + Q_UNUSED( model ); + qDebug() << "Explicitly use setTrackModel instead"; + Q_ASSERT( false ); +} - if ( !tmodel ) - return; - else - m_model = tmodel; + +void +TrackView::setTrackModel( TrackModel* model ) +{ + m_model = model; if ( m_proxyModel ) { - m_proxyModel->setSourceModel( model ); + m_proxyModel->setSourceModel( m_model ); } connect( m_model, SIGNAL( itemSizeChanged( QModelIndex ) ), SLOT( onItemResized( QModelIndex ) ) ); diff --git a/src/libtomahawk/playlist/trackview.h b/src/libtomahawk/playlist/trackview.h index 2d9707f26..aac8b2a11 100644 --- a/src/libtomahawk/playlist/trackview.h +++ b/src/libtomahawk/playlist/trackview.h @@ -44,6 +44,7 @@ public: virtual QString guid() const { return m_guid; } virtual void setGuid( const QString& guid ); + virtual void setTrackModel( TrackModel* model ); virtual void setModel( QAbstractItemModel* model ); void setProxyModel( TrackProxyModel* model ); From 5455ee0f214a2ca7b4ade27b564ab5394fbec0a1 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Tue, 12 Apr 2011 16:52:25 -0400 Subject: [PATCH 31/75] Unused warning cleanups --- src/infosystem/infoplugins/echonestplugin.cpp | 2 ++ src/libtomahawk/audio/dummytranscode.cpp | 2 ++ src/libtomahawk/audio/flactranscode.cpp | 2 ++ src/libtomahawk/audio/vorbistranscode.cpp | 6 ++++++ src/libtomahawk/network/bufferiodevice.cpp | 3 +++ src/libtomahawk/playlist/collectionmodel.cpp | 1 + src/libtomahawk/playlist/collectionview.cpp | 1 + .../playlist/dynamic/GeneratorInterface.cpp | 1 + .../dynamic/widgets/DynamicSetupWidget.cpp | 2 +- .../playlist/dynamic/widgets/LoadingSpinner.cpp | 1 + src/libtomahawk/utils/querylabel.cpp | 1 + src/libtomahawk/widgets/overlaywidget.cpp | 1 + src/musicscanner.cpp | 1 + src/scanmanager.cpp | 1 + src/sip/jabber/jabber_p.cpp | 14 ++++++++++++-- src/sip/twitter/twitter.cpp | 2 ++ src/sip/twitter/twitter.h | 5 +++++ src/sip/twitter/twitterconfigwidget.cpp | 1 + src/sip/zeroconf/zeroconf.h | 5 +++++ src/web/api_v1.cpp | 3 +++ 20 files changed, 52 insertions(+), 3 deletions(-) diff --git a/src/infosystem/infoplugins/echonestplugin.cpp b/src/infosystem/infoplugins/echonestplugin.cpp index 38f64ed4c..7bec6c653 100644 --- a/src/infosystem/infoplugins/echonestplugin.cpp +++ b/src/infosystem/infoplugins/echonestplugin.cpp @@ -68,6 +68,7 @@ void EchoNestPlugin::getInfo(const QString &caller, const InfoType type, const Q void EchoNestPlugin::getSongProfile(const QString &caller, const QVariant& data, InfoCustomData &customData, const QString &item) { //WARNING: Totally not implemented yet + Q_UNUSED( item ); if( !isValidTrackData( caller, data, customData ) ) return; @@ -139,6 +140,7 @@ void EchoNestPlugin::getArtistTerms(const QString &caller, const QVariant& data, void EchoNestPlugin::getMiscTopTerms(const QString &caller, const QVariant& data, InfoCustomData& customData) { + Q_UNUSED( data ); QNetworkReply* reply = Echonest::Artist::topTerms( 20 ); m_replyMap[reply] = customData; m_callerMap[reply] = caller; diff --git a/src/libtomahawk/audio/dummytranscode.cpp b/src/libtomahawk/audio/dummytranscode.cpp index 1ab245d86..92b5efc6e 100644 --- a/src/libtomahawk/audio/dummytranscode.cpp +++ b/src/libtomahawk/audio/dummytranscode.cpp @@ -36,6 +36,7 @@ DummyTranscode::~DummyTranscode() void DummyTranscode::processData( const QByteArray &buffer, bool finish ) { + Q_UNUSED( finish ); m_buffer.append( buffer ); // qDebug() << "DUMMYTRANSCODING:" << buffer.size(); @@ -49,6 +50,7 @@ DummyTranscode::processData( const QByteArray &buffer, bool finish ) void DummyTranscode::onSeek( int seconds ) { + Q_UNUSED( seconds ); m_buffer.clear(); } diff --git a/src/libtomahawk/audio/flactranscode.cpp b/src/libtomahawk/audio/flactranscode.cpp index aee7299d1..c66c5a557 100644 --- a/src/libtomahawk/audio/flactranscode.cpp +++ b/src/libtomahawk/audio/flactranscode.cpp @@ -39,6 +39,7 @@ FLACTranscode::~FLACTranscode() void FLACTranscode::onSeek( int seconds ) { + Q_UNUSED( seconds ); QMutexLocker locker( &m_mutex ); m_buffer.clear(); @@ -120,6 +121,7 @@ FLACTranscode::write_callback( const ::FLAC__Frame *frame, const FLAC__int32 *co ::FLAC__StreamDecoderSeekStatus FLACTranscode::seek_callback(FLAC__uint64 absolute_byte_offset) { + Q_UNUSED( absolute_byte_offset ); return FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED; } diff --git a/src/libtomahawk/audio/vorbistranscode.cpp b/src/libtomahawk/audio/vorbistranscode.cpp index 826c0f272..20403684c 100644 --- a/src/libtomahawk/audio/vorbistranscode.cpp +++ b/src/libtomahawk/audio/vorbistranscode.cpp @@ -39,6 +39,9 @@ vorbis_read( void* data_ptr, size_t byteSize, size_t sizeToRead, void* data_src int vorbis_seek( void* data_src, ogg_int64_t offset, int origin ) { + Q_UNUSED( data_src ); + Q_UNUSED( offset ); + Q_UNUSED( origin ); return -1; } @@ -46,6 +49,7 @@ vorbis_seek( void* data_src, ogg_int64_t offset, int origin ) int vorbis_close( void* data_src ) { + Q_UNUSED( data_src ); // done ;-) return 0; } @@ -54,6 +58,7 @@ vorbis_close( void* data_src ) long vorbis_tell( void* data_src ) { + Q_UNUSED( data_src ); return -1; } @@ -74,6 +79,7 @@ VorbisTranscode::~VorbisTranscode() void VorbisTranscode::onSeek( int seconds ) { + Q_UNUSED( seconds ); QMutexLocker locker( &m_mutex ); m_buffer.clear(); diff --git a/src/libtomahawk/network/bufferiodevice.cpp b/src/libtomahawk/network/bufferiodevice.cpp index 435a2b2cd..bceca0745 100644 --- a/src/libtomahawk/network/bufferiodevice.cpp +++ b/src/libtomahawk/network/bufferiodevice.cpp @@ -38,6 +38,7 @@ BufferIODevice::BufferIODevice( unsigned int size, QObject* parent ) bool BufferIODevice::open( OpenMode mode ) { + Q_UNUSED( mode ); QMutexLocker lock( &m_mut ); qDebug() << Q_FUNC_INFO; @@ -148,6 +149,8 @@ BufferIODevice::readData( char* data, qint64 maxSize ) qint64 BufferIODevice::writeData( const char* data, qint64 maxSize ) { + Q_UNUSED( data ); + Q_UNUSED( maxSize ); // call addData instead Q_ASSERT( false ); return 0; diff --git a/src/libtomahawk/playlist/collectionmodel.cpp b/src/libtomahawk/playlist/collectionmodel.cpp index ac0a5dc18..ec8808764 100644 --- a/src/libtomahawk/playlist/collectionmodel.cpp +++ b/src/libtomahawk/playlist/collectionmodel.cpp @@ -75,6 +75,7 @@ CollectionModel::rowCount( const QModelIndex& parent ) const int CollectionModel::columnCount( const QModelIndex& parent ) const { + Q_UNUSED( parent ); return 4; } diff --git a/src/libtomahawk/playlist/collectionview.cpp b/src/libtomahawk/playlist/collectionview.cpp index 9f3b439ef..ff538e3c1 100644 --- a/src/libtomahawk/playlist/collectionview.cpp +++ b/src/libtomahawk/playlist/collectionview.cpp @@ -53,6 +53,7 @@ CollectionView::~CollectionView() void CollectionView::setModel( QAbstractItemModel* model ) { + Q_UNUSED( model ); qDebug() << "Explicitly use setTrackModel instead"; Q_ASSERT( false ); } diff --git a/src/libtomahawk/playlist/dynamic/GeneratorInterface.cpp b/src/libtomahawk/playlist/dynamic/GeneratorInterface.cpp index 999d8aa45..0ccf5888a 100644 --- a/src/libtomahawk/playlist/dynamic/GeneratorInterface.cpp +++ b/src/libtomahawk/playlist/dynamic/GeneratorInterface.cpp @@ -71,6 +71,7 @@ void Tomahawk::GeneratorInterface::removeControl(const Tomahawk::dyncontrol_ptr& Tomahawk::dyncontrol_ptr Tomahawk::GeneratorInterface::createControl(const QString& type) { + Q_UNUSED( type ); Q_ASSERT( false ); return dyncontrol_ptr(); } diff --git a/src/libtomahawk/playlist/dynamic/widgets/DynamicSetupWidget.cpp b/src/libtomahawk/playlist/dynamic/widgets/DynamicSetupWidget.cpp index 062fa6485..8eec49f0a 100644 --- a/src/libtomahawk/playlist/dynamic/widgets/DynamicSetupWidget.cpp +++ b/src/libtomahawk/playlist/dynamic/widgets/DynamicSetupWidget.cpp @@ -104,7 +104,7 @@ DynamicSetupWidget::~DynamicSetupWidget() void DynamicSetupWidget::setPlaylist( const Tomahawk::dynplaylist_ptr& playlist ) { - + Q_UNUSED( playlist ); } void diff --git a/src/libtomahawk/playlist/dynamic/widgets/LoadingSpinner.cpp b/src/libtomahawk/playlist/dynamic/widgets/LoadingSpinner.cpp index a532d51da..b1bd4efc2 100644 --- a/src/libtomahawk/playlist/dynamic/widgets/LoadingSpinner.cpp +++ b/src/libtomahawk/playlist/dynamic/widgets/LoadingSpinner.cpp @@ -106,6 +106,7 @@ LoadingSpinner::reposition() void LoadingSpinner::paintEvent( QPaintEvent* ev ) { + Q_UNUSED( ev ); QPainter p( this ); // qDebug() << "FADING" << ( m_showHide->state() == QTimeLine::Running ) << "at frame:" << m_showHide->currentValue(); diff --git a/src/libtomahawk/utils/querylabel.cpp b/src/libtomahawk/utils/querylabel.cpp index 8a5d77ce0..d765f65dd 100644 --- a/src/libtomahawk/utils/querylabel.cpp +++ b/src/libtomahawk/utils/querylabel.cpp @@ -544,6 +544,7 @@ QueryLabel::mouseMoveEvent( QMouseEvent* event ) void QueryLabel::leaveEvent( QEvent* event ) { + Q_UNUSED( event ); m_hoverArea = QRect(); m_hoverType = None; repaint(); diff --git a/src/libtomahawk/widgets/overlaywidget.cpp b/src/libtomahawk/widgets/overlaywidget.cpp index 3f46f5e11..64471b272 100644 --- a/src/libtomahawk/widgets/overlaywidget.cpp +++ b/src/libtomahawk/widgets/overlaywidget.cpp @@ -121,6 +121,7 @@ OverlayWidget::shown() const void OverlayWidget::paintEvent( QPaintEvent* event ) { + Q_UNUSED( event ); QPoint center( ( m_parent->width() - width() ) / 2, ( m_parent->height() - height() ) / 2 ); move( center ); diff --git a/src/musicscanner.cpp b/src/musicscanner.cpp index 3cc36305e..601d89288 100644 --- a/src/musicscanner.cpp +++ b/src/musicscanner.cpp @@ -263,6 +263,7 @@ MusicScanner::listerQuit() void MusicScanner::listerDestroyed( QObject* dirLister ) { + Q_UNUSED( dirLister ); qDebug() << Q_FUNC_INFO; m_dirListerThreadController->deleteLater(); m_dirListerThreadController = 0; diff --git a/src/scanmanager.cpp b/src/scanmanager.cpp index f28cf0f82..27f134e01 100644 --- a/src/scanmanager.cpp +++ b/src/scanmanager.cpp @@ -273,6 +273,7 @@ ScanManager::scannerQuit() void ScanManager::scannerDestroyed( QObject* scanner ) { + Q_UNUSED( scanner ); qDebug() << Q_FUNC_INFO; m_musicScannerThreadController->deleteLater(); m_musicScannerThreadController = 0; diff --git a/src/sip/jabber/jabber_p.cpp b/src/sip/jabber/jabber_p.cpp index 267322f6b..6f38dd292 100644 --- a/src/sip/jabber/jabber_p.cpp +++ b/src/sip/jabber/jabber_p.cpp @@ -479,6 +479,7 @@ Jabber_p::handleLog( gloox::LogLevel level, gloox::LogArea area, const std::stri void Jabber_p::onResourceBindError( gloox::ResourceBindError error ) { + Q_UNUSED( error ); qDebug() << Q_FUNC_INFO; } @@ -486,6 +487,7 @@ Jabber_p::onResourceBindError( gloox::ResourceBindError error ) void Jabber_p::onSessionCreateError( gloox::SessionCreateError error ) { + Q_UNUSED( error ); qDebug() << Q_FUNC_INFO; } @@ -731,6 +733,7 @@ Jabber_p::handleNonrosterPresence( const gloox::Presence& presence ) void Jabber_p::handleVCard( const gloox::JID& jid, const gloox::VCard* vcard ) { + Q_UNUSED( vcard ); qDebug() << "VCARD RECEIVED!" << jid.bare().c_str(); } @@ -738,6 +741,8 @@ Jabber_p::handleVCard( const gloox::JID& jid, const gloox::VCard* vcard ) void Jabber_p::handleVCardResult( gloox::VCardHandler::VCardContext context, const gloox::JID& jid, gloox::StanzaError se ) { + Q_UNUSED( context ); + Q_UNUSED( se ); qDebug() << "VCARD RESULT RECEIVED!" << jid.bare().c_str(); } @@ -746,6 +751,7 @@ Jabber_p::handleVCardResult( gloox::VCardHandler::VCardContext context, const gl void Jabber_p::handleDiscoInfo( const gloox::JID& from, const gloox::Disco::Info& info, int context ) { + Q_UNUSED( context ); QString jidstr( from.full().c_str() ); //qDebug() << "DISCOinfo" << jidstr; if ( info.hasFeature("tomahawk:player") ) @@ -762,15 +768,19 @@ Jabber_p::handleDiscoInfo( const gloox::JID& from, const gloox::Disco::Info& inf void -Jabber_p::handleDiscoItems( const gloox::JID& /*iq*/, const gloox::Disco::Items&, int /*context*/ ) +Jabber_p::handleDiscoItems( const gloox::JID& iq, const gloox::Disco::Items& items, int context ) { + Q_UNUSED( iq ); + Q_UNUSED( items ); + Q_UNUSED( context ); qDebug() << Q_FUNC_INFO; } void -Jabber_p::handleDiscoError( const gloox::JID& j, const gloox::Error* e, int /*context*/ ) +Jabber_p::handleDiscoError( const gloox::JID& j, const gloox::Error* e, int context ) { + Q_UNUSED( context ); qDebug() << Q_FUNC_INFO << j.full().c_str() << e->text().c_str() << e->type(); } /// END DISCO STUFF diff --git a/src/sip/twitter/twitter.cpp b/src/sip/twitter/twitter.cpp index d1ef42b33..643f11fcd 100644 --- a/src/sip/twitter/twitter.cpp +++ b/src/sip/twitter/twitter.cpp @@ -638,6 +638,8 @@ TwitterPlugin::directMessagePosted( const QTweetDMStatus& message ) void TwitterPlugin::directMessagePostError( QTweetNetBase::ErrorCode errorCode, const QString &message ) { + Q_UNUSED( errorCode ); + Q_UNUSED( message ); qDebug() << Q_FUNC_INFO; qDebug() << "TwitterPlugin received an error posting direct message: " << m_directMessageNew.data()->lastErrorMessage(); } diff --git a/src/sip/twitter/twitter.h b/src/sip/twitter/twitter.h index c0da00d7f..418cc1f07 100644 --- a/src/sip/twitter/twitter.h +++ b/src/sip/twitter/twitter.h @@ -64,14 +64,19 @@ public slots: void sendMsg( const QString& to, const QString& msg ) { + Q_UNUSED( to ); + Q_UNUSED( msg ); } void broadcastMsg( const QString &msg ) { + Q_UNUSED( msg ); } void addContact( const QString &jid, const QString& msg = QString() ) { + Q_UNUSED( jid ); + Q_UNUSED( msg ); } private slots: diff --git a/src/sip/twitter/twitterconfigwidget.cpp b/src/sip/twitter/twitterconfigwidget.cpp index 00eb46d87..f728b4107 100644 --- a/src/sip/twitter/twitterconfigwidget.cpp +++ b/src/sip/twitter/twitterconfigwidget.cpp @@ -170,6 +170,7 @@ TwitterConfigWidget::deauthenticateTwitter() void TwitterConfigWidget::tweetComboBoxIndexChanged( int index ) { + Q_UNUSED( index ); if( ui->twitterTweetComboBox->currentText() == tr( "Global Tweet" ) ) //FIXME: use data! { ui->twitterUserTweetLineEdit->setReadOnly( true ); diff --git a/src/sip/zeroconf/zeroconf.h b/src/sip/zeroconf/zeroconf.h index d538f9a67..2d971ebb0 100644 --- a/src/sip/zeroconf/zeroconf.h +++ b/src/sip/zeroconf/zeroconf.h @@ -57,14 +57,19 @@ public slots: void sendMsg( const QString& to, const QString& msg ) { + Q_UNUSED( to ); + Q_UNUSED( msg ); } void broadcastMsg( const QString &msg ) { + Q_UNUSED( msg ); } void addContact( const QString &jid, const QString& msg = QString() ) { + Q_UNUSED( jid ); + Q_UNUSED( msg ); } private slots: diff --git a/src/web/api_v1.cpp b/src/web/api_v1.cpp index 67b2e4d8b..d0a3b0475 100644 --- a/src/web/api_v1.cpp +++ b/src/web/api_v1.cpp @@ -145,6 +145,7 @@ Api_v1::api( QxtWebRequestEvent* event ) void Api_v1::sid( QxtWebRequestEvent* event, QString unused ) { + Q_UNUSED( unused ); using namespace Tomahawk; RID rid = event->url.path().mid( 5 ); qDebug() << "Request for sid " << rid; @@ -206,6 +207,8 @@ Api_v1::stat( QxtWebRequestEvent* event ) void Api_v1::statResult( const QString& clientToken, const QString& name, bool valid ) { + Q_UNUSED( clientToken ) + Q_UNUSED( name ) QVariantMap m; m.insert( "name", "playdar" ); m.insert( "version", "0.1.1" ); // TODO (needs to be >=0.1.1 for JS to work) From d3ca52cba33c01401e04c7550e4433e48c6aff54 Mon Sep 17 00:00:00 2001 From: Frank Osterfeld Date: Wed, 13 Apr 2011 04:49:12 +0800 Subject: [PATCH 32/75] link on OS X --- src/sip/jreen/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sip/jreen/CMakeLists.txt b/src/sip/jreen/CMakeLists.txt index df2a4f7b6..b06fac816 100644 --- a/src/sip/jreen/CMakeLists.txt +++ b/src/sip/jreen/CMakeLists.txt @@ -37,6 +37,7 @@ target_link_libraries( tomahawk_sipjreen ${QT_LIBRARIES} ${LIBJREEN_LIBRARY} ${OS_SPECIFIC_LINK_LIBRARIES} + tomahawklib ) IF( APPLE ) From 800c06e67881cdcc00c1442ec773c1992a007d92 Mon Sep 17 00:00:00 2001 From: Frank Osterfeld Date: Wed, 13 Apr 2011 04:49:48 +0800 Subject: [PATCH 33/75] initialize m_dragging variable (fixes valgrind warning). --- src/libtomahawk/playlist/trackview.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libtomahawk/playlist/trackview.cpp b/src/libtomahawk/playlist/trackview.cpp index 3e7b11bef..ce1240b1b 100644 --- a/src/libtomahawk/playlist/trackview.cpp +++ b/src/libtomahawk/playlist/trackview.cpp @@ -47,6 +47,7 @@ TrackView::TrackView( QWidget* parent ) , m_overlay( new OverlayWidget( this ) ) , m_loadingSpinner( new LoadingSpinner( this ) ) , m_resizing( false ) + , m_dragging( false ) { setSortingEnabled( false ); setAlternatingRowColors( true ); From b214dd01f8fbd4680869466446a5983ef2e5f841 Mon Sep 17 00:00:00 2001 From: Frank Osterfeld Date: Wed, 13 Apr 2011 04:50:51 +0800 Subject: [PATCH 34/75] randomize XMPP resource name so that multiple Tomahawk/JReen instances do not collide. --- src/sip/jreen/jabber_p.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sip/jreen/jabber_p.cpp b/src/sip/jreen/jabber_p.cpp index 93987b35e..9e4aa8798 100644 --- a/src/sip/jreen/jabber_p.cpp +++ b/src/sip/jreen/jabber_p.cpp @@ -60,7 +60,7 @@ Jabber_p::Jabber_p( const QString& jid, const QString& password, const QString& m_jid = Jreen::JID( jid ); m_client = new Jreen::Client( jid, password ); - m_client->setResource( QString( "tomahawk%1" ).arg( "DOMME" ) ); + m_client->setResource( QString( "tomahawk-jreen%1" ).arg( QString::number( qrand() % 10000 ) ) ); Jreen::Capabilities::Ptr caps = m_client->presence().findExtension(); caps->setNode(TOMAHAWK_CAP_NODE_NAME); From aca94b1b55855ca98998aceb59b17ad269211528 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Tue, 12 Apr 2011 18:19:50 -0400 Subject: [PATCH 35/75] Fix some bad function usage asserts --- src/libtomahawk/playlist/albumproxymodel.cpp | 2 +- src/libtomahawk/playlist/albumview.cpp | 2 +- src/libtomahawk/playlist/collectionview.cpp | 2 +- src/libtomahawk/playlist/playlistmanager.cpp | 6 +++--- src/libtomahawk/playlist/playlistview.cpp | 2 +- src/libtomahawk/playlist/trackproxymodel.cpp | 2 +- src/libtomahawk/playlist/trackview.cpp | 2 +- src/libtomahawk/widgets/welcomewidget.cpp | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/libtomahawk/playlist/albumproxymodel.cpp b/src/libtomahawk/playlist/albumproxymodel.cpp index c3b3fe29c..f35aa9b26 100644 --- a/src/libtomahawk/playlist/albumproxymodel.cpp +++ b/src/libtomahawk/playlist/albumproxymodel.cpp @@ -38,7 +38,7 @@ AlbumProxyModel::AlbumProxyModel( QObject* parent ) setSortCaseSensitivity( Qt::CaseInsensitive ); setDynamicSortFilter( true ); - setSourceModel( 0 ); + setSourceAlbumModel( 0 ); } void diff --git a/src/libtomahawk/playlist/albumview.cpp b/src/libtomahawk/playlist/albumview.cpp index 9f6ad1a57..351fd8ea2 100644 --- a/src/libtomahawk/playlist/albumview.cpp +++ b/src/libtomahawk/playlist/albumview.cpp @@ -87,7 +87,7 @@ AlbumView::setAlbumModel( AlbumModel* model ) if ( m_proxyModel ) { - m_proxyModel->setSourceModel( m_model ); + m_proxyModel->setSourceAlbumModel( m_model ); m_proxyModel->sort( 0 ); } diff --git a/src/libtomahawk/playlist/collectionview.cpp b/src/libtomahawk/playlist/collectionview.cpp index ff538e3c1..6d93742f6 100644 --- a/src/libtomahawk/playlist/collectionview.cpp +++ b/src/libtomahawk/playlist/collectionview.cpp @@ -62,7 +62,7 @@ CollectionView::setModel( QAbstractItemModel* model ) void CollectionView::setTrackModel( TrackModel* model ) { - TrackView::setModel( model ); + TrackView::setTrackModel( model ); setGuid( "collectionview" ); connect( model, SIGNAL( trackCountChanged( unsigned int ) ), SLOT( onTrackCountChanged( unsigned int ) ) ); diff --git a/src/libtomahawk/playlist/playlistmanager.cpp b/src/libtomahawk/playlist/playlistmanager.cpp index 1fada1bc0..a1fec6071 100644 --- a/src/libtomahawk/playlist/playlistmanager.cpp +++ b/src/libtomahawk/playlist/playlistmanager.cpp @@ -89,7 +89,7 @@ PlaylistManager::PlaylistManager( QObject* parent ) m_queueView = new QueueView( m_splitter ); m_queueModel = new PlaylistModel( m_queueView ); - m_queueView->queue()->setModel( m_queueModel ); + m_queueView->queue()->setPlaylistModel( m_queueModel ); AudioEngine::instance()->setQueue( m_queueView->queue()->proxyModel() ); m_splitter->addWidget( m_queueView ); @@ -102,14 +102,14 @@ PlaylistManager::PlaylistManager( QObject* parent ) m_superCollectionView = new CollectionView(); m_superCollectionFlatModel = new CollectionFlatModel( m_superCollectionView ); - m_superCollectionView->setModel( m_superCollectionFlatModel ); + m_superCollectionView->setTrackModel( m_superCollectionFlatModel ); m_superCollectionView->setFrameShape( QFrame::NoFrame ); m_superCollectionView->setAttribute( Qt::WA_MacShowFocusRect, 0 ); m_superCollectionView->proxyModel()->setShowOfflineResults( false ); m_superAlbumView = new AlbumView(); m_superAlbumModel = new AlbumModel( m_superAlbumView ); - m_superAlbumView->setModel( m_superAlbumModel ); + m_superAlbumView->setAlbumModel( m_superAlbumModel ); m_superAlbumView->setFrameShape( QFrame::NoFrame ); m_superAlbumView->setAttribute( Qt::WA_MacShowFocusRect, 0 ); diff --git a/src/libtomahawk/playlist/playlistview.cpp b/src/libtomahawk/playlist/playlistview.cpp index 0ba3373db..175d0705a 100644 --- a/src/libtomahawk/playlist/playlistview.cpp +++ b/src/libtomahawk/playlist/playlistview.cpp @@ -58,7 +58,7 @@ PlaylistView::setPlaylistModel( PlaylistModel* model ) { m_model = model; - TrackView::setModel( m_model ); + TrackView::setTrackModel( m_model ); setColumnHidden( 5, true ); // Hide age column per default if ( !m_model->playlist().isNull() ) diff --git a/src/libtomahawk/playlist/trackproxymodel.cpp b/src/libtomahawk/playlist/trackproxymodel.cpp index 2c11bcd6d..91283c7ad 100644 --- a/src/libtomahawk/playlist/trackproxymodel.cpp +++ b/src/libtomahawk/playlist/trackproxymodel.cpp @@ -40,7 +40,7 @@ TrackProxyModel::TrackProxyModel( QObject* parent ) setSortCaseSensitivity( Qt::CaseInsensitive ); setDynamicSortFilter( true ); - setSourceModel( 0 ); + setSourceTrackModel( 0 ); } diff --git a/src/libtomahawk/playlist/trackview.cpp b/src/libtomahawk/playlist/trackview.cpp index ce1240b1b..4016382d8 100644 --- a/src/libtomahawk/playlist/trackview.cpp +++ b/src/libtomahawk/playlist/trackview.cpp @@ -124,7 +124,7 @@ TrackView::setTrackModel( TrackModel* model ) if ( m_proxyModel ) { - m_proxyModel->setSourceModel( m_model ); + m_proxyModel->setSourceTrackModel( m_model ); } connect( m_model, SIGNAL( itemSizeChanged( QModelIndex ) ), SLOT( onItemResized( QModelIndex ) ) ); diff --git a/src/libtomahawk/widgets/welcomewidget.cpp b/src/libtomahawk/widgets/welcomewidget.cpp index 55154e32f..5297710e5 100644 --- a/src/libtomahawk/widgets/welcomewidget.cpp +++ b/src/libtomahawk/widgets/welcomewidget.cpp @@ -47,7 +47,7 @@ WelcomeWidget::WelcomeWidget( QWidget* parent ) ui->tracksView->overlay()->setEnabled( false ); m_tracksModel = new PlaylistModel( ui->tracksView ); - ui->tracksView->setModel( m_tracksModel ); + ui->tracksView->setPlaylistModel( m_tracksModel ); m_tracksModel->loadHistory( Tomahawk::source_ptr(), HISTORY_TRACK_ITEMS ); m_timer = new QTimer( this ); From 9d28c11089db367f7eda5734a11a5a339c32d357 Mon Sep 17 00:00:00 2001 From: Frank Osterfeld Date: Wed, 13 Apr 2011 14:08:11 +0200 Subject: [PATCH 36/75] build on OS X These flags break the build and are also disabled for all the other plugins. --- src/sip/twitter/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sip/twitter/CMakeLists.txt b/src/sip/twitter/CMakeLists.txt index bb5b26346..f50abba2d 100644 --- a/src/sip/twitter/CMakeLists.txt +++ b/src/sip/twitter/CMakeLists.txt @@ -47,7 +47,7 @@ target_link_libraries( tomahawk_siptwitter ) IF( APPLE ) - SET( CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} "-undefined dynamic_lookup" ) +# SET( CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} "-undefined dynamic_lookup" ) ENDIF( APPLE ) install( TARGETS tomahawk_siptwitter DESTINATION lib${LIB_SUFFIX} ) From 9b5be063bd35b593fba1c6e6097094bec98d60d1 Mon Sep 17 00:00:00 2001 From: Frank Osterfeld Date: Wed, 13 Apr 2011 14:08:55 +0200 Subject: [PATCH 37/75] use setTrackModel, as CollectionView::setModel() suggests. Fixes assertion when selecting a collection. --- src/libtomahawk/playlist/playlistmanager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libtomahawk/playlist/playlistmanager.cpp b/src/libtomahawk/playlist/playlistmanager.cpp index a1fec6071..78cf5d809 100644 --- a/src/libtomahawk/playlist/playlistmanager.cpp +++ b/src/libtomahawk/playlist/playlistmanager.cpp @@ -269,7 +269,7 @@ PlaylistManager::show( const Tomahawk::collection_ptr& collection ) { view = new CollectionView(); CollectionFlatModel* model = new CollectionFlatModel(); - view->setModel( model ); + view->setTrackModel( model ); view->setFrameShape( QFrame::NoFrame ); view->setAttribute( Qt::WA_MacShowFocusRect, 0 ); From 34fe17a3e6730d27129ebaa6bf599151b0ee46e5 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Wed, 13 Apr 2011 08:58:36 -0400 Subject: [PATCH 38/75] assert less :( --- src/libtomahawk/playlist/playlistmanager.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libtomahawk/playlist/playlistmanager.cpp b/src/libtomahawk/playlist/playlistmanager.cpp index 78cf5d809..94302de16 100644 --- a/src/libtomahawk/playlist/playlistmanager.cpp +++ b/src/libtomahawk/playlist/playlistmanager.cpp @@ -156,7 +156,7 @@ PlaylistManager::show( const Tomahawk::playlist_ptr& playlist ) { view = new PlaylistView(); PlaylistModel* model = new PlaylistModel(); - view->setModel( model ); + view->setPlaylistModel( model ); view->setFrameShape( QFrame::NoFrame ); view->setAttribute( Qt::WA_MacShowFocusRect, 0 ); model->loadPlaylist( playlist ); @@ -212,7 +212,7 @@ PlaylistManager::show( const Tomahawk::artist_ptr& artist ) { view = new PlaylistView(); PlaylistModel* model = new PlaylistModel(); - view->setModel( model ); + view->setPlaylistModel( model ); view->setFrameShape( QFrame::NoFrame ); view->setAttribute( Qt::WA_MacShowFocusRect, 0 ); model->append( artist ); @@ -239,7 +239,7 @@ PlaylistManager::show( const Tomahawk::album_ptr& album ) { view = new PlaylistView(); PlaylistModel* model = new PlaylistModel(); - view->setModel( model ); + view->setPlaylistModel( model ); view->setFrameShape( QFrame::NoFrame ); view->setAttribute( Qt::WA_MacShowFocusRect, 0 ); model->append( album ); @@ -292,7 +292,7 @@ PlaylistManager::show( const Tomahawk::collection_ptr& collection ) { aview = new AlbumView(); AlbumModel* amodel = new AlbumModel( aview ); - aview->setModel( amodel ); + aview->setAlbumModel( amodel ); aview->setFrameShape( QFrame::NoFrame ); aview->setAttribute( Qt::WA_MacShowFocusRect, 0 ); amodel->addCollection( collection ); From 1c409e40f29fa95e34af07288cac53d8c766285f Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Wed, 13 Apr 2011 10:34:40 -0400 Subject: [PATCH 39/75] more crash fixes..... --- .../playlist/dynamic/DynamicView.cpp | 48 +++++++++---------- .../dynamic/widgets/DynamicWidget.cpp | 2 +- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/libtomahawk/playlist/dynamic/DynamicView.cpp b/src/libtomahawk/playlist/dynamic/DynamicView.cpp index 85b87aa53..ab1a67deb 100644 --- a/src/libtomahawk/playlist/dynamic/DynamicView.cpp +++ b/src/libtomahawk/playlist/dynamic/DynamicView.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -49,18 +49,18 @@ DynamicView::DynamicView( QWidget* parent ) setContentsMargins( 0, 0, 0, 0 ); setFrameShape( QFrame::NoFrame ); setAttribute( Qt::WA_MacShowFocusRect, 0 ); - + m_fadeOutAnim.setDuration( FADE_LENGTH ); m_fadeOutAnim.setCurveShape( QTimeLine::LinearCurve ); m_fadeOutAnim.setFrameRange( 100, 0 ); m_fadeOutAnim.setUpdateInterval( 5 ); - + QEasingCurve curve( QEasingCurve::OutBounce ); curve.setAmplitude( .25 ); m_slideAnim.setEasingCurve( curve ); m_slideAnim.setDirection( QTimeLine::Forward ); m_fadeOutAnim.setUpdateInterval( 5 ); - + connect( &m_fadeOutAnim, SIGNAL( frameChanged( int ) ), viewport(), SLOT( update() ) ); connect( &m_fadeOutAnim, SIGNAL( finished() ), this, SLOT( animFinished() ) ); } @@ -70,12 +70,12 @@ DynamicView::~DynamicView() } -void +void DynamicView::setDynamicModel( DynamicModel* model) { m_model = model; - PlaylistView::setModel( m_model ); - + PlaylistView::setPlaylistModel( m_model ); + connect( m_model, SIGNAL( trackCountChanged( unsigned int ) ), SLOT( onTrackCountChanged( unsigned int ) ) ); connect( m_model, SIGNAL( checkForOverflow() ), this, SLOT( checkForOverflow() ) ); } @@ -84,37 +84,37 @@ void DynamicView::setOnDemand( bool onDemand ) { m_onDemand = onDemand; - + if( m_onDemand ) setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff ); else setVerticalScrollBarPolicy( Qt::ScrollBarAsNeeded ); } -void +void DynamicView::setReadOnly( bool readOnly ) { m_readOnly = readOnly; } -void +void DynamicView::showMessageTimeout( const QString& title, const QString& body ) { m_title = title; m_body = body; - + overlay()->setText( QString( "%1:\n\n%2" ).arg( m_title, m_body ) ); overlay()->show( 10 ); } -void +void DynamicView::showMessage(const QString& message) { overlay()->setText( message ); overlay()->show(); } -void +void DynamicView::setDynamicWorking(bool working) { m_working = working; @@ -125,7 +125,7 @@ DynamicView::setDynamicWorking(bool working) } -void +void DynamicView::onTrackCountChanged( unsigned int tracks ) { if ( tracks == 0 && !m_working ) @@ -173,7 +173,7 @@ DynamicView::checkForOverflow() } } -void +void DynamicView::collapseEntries( int startRow, int num, int numToKeep ) { qDebug() << "BEGINNING TO COLLAPSE FROM" << startRow << num << numToKeep; @@ -192,7 +192,7 @@ DynamicView::collapseEntries( int startRow, int num, int numToKeep ) } else { m_fadeOnly = false; } - + // we capture the image of the rows we're going to collapse // then we capture the image of the target row we're going to animate downwards // then we fade the first image out while sliding the second image up. @@ -204,7 +204,7 @@ DynamicView::collapseEntries( int startRow, int num, int numToKeep ) QRect fadingRectViewport = fadingRect; // all values that we use in paintEvent() have to be in viewport coords fadingRect.moveTo( viewport()->mapTo( this, fadingRect.topLeft() ) ); //fadingRect.setBottom( qMin( fadingRect.bottom(), viewport()->mapTo( this, viewport()->rect().bottomLeft() ).y() ) ); // limit what we capture to the viewport rect, if the last item is partially obscured - + m_fadingIndexes = QPixmap::grabWidget( this, fadingRect ); // but all values we use to grab the widgetr have to be in scrollarea coords :( m_fadingPointAnchor = QPoint( 0, fadingRectViewport.topLeft().y() ); @@ -212,7 +212,7 @@ DynamicView::collapseEntries( int startRow, int num, int numToKeep ) m_bg = backgroundBetween( m_fadingIndexes.rect(), startRow ); m_fadeOutAnim.start(); - + qDebug() << "Grabbed fading indexes from rect:" << fadingRect << m_fadingIndexes.size() << "ANCHORED:" << m_fadingPointAnchor; if( !m_fadeOnly ) { @@ -233,7 +233,7 @@ DynamicView::collapseEntries( int startRow, int num, int numToKeep ) QRect slidingRectViewport = slidingRect; // map internal view coord to external qscrollarea slidingRect.moveTo( viewport()->mapTo( this, slidingRect.topLeft() ) ); - + m_slidingIndex = QPixmap::grabWidget( this, slidingRect ); m_bottomAnchor = QPoint( 0, slidingRectViewport.topLeft().y() ); m_bottomOfAnim = QPoint( 0, slidingRectViewport.bottomLeft().y() ); @@ -246,7 +246,7 @@ DynamicView::collapseEntries( int startRow, int num, int numToKeep ) QTimer::singleShot( SLIDE_OFFSET, &m_slideAnim, SLOT( start() ) ); } - + // delete the actual indices QModelIndexList todel; for( int i = 0; i < num; i++ ) { @@ -294,11 +294,11 @@ DynamicView::animFinished() m_checkOnCollapse = false; } -void +void DynamicView::paintEvent( QPaintEvent* event ) { TrackView::paintEvent(event); - + QPainter p( viewport() ); if( m_fadeOutAnim.state() == QTimeLine::Running ) { // both run together p.save(); @@ -316,8 +316,8 @@ DynamicView::paintEvent( QPaintEvent* event ) // qDebug() << "FAST SETOPACITY:" << p.paintEngine()->hasFeature(QPaintEngine::ConstantOpacity); p.setOpacity( 1 - m_fadeOutAnim.currentValue() ); p.drawPixmap( m_fadingPointAnchor, m_fadingIndexes ); - p.restore(); - + p.restore(); + if( m_slideAnim.state() == QTimeLine::Running ) { // draw the collapsing entry p.drawPixmap( 0, m_slideAnim.currentFrame(), m_slidingIndex ); diff --git a/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.cpp b/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.cpp index 0aa65d3bc..60a4fc52d 100644 --- a/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.cpp +++ b/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.cpp @@ -65,7 +65,7 @@ DynamicWidget::DynamicWidget( const Tomahawk::dynplaylist_ptr& playlist, QWidget m_model = new DynamicModel( this ); m_view = new DynamicView( this ); - m_view->setModel( m_model ); + m_view->setDynamicModel( m_model ); m_view->setContentsMargins( 0, 0, 0, 0 ); m_layout->addWidget( m_view, 1 ); From f2308beb18d279ed107e2407c978d4cbd2f72385 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Wed, 6 Apr 2011 12:51:16 +0200 Subject: [PATCH 40/75] * Split up PlItem into Track- and TreeModelItem. --- src/libtomahawk/CMakeLists.txt | 2 ++ src/libtomahawk/playlist/collectionmodel.cpp | 30 +++++++++---------- src/libtomahawk/playlist/collectionmodel.h | 8 ++--- .../playlist/collectionproxymodel.cpp | 5 ---- src/libtomahawk/playlist/trackmodel.cpp | 15 ---------- src/libtomahawk/playlist/trackmodelitem.cpp | 25 +++++----------- src/libtomahawk/playlist/trackmodelitem.h | 3 -- 7 files changed, 28 insertions(+), 60 deletions(-) diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index cdc92f878..b5c91ac14 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -90,6 +90,7 @@ set( libSources playlist/trackproxymodel.cpp playlist/trackview.cpp playlist/trackheader.cpp + playlist/treemodelitem.cpp playlist/albumitem.cpp playlist/albummodel.cpp playlist/albumproxymodel.cpp @@ -245,6 +246,7 @@ set( libHeaders playlist/trackproxymodel.h playlist/trackview.h playlist/trackheader.h + playlist/treemodelitem.h playlist/albumitem.h playlist/albummodel.h playlist/albumproxymodel.h diff --git a/src/libtomahawk/playlist/collectionmodel.cpp b/src/libtomahawk/playlist/collectionmodel.cpp index ec8808764..ded4d0bde 100644 --- a/src/libtomahawk/playlist/collectionmodel.cpp +++ b/src/libtomahawk/playlist/collectionmodel.cpp @@ -49,8 +49,8 @@ CollectionModel::index( int row, int column, const QModelIndex& parent ) const if ( !m_rootItem || row < 0 || column < 0 ) return QModelIndex(); - TrackModelItem* parentItem = itemFromIndex( parent ); - TrackModelItem* childItem = parentItem->children.value( row ); + TreeModelItem* parentItem = itemFromIndex( parent ); + TreeModelItem* childItem = parentItem->children.value( row ); if ( !childItem ) return QModelIndex(); @@ -64,7 +64,7 @@ CollectionModel::rowCount( const QModelIndex& parent ) const if ( parent.column() > 0 ) return 0; - TrackModelItem* parentItem = itemFromIndex( parent ); + TreeModelItem* parentItem = itemFromIndex( parent ); if ( !parentItem ) return 0; @@ -83,15 +83,15 @@ CollectionModel::columnCount( const QModelIndex& parent ) const QModelIndex CollectionModel::parent( const QModelIndex& child ) const { - TrackModelItem* entry = itemFromIndex( child ); + TreeModelItem* entry = itemFromIndex( child ); if ( !entry ) return QModelIndex(); - TrackModelItem* parentEntry = entry->parent; + TreeModelItem* parentEntry = entry->parent; if ( !parentEntry ) return QModelIndex(); - TrackModelItem* grandparentEntry = parentEntry->parent; + TreeModelItem* grandparentEntry = parentEntry->parent; if ( !grandparentEntry ) return QModelIndex(); @@ -106,7 +106,7 @@ CollectionModel::data( const QModelIndex& index, int role ) const if ( role != Qt::DisplayRole ) return QVariant(); - TrackModelItem* entry = itemFromIndex( index ); + TreeModelItem* entry = itemFromIndex( index ); if ( !entry ) return QVariant(); @@ -199,7 +199,7 @@ CollectionModel::removeCollection( const collection_ptr& collection ) disconnect( collection.data(), SIGNAL( tracksFinished( Tomahawk::collection_ptr ) ), this, SLOT( onTracksAddingFinished( Tomahawk::collection_ptr ) ) ); - QList plitems = m_collectionIndex.values( collection ); + QList plitems = m_collectionIndex.values( collection ); m_collectionIndex.remove( collection ); } @@ -210,17 +210,17 @@ CollectionModel::onTracksAdded( const QList& tracks, const { // int c = rowCount( QModelIndex() ); - TrackModelItem* plitem; + TreeModelItem* plitem; foreach( const Tomahawk::query_ptr& query, tracks ) { - TrackModelItem* parent = m_rootItem; + TreeModelItem* parent = m_rootItem; if ( parent->hash.contains( query->artist() ) ) { parent = parent->hash.value( query->artist() ); } else { - parent = new TrackModelItem( query->artist(), m_rootItem ); + parent = new TreeModelItem( query->artist(), m_rootItem ); m_rootItem->hash.insert( query->artist(), parent ); } @@ -232,14 +232,14 @@ CollectionModel::onTracksAdded( const QList& tracks, const } else { - TrackModelItem* subitem = new TrackModelItem( query->album(), parent ); + TreeModelItem* subitem = new TreeModelItem( query->album(), parent ); parent->hash.insert( query->album(), subitem ); parent->childCount++; subitem->childCount++; parent = subitem; } - plitem = new TrackModelItem( query, parent ); + plitem = new TreeModelItem( query, parent ); m_collectionIndex.insertMulti( collection, plitem ); } @@ -275,11 +275,11 @@ CollectionModel::onSourceOffline( Tomahawk::source_ptr src ) } -TrackModelItem* +TreeModelItem* CollectionModel::itemFromIndex( const QModelIndex& index ) const { if ( index.isValid() ) - return static_cast( index.internalPointer() ); + return static_cast( index.internalPointer() ); else { return m_rootItem; diff --git a/src/libtomahawk/playlist/collectionmodel.h b/src/libtomahawk/playlist/collectionmodel.h index 2ba760743..32d0e611b 100644 --- a/src/libtomahawk/playlist/collectionmodel.h +++ b/src/libtomahawk/playlist/collectionmodel.h @@ -23,7 +23,7 @@ #include #include -#include "trackmodelitem.h" +#include "treemodelitem.h" #include "collection.h" #include "query.h" #include "typedefs.h" @@ -62,7 +62,7 @@ public: virtual void setRepeatMode( PlaylistInterface::RepeatMode /*mode*/ ) {} virtual void setShuffled( bool /*shuffled*/ ) {} - TrackModelItem* itemFromIndex( const QModelIndex& index ) const; + TreeModelItem* itemFromIndex( const QModelIndex& index ) const; signals: void repeatModeChanged( PlaylistInterface::RepeatMode mode ); @@ -79,8 +79,8 @@ private slots: void onSourceOffline( Tomahawk::source_ptr src ); private: - TrackModelItem* m_rootItem; - QMap< Tomahawk::collection_ptr, TrackModelItem* > m_collectionIndex; + TreeModelItem* m_rootItem; + QMap< Tomahawk::collection_ptr, TreeModelItem* > m_collectionIndex; }; #endif // COLLECTIONMODEL_H diff --git a/src/libtomahawk/playlist/collectionproxymodel.cpp b/src/libtomahawk/playlist/collectionproxymodel.cpp index f6c5dd7b5..668b3266f 100644 --- a/src/libtomahawk/playlist/collectionproxymodel.cpp +++ b/src/libtomahawk/playlist/collectionproxymodel.cpp @@ -46,11 +46,6 @@ CollectionProxyModel::lessThan( const QModelIndex& left, const QModelIndex& righ const Tomahawk::query_ptr& q1 = p1->query(); const Tomahawk::query_ptr& q2 = p2->query(); - if ( q1.isNull() || q2.isNull() ) - { - return QString::localeAwareCompare( p1->caption, p2->caption ) < 0; - } - QString artist1 = q1->artist(); QString artist2 = q2->artist(); QString album1 = q1->album(); diff --git a/src/libtomahawk/playlist/trackmodel.cpp b/src/libtomahawk/playlist/trackmodel.cpp index 0249aa1d1..51ae0590a 100644 --- a/src/libtomahawk/playlist/trackmodel.cpp +++ b/src/libtomahawk/playlist/trackmodel.cpp @@ -127,21 +127,6 @@ TrackModel::data( const QModelIndex& index, int role ) const return QVariant(); const query_ptr& query = entry->query(); - if ( query.isNull() ) - { - if ( !index.column() ) - { - return entry->caption.isEmpty() ? "Unknown" : entry->caption; - } - - if ( index.column() == 1 ) - { - return entry->childCount; - } - - return QVariant( "" ); - } - if ( !query->numResults() ) { switch( index.column() ) diff --git a/src/libtomahawk/playlist/trackmodelitem.cpp b/src/libtomahawk/playlist/trackmodelitem.cpp index e88659601..b421bb3f8 100644 --- a/src/libtomahawk/playlist/trackmodelitem.cpp +++ b/src/libtomahawk/playlist/trackmodelitem.cpp @@ -56,22 +56,6 @@ TrackModelItem::TrackModelItem( TrackModelItem* parent, QAbstractItemModel* mode } -TrackModelItem::TrackModelItem( const QString& caption, TrackModelItem* parent ) -{ - this->parent = parent; - this->caption = caption; - this->model = parent->model; - childCount = 0; - m_isPlaying = false; - toberemoved = false; - - if ( parent ) - { - parent->children.append( this ); - } -} - - TrackModelItem::TrackModelItem( const Tomahawk::query_ptr& query, TrackModelItem* parent, int row ) : QObject( parent ) { @@ -86,16 +70,21 @@ TrackModelItem::TrackModelItem( const Tomahawk::plentry_ptr& entry, TrackModelIt setupItem( entry->query(), parent, row ); } + const Tomahawk::plentry_ptr& TrackModelItem::entry() const { return m_entry; } + const Tomahawk::query_ptr& TrackModelItem::query() const { - if ( !m_entry.isNull() ) return m_entry->query(); else return m_query; + if ( !m_entry.isNull() ) + return m_entry->query(); + else + return m_query; } @@ -123,7 +112,7 @@ TrackModelItem::setupItem( const Tomahawk::query_ptr& query, TrackModelItem* par m_query = query; if ( query->numResults() ) { - emit dataChanged(); +// emit dataChanged(); } else { diff --git a/src/libtomahawk/playlist/trackmodelitem.h b/src/libtomahawk/playlist/trackmodelitem.h index 70b93923c..3d0118c6c 100644 --- a/src/libtomahawk/playlist/trackmodelitem.h +++ b/src/libtomahawk/playlist/trackmodelitem.h @@ -37,7 +37,6 @@ public: virtual ~TrackModelItem(); explicit TrackModelItem( TrackModelItem* parent = 0, QAbstractItemModel* model = 0 ); - explicit TrackModelItem( const QString& caption, TrackModelItem* parent = 0 ); explicit TrackModelItem( const Tomahawk::query_ptr& query, TrackModelItem* parent = 0, int row = -1 ); explicit TrackModelItem( const Tomahawk::plentry_ptr& entry, TrackModelItem* parent = 0, int row = -1 ); @@ -49,8 +48,6 @@ public: TrackModelItem* parent; QVector children; - QHash hash; - QString caption; int childCount; QPersistentModelIndex index; QAbstractItemModel* model; From d4745e1e40adcec007464b3b5c6709753e6a0693 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Thu, 7 Apr 2011 06:21:19 +0200 Subject: [PATCH 41/75] * Further progress making a clean(er) tree model. --- src/libtomahawk/CMakeLists.txt | 12 ++++- src/libtomahawk/playlist/albumproxymodel.cpp | 3 +- .../playlist/collectionproxymodel.cpp | 1 - src/libtomahawk/playlist/playlistmanager.cpp | 29 ++++++++-- src/libtomahawk/playlist/playlistmanager.h | 4 ++ src/libtomahawk/playlist/topbar/topbar.cpp | 14 +++-- src/libtomahawk/playlist/trackproxymodel.cpp | 1 - .../{collectionmodel.cpp => treemodel.cpp} | 53 +++++++++++++------ .../{collectionmodel.h => treemodel.h} | 14 +++-- src/sourcetree/sourcetreeview.cpp | 2 - src/sourcetree/sourcetreeview.h | 9 ++-- 11 files changed, 99 insertions(+), 43 deletions(-) rename src/libtomahawk/playlist/{collectionmodel.cpp => treemodel.cpp} (83%) rename src/libtomahawk/playlist/{collectionmodel.h => treemodel.h} (87%) diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index b5c91ac14..77ad46ca1 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -74,7 +74,10 @@ set( libSources database/databasecommand_clientauthvalid.cpp database/database.cpp - playlist/collectionmodel.cpp + playlist/treemodel.cpp + playlist/treeproxymodel.cpp + playlist/treeheader.cpp + playlist/treeitemdelegate.cpp playlist/collectionproxymodel.cpp playlist/collectionflatmodel.cpp playlist/collectionview.cpp @@ -96,6 +99,7 @@ set( libSources playlist/albumproxymodel.cpp playlist/albumitemdelegate.cpp playlist/albumview.cpp + playlist/artistview.cpp playlist/topbar/topbar.cpp playlist/topbar/clearbutton.cpp @@ -230,7 +234,10 @@ set( libHeaders network/controlconnection.h network/portfwdthread.h - playlist/collectionmodel.h + playlist/treemodel.h + playlist/treeproxymodel.h + playlist/treeheader.h + playlist/treeitemdelegate.h playlist/collectionproxymodel.h playlist/collectionflatmodel.h playlist/collectionview.h @@ -252,6 +259,7 @@ set( libHeaders playlist/albumproxymodel.h playlist/albumitemdelegate.h playlist/albumview.h + playlist/artistview.h playlist/topbar/topbar.h playlist/topbar/clearbutton.h diff --git a/src/libtomahawk/playlist/albumproxymodel.cpp b/src/libtomahawk/playlist/albumproxymodel.cpp index f35aa9b26..95a764e15 100644 --- a/src/libtomahawk/playlist/albumproxymodel.cpp +++ b/src/libtomahawk/playlist/albumproxymodel.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -22,7 +22,6 @@ #include #include "query.h" -#include "collectionmodel.h" AlbumProxyModel::AlbumProxyModel( QObject* parent ) diff --git a/src/libtomahawk/playlist/collectionproxymodel.cpp b/src/libtomahawk/playlist/collectionproxymodel.cpp index 668b3266f..4f602e5db 100644 --- a/src/libtomahawk/playlist/collectionproxymodel.cpp +++ b/src/libtomahawk/playlist/collectionproxymodel.cpp @@ -23,7 +23,6 @@ #include "album.h" #include "query.h" -#include "collectionmodel.h" CollectionProxyModel::CollectionProxyModel( QObject* parent ) diff --git a/src/libtomahawk/playlist/playlistmanager.cpp b/src/libtomahawk/playlist/playlistmanager.cpp index 94302de16..6eefc11d4 100644 --- a/src/libtomahawk/playlist/playlistmanager.cpp +++ b/src/libtomahawk/playlist/playlistmanager.cpp @@ -28,7 +28,7 @@ #include "widgets/infowidgets/sourceinfowidget.h" #include "widgets/welcomewidget.h" -#include "collectionmodel.h" +#include "treemodel.h" #include "collectionflatmodel.h" #include "collectionview.h" #include "playlistmodel.h" @@ -36,6 +36,7 @@ #include "queueview.h" #include "trackproxymodel.h" #include "trackmodel.h" +#include "artistview.h" #include "albumview.h" #include "albumproxymodel.h" #include "albummodel.h" @@ -261,6 +262,7 @@ PlaylistManager::show( const Tomahawk::album_ptr& album ) bool PlaylistManager::show( const Tomahawk::collection_ptr& collection ) { + qDebug() << Q_FUNC_INFO << m_currentMode; m_currentCollection = collection; if ( m_currentMode == 0 ) { @@ -285,6 +287,29 @@ PlaylistManager::show( const Tomahawk::collection_ptr& collection ) setPage( view ); } + if ( m_currentMode == 1 ) + { + ArtistView* view; + if ( !m_treeViews.contains( collection ) ) + { + view = new ArtistView(); + TreeModel* model = new TreeModel(); + view->setModel( model ); + view->setFrameShape( QFrame::NoFrame ); + view->setAttribute( Qt::WA_MacShowFocusRect, 0 ); + + model->addCollection( collection ); + + m_treeViews.insert( collection, view ); + } + else + { + view = m_treeViews.value( collection ); + } + + setPage( view ); + } + if ( m_currentMode == 2 ) { AlbumView* aview; @@ -400,8 +425,6 @@ PlaylistManager::setTableMode() void PlaylistManager::setTreeMode() { - return; - qDebug() << Q_FUNC_INFO; m_currentMode = 1; diff --git a/src/libtomahawk/playlist/playlistmanager.h b/src/libtomahawk/playlist/playlistmanager.h index 6c7f66578..bceb89d08 100644 --- a/src/libtomahawk/playlist/playlistmanager.h +++ b/src/libtomahawk/playlist/playlistmanager.h @@ -32,6 +32,7 @@ class AnimatedSplitter; class AlbumModel; class AlbumView; +class ArtistView; class CollectionModel; class CollectionFlatModel; class CollectionView; @@ -40,6 +41,8 @@ class PlaylistView; class QueueView; class TrackProxyModel; class TrackModel; +class TreeProxyModel; +class TreeModel; class TrackView; class SourceInfoWidget; class InfoBar; @@ -167,6 +170,7 @@ private: QHash< Tomahawk::dynplaylist_ptr, Tomahawk::DynamicWidget* > m_dynamicWidgets; QHash< Tomahawk::collection_ptr, CollectionView* > m_collectionViews; + QHash< Tomahawk::collection_ptr, ArtistView* > m_treeViews; QHash< Tomahawk::collection_ptr, AlbumView* > m_collectionAlbumViews; QHash< Tomahawk::artist_ptr, PlaylistView* > m_artistViews; QHash< Tomahawk::album_ptr, PlaylistView* > m_albumViews; diff --git a/src/libtomahawk/playlist/topbar/topbar.cpp b/src/libtomahawk/playlist/topbar/topbar.cpp index 5018092f3..b60741a9e 100644 --- a/src/libtomahawk/playlist/topbar/topbar.cpp +++ b/src/libtomahawk/playlist/topbar/topbar.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -72,8 +72,6 @@ TopBar::TopBar( QWidget* parent ) ui->radioDetailed->setFocusPolicy( Qt::NoFocus ); ui->radioCloud->setFocusPolicy( Qt::NoFocus ); - ui->radioDetailed->setEnabled( false ); - connect( ui->radioNormal, SIGNAL( clicked() ), SIGNAL( flatMode() ) ); connect( ui->radioDetailed, SIGNAL( clicked() ), SIGNAL( artistMode() ) ); connect( ui->radioCloud, SIGNAL( clicked() ), SIGNAL( albumMode() ) ); @@ -87,19 +85,19 @@ TopBar::TopBar( QWidget* parent ) connect( PlaylistManager::instance(), SIGNAL( numSourcesChanged( unsigned int ) ), SLOT( setNumSources( unsigned int ) ) ); - + connect( PlaylistManager::instance(), SIGNAL( numTracksChanged( unsigned int ) ), SLOT( setNumTracks( unsigned int ) ) ); - + connect( PlaylistManager::instance(), SIGNAL( numArtistsChanged( unsigned int ) ), SLOT( setNumArtists( unsigned int ) ) ); - + connect( PlaylistManager::instance(), SIGNAL( numShownChanged( unsigned int ) ), SLOT( setNumShown( unsigned int ) ) ); - + connect( PlaylistManager::instance(), SIGNAL( statsAvailable( bool ) ), SLOT( setStatsVisible( bool ) ) ); - + connect( PlaylistManager::instance(), SIGNAL( modesAvailable( bool ) ), SLOT( setModesVisible( bool ) ) ); diff --git a/src/libtomahawk/playlist/trackproxymodel.cpp b/src/libtomahawk/playlist/trackproxymodel.cpp index 91283c7ad..2ed2c94b1 100644 --- a/src/libtomahawk/playlist/trackproxymodel.cpp +++ b/src/libtomahawk/playlist/trackproxymodel.cpp @@ -23,7 +23,6 @@ #include "album.h" #include "query.h" -#include "collectionmodel.h" TrackProxyModel::TrackProxyModel( QObject* parent ) diff --git a/src/libtomahawk/playlist/collectionmodel.cpp b/src/libtomahawk/playlist/treemodel.cpp similarity index 83% rename from src/libtomahawk/playlist/collectionmodel.cpp rename to src/libtomahawk/playlist/treemodel.cpp index ded4d0bde..814134dbb 100644 --- a/src/libtomahawk/playlist/collectionmodel.cpp +++ b/src/libtomahawk/playlist/treemodel.cpp @@ -16,7 +16,7 @@ * along with Tomahawk. If not, see . */ -#include "collectionmodel.h" +#include "treemodel.h" #include #include @@ -28,7 +28,7 @@ using namespace Tomahawk; -CollectionModel::CollectionModel( QObject* parent ) +TreeModel::TreeModel( QObject* parent ) : QAbstractItemModel( parent ) , m_rootItem( 0 ) { @@ -38,13 +38,13 @@ CollectionModel::CollectionModel( QObject* parent ) } -CollectionModel::~CollectionModel() +TreeModel::~TreeModel() { } QModelIndex -CollectionModel::index( int row, int column, const QModelIndex& parent ) const +TreeModel::index( int row, int column, const QModelIndex& parent ) const { if ( !m_rootItem || row < 0 || column < 0 ) return QModelIndex(); @@ -59,7 +59,7 @@ CollectionModel::index( int row, int column, const QModelIndex& parent ) const int -CollectionModel::rowCount( const QModelIndex& parent ) const +TreeModel::rowCount( const QModelIndex& parent ) const { if ( parent.column() > 0 ) return 0; @@ -73,7 +73,7 @@ CollectionModel::rowCount( const QModelIndex& parent ) const int -CollectionModel::columnCount( const QModelIndex& parent ) const +TreeModel::columnCount( const QModelIndex& parent ) const { Q_UNUSED( parent ); return 4; @@ -81,7 +81,7 @@ CollectionModel::columnCount( const QModelIndex& parent ) const QModelIndex -CollectionModel::parent( const QModelIndex& child ) const +TreeModel::parent( const QModelIndex& child ) const { TreeModelItem* entry = itemFromIndex( child ); if ( !entry ) @@ -101,7 +101,7 @@ CollectionModel::parent( const QModelIndex& child ) const QVariant -CollectionModel::data( const QModelIndex& index, int role ) const +TreeModel::data( const QModelIndex& index, int role ) const { if ( role != Qt::DisplayRole ) return QVariant(); @@ -162,7 +162,7 @@ CollectionModel::data( const QModelIndex& index, int role ) const QVariant -CollectionModel::headerData( int section, Qt::Orientation orientation, int role ) const +TreeModel::headerData( int section, Qt::Orientation orientation, int role ) const { QStringList headers; headers << tr( "Name" ) << tr( "Tracks" ) << tr( "Duration" ) << tr( "Origin" ); @@ -176,7 +176,30 @@ CollectionModel::headerData( int section, Qt::Orientation orientation, int role void -CollectionModel::addCollection( const collection_ptr& collection ) +TreeModel::setCurrentItem( const QModelIndex& index ) +{ + qDebug() << Q_FUNC_INFO; + TreeModelItem* oldEntry = itemFromIndex( m_currentIndex ); + if ( oldEntry ) + { + oldEntry->setIsPlaying( false ); + } + + TreeModelItem* entry = itemFromIndex( index ); + if ( entry ) + { + m_currentIndex = index; + entry->setIsPlaying( true ); + } + else + { + m_currentIndex = QModelIndex(); + } +} + + +void +TreeModel::addCollection( const collection_ptr& collection ) { qDebug() << Q_FUNC_INFO << collection->name() << collection->source()->id() @@ -192,7 +215,7 @@ CollectionModel::addCollection( const collection_ptr& collection ) void -CollectionModel::removeCollection( const collection_ptr& collection ) +TreeModel::removeCollection( const collection_ptr& collection ) { disconnect( collection.data(), SIGNAL( tracksAdded( QList, Tomahawk::collection_ptr ) ), this, SLOT( onTracksAdded( QList, Tomahawk::collection_ptr ) ) ); @@ -206,7 +229,7 @@ CollectionModel::removeCollection( const collection_ptr& collection ) void -CollectionModel::onTracksAdded( const QList& tracks, const collection_ptr& collection ) +TreeModel::onTracksAdded( const QList& tracks, const collection_ptr& collection ) { // int c = rowCount( QModelIndex() ); @@ -250,7 +273,7 @@ CollectionModel::onTracksAdded( const QList& tracks, const void -CollectionModel::onTracksAddingFinished( const Tomahawk::collection_ptr& collection ) +TreeModel::onTracksAddingFinished( const Tomahawk::collection_ptr& collection ) { qDebug() << "Finished loading tracks" << collection->source()->friendlyName(); @@ -264,7 +287,7 @@ CollectionModel::onTracksAddingFinished( const Tomahawk::collection_ptr& collect void -CollectionModel::onSourceOffline( Tomahawk::source_ptr src ) +TreeModel::onSourceOffline( Tomahawk::source_ptr src ) { qDebug() << Q_FUNC_INFO; @@ -276,7 +299,7 @@ CollectionModel::onSourceOffline( Tomahawk::source_ptr src ) TreeModelItem* -CollectionModel::itemFromIndex( const QModelIndex& index ) const +TreeModel::itemFromIndex( const QModelIndex& index ) const { if ( index.isValid() ) return static_cast( index.internalPointer() ); diff --git a/src/libtomahawk/playlist/collectionmodel.h b/src/libtomahawk/playlist/treemodel.h similarity index 87% rename from src/libtomahawk/playlist/collectionmodel.h rename to src/libtomahawk/playlist/treemodel.h index 32d0e611b..393a9ed6d 100644 --- a/src/libtomahawk/playlist/collectionmodel.h +++ b/src/libtomahawk/playlist/treemodel.h @@ -34,13 +34,13 @@ class QMetaData; -class DLLEXPORT CollectionModel : public QAbstractItemModel +class DLLEXPORT TreeModel : public QAbstractItemModel { Q_OBJECT public: - explicit CollectionModel( QObject* parent = 0 ); - ~CollectionModel(); + explicit TreeModel( QObject* parent = 0 ); + ~TreeModel(); QModelIndex index( int row, int column, const QModelIndex& parent ) const; QModelIndex parent( const QModelIndex& child ) const; @@ -50,12 +50,14 @@ public: int rowCount( const QModelIndex& parent ) const; int columnCount( const QModelIndex& parent ) const; - QVariant data( const QModelIndex& index, int role ) const; + QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const; QVariant headerData( int section, Qt::Orientation orientation, int role ) const; void addCollection( const Tomahawk::collection_ptr& collection ); void removeCollection( const Tomahawk::collection_ptr& collection ); + virtual QPersistentModelIndex currentItem() { return m_currentIndex; } + virtual PlaylistInterface::RepeatMode repeatMode() const { return PlaylistInterface::NoRepeat; } virtual bool shuffled() const { return false; } @@ -64,6 +66,9 @@ public: TreeModelItem* itemFromIndex( const QModelIndex& index ) const; +public slots: + virtual void setCurrentItem( const QModelIndex& index ); + signals: void repeatModeChanged( PlaylistInterface::RepeatMode mode ); void shuffleModeChanged( bool enabled ); @@ -81,6 +86,7 @@ private slots: private: TreeModelItem* m_rootItem; QMap< Tomahawk::collection_ptr, TreeModelItem* > m_collectionIndex; + QPersistentModelIndex m_currentIndex; }; #endif // COLLECTIONMODEL_H diff --git a/src/sourcetree/sourcetreeview.cpp b/src/sourcetree/sourcetreeview.cpp index 4ceccd2c1..4935b8d0e 100644 --- a/src/sourcetree/sourcetreeview.cpp +++ b/src/sourcetree/sourcetreeview.cpp @@ -19,7 +19,6 @@ #include "sourcetreeview.h" #include "playlist.h" -#include "playlist/collectionmodel.h" #include "playlist/playlistmanager.h" #include "sourcetreeitem.h" #include "sourcesmodel.h" @@ -61,7 +60,6 @@ private: SourceTreeView::SourceTreeView( QWidget* parent ) : QTreeView( parent ) - , m_collectionModel( new CollectionModel( this ) ) , m_dragging( false ) { setFrameShape( QFrame::NoFrame ); diff --git a/src/sourcetree/sourcetreeview.h b/src/sourcetree/sourcetreeview.h index e9cbe51b0..f2d8581e3 100644 --- a/src/sourcetree/sourcetreeview.h +++ b/src/sourcetree/sourcetreeview.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -39,7 +39,7 @@ public: public slots: void showOfflineSources(); void hideOfflineSources(); - + signals: void onOnline( const QModelIndex& index ); void onOffline( const QModelIndex& index ); @@ -50,14 +50,14 @@ private slots: void onCollectionActivated( const Tomahawk::collection_ptr& collection ); void onSuperCollectionActivated(); void onTempPageActivated(); - + void onItemActivated( const QModelIndex& index ); void onSelectionChanged(); void loadPlaylist(); void deletePlaylist(); void renamePlaylist(); - + void onCustomContextMenu( const QPoint& pos ); void onSourceOffline( Tomahawk::source_ptr ); @@ -75,7 +75,6 @@ protected: private: void setupMenus(); - CollectionModel* m_collectionModel; SourcesModel* m_model; SourcesProxyModel* m_proxyModel; QModelIndex m_contextMenuIndex; From 43a08b795746ae9bf7068236546f85aea587dc9c Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sun, 10 Apr 2011 09:24:24 +0200 Subject: [PATCH 42/75] * Work in progress: The ArtistView & TreeModel. --- src/audiocontrols.cpp | 47 +- src/audiocontrols.h | 7 +- src/libtomahawk/CMakeLists.txt | 2 + src/libtomahawk/database/databasecommand.h | 7 +- .../database/databasecommand_allalbums.cpp | 103 +++- .../database/databasecommand_allalbums.h | 14 +- .../database/databasecommand_allartists.cpp | 68 +++ .../database/databasecommand_allartists.h | 69 +++ .../database/databasecommand_alltracks.cpp | 7 +- .../database/databasecommand_alltracks.h | 4 +- src/libtomahawk/playlist/albummodel.cpp | 8 +- src/libtomahawk/playlist/albummodel.h | 6 +- src/libtomahawk/playlist/artistview.cpp | 152 ++++++ src/libtomahawk/playlist/artistview.h | 79 +++ src/libtomahawk/playlist/playlistmanager.cpp | 18 +- src/libtomahawk/playlist/playlistmanager.h | 4 +- src/libtomahawk/playlist/treeheader.cpp | 145 +++++ src/libtomahawk/playlist/treeheader.h | 61 +++ src/libtomahawk/playlist/treeitemdelegate.cpp | 101 ++++ src/libtomahawk/playlist/treeitemdelegate.h | 46 ++ src/libtomahawk/playlist/treemodel.cpp | 494 +++++++++++++----- src/libtomahawk/playlist/treemodel.h | 101 ++-- src/libtomahawk/playlist/treemodelitem.cpp | 133 +++++ src/libtomahawk/playlist/treemodelitem.h | 69 +++ src/libtomahawk/playlist/treeproxymodel.cpp | 158 ++++++ src/libtomahawk/playlist/treeproxymodel.h | 81 +++ 26 files changed, 1734 insertions(+), 250 deletions(-) create mode 100644 src/libtomahawk/database/databasecommand_allartists.cpp create mode 100644 src/libtomahawk/database/databasecommand_allartists.h create mode 100644 src/libtomahawk/playlist/artistview.cpp create mode 100644 src/libtomahawk/playlist/artistview.h create mode 100644 src/libtomahawk/playlist/treeheader.cpp create mode 100644 src/libtomahawk/playlist/treeheader.h create mode 100644 src/libtomahawk/playlist/treeitemdelegate.cpp create mode 100644 src/libtomahawk/playlist/treeitemdelegate.h create mode 100644 src/libtomahawk/playlist/treemodelitem.cpp create mode 100644 src/libtomahawk/playlist/treemodelitem.h create mode 100644 src/libtomahawk/playlist/treeproxymodel.cpp create mode 100644 src/libtomahawk/playlist/treeproxymodel.h diff --git a/src/audiocontrols.cpp b/src/audiocontrols.cpp index e7b0e8739..4465e266b 100644 --- a/src/audiocontrols.cpp +++ b/src/audiocontrols.cpp @@ -31,7 +31,8 @@ #define LASTFM_DEFAULT_COVER "http://cdn.last.fm/flatness/catalogue/noimage" -static QString s_infoIdentifier = QString("AUDIOCONTROLS"); +static QString s_infoIdentifier = QString( "AUDIOCONTROLS" ); + AudioControls::AudioControls( QWidget* parent ) : QWidget( parent ) @@ -208,40 +209,6 @@ AudioControls::onVolumeChanged( int volume ) } -void -AudioControls::onCoverArtDownloaded() -{ - if ( m_currentTrack.isNull() ) - return; - - QNetworkReply* reply = qobject_cast( sender() ); - QUrl redir = reply->attribute( QNetworkRequest::RedirectionTargetAttribute ).toUrl(); - if ( redir.isEmpty() ) - { - const QByteArray ba = reply->readAll(); - if ( ba.length() ) - { - QPixmap pm; - pm.loadFromData( ba ); - - if ( pm.isNull() || reply->url().toString().startsWith( LASTFM_DEFAULT_COVER ) ) - ui->coverImage->setPixmap( m_defaultCover ); - else - ui->coverImage->setPixmap( pm.scaled( ui->coverImage->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation ) ); - } - } - else - { - // Follow HTTP redirect - QNetworkRequest req( redir ); - QNetworkReply* reply = TomahawkUtils::nam()->get( req ); - connect( reply, SIGNAL( finished() ), SLOT( onCoverArtDownloaded() ) ); - } - - reply->deleteLater(); -} - - void AudioControls::onPlaybackStarted( const Tomahawk::result_ptr& result ) { @@ -249,18 +216,16 @@ AudioControls::onPlaybackStarted( const Tomahawk::result_ptr& result ) onPlaybackLoading( result ); - QString artistName = result->artist()->name(); - QString albumName = result->album()->name(); - Tomahawk::InfoSystem::InfoCustomData trackInfo; - trackInfo["artist"] = QVariant::fromValue< QString >( result->artist()->name() ); trackInfo["album"] = QVariant::fromValue< QString >( result->album()->name() ); + TomahawkApp::instance()->infoSystem()->getInfo( s_infoIdentifier, Tomahawk::InfoSystem::InfoAlbumCoverArt, QVariant::fromValue< Tomahawk::InfoSystem::InfoCustomData >( trackInfo ), Tomahawk::InfoSystem::InfoCustomData() ); } + void AudioControls::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ) { @@ -270,7 +235,7 @@ AudioControls::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType ty qDebug() << Q_FUNC_INFO; if ( caller != s_infoIdentifier || type != Tomahawk::InfoSystem::InfoAlbumCoverArt ) { - qDebug() << "info of wrong type or not with our identifier"; + qDebug() << "Info of wrong type or not with our identifier"; return; } @@ -300,6 +265,7 @@ AudioControls::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType ty } } + void AudioControls::infoSystemFinished( QString target ) { @@ -307,6 +273,7 @@ AudioControls::infoSystemFinished( QString target ) qDebug() << Q_FUNC_INFO; } + void AudioControls::onPlaybackLoading( const Tomahawk::result_ptr& result ) { diff --git a/src/audiocontrols.h b/src/audiocontrols.h index 3b90005d6..126608a05 100644 --- a/src/audiocontrols.h +++ b/src/audiocontrols.h @@ -41,12 +41,10 @@ public: signals: void playPressed(); void pausePressed(); - + public slots: void onRepeatModeChanged( PlaylistInterface::RepeatMode mode ); void onShuffleModeChanged( bool enabled ); - void infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ); - void infoSystemFinished( QString target ); protected: void changeEvent( QEvent* e ); @@ -68,7 +66,8 @@ private slots: void onAlbumClicked(); void onTrackClicked(); - void onCoverArtDownloaded(); + void infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ); + void infoSystemFinished( QString target ); private: Ui::AudioControls *ui; diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index 77ad46ca1..4b945ef7d 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -43,6 +43,7 @@ set( libSources database/databasecommand.cpp database/databasecommandloggable.cpp database/databasecommand_resolve.cpp + database/databasecommand_allartists.cpp database/databasecommand_allalbums.cpp database/databasecommand_alltracks.cpp database/databasecommand_addfiles.cpp @@ -194,6 +195,7 @@ set( libHeaders database/databasecommand.h database/databasecommandloggable.h database/databasecommand_resolve.h + database/databasecommand_allartists.h database/databasecommand_allalbums.h database/databasecommand_alltracks.h database/databasecommand_addfiles.h diff --git a/src/libtomahawk/database/databasecommand.h b/src/libtomahawk/database/databasecommand.h index 35fff3dfc..3ce9b6873 100644 --- a/src/libtomahawk/database/databasecommand.h +++ b/src/libtomahawk/database/databasecommand.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -76,6 +76,9 @@ public: virtual bool singletonCmd() const { return false; } virtual bool localOnly() const { return false; } + virtual QVariant data() const { return m_data; } + virtual void setData( const QVariant& data ) { m_data = data; } + QString guid() const { if( m_guid.isEmpty() ) @@ -98,6 +101,8 @@ private: State m_state; Tomahawk::source_ptr m_source; mutable QString m_guid; + + QVariant m_data; }; Q_DECLARE_METATYPE( DatabaseCommand ) diff --git a/src/libtomahawk/database/databasecommand_allalbums.cpp b/src/libtomahawk/database/databasecommand_allalbums.cpp index 99af75aff..15aca3ed3 100644 --- a/src/libtomahawk/database/databasecommand_allalbums.cpp +++ b/src/libtomahawk/database/databasecommand_allalbums.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -22,14 +22,13 @@ #include "databaseimpl.h" -void -DatabaseCommand_AllAlbums::exec( DatabaseImpl* dbi ) -{ - Q_ASSERT( !m_collection->source().isNull() ); +void +DatabaseCommand_AllAlbums::execForArtist( DatabaseImpl* dbi ) +{ TomahawkSqlQuery query = dbi->newquery(); QList al; - QString m_orderToken; + QString orderToken, sourceToken; switch ( m_sortOrder ) { @@ -37,22 +36,70 @@ DatabaseCommand_AllAlbums::exec( DatabaseImpl* dbi ) break; case ModificationTime: - m_orderToken = "file.mtime"; + orderToken = "file.mtime"; + } + + if ( !m_collection.isNull() ) + sourceToken = QString( "AND file.source %1 " ).arg( m_collection->source()->isLocal() ? "IS NULL" : QString( "= %1" ).arg( m_collection->source()->id() ) ); + + QString sql = QString( + "SELECT DISTINCT album.id, album.name " + "FROM album, file, file_join " + "WHERE file.id = file_join.file " + "AND file_join.album = album.id " + "AND album.artist = %1 " + "%2 " + "%3 %4 %5" + ).arg( m_artist->id() ) + .arg( sourceToken ) + .arg( m_sortOrder > 0 ? QString( "ORDER BY %1" ).arg( orderToken ) : QString() ) + .arg( m_sortDescending ? "DESC" : QString() ) + .arg( m_amount > 0 ? QString( "LIMIT 0, %1" ).arg( m_amount ) : QString() ); + + query.prepare( sql ); + query.exec(); + + while( query.next() ) + { + Tomahawk::album_ptr album = Tomahawk::Album::get( query.value( 0 ).toUInt(), query.value( 1 ).toString(), m_artist ); + al << album; + } + + if ( al.count() ) + emit albums( al, data() ); + emit done(); +} + + +void +DatabaseCommand_AllAlbums::execForCollection( DatabaseImpl* dbi ) +{ + TomahawkSqlQuery query = dbi->newquery(); + QList al; + QString orderToken; + + switch ( m_sortOrder ) + { + case 0: + break; + + case ModificationTime: + orderToken = "file.mtime"; } QString sql = QString( - "SELECT DISTINCT album.id, album.name, album.artist, artist.name " - "FROM album, file, file_join " - "LEFT OUTER JOIN artist " - "ON album.artist = artist.id " - "WHERE file.id = file_join.file " - "AND file_join.album = album.id " - "AND file.source %1 " - "%2 %3 %4" - ).arg( m_collection->source()->isLocal() ? "IS NULL" : QString( "= %1" ).arg( m_collection->source()->id() ) ) - .arg( m_sortOrder > 0 ? QString( "ORDER BY %1" ).arg( m_orderToken ) : QString() ) - .arg( m_sortDescending ? "DESC" : QString() ) - .arg( m_amount > 0 ? QString( "LIMIT 0, %1" ).arg( m_amount ) : QString() ); + "SELECT DISTINCT album.id, album.name, album.artist, artist.name " + "FROM album, file, file_join " + "LEFT OUTER JOIN artist " + "ON album.artist = artist.id " + "WHERE file.id = file_join.file " + "AND file_join.album = album.id " + "AND file.source %1 " + "%2 %3 %4" + ).arg( m_collection->source()->isLocal() ? "IS NULL" : QString( "= %1" ).arg( m_collection->source()->id() ) ) + .arg( m_sortOrder > 0 ? QString( "ORDER BY %1" ).arg( orderToken ) : QString() ) + .arg( m_sortDescending ? "DESC" : QString() ) + .arg( m_amount > 0 ? QString( "LIMIT 0, %1" ).arg( m_amount ) : QString() ); query.prepare( sql ); query.exec(); @@ -66,6 +113,20 @@ DatabaseCommand_AllAlbums::exec( DatabaseImpl* dbi ) } if ( al.count() ) - emit albums( al, m_collection ); - emit done( m_collection ); + emit albums( al, data() ); + emit done(); +} + + +void +DatabaseCommand_AllAlbums::exec( DatabaseImpl* dbi ) +{ + if ( !m_artist.isNull() ) + { + execForArtist( dbi ); + } + else + { + execForCollection( dbi ); + } } diff --git a/src/libtomahawk/database/databasecommand_allalbums.h b/src/libtomahawk/database/databasecommand_allalbums.h index 501e9ae5e..8520e0d07 100644 --- a/src/libtomahawk/database/databasecommand_allalbums.h +++ b/src/libtomahawk/database/databasecommand_allalbums.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -38,9 +38,10 @@ public: ModificationTime = 1 }; - explicit DatabaseCommand_AllAlbums( const Tomahawk::collection_ptr& collection, QObject* parent = 0 ) + explicit DatabaseCommand_AllAlbums( const Tomahawk::collection_ptr& collection, const Tomahawk::artist_ptr& artist = Tomahawk::artist_ptr(), QObject* parent = 0 ) : DatabaseCommand( parent ) , m_collection( collection ) + , m_artist( artist ) , m_amount( 0 ) , m_sortOrder( DatabaseCommand_AllAlbums::None ) , m_sortDescending( false ) @@ -51,16 +52,21 @@ public: virtual bool doesMutates() const { return false; } virtual QString commandname() const { return "allalbums"; } + void execForCollection( DatabaseImpl* ); + void execForArtist( DatabaseImpl* ); + void setLimit( unsigned int amount ) { m_amount = amount; } void setSortOrder( DatabaseCommand_AllAlbums::SortOrder order ) { m_sortOrder = order; } void setSortDescending( bool descending ) { m_sortDescending = descending; } signals: - void albums( const QList&, const Tomahawk::collection_ptr& ); - void done( const Tomahawk::collection_ptr& ); + void albums( const QList&, const QVariant& data ); + void done(); private: Tomahawk::collection_ptr m_collection; + Tomahawk::artist_ptr m_artist; + unsigned int m_amount; DatabaseCommand_AllAlbums::SortOrder m_sortOrder; bool m_sortDescending; diff --git a/src/libtomahawk/database/databasecommand_allartists.cpp b/src/libtomahawk/database/databasecommand_allartists.cpp new file mode 100644 index 000000000..41b7e3079 --- /dev/null +++ b/src/libtomahawk/database/databasecommand_allartists.cpp @@ -0,0 +1,68 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Christian Muehlhaeuser + * + * Tomahawk 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 3 of the License, or + * (at your option) any later version. + * + * Tomahawk 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#include "databasecommand_allartists.h" + +#include + +#include "databaseimpl.h" + +void +DatabaseCommand_AllArtists::exec( DatabaseImpl* dbi ) +{ + TomahawkSqlQuery query = dbi->newquery(); + QList al; + QString orderToken, sourceToken; + + switch ( m_sortOrder ) + { + case 0: + break; + + case ModificationTime: + orderToken = "file.mtime"; + } + + if ( !m_collection.isNull() ) + sourceToken = QString( "AND file.source %1 " ).arg( m_collection->source()->isLocal() ? "IS NULL" : QString( "= %1" ).arg( m_collection->source()->id() ) ); + + QString sql = QString( + "SELECT DISTINCT artist.id, artist.name " + "FROM artist, file, file_join " + "WHERE file.id = file_join.file " + "AND file_join.artist = artist.id " + "%1 %2 %3 %4" + ).arg( sourceToken ) + .arg( m_sortOrder > 0 ? QString( "ORDER BY %1" ).arg( orderToken ) : QString() ) + .arg( m_sortDescending ? "DESC" : QString() ) + .arg( m_amount > 0 ? QString( "LIMIT 0, %1" ).arg( m_amount ) : QString() ); + + query.prepare( sql ); + query.exec(); + + while( query.next() ) + { + Tomahawk::artist_ptr artist = Tomahawk::Artist::get( query.value( 0 ).toUInt(), query.value( 1 ).toString() ); + + al << artist; + } + + if ( al.count() ) + emit artists( al ); + emit done(); +} diff --git a/src/libtomahawk/database/databasecommand_allartists.h b/src/libtomahawk/database/databasecommand_allartists.h new file mode 100644 index 000000000..6d13a107c --- /dev/null +++ b/src/libtomahawk/database/databasecommand_allartists.h @@ -0,0 +1,69 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Christian Muehlhaeuser + * + * Tomahawk 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 3 of the License, or + * (at your option) any later version. + * + * Tomahawk 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#ifndef DATABASECOMMAND_ALLARTISTS_H +#define DATABASECOMMAND_ALLARTISTS_H + +#include +#include + +#include "databasecommand.h" +#include "album.h" +#include "collection.h" +#include "typedefs.h" + +#include "dllmacro.h" + +class DLLEXPORT DatabaseCommand_AllArtists : public DatabaseCommand +{ +Q_OBJECT +public: + enum SortOrder { + None = 0, + ModificationTime = 1 + }; + + explicit DatabaseCommand_AllArtists( const Tomahawk::collection_ptr& collection = Tomahawk::collection_ptr(), QObject* parent = 0 ) + : DatabaseCommand( parent ) + , m_collection( collection ) + , m_amount( 0 ) + , m_sortOrder( DatabaseCommand_AllArtists::None ) + , m_sortDescending( false ) + {} + + virtual void exec( DatabaseImpl* ); + + virtual bool doesMutates() const { return false; } + virtual QString commandname() const { return "allartists"; } + + void setLimit( unsigned int amount ) { m_amount = amount; } + void setSortOrder( DatabaseCommand_AllArtists::SortOrder order ) { m_sortOrder = order; } + void setSortDescending( bool descending ) { m_sortDescending = descending; } + +signals: + void artists( const QList& ); + void done(); + +private: + Tomahawk::collection_ptr m_collection; + unsigned int m_amount; + DatabaseCommand_AllArtists::SortOrder m_sortOrder; + bool m_sortDescending; +}; + +#endif // DATABASECOMMAND_ALLARTISTS_H diff --git a/src/libtomahawk/database/databasecommand_alltracks.cpp b/src/libtomahawk/database/databasecommand_alltracks.cpp index 8e2548a3c..57ebf3afa 100644 --- a/src/libtomahawk/database/databasecommand_alltracks.cpp +++ b/src/libtomahawk/database/databasecommand_alltracks.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -51,7 +51,6 @@ DatabaseCommand_AllTracks::exec( DatabaseImpl* dbi ) break; } - if ( !m_collection.isNull() ) sourceToken = QString( "AND file.source %1" ).arg( m_collection->source()->isLocal() ? "IS NULL" : QString( "= %1" ).arg( m_collection->source()->id() ) ); @@ -138,12 +137,12 @@ DatabaseCommand_AllTracks::exec( DatabaseImpl* dbi ) results << result; qry->addResults( results ); qry->setResolveFinished( true ); - + ql << qry; } qDebug() << Q_FUNC_INFO << ql.length(); - emit tracks( ql ); + emit tracks( ql, data() ); emit done( m_collection ); } diff --git a/src/libtomahawk/database/databasecommand_alltracks.h b/src/libtomahawk/database/databasecommand_alltracks.h index 5b8981aed..335c11585 100644 --- a/src/libtomahawk/database/databasecommand_alltracks.h +++ b/src/libtomahawk/database/databasecommand_alltracks.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -63,7 +63,7 @@ public: void setSortDescending( bool descending ) { m_sortDescending = descending; } signals: - void tracks( const QList& ); + void tracks( const QList&, const QVariant& data ); void done( const Tomahawk::collection_ptr& ); private: diff --git a/src/libtomahawk/playlist/albummodel.cpp b/src/libtomahawk/playlist/albummodel.cpp index 6be94ee1a..8a1d36cb2 100644 --- a/src/libtomahawk/playlist/albummodel.cpp +++ b/src/libtomahawk/playlist/albummodel.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -262,8 +262,8 @@ AlbumModel::addFilteredCollection( const collection_ptr& collection, unsigned in cmd->setSortOrder( order ); cmd->setSortDescending( true ); - connect( cmd, SIGNAL( albums( QList, Tomahawk::collection_ptr ) ), - SLOT( onAlbumsAdded( QList, Tomahawk::collection_ptr ) ) ); + connect( cmd, SIGNAL( albums( QList ) ), + SLOT( onAlbumsAdded( QList ) ) ); Database::instance()->enqueue( QSharedPointer( cmd ) ); @@ -272,7 +272,7 @@ AlbumModel::addFilteredCollection( const collection_ptr& collection, unsigned in void -AlbumModel::onAlbumsAdded( const QList& albums, const Tomahawk::collection_ptr& collection ) +AlbumModel::onAlbumsAdded( const QList& albums ) { Q_UNUSED( collection ); if ( !albums.count() ) diff --git a/src/libtomahawk/playlist/albummodel.h b/src/libtomahawk/playlist/albummodel.h index fd9361b60..ae8658e19 100644 --- a/src/libtomahawk/playlist/albummodel.h +++ b/src/libtomahawk/playlist/albummodel.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -69,7 +69,7 @@ public: virtual QString description() const { return m_description; } virtual void setTitle( const QString& title ) { m_title = title; } virtual void setDescription( const QString& description ) { m_description = description; } - + AlbumItem* itemFromIndex( const QModelIndex& index ) const { if ( index.isValid() ) @@ -93,7 +93,7 @@ signals: protected: private slots: - void onAlbumsAdded( const QList& albums, const Tomahawk::collection_ptr& collection ); + void onAlbumsAdded( const QList& albums ); void onCoverArtDownloaded(); void onDataChanged(); diff --git a/src/libtomahawk/playlist/artistview.cpp b/src/libtomahawk/playlist/artistview.cpp new file mode 100644 index 000000000..ab79538b4 --- /dev/null +++ b/src/libtomahawk/playlist/artistview.cpp @@ -0,0 +1,152 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Christian Muehlhaeuser + * + * Tomahawk 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 3 of the License, or + * (at your option) any later version. + * + * Tomahawk 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#include "artistview.h" + +#include +#include +#include +#include +#include + +#include "audio/audioengine.h" + +#include "tomahawksettings.h" +#include "treeitemdelegate.h" +#include "playlistmanager.h" + +using namespace Tomahawk; + + +ArtistView::ArtistView( QWidget* parent ) + : QTreeView( parent ) + , m_model( 0 ) + , m_proxyModel( 0 ) +// , m_delegate( 0 ) +{ + setDragEnabled( true ); + setDropIndicatorShown( false ); + setDragDropOverwriteMode( false ); + setUniformRowHeights( false ); + setVerticalScrollMode( QAbstractItemView::ScrollPerPixel ); + setRootIsDecorated( true ); + + setProxyModel( new TreeProxyModel( this ) ); + + connect( this, SIGNAL( doubleClicked( QModelIndex ) ), SLOT( onItemActivated( QModelIndex ) ) ); +} + + +ArtistView::~ArtistView() +{ + qDebug() << Q_FUNC_INFO; +} + + +void +ArtistView::setProxyModel( TreeProxyModel* model ) +{ + m_proxyModel = model; + setItemDelegate( new TreeItemDelegate( this, m_proxyModel ) ); + + QTreeView::setModel( m_proxyModel ); +} + + +void +ArtistView::setModel( TreeModel* model ) +{ + m_model = model; + + if ( m_proxyModel ) + { + m_proxyModel->setSourceModel( model ); + m_proxyModel->sort( 0 ); + } + + connect( m_proxyModel, SIGNAL( filterChanged( QString ) ), SLOT( onFilterChanged( QString ) ) ); + + setAcceptDrops( false ); +} + + +void +ArtistView::onItemActivated( const QModelIndex& index ) +{ + TreeModelItem* item = m_model->itemFromIndex( m_proxyModel->mapToSource( index ) ); + if ( item ) + { + if ( !item->artist().isNull() ) + PlaylistManager::instance()->show( item->artist() ); + else if ( !item->album().isNull() ) + PlaylistManager::instance()->show( item->album() ); + else if ( !item->result().isNull() ) + AudioEngine::instance()->playItem( 0, item->result() ); + } +} + + +void +ArtistView::dragEnterEvent( QDragEnterEvent* event ) +{ + qDebug() << Q_FUNC_INFO; + QTreeView::dragEnterEvent( event ); +} + + +void +ArtistView::dragMoveEvent( QDragMoveEvent* event ) +{ + QTreeView::dragMoveEvent( event ); +} + + +void +ArtistView::dropEvent( QDropEvent* event ) +{ + QTreeView::dropEvent( event ); +} + + +void +ArtistView::paintEvent( QPaintEvent* event ) +{ + QTreeView::paintEvent( event ); +} + + +void +ArtistView::onFilterChanged( const QString& ) +{ + if ( selectedIndexes().count() ) + scrollTo( selectedIndexes().at( 0 ), QAbstractItemView::PositionAtCenter ); +} + + +void +ArtistView::startDrag( Qt::DropActions supportedActions ) +{ +} + + +// Inspired from dolphin's draganddrophelper.cpp +QPixmap +ArtistView::createDragPixmap( int itemCount ) const +{ + return QPixmap(); +} diff --git a/src/libtomahawk/playlist/artistview.h b/src/libtomahawk/playlist/artistview.h new file mode 100644 index 000000000..e22205c24 --- /dev/null +++ b/src/libtomahawk/playlist/artistview.h @@ -0,0 +1,79 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Christian Muehlhaeuser + * + * Tomahawk 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 3 of the License, or + * (at your option) any later version. + * + * Tomahawk 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#ifndef ARTISTVIEW_H +#define ARTISTVIEW_H + +#include +#include + +#include "treemodel.h" +#include "treeproxymodel.h" +#include "viewpage.h" + +#include "dllmacro.h" + +class DLLEXPORT ArtistView : public QTreeView, public Tomahawk::ViewPage +{ +Q_OBJECT + +public: + explicit ArtistView( QWidget* parent = 0 ); + ~ArtistView(); + + void setProxyModel( TreeProxyModel* model ); + + TreeModel* model() const { return m_model; } + TreeProxyModel* proxyModel() const { return m_proxyModel; } +// PlaylistItemDelegate* delegate() { return m_delegate; } + + void setModel( TreeModel* model ); + + virtual QWidget* widget() { return this; } + virtual PlaylistInterface* playlistInterface() const { return proxyModel(); } + + virtual QString title() const { return m_model->title(); } + virtual QString description() const { return m_model->description(); } + + virtual bool showModes() const { return true; } + + virtual bool jumpToCurrentTrack() { return false; } + +public slots: + void onItemActivated( const QModelIndex& index ); + +protected: + virtual void startDrag( Qt::DropActions supportedActions ); + virtual void dragEnterEvent( QDragEnterEvent* event ); + virtual void dragMoveEvent( QDragMoveEvent* event ); + virtual void dropEvent( QDropEvent* event ); + + void paintEvent( QPaintEvent* event ); + +private slots: + void onFilterChanged( const QString& filter ); + +private: + QPixmap createDragPixmap( int itemCount ) const; + + TreeModel* m_model; + TreeProxyModel* m_proxyModel; +// PlaylistItemDelegate* m_delegate; +}; + +#endif // ARTISTVIEW_H diff --git a/src/libtomahawk/playlist/playlistmanager.cpp b/src/libtomahawk/playlist/playlistmanager.cpp index 6eefc11d4..52a08c778 100644 --- a/src/libtomahawk/playlist/playlistmanager.cpp +++ b/src/libtomahawk/playlist/playlistmanager.cpp @@ -101,12 +101,12 @@ PlaylistManager::PlaylistManager( QObject* parent ) m_widget->layout()->addWidget( line ); m_widget->layout()->addWidget( m_splitter ); - m_superCollectionView = new CollectionView(); - m_superCollectionFlatModel = new CollectionFlatModel( m_superCollectionView ); - m_superCollectionView->setTrackModel( m_superCollectionFlatModel ); + m_superCollectionView = new ArtistView(); + m_superCollectionModel = new TreeModel( m_superCollectionView ); + m_superCollectionView->setModel( m_superCollectionModel ); m_superCollectionView->setFrameShape( QFrame::NoFrame ); m_superCollectionView->setAttribute( Qt::WA_MacShowFocusRect, 0 ); - m_superCollectionView->proxyModel()->setShowOfflineResults( false ); +// m_superCollectionView->proxyModel()->setShowOfflineResults( false ); m_superAlbumView = new AlbumView(); m_superAlbumModel = new AlbumModel( m_superAlbumView ); @@ -371,19 +371,19 @@ PlaylistManager::show( ViewPage* page ) bool PlaylistManager::showSuperCollection() { - QList< collection_ptr > toAdd; + if ( m_superCollections.isEmpty() ) + m_superCollectionModel->addAllCollections(); + foreach( const Tomahawk::source_ptr& source, SourceList::instance()->sources() ) { if ( !m_superCollections.contains( source->collection() ) ) { m_superCollections.append( source->collection() ); - toAdd << source->collection(); - m_superAlbumModel->addCollection( source->collection() ); +// m_superAlbumModel->addCollection( source->collection() ); } } - m_superCollectionFlatModel->addCollections( toAdd ); - m_superCollectionFlatModel->setTitle( tr( "All available tracks" ) ); + m_superCollectionModel->setTitle( tr( "All available tracks" ) ); m_superAlbumModel->setTitle( tr( "All available albums" ) ); if ( m_currentMode == 0 ) diff --git a/src/libtomahawk/playlist/playlistmanager.h b/src/libtomahawk/playlist/playlistmanager.h index bceb89d08..8ccf91f9d 100644 --- a/src/libtomahawk/playlist/playlistmanager.h +++ b/src/libtomahawk/playlist/playlistmanager.h @@ -162,8 +162,8 @@ private: AlbumModel* m_superAlbumModel; AlbumView* m_superAlbumView; - CollectionFlatModel* m_superCollectionFlatModel; - CollectionView* m_superCollectionView; + TreeModel* m_superCollectionModel; + ArtistView* m_superCollectionView; WelcomeWidget* m_welcomeWidget; QList< Tomahawk::collection_ptr > m_superCollections; diff --git a/src/libtomahawk/playlist/treeheader.cpp b/src/libtomahawk/playlist/treeheader.cpp new file mode 100644 index 000000000..12ca97c04 --- /dev/null +++ b/src/libtomahawk/playlist/treeheader.cpp @@ -0,0 +1,145 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Christian Muehlhaeuser + * + * Tomahawk 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 3 of the License, or + * (at your option) any later version. + * + * Tomahawk 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#include "treeheader.h" + +#include +#include +#include + +#include "tomahawksettings.h" +#include "playlist/treemodel.h" +#include "playlist/artistview.h" + + +TreeHeader::TreeHeader( ArtistView* parent ) + : QHeaderView( Qt::Horizontal, parent ) + , m_parent( parent ) + , m_menu( new QMenu( this ) ) + , m_sigmap( new QSignalMapper( this ) ) + , m_init( false ) +{ + setResizeMode( QHeaderView::Interactive ); + setMinimumSectionSize( 60 ); + setDefaultAlignment( Qt::AlignLeft ); + setMovable( true ); + setStretchLastSection( true ); +// setCascadingSectionResizes( true ); + +// m_menu->addAction( tr( "Resize columns to fit window" ), this, SLOT( onToggleResizeColumns() ) ); +// m_menu->addSeparator(); + + connect( this, SIGNAL( sectionResized( int, int, int ) ), SLOT( onSectionResized() ) ); + connect( m_sigmap, SIGNAL( mapped( int ) ), SLOT( toggleVisibility( int ) ) ); +} + + +TreeHeader::~TreeHeader() +{ +} + + +void +TreeHeader::onSectionResized() +{ + if ( !m_init ) + return; + +// TomahawkSettings::instance()->setPlaylistColumnSizes( m_parent->guid(), saveState() ); +} + + +int +TreeHeader::visibleSectionCount() const +{ + return count() - hiddenSectionCount(); +} + + +void +TreeHeader::checkState() +{ + if ( !count() || m_init ) + return; + +/* QByteArray state = TomahawkSettings::instance()->playlistColumnSizes( m_parent->guid() ); + if ( !state.isEmpty() ) + restoreState( state ); + else + { + QList< double > m_columnWeights; + m_columnWeights << 0.21 << 0.22 << 0.20 << 0.05 << 0.05 << 0.05 << 0.05 << 0.05; // << 0.12; + + for ( int i = 0; i < count() - 1; i++ ) + { + if ( isSectionHidden( i ) ) + continue; + + double nw = (double)m_parent->width() * m_columnWeights.at( i ); + qDebug() << "Setting default size:" << i << nw; + resizeSection( i, qMax( minimumSectionSize(), int( nw - 0.5 ) ) ); + } + } + + m_init = true;*/ +} + + +void +TreeHeader::addColumnToMenu( int index ) +{ + QString title = m_parent->model()->headerData( index, Qt::Horizontal, Qt::DisplayRole ).toString(); + + QAction* action = m_menu->addAction( title, m_sigmap, SLOT( map() ) ); + action->setCheckable( true ); + action->setChecked( !isSectionHidden( index ) ); + m_visActions << action; + + m_sigmap->setMapping( action, index ); +} + + +void +TreeHeader::contextMenuEvent( QContextMenuEvent* e ) +{ + qDeleteAll( m_visActions ); + m_visActions.clear(); + + for ( int i = 0; i < count(); i++ ) + addColumnToMenu( i ); + + m_menu->popup( e->globalPos() ); +} + + +void +TreeHeader::onToggleResizeColumns() +{ +} + + +void +TreeHeader::toggleVisibility( int index ) +{ + qDebug() << Q_FUNC_INFO << index; + + if ( isSectionHidden( index ) ) + showSection( index ); + else + hideSection( index ); +} diff --git a/src/libtomahawk/playlist/treeheader.h b/src/libtomahawk/playlist/treeheader.h new file mode 100644 index 000000000..73a81ada6 --- /dev/null +++ b/src/libtomahawk/playlist/treeheader.h @@ -0,0 +1,61 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Christian Muehlhaeuser + * + * Tomahawk 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 3 of the License, or + * (at your option) any later version. + * + * Tomahawk 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#ifndef TREEHEADER_H +#define TREEHEADER_H + +#include +#include + +#include "dllmacro.h" + +class ArtistView; + +class DLLEXPORT TreeHeader : public QHeaderView +{ +Q_OBJECT + +public: + explicit TreeHeader( ArtistView* parent = 0 ); + ~TreeHeader(); + + int visibleSectionCount() const; + +public slots: + void toggleVisibility( int index ); + void checkState(); + +protected: + void contextMenuEvent( QContextMenuEvent* e ); + +private slots: + void onSectionResized(); + void onToggleResizeColumns(); + +private: + void addColumnToMenu( int index ); + + ArtistView* m_parent; + + QMenu* m_menu; + QSignalMapper* m_sigmap; + QList m_visActions; + bool m_init; +}; + +#endif diff --git a/src/libtomahawk/playlist/treeitemdelegate.cpp b/src/libtomahawk/playlist/treeitemdelegate.cpp new file mode 100644 index 000000000..fbc1fa16b --- /dev/null +++ b/src/libtomahawk/playlist/treeitemdelegate.cpp @@ -0,0 +1,101 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Christian Muehlhaeuser + * + * Tomahawk 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 3 of the License, or + * (at your option) any later version. + * + * Tomahawk 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#include "treeitemdelegate.h" + +#include +#include +#include +#include + +#include "query.h" +#include "result.h" + +#include "utils/tomahawkutils.h" + +#include "treemodelitem.h" +#include "treeproxymodel.h" + + +TreeItemDelegate::TreeItemDelegate( QAbstractItemView* parent, TreeProxyModel* proxy ) + : QStyledItemDelegate( (QObject*)parent ) + , m_view( parent ) + , m_model( proxy ) +{ +} + + +QSize +TreeItemDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const +{ + QSize size = QStyledItemDelegate::sizeHint( option, index ); + return size; +} + + +void +TreeItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const +{ + TreeModelItem* item = m_model->sourceModel()->itemFromIndex( m_model->mapToSource( index ) ); + if ( !item ) + return; + + QString text; + if ( !item->artist().isNull() ) + { + text = item->artist()->name(); + } + else if ( !item->album().isNull() ) + { + text = item->album()->name(); + } + else if ( !item->result().isNull() ) + { + return QStyledItemDelegate::paint( painter, option, index ); + } + + QStyleOptionViewItemV4 opt = option; + initStyleOption( &opt, QModelIndex() ); + qApp->style()->drawControl( QStyle::CE_ItemViewItem, &opt, painter ); + + if ( option.state & QStyle::State_Selected ) + { + opt.palette.setColor( QPalette::Text, opt.palette.color( QPalette::HighlightedText ) ); + } + + painter->save(); + painter->setRenderHint( QPainter::Antialiasing ); + painter->setPen( opt.palette.color( QPalette::Text ) ); + + QRect r = option.rect.adjusted( 4, 4, -option.rect.width() + option.rect.height() - 8, -4 ); +// painter->drawPixmap( option.rect.adjusted( 4, 4, -4, -38 ), QPixmap( RESPATH "images/cover-shadow.png" ) ); + painter->drawPixmap( r, item->cover ); + + QTextOption to; + to.setAlignment( Qt::AlignVCenter ); + QFont font = opt.font; + QFont boldFont = opt.font; + boldFont.setBold( true ); + + r = option.rect.adjusted( option.rect.height(), 6, 0, -option.rect.height() + 22 ); + painter->drawText( r, text, to ); + + painter->setFont( boldFont ); + + painter->restore(); +} diff --git a/src/libtomahawk/playlist/treeitemdelegate.h b/src/libtomahawk/playlist/treeitemdelegate.h new file mode 100644 index 000000000..234b0d326 --- /dev/null +++ b/src/libtomahawk/playlist/treeitemdelegate.h @@ -0,0 +1,46 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Christian Muehlhaeuser + * + * Tomahawk 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 3 of the License, or + * (at your option) any later version. + * + * Tomahawk 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#ifndef TREEITEMDELEGATE_H +#define TREEITEMDELEGATE_H + +#include + +#include "dllmacro.h" + +class TreeProxyModel; + +class DLLEXPORT TreeItemDelegate : public QStyledItemDelegate +{ +Q_OBJECT + +public: + TreeItemDelegate( QAbstractItemView* parent = 0, TreeProxyModel* proxy = 0 ); + +protected: + void paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const; + QSize sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const; + +// QWidget* createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const; + +private: + QAbstractItemView* m_view; + TreeProxyModel* m_model; +}; + +#endif // TREEITEMDELEGATE_H diff --git a/src/libtomahawk/playlist/treemodel.cpp b/src/libtomahawk/playlist/treemodel.cpp index 814134dbb..86dc33077 100644 --- a/src/libtomahawk/playlist/treemodel.cpp +++ b/src/libtomahawk/playlist/treemodel.cpp @@ -19,22 +19,36 @@ #include "treemodel.h" #include +#include #include -#include +#include -#include "sourcelist.h" +#include "database/databasecommand_allalbums.h" +#include "database/databasecommand_alltracks.h" +#include "database/database.h" #include "utils/tomahawkutils.h" +#define LASTFM_DEFAULT_COVER "http://cdn.last.fm/flatness/catalogue/noimage" + +static QString s_infoIdentifier = QString( "TREEMODEL" ); + using namespace Tomahawk; TreeModel::TreeModel( QObject* parent ) : QAbstractItemModel( parent ) - , m_rootItem( 0 ) + , m_rootItem( new TreeModelItem( 0, this ) ) { qDebug() << Q_FUNC_INFO; - connect( SourceList::instance(), SIGNAL( sourceRemoved( Tomahawk::source_ptr ) ), SLOT( onSourceOffline( Tomahawk::source_ptr ) ) ); + m_defaultCover = QPixmap( RESPATH "images/no-album-art-placeholder.png" ) + .scaled( QSize( 120, 120 ), Qt::IgnoreAspectRatio, Qt::SmoothTransformation ); + +/* connect( TomahawkApp::instance()->infoSystem(), + SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ), + SLOT( infoSystemInfo( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ) ); + + connect( TomahawkApp::instance()->infoSystem(), SIGNAL( finished( QString ) ), SLOT( infoSystemFinished( QString ) ) );*/ } @@ -58,6 +72,52 @@ TreeModel::index( int row, int column, const QModelIndex& parent ) const } +bool +TreeModel::canFetchMore( const QModelIndex& parent ) const +{ + TreeModelItem* parentItem = itemFromIndex( parent ); + + if ( parentItem->fetchingMore ) + return false; + + if ( !parentItem->artist().isNull() ) + { + return true; + } + else if ( !parentItem->album().isNull() ) + { + return true; + } + + return false; +} + + +void +TreeModel::fetchMore( const QModelIndex& parent ) +{ + qDebug() << Q_FUNC_INFO; + + TreeModelItem* parentItem = itemFromIndex( parent ); + if ( !parentItem || parentItem->fetchingMore ) + return; + + parentItem->fetchingMore = true; + if ( !parentItem->artist().isNull() ) + { + qDebug() << "Artist" << parentItem->artist()->name(); + addAlbums( parentItem->artist(), parent ); + } + else if ( !parentItem->album().isNull() ) + { + qDebug() << "Artist" << parentItem->album()->name(); + addTracks( parentItem->album(), parent ); + } + else + qDebug() << "Something else"; +} + + int TreeModel::rowCount( const QModelIndex& parent ) const { @@ -68,6 +128,12 @@ TreeModel::rowCount( const QModelIndex& parent ) const if ( !parentItem ) return 0; + if ( !parentItem->artist().isNull() || !parentItem->album().isNull() ) + { + if ( !parentItem->children.count() ) + return 1; + } + return parentItem->children.count(); } @@ -103,58 +169,43 @@ TreeModel::parent( const QModelIndex& child ) const QVariant TreeModel::data( const QModelIndex& index, int role ) const { - if ( role != Qt::DisplayRole ) - return QVariant(); - TreeModelItem* entry = itemFromIndex( index ); if ( !entry ) return QVariant(); - const query_ptr& query = entry->query(); - if ( query.isNull() ) + if ( role == Qt::SizeHintRole ) { - if ( !index.column() ) + if ( !entry->result().isNull() ) { - return entry->caption.isEmpty() ? "Unknown" : entry->caption; + return QSize( 128, 20 ); + } + else if ( !entry->album().isNull() ) + { + return QSize( 128, 32 ); } - if ( index.column() == 1 ) - { - return entry->childCount; - } - - return QVariant( "" ); + return QSize( 128, 44 ); } - if ( !query->numResults() ) + if ( role != Qt::DisplayRole ) // && role != Qt::ToolTipRole ) + return QVariant(); + + switch( index.column() ) { - switch( index.column() ) - { - case 0: - return query->track(); - break; - } - } - else - { - switch( index.column() ) - { - case 0: - return query->results().first()->track(); - break; - - case 1: - return QVariant(); - break; - - case 2: - return TomahawkUtils::timeToString( query->results().first()->duration() ); - break; - - case 3: - return query->results().first()->collection()->source()->friendlyName(); - break; - } + case 0: + if ( !entry->artist().isNull() ) + { + return entry->artist()->name(); + } + else if ( !entry->artist().isNull() ) + { + return entry->album()->name(); + } + else if ( !entry->result().isNull() ) + { + return entry->result()->track(); + } + break; } return QVariant(); @@ -165,7 +216,7 @@ QVariant TreeModel::headerData( int section, Qt::Orientation orientation, int role ) const { QStringList headers; - headers << tr( "Name" ) << tr( "Tracks" ) << tr( "Duration" ) << tr( "Origin" ); + headers << tr( "Artist" ); if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 ) { return headers.at( section ); @@ -175,29 +226,136 @@ TreeModel::headerData( int section, Qt::Orientation orientation, int role ) cons } -void -TreeModel::setCurrentItem( const QModelIndex& index ) +Qt::ItemFlags +TreeModel::flags( const QModelIndex& index ) const +{ + Qt::ItemFlags defaultFlags = QAbstractItemModel::flags( index ); + + if ( index.isValid() && index.column() == 0 ) + return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags; + else + return defaultFlags; +} + + +QStringList +TreeModel::mimeTypes() const +{ + QStringList types; + types << "application/tomahawk.query.list"; + return types; +} + + +QMimeData* +TreeModel::mimeData( const QModelIndexList &indexes ) const { qDebug() << Q_FUNC_INFO; - TreeModelItem* oldEntry = itemFromIndex( m_currentIndex ); - if ( oldEntry ) + + QByteArray queryData; + QDataStream queryStream( &queryData, QIODevice::WriteOnly ); + + foreach ( const QModelIndex& i, indexes ) { - oldEntry->setIsPlaying( false ); + if ( i.column() > 0 ) + continue; + + QModelIndex idx = index( i.row(), 0, i.parent() ); + TreeModelItem* item = itemFromIndex( idx ); + if ( item ) + { + const album_ptr& album = item->album(); + queryStream << qlonglong( &album ); + } } - TreeModelItem* entry = itemFromIndex( index ); - if ( entry ) + QMimeData* mimeData = new QMimeData(); + mimeData->setData( "application/tomahawk.query.list", queryData ); + + return mimeData; +} + + +void +TreeModel::removeIndex( const QModelIndex& index ) +{ + qDebug() << Q_FUNC_INFO; + + if ( index.column() > 0 ) + return; + + TreeModelItem* item = itemFromIndex( index ); + if ( item ) { - m_currentIndex = index; - entry->setIsPlaying( true ); + emit beginRemoveRows( index.parent(), index.row(), index.row() ); + delete item; + emit endRemoveRows(); } - else +} + + +void +TreeModel::removeIndexes( const QList& indexes ) +{ + foreach( const QModelIndex& idx, indexes ) { - m_currentIndex = QModelIndex(); + removeIndex( idx ); } } +void +TreeModel::addAllCollections() +{ + qDebug() << Q_FUNC_INFO; + + DatabaseCommand_AllArtists* cmd = new DatabaseCommand_AllArtists(); + + connect( cmd, SIGNAL( artists( QList ) ), + SLOT( onArtistsAdded( QList ) ) ); + + Database::instance()->enqueue( QSharedPointer( cmd ) ); + + m_title = tr( "All Artists" ); +} + + +void +TreeModel::addAlbums( const artist_ptr& artist, const QModelIndex& parent ) +{ + qDebug() << Q_FUNC_INFO; + + DatabaseCommand_AllAlbums* cmd = new DatabaseCommand_AllAlbums( m_collection, artist ); + cmd->setData( parent.row() ); + + connect( cmd, SIGNAL( albums( QList, QVariant ) ), + SLOT( onAlbumsAdded( QList, QVariant ) ) ); + + Database::instance()->enqueue( QSharedPointer( cmd ) ); +} + + +void +TreeModel::addTracks( const album_ptr& album, const QModelIndex& parent ) +{ + qDebug() << Q_FUNC_INFO; + + DatabaseCommand_AllTracks* cmd = new DatabaseCommand_AllTracks( m_collection ); + cmd->setAlbum( album.data() ); + + QList< QVariant > rows; + rows << parent.row(); + rows << parent.parent().row(); + + cmd->setData( QVariant( rows ) ); + + connect( cmd, SIGNAL( tracks( QList, QVariant ) ), + SLOT( onTracksAdded( QList, QVariant ) ) ); + + Database::instance()->enqueue( QSharedPointer( cmd ) ); +} + + void TreeModel::addCollection( const collection_ptr& collection ) { @@ -205,106 +363,200 @@ TreeModel::addCollection( const collection_ptr& collection ) << collection->source()->id() << collection->source()->userName(); - emit loadingStarts(); + m_collection = collection; + DatabaseCommand_AllArtists* cmd = new DatabaseCommand_AllArtists( collection ); - connect( collection.data(), SIGNAL( tracksAdded( QList, Tomahawk::collection_ptr ) ), - SLOT( onTracksAdded( QList, Tomahawk::collection_ptr ) ) ); - connect( collection.data(), SIGNAL( tracksFinished( Tomahawk::collection_ptr ) ), - SLOT( onTracksAddingFinished( Tomahawk::collection_ptr ) ) ); + connect( cmd, SIGNAL( artists( QList ) ), + SLOT( onArtistsAdded( QList ) ) ); + + Database::instance()->enqueue( QSharedPointer( cmd ) ); + + m_title = tr( "All artists from %1" ).arg( collection->source()->friendlyName() ); } void -TreeModel::removeCollection( const collection_ptr& collection ) +TreeModel::addFilteredCollection( const collection_ptr& collection, unsigned int amount, DatabaseCommand_AllArtists::SortOrder order ) { - disconnect( collection.data(), SIGNAL( tracksAdded( QList, Tomahawk::collection_ptr ) ), - this, SLOT( onTracksAdded( QList, Tomahawk::collection_ptr ) ) ); - disconnect( collection.data(), SIGNAL( tracksFinished( Tomahawk::collection_ptr ) ), - this, SLOT( onTracksAddingFinished( Tomahawk::collection_ptr ) ) ); + qDebug() << Q_FUNC_INFO << collection->name() + << collection->source()->id() + << collection->source()->userName() + << amount << order; - QList plitems = m_collectionIndex.values( collection ); + DatabaseCommand_AllArtists* cmd = new DatabaseCommand_AllArtists( collection ); + cmd->setLimit( amount ); + cmd->setSortOrder( order ); + cmd->setSortDescending( true ); - m_collectionIndex.remove( collection ); + connect( cmd, SIGNAL( artists( QList, Tomahawk::collection_ptr ) ), + SLOT( onArtistsAdded( QList, Tomahawk::collection_ptr ) ) ); + + Database::instance()->enqueue( QSharedPointer( cmd ) ); + + m_title = tr( "All albums from %1" ).arg( collection->source()->friendlyName() ); } void -TreeModel::onTracksAdded( const QList& tracks, const collection_ptr& collection ) +TreeModel::onArtistsAdded( const QList& artists ) { -// int c = rowCount( QModelIndex() ); + if ( !artists.count() ) + return; - TreeModelItem* plitem; - foreach( const Tomahawk::query_ptr& query, tracks ) + int c = rowCount( QModelIndex() ); + QPair< int, int > crows; + crows.first = c; + crows.second = c + artists.count() - 1; + + emit beginInsertRows( QModelIndex(), crows.first, crows.second ); + + TreeModelItem* artistitem; + foreach( const artist_ptr& artist, artists ) { - TreeModelItem* parent = m_rootItem; - if ( parent->hash.contains( query->artist() ) ) - { - parent = parent->hash.value( query->artist() ); - } - else - { - parent = new TreeModelItem( query->artist(), m_rootItem ); - m_rootItem->hash.insert( query->artist(), parent ); - } + qDebug() << artist->name(); + artistitem = new TreeModelItem( artist, m_rootItem ); + artistitem->cover = m_defaultCover; + artistitem->index = createIndex( m_rootItem->children.count() - 1, 0, artistitem ); - if ( parent->hash.contains( query->album() ) ) - { - parent->childCount++; - parent = parent->hash.value( query->album() ); - parent->childCount++; - } - else - { - TreeModelItem* subitem = new TreeModelItem( query->album(), parent ); - parent->hash.insert( query->album(), subitem ); - parent->childCount++; - subitem->childCount++; - parent = subitem; - } - - plitem = new TreeModelItem( query, parent ); - m_collectionIndex.insertMulti( collection, plitem ); + connect( artistitem, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) ); } - reset(); - + emit endInsertRows(); qDebug() << rowCount( QModelIndex() ); } void -TreeModel::onTracksAddingFinished( const Tomahawk::collection_ptr& collection ) +TreeModel::onAlbumsAdded( const QList& albums, const QVariant& data ) { - qDebug() << "Finished loading tracks" << collection->source()->friendlyName(); + qDebug() << Q_FUNC_INFO << albums.count(); + if ( !albums.count() ) + return; - disconnect( collection.data(), SIGNAL( tracksAdded( QList, Tomahawk::collection_ptr ) ), - this, SLOT( onTracksAdded( QList, Tomahawk::collection_ptr ) ) ); - disconnect( collection.data(), SIGNAL( tracksFinished( Tomahawk::collection_ptr ) ), - this, SLOT( onTracksAddingFinished( Tomahawk::collection_ptr ) ) ); + QModelIndex parent = index( data.toUInt(), 0, QModelIndex() ); + TreeModelItem* parentItem = itemFromIndex( parent ); - emit loadingFinished(); + // the -1 is because we fake a rowCount of 1 to trigger Qt calling fetchMore() + int c = rowCount( parent ) - 1; + QPair< int, int > crows; + crows.first = c; + crows.second = c + albums.count() - 1; + + if ( crows.second > 0 ) + emit beginInsertRows( parent, crows.first + 1, crows.second ); + + TreeModelItem* albumitem; + foreach( const album_ptr& album, albums ) + { + albumitem = new TreeModelItem( album, parentItem ); + albumitem->cover = m_defaultCover; + albumitem->index = createIndex( parentItem->children.count() - 1, 0, albumitem ); + connect( albumitem, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) ); + +/* Tomahawk::InfoSystem::InfoCustomData trackInfo; + trackInfo["artist"] = QVariant::fromValue< QString >( album->artist()->name() ); + trackInfo["album"] = QVariant::fromValue< QString >( album->name() ); + trackInfo["pptr"] = (qlonglong)albumitem; + + TomahawkApp::instance()->infoSystem()->getInfo( + s_infoIdentifier, Tomahawk::InfoSystem::InfoAlbumCoverArt, + QVariant::fromValue< Tomahawk::InfoSystem::InfoCustomData >( trackInfo ), Tomahawk::InfoSystem::InfoCustomData() );*/ + } + + if ( crows.second > 0 ) + emit endInsertRows(); + else + emit dataChanged( albumitem->index, albumitem->index.sibling( albumitem->index.row(), columnCount( QModelIndex() ) - 1 ) ); + + qDebug() << rowCount( parent ); } void -TreeModel::onSourceOffline( Tomahawk::source_ptr src ) +TreeModel::onTracksAdded( const QList& tracks, const QVariant& data ) +{ + qDebug() << Q_FUNC_INFO << tracks.count(); + if ( !tracks.count() ) + return; + + QList< QVariant > rows = data.toList(); + + QModelIndex parent = index( rows.first().toUInt(), 0, index( rows.at( 1 ).toUInt(), 0, QModelIndex() ) ); + TreeModelItem* parentItem = itemFromIndex( parent ); + + // the -1 is because we fake a rowCount of 1 to trigger Qt calling fetchMore() + int c = rowCount( parent ) - 1; + QPair< int, int > crows; + crows.first = c; + crows.second = c + tracks.count() - 1; + + if ( crows.second > 0 ) + emit beginInsertRows( parent, crows.first + 1, crows.second ); + + TreeModelItem* item; + foreach( const query_ptr& query, tracks ) + { + qDebug() << query->toString(); + item = new TreeModelItem( query->results().first(), parentItem ); + item->cover = m_defaultCover; + item->index = createIndex( parentItem->children.count() - 1, 0, item ); + + connect( item, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) ); + } + + if ( crows.second > 0 ) + emit endInsertRows(); + else + emit dataChanged( item->index, item->index.sibling( item->index.row(), columnCount( QModelIndex() ) - 1 ) ); + + qDebug() << rowCount( parent ); +} + + +void +TreeModel::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ) { qDebug() << Q_FUNC_INFO; - - if ( m_collectionIndex.contains( src->collection() ) ) + if ( caller != s_infoIdentifier || type != Tomahawk::InfoSystem::InfoAlbumCoverArt ) { - removeCollection( src->collection() ); + qDebug() << "Info of wrong type or not with our identifier"; + return; + } + + if ( !output.canConvert< Tomahawk::InfoSystem::InfoCustomData >() ) + { + qDebug() << "Cannot convert fetched art from a QByteArray"; + return; + } + + Tomahawk::InfoSystem::InfoCustomData returnedData = output.value< Tomahawk::InfoSystem::InfoCustomData >(); + const QByteArray ba = returnedData["imgbytes"].toByteArray(); + if ( ba.length() ) + { + QPixmap pm; + pm.loadFromData( ba ); + + qlonglong pptr = input.toLongLong(); + TreeModelItem* ai = reinterpret_cast(pptr); + + if ( pm.isNull() || returnedData["url"].toString().startsWith( LASTFM_DEFAULT_COVER ) ) + ai->cover = m_defaultCover; + else + ai->cover = pm; } } -TreeModelItem* -TreeModel::itemFromIndex( const QModelIndex& index ) const +void +TreeModel::infoSystemFinished( QString target ) { - if ( index.isValid() ) - return static_cast( index.internalPointer() ); - else - { - return m_rootItem; - } + qDebug() << Q_FUNC_INFO; +} + + +void +TreeModel::onDataChanged() +{ + TreeModelItem* p = (TreeModelItem*)sender(); + emit dataChanged( p->index, p->index.sibling( p->index.row(), columnCount( QModelIndex() ) - 1 ) ); } diff --git a/src/libtomahawk/playlist/treemodel.h b/src/libtomahawk/playlist/treemodel.h index 393a9ed6d..6062c37cb 100644 --- a/src/libtomahawk/playlist/treemodel.h +++ b/src/libtomahawk/playlist/treemodel.h @@ -16,19 +16,19 @@ * along with Tomahawk. If not, see . */ -#ifndef COLLECTIONMODEL_H -#define COLLECTIONMODEL_H +#ifndef TREEMODEL_H +#define TREEMODEL_H #include -#include -#include +#include + +#include "album.h" +#include "collection.h" +#include "playlistinterface.h" +#include "database/databasecommand_allartists.h" #include "treemodelitem.h" -#include "collection.h" -#include "query.h" -#include "typedefs.h" -#include "playlist.h" -#include "playlistinterface.h" +#include "tomahawk/infosystem.h" #include "dllmacro.h" @@ -40,53 +40,84 @@ Q_OBJECT public: explicit TreeModel( QObject* parent = 0 ); - ~TreeModel(); + virtual ~TreeModel(); - QModelIndex index( int row, int column, const QModelIndex& parent ) const; - QModelIndex parent( const QModelIndex& child ) const; + virtual QModelIndex index( int row, int column, const QModelIndex& parent ) const; + virtual QModelIndex parent( const QModelIndex& child ) const; - int trackCount() const { return rowCount( QModelIndex() ); } + virtual bool isReadOnly() const { return true; } - int rowCount( const QModelIndex& parent ) const; - int columnCount( const QModelIndex& parent ) const; + virtual int trackCount() const { return rowCount( QModelIndex() ); } + virtual int albumCount() const { return rowCount( QModelIndex() ); } - QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const; - QVariant headerData( int section, Qt::Orientation orientation, int role ) const; + virtual int rowCount( const QModelIndex& parent ) const; + virtual int columnCount( const QModelIndex& parent ) const; + virtual QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const; + virtual QVariant headerData( int section, Qt::Orientation orientation, int role ) const; + + virtual void removeIndex( const QModelIndex& index ); + virtual void removeIndexes( const QList& indexes ); + + virtual QMimeData* mimeData( const QModelIndexList& indexes ) const; + virtual QStringList mimeTypes() const; + virtual Qt::ItemFlags flags( const QModelIndex& index ) const; + + void addAllCollections(); void addCollection( const Tomahawk::collection_ptr& collection ); - void removeCollection( const Tomahawk::collection_ptr& collection ); + void addFilteredCollection( const Tomahawk::collection_ptr& collection, unsigned int amount, DatabaseCommand_AllArtists::SortOrder order ); - virtual QPersistentModelIndex currentItem() { return m_currentIndex; } + void addAlbums( const Tomahawk::artist_ptr& artist, const QModelIndex& parent ); + void addTracks( const Tomahawk::album_ptr& album, const QModelIndex& parent ); - virtual PlaylistInterface::RepeatMode repeatMode() const { return PlaylistInterface::NoRepeat; } - virtual bool shuffled() const { return false; } + virtual QString title() const { return m_title; } + virtual QString description() const { return m_description; } + virtual void setTitle( const QString& title ) { m_title = title; } + virtual void setDescription( const QString& description ) { m_description = description; } - virtual void setRepeatMode( PlaylistInterface::RepeatMode /*mode*/ ) {} - virtual void setShuffled( bool /*shuffled*/ ) {} - - TreeModelItem* itemFromIndex( const QModelIndex& index ) const; + TreeModelItem* itemFromIndex( const QModelIndex& index ) const + { + if ( index.isValid() ) + return static_cast( index.internalPointer() ); + else + { + return m_rootItem; + } + } public slots: - virtual void setCurrentItem( const QModelIndex& index ); + virtual void setRepeatMode( PlaylistInterface::RepeatMode /*mode*/ ) {} + virtual void setShuffled( bool /*shuffled*/ ) {} signals: void repeatModeChanged( PlaylistInterface::RepeatMode mode ); void shuffleModeChanged( bool enabled ); - void loadingStarts(); - void loadingFinished(); void trackCountChanged( unsigned int tracks ); -private slots: - void onTracksAdded( const QList& tracks, const Tomahawk::collection_ptr& collection ); - void onTracksAddingFinished( const Tomahawk::collection_ptr& collection ); +protected: + bool canFetchMore( const QModelIndex& parent ) const; + void fetchMore( const QModelIndex& parent ); - void onSourceOffline( Tomahawk::source_ptr src ); +private slots: + void onArtistsAdded( const QList& artists ); + void onAlbumsAdded( const QList& albums, const QVariant& data ); + void onTracksAdded( const QList& tracks, const QVariant& data ); + + void infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ); + void infoSystemFinished( QString target ); + + void onDataChanged(); private: - TreeModelItem* m_rootItem; - QMap< Tomahawk::collection_ptr, TreeModelItem* > m_collectionIndex; QPersistentModelIndex m_currentIndex; + TreeModelItem* m_rootItem; + QPixmap m_defaultCover; + + QString m_title; + QString m_description; + + Tomahawk::collection_ptr m_collection; }; -#endif // COLLECTIONMODEL_H +#endif // ALBUMMODEL_H diff --git a/src/libtomahawk/playlist/treemodelitem.cpp b/src/libtomahawk/playlist/treemodelitem.cpp new file mode 100644 index 000000000..9e1c03fa2 --- /dev/null +++ b/src/libtomahawk/playlist/treemodelitem.cpp @@ -0,0 +1,133 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Christian Muehlhaeuser + * + * Tomahawk 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 3 of the License, or + * (at your option) any later version. + * + * Tomahawk 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#include "treemodelitem.h" + +#include "utils/tomahawkutils.h" + +#include + +using namespace Tomahawk; + + +TreeModelItem::~TreeModelItem() +{ + // Don't use qDeleteAll here! The children will remove themselves + // from the list when they get deleted and the qDeleteAll iterator + // will fail badly! + for ( int i = children.count() - 1; i >= 0; i-- ) + delete children.at( i ); + + if ( parent && index.isValid() ) + { + parent->children.removeAt( index.row() ); + } +} + + +TreeModelItem::TreeModelItem( TreeModelItem* parent, QAbstractItemModel* model ) +{ + this->parent = parent; + this->model = model; + childCount = 0; + toberemoved = false; + fetchingMore = false; + + if ( parent ) + { + parent->children.append( this ); + } +} + + +TreeModelItem::TreeModelItem( const Tomahawk::album_ptr& album, TreeModelItem* parent, int row ) + : QObject( parent ) + , m_album( album ) +{ + this->parent = parent; + fetchingMore = false; + + if ( parent ) + { + if ( row < 0 ) + { + parent->children.append( this ); + row = parent->children.count() - 1; + } + else + { + parent->children.insert( row, this ); + } + + this->model = parent->model; + } + + toberemoved = false; +} + + +TreeModelItem::TreeModelItem( const Tomahawk::artist_ptr& artist, TreeModelItem* parent, int row ) + : QObject( parent ) + , m_artist( artist ) +{ + this->parent = parent; + fetchingMore = false; + + if ( parent ) + { + if ( row < 0 ) + { + parent->children.append( this ); + row = parent->children.count() - 1; + } + else + { + parent->children.insert( row, this ); + } + + this->model = parent->model; + } + + toberemoved = false; +} + + +TreeModelItem::TreeModelItem( const Tomahawk::result_ptr& result, TreeModelItem* parent, int row ) + : QObject( parent ) + , m_result( result ) +{ + this->parent = parent; + fetchingMore = false; + + if ( parent ) + { + if ( row < 0 ) + { + parent->children.append( this ); + row = parent->children.count() - 1; + } + else + { + parent->children.insert( row, this ); + } + + this->model = parent->model; + } + + toberemoved = false; +} diff --git a/src/libtomahawk/playlist/treemodelitem.h b/src/libtomahawk/playlist/treemodelitem.h new file mode 100644 index 000000000..16538727b --- /dev/null +++ b/src/libtomahawk/playlist/treemodelitem.h @@ -0,0 +1,69 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Christian Muehlhaeuser + * + * Tomahawk 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 3 of the License, or + * (at your option) any later version. + * + * Tomahawk 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#ifndef TREEMODELITEM_H +#define TREEMODELITEM_H + +#include +#include +#include +#include + +#include "result.h" + +#include "dllmacro.h" + +class DLLEXPORT TreeModelItem : public QObject +{ +Q_OBJECT + +public: + ~TreeModelItem(); + + explicit TreeModelItem( TreeModelItem* parent = 0, QAbstractItemModel* model = 0 ); + explicit TreeModelItem( const Tomahawk::artist_ptr& artist, TreeModelItem* parent = 0, int row = -1 ); + explicit TreeModelItem( const Tomahawk::album_ptr& album, TreeModelItem* parent = 0, int row = -1 ); + explicit TreeModelItem( const Tomahawk::result_ptr& result, TreeModelItem* parent = 0, int row = -1 ); + + const Tomahawk::artist_ptr& artist() const { return m_artist; }; + const Tomahawk::album_ptr& album() const { return m_album; }; + const Tomahawk::result_ptr& result() const { return m_result; }; + + void setCover( const QPixmap& cover ) { this->cover = cover; emit dataChanged(); } + + TreeModelItem* parent; + QList children; + QHash hash; + int childCount; + QPersistentModelIndex index; + QAbstractItemModel* model; + QPixmap cover; + + bool toberemoved; + bool fetchingMore; + +signals: + void dataChanged(); + +private: + Tomahawk::artist_ptr m_artist; + Tomahawk::album_ptr m_album; + Tomahawk::result_ptr m_result; +}; + +#endif // TREEMODELITEM_H diff --git a/src/libtomahawk/playlist/treeproxymodel.cpp b/src/libtomahawk/playlist/treeproxymodel.cpp new file mode 100644 index 000000000..357596ed0 --- /dev/null +++ b/src/libtomahawk/playlist/treeproxymodel.cpp @@ -0,0 +1,158 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Christian Muehlhaeuser + * + * Tomahawk 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 3 of the License, or + * (at your option) any later version. + * + * Tomahawk 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#include "treeproxymodel.h" + +#include +#include + +#include "query.h" + + +TreeProxyModel::TreeProxyModel( QObject* parent ) + : QSortFilterProxyModel( parent ) + , PlaylistInterface( this ) + , m_model( 0 ) + , m_repeatMode( PlaylistInterface::NoRepeat ) + , m_shuffled( false ) +{ + qsrand( QTime( 0, 0, 0 ).secsTo( QTime::currentTime() ) ); + + setFilterCaseSensitivity( Qt::CaseInsensitive ); + setSortCaseSensitivity( Qt::CaseInsensitive ); + setDynamicSortFilter( true ); + + setSourceModel( 0 ); +} + + +void +TreeProxyModel::setSourceModel( TreeModel* sourceModel ) +{ + m_model = sourceModel; + + connect( m_model, SIGNAL( trackCountChanged( unsigned int ) ), + SIGNAL( sourceTrackCountChanged( unsigned int ) ) ); + + QSortFilterProxyModel::setSourceModel( sourceModel ); +} + + +void +TreeProxyModel::setFilter( const QString& pattern ) +{ + qDebug() << Q_FUNC_INFO; + setFilterRegExp( pattern ); + + emit filterChanged( pattern ); +} + + +bool +TreeProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex& sourceParent ) const +{ + if ( filterRegExp().isEmpty() ) + return true; + + TreeModelItem* pi = sourceModel()->itemFromIndex( sourceModel()->index( sourceRow, 0, sourceParent ) ); + if ( !pi ) + return false; + + QStringList sl = filterRegExp().pattern().split( " ", QString::SkipEmptyParts ); + + bool found = true; + foreach( const QString& s, sl ) + { + if ( !textForItem( pi ).contains( s, Qt::CaseInsensitive ) ) + { + found = false; + } + } + + return found; +} + + +bool +TreeProxyModel::lessThan( const QModelIndex& left, const QModelIndex& right ) const +{ + TreeModelItem* p1 = sourceModel()->itemFromIndex( left ); + TreeModelItem* p2 = sourceModel()->itemFromIndex( right ); + + if ( !p1 ) + return true; + if ( !p2 ) + return false; + + return QString::localeAwareCompare( textForItem( p1 ), textForItem( p2 ) ) < 0; +} + + +void +TreeProxyModel::removeIndex( const QModelIndex& index ) +{ + qDebug() << Q_FUNC_INFO; + + if ( !sourceModel() ) + return; + if ( index.column() > 0 ) + return; + + sourceModel()->removeIndex( mapToSource( index ) ); +} + + +void +TreeProxyModel::removeIndexes( const QList& indexes ) +{ + if ( !sourceModel() ) + return; + + foreach( const QModelIndex& idx, indexes ) + { + removeIndex( idx ); + } +} + + +Tomahawk::result_ptr +TreeProxyModel::siblingItem( int itemsAway ) +{ + qDebug() << Q_FUNC_INFO; + return Tomahawk::result_ptr( 0 ); +} + + +QString +TreeProxyModel::textForItem( TreeModelItem* item ) const +{ + if ( !item->artist().isNull() ) + { + return item->artist()->name(); + } + else if ( !item->album().isNull() ) + { + return item->album()->name(); + } + else if ( !item->result().isNull() ) + { + return item->result()->track(); + } + + return QString(); +} diff --git a/src/libtomahawk/playlist/treeproxymodel.h b/src/libtomahawk/playlist/treeproxymodel.h new file mode 100644 index 000000000..b441e155b --- /dev/null +++ b/src/libtomahawk/playlist/treeproxymodel.h @@ -0,0 +1,81 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Christian Muehlhaeuser + * + * Tomahawk 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 3 of the License, or + * (at your option) any later version. + * + * Tomahawk 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#ifndef TREEPROXYMODEL_H +#define TREEPROXYMODEL_H + +#include + +#include "playlistinterface.h" +#include "treemodel.h" + +#include "dllmacro.h" + +class DLLEXPORT TreeProxyModel : public QSortFilterProxyModel, public PlaylistInterface +{ +Q_OBJECT + +public: + explicit TreeProxyModel( QObject* parent = 0 ); + + virtual TreeModel* sourceModel() const { return m_model; } + virtual void setSourceModel( TreeModel* sourceModel ); + + virtual QList tracks() { Q_ASSERT( FALSE ); QList queries; return queries; } + + virtual int unfilteredTrackCount() const { return sourceModel()->rowCount( QModelIndex() ); } + virtual int trackCount() const { return rowCount( QModelIndex() ); } + virtual int albumCount() const { return rowCount( QModelIndex() ); } + + virtual void removeIndex( const QModelIndex& index ); + virtual void removeIndexes( const QList& indexes ); + + virtual Tomahawk::result_ptr siblingItem( int direction ); + + virtual void setFilter( const QString& pattern ); + + virtual PlaylistInterface::RepeatMode repeatMode() const { return m_repeatMode; } + virtual bool shuffled() const { return m_shuffled; } + virtual PlaylistInterface::ViewMode viewMode() const { return PlaylistInterface::Tree; } + +signals: + void repeatModeChanged( PlaylistInterface::RepeatMode mode ); + void shuffleModeChanged( bool enabled ); + + void trackCountChanged( unsigned int tracks ); + void sourceTrackCountChanged( unsigned int tracks ); + + void filterChanged( const QString& filter ); + +public slots: + virtual void setRepeatMode( RepeatMode mode ) { m_repeatMode = mode; emit repeatModeChanged( mode ); } + virtual void setShuffled( bool enabled ) { m_shuffled = enabled; emit shuffleModeChanged( enabled ); } + +protected: + bool filterAcceptsRow( int sourceRow, const QModelIndex& sourceParent ) const; + bool lessThan( const QModelIndex& left, const QModelIndex& right ) const; + +private: + QString textForItem( TreeModelItem* item ) const; + + TreeModel* m_model; + RepeatMode m_repeatMode; + bool m_shuffled; +}; + +#endif // TREEPROXYMODEL_H From 9f4c3bb461765a088c15d17c083758dd9522fd92 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Thu, 14 Apr 2011 00:32:16 +0200 Subject: [PATCH 43/75] * Moved InfoSystem into libTomahawk. * Made InfoSystem a singleton. * Don't access InfoSystem via TomahawkApp any longer. * Progress on ArtistView & TreeModel. --- include/tomahawk/tomahawkapp.h | 7 -- src/CMakeLists.txt | 14 ---- src/audiocontrols.cpp | 15 ++-- src/audiocontrols.h | 2 +- src/libtomahawk/CMakeLists.txt | 19 ++++- src/libtomahawk/album.cpp | 4 +- src/libtomahawk/artist.cpp | 4 +- .../database/databasecollection.cpp | 12 +-- .../infosystem/infoplugins/echonestplugin.cpp | 22 +++-- .../infosystem/infoplugins/echonestplugin.h | 14 ++-- .../infosystem/infoplugins/lastfmplugin.cpp | 40 ++++----- .../infosystem/infoplugins/lastfmplugin.h | 16 ++-- .../infoplugins/musixmatchplugin.cpp | 8 +- .../infosystem/infoplugins/musixmatchplugin.h | 13 +-- .../infosystem/infosystem.cpp | 44 ++++++---- .../libtomahawk/infosystem}/infosystem.h | 57 +++++++------ .../infosystem/infosystemcache.cpp | 0 .../infosystem/infosystemcache.h | 12 +-- src/libtomahawk/network/servent.cpp | 2 +- src/libtomahawk/playlist/albummodel.cpp | 6 +- src/libtomahawk/playlist/artistview.cpp | 19 +++++ src/libtomahawk/playlist/artistview.h | 3 + .../playlist/collectionflatmodel.cpp | 4 +- src/libtomahawk/playlist/playlistmanager.cpp | 4 + src/libtomahawk/playlist/treeitemdelegate.cpp | 6 +- src/libtomahawk/playlist/treemodel.cpp | 84 ++++++++++++------- src/libtomahawk/playlist/treemodel.h | 13 ++- src/libtomahawk/playlist/treeproxymodel.cpp | 6 ++ src/scanmanager.cpp | 28 +++---- src/scrobbler.cpp | 45 +++++----- src/scrobbler.h | 12 +-- src/tomahawkapp.cpp | 8 +- src/web/api_v1.h | 5 +- src/xmppbot/xmppbot.cpp | 59 +++++++------ src/xmppbot/xmppbot.h | 18 ++-- 35 files changed, 352 insertions(+), 273 deletions(-) rename src/{ => libtomahawk}/infosystem/infoplugins/echonestplugin.cpp (98%) rename src/{ => libtomahawk}/infosystem/infoplugins/echonestplugin.h (97%) rename src/{ => libtomahawk}/infosystem/infoplugins/lastfmplugin.cpp (98%) rename src/{ => libtomahawk}/infosystem/infoplugins/lastfmplugin.h (97%) rename src/{ => libtomahawk}/infosystem/infoplugins/musixmatchplugin.cpp (98%) rename src/{ => libtomahawk}/infosystem/infoplugins/musixmatchplugin.h (96%) rename src/{ => libtomahawk}/infosystem/infosystem.cpp (92%) rename {include/tomahawk => src/libtomahawk/infosystem}/infosystem.h (96%) rename src/{ => libtomahawk}/infosystem/infosystemcache.cpp (100%) rename src/{ => libtomahawk}/infosystem/infosystemcache.h (97%) diff --git a/include/tomahawk/tomahawkapp.h b/include/tomahawk/tomahawkapp.h index 5ff7b6c27..5e7a7db7f 100644 --- a/include/tomahawk/tomahawkapp.h +++ b/include/tomahawk/tomahawkapp.h @@ -52,10 +52,6 @@ class XMPPBot; namespace Tomahawk { class ShortcutHandler; - namespace InfoSystem - { - class InfoSystem; - } } #ifdef LIBLASTFM_FOUND @@ -83,7 +79,6 @@ public: static TomahawkApp* instance(); SipHandler* sipHandler() { return m_sipHandler; } - Tomahawk::InfoSystem::InfoSystem* infoSystem() { return m_infoSystem; } XMPPBot* xmppBot() { return m_xmppBot; } #ifndef TOMAHAWK_HEADLESS @@ -138,8 +133,6 @@ private: bool m_headless; - Tomahawk::InfoSystem::InfoSystem* m_infoSystem; - QxtHttpServerConnector m_connector; QxtHttpSessionManager m_session; }; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 933c6a7ac..1b9a95e65 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -34,12 +34,6 @@ ENDIF() SET( tomahawkSources ${tomahawkSources} sip/SipHandler.cpp - infosystem/infosystemcache.cpp - infosystem/infosystem.cpp - infosystem/infoplugins/echonestplugin.cpp - infosystem/infoplugins/lastfmplugin.cpp - infosystem/infoplugins/musixmatchplugin.cpp - web/api_v1.cpp resolvers/scriptresolver.cpp @@ -74,15 +68,9 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui} SET( tomahawkHeaders ${tomahawkHeaders} "${TOMAHAWK_INC_DIR}/tomahawk/tomahawkapp.h" - "${TOMAHAWK_INC_DIR}/tomahawk/infosystem.h" sip/SipHandler.h - infosystem/infosystemcache.h - infosystem/infoplugins/echonestplugin.h - infosystem/infoplugins/lastfmplugin.h - infosystem/infoplugins/musixmatchplugin.h - web/api_v1.h resolvers/scriptresolver.h @@ -137,8 +125,6 @@ INCLUDE_DIRECTORIES( topbar utils libtomahawk - libtomahawk/utils - infosystem mac ${THIRDPARTY_DIR}/alsa-playback diff --git a/src/audiocontrols.cpp b/src/audiocontrols.cpp index 4465e266b..93bfd71e7 100644 --- a/src/audiocontrols.cpp +++ b/src/audiocontrols.cpp @@ -21,7 +21,6 @@ #include -#include "tomahawk/tomahawkapp.h" #include "audio/audioengine.h" #include "playlist/playlistmanager.h" #include "utils/imagebutton.h" @@ -31,7 +30,7 @@ #define LASTFM_DEFAULT_COVER "http://cdn.last.fm/flatness/catalogue/noimage" -static QString s_infoIdentifier = QString( "AUDIOCONTROLS" ); +static QString s_acInfoIdentifier = QString( "AUDIOCONTROLS" ); AudioControls::AudioControls( QWidget* parent ) @@ -168,11 +167,11 @@ AudioControls::AudioControls( QWidget* parent ) m_defaultCover = QPixmap( RESPATH "images/no-album-art-placeholder.png" ) .scaled( ui->coverImage->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation ); - connect( TomahawkApp::instance()->infoSystem(), + connect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ), SLOT( infoSystemInfo( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ) ); - connect( TomahawkApp::instance()->infoSystem(), SIGNAL( finished( QString ) ), SLOT( infoSystemFinished( QString ) ) ); + connect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( finished( QString ) ), SLOT( infoSystemFinished( QString ) ) ); onPlaybackStopped(); // initial state } @@ -220,8 +219,8 @@ AudioControls::onPlaybackStarted( const Tomahawk::result_ptr& result ) trackInfo["artist"] = QVariant::fromValue< QString >( result->artist()->name() ); trackInfo["album"] = QVariant::fromValue< QString >( result->album()->name() ); - TomahawkApp::instance()->infoSystem()->getInfo( - s_infoIdentifier, Tomahawk::InfoSystem::InfoAlbumCoverArt, + Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( + s_acInfoIdentifier, Tomahawk::InfoSystem::InfoAlbumCoverArt, QVariant::fromValue< Tomahawk::InfoSystem::InfoCustomData >( trackInfo ), Tomahawk::InfoSystem::InfoCustomData() ); } @@ -232,8 +231,8 @@ AudioControls::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType ty Q_UNUSED( input ); Q_UNUSED( customData ); - qDebug() << Q_FUNC_INFO; - if ( caller != s_infoIdentifier || type != Tomahawk::InfoSystem::InfoAlbumCoverArt ) + qDebug() << Q_FUNC_INFO << caller << type << s_acInfoIdentifier << Tomahawk::InfoSystem::InfoAlbumCoverArt; + if ( caller != s_acInfoIdentifier || type != Tomahawk::InfoSystem::InfoAlbumCoverArt ) { qDebug() << "Info of wrong type or not with our identifier"; return; diff --git a/src/audiocontrols.h b/src/audiocontrols.h index 126608a05..a2de2d35b 100644 --- a/src/audiocontrols.h +++ b/src/audiocontrols.h @@ -23,7 +23,7 @@ #include "result.h" #include "playlistinterface.h" -#include "tomahawk/infosystem.h" +#include "infosystem/infosystem.h" namespace Ui { diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index 4b945ef7d..ae7dc0350 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -75,6 +75,12 @@ set( libSources database/databasecommand_clientauthvalid.cpp database/database.cpp + infosystem/infosystemcache.cpp + infosystem/infosystem.cpp + infosystem/infoplugins/echonestplugin.cpp + infosystem/infoplugins/lastfmplugin.cpp + infosystem/infoplugins/musixmatchplugin.cpp + playlist/treemodel.cpp playlist/treeproxymodel.cpp playlist/treeheader.cpp @@ -226,6 +232,12 @@ set( libHeaders database/databasecommand_addclientauth.h database/databasecommand_clientauthvalid.h + infosystem/infosystem.h + infosystem/infosystemcache.h + infosystem/infoplugins/echonestplugin.h + infosystem/infoplugins/lastfmplugin.h + infosystem/infoplugins/musixmatchplugin.h + network/bufferiodevice.h network/msgprocessor.h network/remotecollection.h @@ -330,9 +342,9 @@ include_directories( . ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/. ${LIBECHONEST_INCLUDE_DIR}/.. ${CLUCENE_INCLUDE_DIR} ${CLUCENE_LIBRARY_DIR} + ${CMAKE_BINARY_DIR}/thirdparty/liblastfm2/src ../../include - ../network playlist ${THIRDPARTY_DIR}/libportfwd/include @@ -394,6 +406,10 @@ IF( UNIX AND NOT APPLE ) ) ENDIF( UNIX AND NOT APPLE ) +IF(LIBLASTFM_FOUND) + SET(LINK_LIBRARIES ${LINK_LIBRARIES} tomahawk_lastfm2 ) +ENDIF(LIBLASTFM_FOUND) + qt4_wrap_ui( libUI_H ${libUI} ) qt4_wrap_cpp( libMoc ${libHeaders} ) @@ -422,6 +438,7 @@ target_link_libraries( tomahawklib ${QT_LIBRARIES} ${OS_SPECIFIC_LINK_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} + ${LINK_LIBRARIES} ) INSTALL( TARGETS tomahawklib DESTINATION lib${LIB_SUFFIX} ) diff --git a/src/libtomahawk/album.cpp b/src/libtomahawk/album.cpp index 5fede95c5..425183174 100644 --- a/src/libtomahawk/album.cpp +++ b/src/libtomahawk/album.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -93,7 +93,7 @@ Album::tracks() cmd->setAlbum( this ); cmd->setSortOrder( DatabaseCommand_AllTracks::AlbumPosition ); - connect( cmd, SIGNAL( tracks( QList ) ), + connect( cmd, SIGNAL( tracks( QList, QVariant ) ), SLOT( onTracksAdded( QList ) ) ); Database::instance()->enqueue( QSharedPointer( cmd ) ); diff --git a/src/libtomahawk/artist.cpp b/src/libtomahawk/artist.cpp index bc130e55f..0d24772a4 100644 --- a/src/libtomahawk/artist.cpp +++ b/src/libtomahawk/artist.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -95,7 +95,7 @@ Artist::tracks() cmd->setArtist( this ); cmd->setSortOrder( DatabaseCommand_AllTracks::Album ); - connect( cmd, SIGNAL( tracks( QList ) ), + connect( cmd, SIGNAL( tracks( QList, QVariant ) ), SLOT( onTracksAdded( QList ) ) ); Database::instance()->enqueue( QSharedPointer( cmd ) ); diff --git a/src/libtomahawk/database/databasecollection.cpp b/src/libtomahawk/database/databasecollection.cpp index 564180398..23e36584d 100644 --- a/src/libtomahawk/database/databasecollection.cpp +++ b/src/libtomahawk/database/databasecollection.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -52,10 +52,10 @@ DatabaseCollection::loadDynamicPlaylists() { qDebug() << Q_FUNC_INFO; DatabaseCommand_LoadAllDynamicPlaylists* cmd = new DatabaseCommand_LoadAllDynamicPlaylists( source() ); - + connect( cmd, SIGNAL( playlistLoaded( Tomahawk::source_ptr, QVariantList ) ), SLOT( dynamicPlaylistCreated( const Tomahawk::source_ptr&, const QVariantList& ) ) ); - + Database::instance()->enqueue( QSharedPointer( cmd ) ); } @@ -68,7 +68,7 @@ DatabaseCollection::loadTracks() setLoaded(); DatabaseCommand_AllTracks* cmd = new DatabaseCommand_AllTracks( source()->collection() ); - connect( cmd, SIGNAL( tracks( QList ) ), + connect( cmd, SIGNAL( tracks( QList, QVariant ) ), SLOT( setTracks( QList ) ) ); Database::instance()->enqueue( QSharedPointer( cmd ) ); @@ -112,12 +112,12 @@ DatabaseCollection::playlists() QList< dynplaylist_ptr > DatabaseCollection::dynamicPlaylists() { qDebug() << Q_FUNC_INFO; - + if ( Collection::dynamicPlaylists().isEmpty() ) { loadDynamicPlaylists(); } - + return Collection::dynamicPlaylists(); } diff --git a/src/infosystem/infoplugins/echonestplugin.cpp b/src/libtomahawk/infosystem/infoplugins/echonestplugin.cpp similarity index 98% rename from src/infosystem/infoplugins/echonestplugin.cpp rename to src/libtomahawk/infosystem/infoplugins/echonestplugin.cpp index 7bec6c653..73dd3b7b2 100644 --- a/src/infosystem/infoplugins/echonestplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/echonestplugin.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -16,8 +16,6 @@ * along with Tomahawk. If not, see . */ -#include "tomahawk/infosystem.h" -#include "tomahawk/tomahawkapp.h" #include "echonestplugin.h" #include #include @@ -72,10 +70,10 @@ void EchoNestPlugin::getSongProfile(const QString &caller, const QVariant& data, if( !isValidTrackData( caller, data, customData ) ) return; - + // Track track( data.toString() ); // Artist artist( customData.data()->property("artistName").toString() ); -// reply->setProperty("artist", QVariant::fromValue(artist)); +// reply->setProperty("artist", QVariant::fromValue(artist)); // reply->setProperty( "data", data ); // m_replyMap[reply] = customData; // connect(reply, SIGNAL(finished()), SLOT(getArtistBiographySlot())); @@ -85,7 +83,7 @@ void EchoNestPlugin::getArtistBiography(const QString &caller, const QVariant& d { if( !isValidArtistData( caller, data, customData ) ) return; - + Echonest::Artist artist( data.toString() ); QNetworkReply *reply = artist.fetchBiographies(); reply->setProperty("artist", QVariant::fromValue(artist)); @@ -99,7 +97,7 @@ void EchoNestPlugin::getArtistFamiliarity(const QString &caller, const QVariant& { if( !isValidArtistData( caller, data, customData ) ) return; - + qDebug() << "Fetching artist familiarity!" << data; Echonest::Artist artist( data.toString() ); QNetworkReply* reply = artist.fetchFamiliarity(); @@ -107,14 +105,14 @@ void EchoNestPlugin::getArtistFamiliarity(const QString &caller, const QVariant& reply->setProperty( "data", data ); m_replyMap[reply] = customData; m_callerMap[reply] = caller; - connect(reply, SIGNAL(finished()), SLOT(getArtistFamiliaritySlot())); + connect(reply, SIGNAL(finished()), SLOT(getArtistFamiliaritySlot())); } void EchoNestPlugin::getArtistHotttnesss(const QString &caller, const QVariant& data, InfoCustomData &customData) { if( !isValidArtistData( caller, data, customData ) ) return; - + Echonest::Artist artist( data.toString() ); QNetworkReply* reply = artist.fetchHotttnesss(); reply->setProperty( "artist", QVariant::fromValue(artist)); @@ -128,7 +126,7 @@ void EchoNestPlugin::getArtistTerms(const QString &caller, const QVariant& data, { if( !isValidArtistData( caller, data, customData ) ) return; - + Echonest::Artist artist( data.toString() ); QNetworkReply* reply = artist.fetchTerms( Echonest::Artist::Weight ); reply->setProperty( "artist", QVariant::fromValue(artist)); @@ -162,7 +160,7 @@ void EchoNestPlugin::getArtistBiographySlot() biographyMap[biography.site()]["attribution"] = biography.license().attribution; biographyMap[biography.site()]["licensetype"] = biography.license().type; biographyMap[biography.site()]["attribution"] = biography.license().url.toString(); - + } emit info( m_callerMap[reply], Tomahawk::InfoSystem::InfoArtistBiography, reply->property( "data" ), QVariant::fromValue(biographyMap), m_replyMap[reply] ); m_replyMap.remove(reply); @@ -256,7 +254,7 @@ bool EchoNestPlugin::isValidTrackData(const QString &caller, const QVariant& dat emit info(caller, Tomahawk::InfoSystem::InfoNoInfo, QVariant(), QVariant(), customData); return false; } - if (!customData.contains("artistName") || + if (!customData.contains("artistName") || customData["artistName"].toString().isEmpty()) return false; return true; diff --git a/src/infosystem/infoplugins/echonestplugin.h b/src/libtomahawk/infosystem/infoplugins/echonestplugin.h similarity index 97% rename from src/infosystem/infoplugins/echonestplugin.h rename to src/libtomahawk/infosystem/infoplugins/echonestplugin.h index d4a4db367..25276c373 100644 --- a/src/infosystem/infoplugins/echonestplugin.h +++ b/src/libtomahawk/infosystem/infoplugins/echonestplugin.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -19,7 +19,7 @@ #ifndef ECHONESTPLUGIN_H #define ECHONESTPLUGIN_H -#include "tomahawk/infosystem.h" +#include "infosystem/infosystem.h" #include @@ -37,13 +37,13 @@ namespace InfoSystem class EchoNestPlugin : public InfoPlugin { Q_OBJECT - + public: EchoNestPlugin(QObject *parent); virtual ~EchoNestPlugin(); - + void getInfo( const QString &caller, const InfoType type, const QVariant &data, InfoCustomData customData ); - + private: void getSongProfile( const QString &caller, const QVariant &data, InfoCustomData &customData, const QString &item = QString() ); void getArtistBiography ( const QString &caller, const QVariant &data, InfoCustomData &customData ); @@ -55,14 +55,14 @@ private: bool isValidArtistData( const QString &caller, const QVariant& data, InfoCustomData& customData ); bool isValidTrackData( const QString &caller, const QVariant& data, InfoCustomData& customData ); Echonest::Artist artistFromReply( QNetworkReply* ); - + private slots: void getArtistBiographySlot(); void getArtistFamiliaritySlot(); void getArtistHotttnesssSlot(); void getArtistTermsSlot(); void getMiscTopSlot(); - + private: QHash< QNetworkReply*, InfoCustomData > m_replyMap; QHash< QNetworkReply*, QString > m_callerMap; diff --git a/src/infosystem/infoplugins/lastfmplugin.cpp b/src/libtomahawk/infosystem/infoplugins/lastfmplugin.cpp similarity index 98% rename from src/infosystem/infoplugins/lastfmplugin.cpp rename to src/libtomahawk/infosystem/infoplugins/lastfmplugin.cpp index fcff625bf..0cb840265 100644 --- a/src/infosystem/infoplugins/lastfmplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/lastfmplugin.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -26,7 +26,7 @@ #include "typedefs.h" #include "audio/audioengine.h" #include "tomahawksettings.h" -#include "tomahawk/tomahawkapp.h" +#include "utils/tomahawkutils.h" #include #include @@ -49,7 +49,7 @@ LastFmPlugin::LastFmPlugin( QObject* parent ) QSet< InfoType > supportedTypes; supportedTypes << InfoMiscSubmitScrobble << InfoMiscSubmitNowPlaying << InfoAlbumCoverArt; qobject_cast< InfoSystem* >(parent)->registerInfoTypes(this, supportedTypes); - + /* Your API Key is 7194b85b6d1f424fe1668173a78c0c4a Your secret is ba80f1df6d27ae63e9cb1d33ccf2052f @@ -61,14 +61,14 @@ LastFmPlugin::LastFmPlugin( QObject* parent ) lastfm::ws::ApiKey = "7194b85b6d1f424fe1668173a78c0c4a"; lastfm::ws::SharedSecret = "ba80f1df6d27ae63e9cb1d33ccf2052f"; lastfm::ws::Username = TomahawkSettings::instance()->lastFmUsername(); - + m_pw = TomahawkSettings::instance()->lastFmPassword(); - + if( TomahawkSettings::instance()->scrobblingEnabled() && !lastfm::ws::Username.isEmpty() ) { createScrobbler(); } - + //HACK work around a bug in liblastfm---it doesn't create its config dir, so when it // tries to write the track cache, it fails silently. until we have a fixed version, do this // code taken from Amarok (src/services/lastfm/ScrobblerAdapter.cpp) @@ -126,7 +126,7 @@ LastFmPlugin::nowPlaying( const QString &caller, const InfoType type, const QVar dataError( caller, type, data, customData ); return; } - + m_track = lastfm::MutableTrack(); m_track.stamp(); @@ -154,7 +154,7 @@ LastFmPlugin::scrobble( const QString &caller, const InfoType type, const QVaria qDebug() << Q_FUNC_INFO << m_track.toString(); m_scrobbler->cache( m_track ); m_scrobbler->submit(); - + emit info( caller, type, data, QVariant(), customData ); } @@ -173,11 +173,11 @@ LastFmPlugin::fetchCoverArt( const QString &caller, const InfoType type, const Q dataError( caller, type, data, customData ); return; } - + Tomahawk::InfoSystem::InfoCacheCriteria criteria; criteria["artist"] = hash["artist"].toString(); criteria["album"] = hash["album"].toString(); - + emit getCachedInfo( criteria, 2419200000, caller, type, data, customData ); } @@ -217,7 +217,7 @@ LastFmPlugin::coverArtReturned() InfoCustomData returnedData; returnedData["imgbytes"] = ba; returnedData["url"] = reply->url().toString(); - + InfoCustomData customData = reply->property( "customData" ).value< Tomahawk::InfoSystem::InfoCustomData >(); InfoType type = (Tomahawk::InfoSystem::InfoType)(reply->property( "type" ).toUInt()); emit info( @@ -227,12 +227,12 @@ LastFmPlugin::coverArtReturned() returnedData, customData ); - + InfoCustomData origData = reply->property( "origData" ).value< Tomahawk::InfoSystem::InfoCustomData >(); Tomahawk::InfoSystem::InfoCacheCriteria criteria; criteria["artist"] = origData["artist"].toString(); criteria["album"] = origData["album"].toString(); - emit updateCache( criteria, type, returnedData ); + emit updateCache( criteria, 2419200000, type, returnedData ); } else { @@ -280,12 +280,12 @@ LastFmPlugin::settingsChanged() void LastFmPlugin::onAuthenticated() { - if( !m_authJob ) + if( !m_authJob ) { qDebug() << Q_FUNC_INFO << "Help! No longer got a last.fm auth job!"; return; } - + if( m_authJob->error() == QNetworkReply::NoError ) { lastfm::XmlQuery lfm = lastfm::XmlQuery( m_authJob->readAll() ); @@ -294,7 +294,7 @@ LastFmPlugin::onAuthenticated() { qDebug() << "Error from authenticating with Last.fm service:" << lfm.text(); TomahawkSettings::instance()->setLastFmSessionKey( QByteArray() ); - + } else { @@ -310,7 +310,7 @@ LastFmPlugin::onAuthenticated() { qDebug() << "Got error in Last.fm authentication job:" << m_authJob->errorString(); } - + m_authJob->deleteLater(); } @@ -321,19 +321,19 @@ LastFmPlugin::createScrobbler() if( TomahawkSettings::instance()->lastFmSessionKey().isEmpty() ) // no session key, so get one { QString authToken = md5( ( lastfm::ws::Username.toLower() + md5( m_pw.toUtf8() ) ).toUtf8() ); - + QMap query; query[ "method" ] = "auth.getMobileSession"; query[ "username" ] = lastfm::ws::Username; query[ "authToken" ] = authToken; m_authJob = lastfm::ws::post( query ); - + connect( m_authJob, SIGNAL( finished() ), SLOT( onAuthenticated() ) ); } else { lastfm::ws::SessionKey = TomahawkSettings::instance()->lastFmSessionKey(); - + m_scrobbler = new lastfm::Audioscrobbler( "thk" ); m_scrobbler->moveToThread( thread() ); } diff --git a/src/infosystem/infoplugins/lastfmplugin.h b/src/libtomahawk/infosystem/infoplugins/lastfmplugin.h similarity index 97% rename from src/infosystem/infoplugins/lastfmplugin.h rename to src/libtomahawk/infosystem/infoplugins/lastfmplugin.h index 589d40db1..00b27b15e 100644 --- a/src/infosystem/infoplugins/lastfmplugin.h +++ b/src/libtomahawk/infosystem/infoplugins/lastfmplugin.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -18,7 +18,7 @@ #ifndef LASTFMPLUGIN_H #define LASTFMPLUGIN_H -#include "tomahawk/infosystem.h" +#include "infosystem/infosystem.h" #include "result.h" #include @@ -38,30 +38,30 @@ namespace InfoSystem class LastFmPlugin : public InfoPlugin { Q_OBJECT - + public: LastFmPlugin( QObject *parent ); virtual ~LastFmPlugin(); - + void getInfo( const QString &caller, const InfoType type, const QVariant &data, InfoCustomData customData ); - + public slots: void settingsChanged(); void onAuthenticated(); void coverArtReturned(); virtual void notInCacheSlot( Tomahawk::InfoSystem::InfoCacheCriteria criteria, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, Tomahawk::InfoSystem::InfoCustomData customData ); - + private: void fetchCoverArt( const QString &caller, const InfoType type, const QVariant& data, Tomahawk::InfoSystem::InfoCustomData &customData ); void scrobble( const QString &caller, const InfoType type, const QVariant& data, InfoCustomData &customData ); void createScrobbler(); void nowPlaying( const QString &caller, const InfoType type, const QVariant& data, InfoCustomData &customData ); void dataError( const QString &caller, const InfoType type, const QVariant& data, InfoCustomData &customData ); - + lastfm::MutableTrack m_track; lastfm::Audioscrobbler* m_scrobbler; QString m_pw; - + QNetworkReply* m_authJob; }; diff --git a/src/infosystem/infoplugins/musixmatchplugin.cpp b/src/libtomahawk/infosystem/infoplugins/musixmatchplugin.cpp similarity index 98% rename from src/infosystem/infoplugins/musixmatchplugin.cpp rename to src/libtomahawk/infosystem/infoplugins/musixmatchplugin.cpp index 128085ca6..914a29e27 100644 --- a/src/infosystem/infoplugins/musixmatchplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/musixmatchplugin.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -16,10 +16,10 @@ * along with Tomahawk. If not, see . */ -#include "tomahawk/infosystem.h" -#include "tomahawk/tomahawkapp.h" #include "musixmatchplugin.h" +#include "utils/tomahawkutils.h" + #include #include @@ -65,7 +65,7 @@ void MusixMatchPlugin::getInfo(const QString &caller, const InfoType type, const reply->setProperty("customData", QVariant::fromValue(customData)); reply->setProperty("origData", data); reply->setProperty("caller", caller); - + connect(reply, SIGNAL(finished()), SLOT(trackSearchSlot())); } diff --git a/src/infosystem/infoplugins/musixmatchplugin.h b/src/libtomahawk/infosystem/infoplugins/musixmatchplugin.h similarity index 96% rename from src/infosystem/infoplugins/musixmatchplugin.h rename to src/libtomahawk/infosystem/infoplugins/musixmatchplugin.h index 255ebd53d..3fcb1ded7 100644 --- a/src/infosystem/infoplugins/musixmatchplugin.h +++ b/src/libtomahawk/infosystem/infoplugins/musixmatchplugin.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -18,7 +18,8 @@ #ifndef MUSIXMATCHPLUGIN_H #define MUSIXMATCHPLUGIN_H -#include "tomahawk/infosystem.h" + +#include "infosystem/infosystem.h" class QNetworkReply; @@ -31,16 +32,16 @@ namespace InfoSystem class MusixMatchPlugin : public InfoPlugin { Q_OBJECT - + public: MusixMatchPlugin(QObject *parent); virtual ~MusixMatchPlugin(); - + void getInfo(const QString &caller, const InfoType type, const QVariant &data, InfoCustomData customData); - + private: bool isValidTrackData( const QString &caller, const QVariant& data, InfoCustomData &customData ); - + public slots: void trackSearchSlot(); void trackLyricsSlot(); diff --git a/src/infosystem/infosystem.cpp b/src/libtomahawk/infosystem/infosystem.cpp similarity index 92% rename from src/infosystem/infosystem.cpp rename to src/libtomahawk/infosystem/infosystem.cpp index 7fd6158c6..6c8357ed6 100644 --- a/src/infosystem/infosystem.cpp +++ b/src/libtomahawk/infosystem/infosystem.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -18,8 +18,8 @@ #include -#include "tomahawk/infosystem.h" -#include "tomahawkutils.h" +#include "infosystem.h" +#include "utils/tomahawkutils.h" #include "infosystemcache.h" #include "infoplugins/echonestplugin.h" #include "infoplugins/musixmatchplugin.h" @@ -27,7 +27,7 @@ namespace Tomahawk { - + namespace InfoSystem { @@ -40,9 +40,9 @@ InfoPlugin::InfoPlugin(QObject *parent) { QObject::connect( this, - SIGNAL( getCachedInfo( Tomahawk::InfoSystem::InfoCacheCriteria, QString, Tomahawk::InfoSystem::InfoType, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ), + SIGNAL( getCachedInfo( Tomahawk::InfoSystem::InfoCacheCriteria, qint64, QString, Tomahawk::InfoSystem::InfoType, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ), system->getCache(), - SLOT( getCachedInfoSlot( Tomahawk::InfoSystem::InfoCacheCriteria, QString, Tomahawk::InfoSystem::InfoType, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ) + SLOT( getCachedInfoSlot( Tomahawk::InfoSystem::InfoCacheCriteria, qint64, QString, Tomahawk::InfoSystem::InfoType, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ) ); QObject::connect( system->getCache(), @@ -52,35 +52,45 @@ InfoPlugin::InfoPlugin(QObject *parent) ); QObject::connect( this, - SIGNAL( updateCache( Tomahawk::InfoSystem::InfoCacheCriteria, Tomahawk::InfoSystem::InfoType, QVariant ) ), + SIGNAL( updateCache( Tomahawk::InfoSystem::InfoCacheCriteria, qint64, Tomahawk::InfoSystem::InfoType, QVariant ) ), system->getCache(), - SLOT( updateCacheSlot( Tomahawk::InfoSystem::InfoCacheCriteria, Tomahawk::InfoSystem::InfoType, QVariant ) ) + SLOT( updateCacheSlot( Tomahawk::InfoSystem::InfoCacheCriteria, qint64, Tomahawk::InfoSystem::InfoType, QVariant ) ) ); } } +InfoSystem* InfoSystem::s_instance = 0; + +InfoSystem* +InfoSystem::instance() +{ + return s_instance; +} + InfoSystem::InfoSystem(QObject *parent) : QObject(parent) { + s_instance = this; + qDebug() << Q_FUNC_INFO; qRegisterMetaType< QMap< QString, QMap< QString, QString > > >( "Tomahawk::InfoSystem::InfoGenericMap" ); qRegisterMetaType< QHash< QString, QVariant > >( "Tomahawk::InfoSystem::InfoCustomData" ); qRegisterMetaType< QHash< QString, QString > >( "Tomahawk::InfoSystem::InfoCacheCriteria" ); qRegisterMetaType< Tomahawk::InfoSystem::InfoType >( "Tomahawk::InfoSystem::InfoType" ); - + m_infoSystemCacheThreadController = new QThread( this ); m_cache = new InfoSystemCache(); m_cache->moveToThread( m_infoSystemCacheThreadController ); m_infoSystemCacheThreadController->start( QThread::IdlePriority ); - + InfoPluginPtr enptr( new EchoNestPlugin( this ) ); m_plugins.append( enptr ); InfoPluginPtr mmptr( new MusixMatchPlugin( this ) ); m_plugins.append( mmptr ); InfoPluginPtr lfmptr( new LastFmPlugin( this ) ); m_plugins.append( lfmptr ); - + Q_FOREACH( InfoPluginPtr plugin, m_plugins ) { connect( @@ -107,19 +117,19 @@ InfoSystem::~InfoSystem() if( m_infoSystemCacheThreadController ) { m_infoSystemCacheThreadController->quit(); - + while( !m_infoSystemCacheThreadController->isFinished() ) { QCoreApplication::processEvents( QEventLoop::AllEvents, 200 ); TomahawkUtils::Sleep::msleep( 100 ); } - + if( m_cache ) { delete m_cache; m_cache = 0; } - + delete m_infoSystemCacheThreadController; m_infoSystemCacheThreadController = 0; } @@ -152,7 +162,7 @@ void InfoSystem::getInfo(const QString &caller, const InfoType type, const QVari emit finished(caller); return; } - + InfoPluginPtr ptr = providers.first(); if (!ptr) { @@ -160,7 +170,7 @@ void InfoSystem::getInfo(const QString &caller, const InfoType type, const QVari emit finished(caller); return; } - + m_dataTracker[caller][type] = m_dataTracker[caller][type] + 1; qDebug() << "current count in dataTracker for type" << type << "is" << m_dataTracker[caller][type]; ptr.data()->getInfo(caller, type, data, customData); @@ -182,7 +192,7 @@ void InfoSystem::infoSlot(QString target, InfoType type, QVariant input, QVarian return; } emit info(target, type, input, output, customData); - + m_dataTracker[target][type] = m_dataTracker[target][type] - 1; qDebug() << "current count in dataTracker is " << m_dataTracker[target][type]; Q_FOREACH(InfoType testtype, m_dataTracker[target].keys()) diff --git a/include/tomahawk/infosystem.h b/src/libtomahawk/infosystem/infosystem.h similarity index 96% rename from include/tomahawk/infosystem.h rename to src/libtomahawk/infosystem/infosystem.h index e1f0017c5..7f883e20f 100644 --- a/include/tomahawk/infosystem.h +++ b/src/libtomahawk/infosystem/infosystem.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -34,7 +34,7 @@ namespace Tomahawk { namespace InfoSystem { class InfoSystemCache; - + enum InfoType { InfoTrackID = 0, InfoTrackArtist, @@ -58,7 +58,7 @@ enum InfoType { InfoTrackDanceability, InfoTrackTempo, InfoTrackLoudness, - + InfoArtistID, InfoArtistName, InfoArtistBiography, @@ -74,7 +74,7 @@ enum InfoType { InfoArtistTerms, InfoArtistLinks, InfoArtistVideos, - + InfoAlbumID, InfoAlbumName, InfoAlbumArtist, @@ -85,10 +85,10 @@ enum InfoType { InfoMiscTopHotttness, InfoMiscTopTerms, - + InfoMiscSubmitNowPlaying, InfoMiscSubmitScrobble, - + InfoNoInfo }; @@ -100,7 +100,7 @@ typedef QHash< QString, QString > InfoCacheCriteria; class InfoPlugin : public QObject { Q_OBJECT - + public: InfoPlugin( QObject *parent ); @@ -108,15 +108,15 @@ public: { qDebug() << Q_FUNC_INFO; } - + virtual void getInfo( const QString &caller, const InfoType type, const QVariant &data, InfoCustomData customData ) = 0; - + signals: void getCachedInfo( Tomahawk::InfoSystem::InfoCacheCriteria criteria, qint64 newMaxAge, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, Tomahawk::InfoSystem::InfoCustomData customData ); - void updateCache( Tomahawk::InfoSystem::InfoCacheCriteria criteria, Tomahawk::InfoSystem::InfoType type, QVariant output ); + void updateCache( Tomahawk::InfoSystem::InfoCacheCriteria criteria, qint64, Tomahawk::InfoSystem::InfoType type, QVariant output ); void info( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ); void finished( QString, Tomahawk::InfoSystem::InfoType ); - + public slots: //FIXME: Make pure virtual when everything supports it virtual void notInCacheSlot( Tomahawk::InfoSystem::InfoCacheCriteria criteria, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, Tomahawk::InfoSystem::InfoCustomData customData ) @@ -127,7 +127,7 @@ public slots: Q_UNUSED( input ); Q_UNUSED( customData ); } - + protected: InfoType m_type; }; @@ -137,38 +137,41 @@ typedef QWeakPointer< InfoPlugin > InfoPluginPtr; class InfoSystem : public QObject { Q_OBJECT - + public: - + static InfoSystem* instance(); + InfoSystem( QObject *parent ); ~InfoSystem(); - + void registerInfoTypes( const InfoPluginPtr &plugin, const QSet< InfoType > &types ); - + void getInfo( const QString &caller, const InfoType type, const QVariant &data, InfoCustomData customData ); void getInfo( const QString &caller, const InfoMap &input, InfoCustomData customData ); - + InfoSystemCache* getCache() { return m_cache; } signals: void info( QString caller, Tomahawk::InfoSystem::InfoType, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ); void finished( QString target ); - + public slots: void infoSlot( QString target, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ); - + private: QLinkedList< InfoPluginPtr > determineOrderedMatches( const InfoType type ) const; - + QMap< InfoType, QLinkedList< InfoPluginPtr > > m_infoMap; - + // For now, statically instantiate plugins; this is just somewhere to keep them QLinkedList< InfoPluginPtr > m_plugins; - + QHash< QString, QHash< InfoType, int > > m_dataTracker; - + InfoSystemCache* m_cache; QThread* m_infoSystemCacheThreadController; + + static InfoSystem* s_instance; }; } @@ -182,14 +185,14 @@ inline uint qHash( Tomahawk::InfoSystem::InfoCacheCriteria hash ) md5.addData( key.toUtf8() ); foreach( QString value, hash.values() ) md5.addData( value.toUtf8() ); - + QString hexData = md5.result(); - + uint returnval = 0; - + foreach( uint val, hexData.toUcs4() ) returnval += val; - + return returnval; } diff --git a/src/infosystem/infosystemcache.cpp b/src/libtomahawk/infosystem/infosystemcache.cpp similarity index 100% rename from src/infosystem/infosystemcache.cpp rename to src/libtomahawk/infosystem/infosystemcache.cpp diff --git a/src/infosystem/infosystemcache.h b/src/libtomahawk/infosystem/infosystemcache.h similarity index 97% rename from src/infosystem/infosystemcache.h rename to src/libtomahawk/infosystem/infosystemcache.h index 0ccad6d19..20307eab8 100644 --- a/src/infosystem/infosystemcache.h +++ b/src/libtomahawk/infosystem/infosystemcache.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -23,11 +23,11 @@ #include #include -#include "tomahawk/infosystem.h" +#include "infosystem.h" namespace Tomahawk { - + namespace InfoSystem { @@ -37,7 +37,7 @@ Q_OBJECT public: InfoSystemCache( QObject *parent = 0 ); - + virtual ~InfoSystemCache(); signals: @@ -47,11 +47,11 @@ signals: public slots: void getCachedInfoSlot( Tomahawk::InfoSystem::InfoCacheCriteria criteria, qint64 newMaxAge, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, Tomahawk::InfoSystem::InfoCustomData customData ); void updateCacheSlot( Tomahawk::InfoSystem::InfoCacheCriteria criteria, qint64 maxAge, Tomahawk::InfoSystem::InfoType type, QVariant output ); - + private: void loadCache( InfoType type, const QString &cacheFile ); void saveCache( InfoType type, const QString &cacheDir ); - + QHash< InfoType, QHash< InfoCacheCriteria, QVariant > > m_dataCache; QHash< InfoType, QHash< InfoCacheCriteria, QDateTime > > m_insertTimeCache; QHash< InfoType, QHash< InfoCacheCriteria, QDateTime > > m_maxTimeCache; diff --git a/src/libtomahawk/network/servent.cpp b/src/libtomahawk/network/servent.cpp index 16f46d428..a1ddff6a2 100644 --- a/src/libtomahawk/network/servent.cpp +++ b/src/libtomahawk/network/servent.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include "result.h" @@ -41,7 +42,6 @@ #include "tomahawksettings.h" #include "utils/tomahawkutils.h" #include -#include using namespace Tomahawk; diff --git a/src/libtomahawk/playlist/albummodel.cpp b/src/libtomahawk/playlist/albummodel.cpp index 8a1d36cb2..bf4ea4c05 100644 --- a/src/libtomahawk/playlist/albummodel.cpp +++ b/src/libtomahawk/playlist/albummodel.cpp @@ -240,8 +240,8 @@ AlbumModel::addCollection( const collection_ptr& collection ) DatabaseCommand_AllAlbums* cmd = new DatabaseCommand_AllAlbums( collection ); - connect( cmd, SIGNAL( albums( QList, Tomahawk::collection_ptr ) ), - SLOT( onAlbumsAdded( QList, Tomahawk::collection_ptr ) ) ); + connect( cmd, SIGNAL( albums( QList, QVariant ) ), + SLOT( onAlbumsAdded( QList ) ) ); Database::instance()->enqueue( QSharedPointer( cmd ) ); @@ -262,7 +262,7 @@ AlbumModel::addFilteredCollection( const collection_ptr& collection, unsigned in cmd->setSortOrder( order ); cmd->setSortDescending( true ); - connect( cmd, SIGNAL( albums( QList ) ), + connect( cmd, SIGNAL( albums( QList, QVariant ) ), SLOT( onAlbumsAdded( QList ) ) ); Database::instance()->enqueue( QSharedPointer( cmd ) ); diff --git a/src/libtomahawk/playlist/artistview.cpp b/src/libtomahawk/playlist/artistview.cpp index ab79538b4..88f83dc08 100644 --- a/src/libtomahawk/playlist/artistview.cpp +++ b/src/libtomahawk/playlist/artistview.cpp @@ -27,6 +27,7 @@ #include "audio/audioengine.h" #include "tomahawksettings.h" +#include "treeheader.h" #include "treeitemdelegate.h" #include "playlistmanager.h" @@ -37,17 +38,35 @@ ArtistView::ArtistView( QWidget* parent ) : QTreeView( parent ) , m_model( 0 ) , m_proxyModel( 0 ) + , m_header( new TreeHeader( this ) ) // , m_delegate( 0 ) { + setAlternatingRowColors( true ); setDragEnabled( true ); setDropIndicatorShown( false ); setDragDropOverwriteMode( false ); setUniformRowHeights( false ); setVerticalScrollMode( QAbstractItemView::ScrollPerPixel ); setRootIsDecorated( true ); + setAnimated( false ); + setAllColumnsShowFocus( true ); + setSelectionMode( QAbstractItemView::ExtendedSelection ); + setSelectionBehavior( QAbstractItemView::SelectRows ); + setHeader( m_header ); setProxyModel( new TreeProxyModel( this ) ); + #ifndef Q_WS_WIN + QFont f = font(); + f.setPointSize( f.pointSize() - 1 ); + setFont( f ); + #endif + + #ifdef Q_WS_MAC + f.setPointSize( f.pointSize() - 2 ); + setFont( f ); + #endif + connect( this, SIGNAL( doubleClicked( QModelIndex ) ), SLOT( onItemActivated( QModelIndex ) ) ); } diff --git a/src/libtomahawk/playlist/artistview.h b/src/libtomahawk/playlist/artistview.h index e22205c24..d272df314 100644 --- a/src/libtomahawk/playlist/artistview.h +++ b/src/libtomahawk/playlist/artistview.h @@ -28,6 +28,8 @@ #include "dllmacro.h" +class TreeHeader; + class DLLEXPORT ArtistView : public QTreeView, public Tomahawk::ViewPage { Q_OBJECT @@ -71,6 +73,7 @@ private slots: private: QPixmap createDragPixmap( int itemCount ) const; + TreeHeader* m_header; TreeModel* m_model; TreeProxyModel* m_proxyModel; // PlaylistItemDelegate* m_delegate; diff --git a/src/libtomahawk/playlist/collectionflatmodel.cpp b/src/libtomahawk/playlist/collectionflatmodel.cpp index aa7cae7e6..2090b6cba 100644 --- a/src/libtomahawk/playlist/collectionflatmodel.cpp +++ b/src/libtomahawk/playlist/collectionflatmodel.cpp @@ -102,8 +102,8 @@ CollectionFlatModel::addFilteredCollection( const collection_ptr& collection, un cmd->setSortOrder( order ); cmd->setSortDescending( true ); - connect( cmd, SIGNAL( tracks( QList, Tomahawk::collection_ptr ) ), - SLOT( onTracksAdded( QList, Tomahawk::collection_ptr ) ), Qt::QueuedConnection ); + connect( cmd, SIGNAL( tracks( QList, QVariant ) ), + SLOT( onTracksAdded( QList ) ), Qt::QueuedConnection ); Database::instance()->enqueue( QSharedPointer( cmd ) ); } diff --git a/src/libtomahawk/playlist/playlistmanager.cpp b/src/libtomahawk/playlist/playlistmanager.cpp index 52a08c778..cbf1337cf 100644 --- a/src/libtomahawk/playlist/playlistmanager.cpp +++ b/src/libtomahawk/playlist/playlistmanager.cpp @@ -390,6 +390,10 @@ PlaylistManager::showSuperCollection() { setPage( m_superCollectionView ); } + else if ( m_currentMode == 1 ) + { + setPage( m_superCollectionView ); + } else if ( m_currentMode == 2 ) { setPage( m_superAlbumView ); diff --git a/src/libtomahawk/playlist/treeitemdelegate.cpp b/src/libtomahawk/playlist/treeitemdelegate.cpp index fbc1fa16b..51704d7e8 100644 --- a/src/libtomahawk/playlist/treeitemdelegate.cpp +++ b/src/libtomahawk/playlist/treeitemdelegate.cpp @@ -78,6 +78,9 @@ TreeItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, opt.palette.setColor( QPalette::Text, opt.palette.color( QPalette::HighlightedText ) ); } + if ( index.column() > 0 ) + return; + painter->save(); painter->setRenderHint( QPainter::Antialiasing ); painter->setPen( opt.palette.color( QPalette::Text ) ); @@ -92,7 +95,8 @@ TreeItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, QFont boldFont = opt.font; boldFont.setBold( true ); - r = option.rect.adjusted( option.rect.height(), 6, 0, -option.rect.height() + 22 ); + r = option.rect.adjusted( option.rect.height(), 6, -4, -option.rect.height() + 22 ); + text = painter->fontMetrics().elidedText( text, Qt::ElideRight, r.width() ); painter->drawText( r, text, to ); painter->setFont( boldFont ); diff --git a/src/libtomahawk/playlist/treemodel.cpp b/src/libtomahawk/playlist/treemodel.cpp index 86dc33077..d95f10240 100644 --- a/src/libtomahawk/playlist/treemodel.cpp +++ b/src/libtomahawk/playlist/treemodel.cpp @@ -30,7 +30,7 @@ #define LASTFM_DEFAULT_COVER "http://cdn.last.fm/flatness/catalogue/noimage" -static QString s_infoIdentifier = QString( "TREEMODEL" ); +static QString s_tmInfoIdentifier = QString( "TREEMODEL" ); using namespace Tomahawk; @@ -44,11 +44,11 @@ TreeModel::TreeModel( QObject* parent ) m_defaultCover = QPixmap( RESPATH "images/no-album-art-placeholder.png" ) .scaled( QSize( 120, 120 ), Qt::IgnoreAspectRatio, Qt::SmoothTransformation ); -/* connect( TomahawkApp::instance()->infoSystem(), + connect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ), SLOT( infoSystemInfo( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ) ); - connect( TomahawkApp::instance()->infoSystem(), SIGNAL( finished( QString ) ), SLOT( infoSystemFinished( QString ) ) );*/ + connect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( finished( QString ) ), SLOT( infoSystemFinished( QString ) ) ); } @@ -142,7 +142,7 @@ int TreeModel::columnCount( const QModelIndex& parent ) const { Q_UNUSED( parent ); - return 4; + return 7; } @@ -190,22 +190,47 @@ TreeModel::data( const QModelIndex& index, int role ) const if ( role != Qt::DisplayRole ) // && role != Qt::ToolTipRole ) return QVariant(); - switch( index.column() ) + if ( !entry->artist().isNull() && index.column() == Name ) { - case 0: - if ( !entry->artist().isNull() ) - { - return entry->artist()->name(); - } - else if ( !entry->artist().isNull() ) - { - return entry->album()->name(); - } - else if ( !entry->result().isNull() ) - { - return entry->result()->track(); - } - break; + return entry->artist()->name(); + } + else if ( !entry->album().isNull() && index.column() == Name ) + { + return entry->album()->name(); + } + else + { + const result_ptr& result = entry->result(); + switch( index.column() ) + { + case Name: + return QString( "%1%2" ).arg( result->albumpos() > 0 ? QString( "%1. ").arg( result->albumpos() ) : QString() ) + .arg( result->track() ); + + case Duration: + return TomahawkUtils::timeToString( result->duration() ); + + case Bitrate: + return result->bitrate(); + + case Age: + return TomahawkUtils::ageToString( QDateTime::fromTime_t( result->modificationTime() ) ); + + case Year: + return result->year(); + + case Filesize: + return TomahawkUtils::filesizeToString( result->size() ); + + case Origin: + return result->friendlySource(); + + case AlbumPosition: + return result->albumpos(); + + default: + return QVariant(); + } } return QVariant(); @@ -216,7 +241,7 @@ QVariant TreeModel::headerData( int section, Qt::Orientation orientation, int role ) const { QStringList headers; - headers << tr( "Artist" ); + headers << tr( "Name" ) << tr( "Duration" ) << tr( "Bitrate" ) << tr( "Age" ) << tr( "Year" ) << tr( "Size" ) << tr( "Origin" ); if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 ) { return headers.at( section ); @@ -453,14 +478,14 @@ TreeModel::onAlbumsAdded( const QList& albums, const QVaria albumitem->index = createIndex( parentItem->children.count() - 1, 0, albumitem ); connect( albumitem, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) ); -/* Tomahawk::InfoSystem::InfoCustomData trackInfo; + Tomahawk::InfoSystem::InfoCustomData trackInfo; trackInfo["artist"] = QVariant::fromValue< QString >( album->artist()->name() ); trackInfo["album"] = QVariant::fromValue< QString >( album->name() ); - trackInfo["pptr"] = (qlonglong)albumitem; + trackInfo["pptr"] = QVariant::fromValue< qlonglong >( (qlonglong)albumitem ); - TomahawkApp::instance()->infoSystem()->getInfo( - s_infoIdentifier, Tomahawk::InfoSystem::InfoAlbumCoverArt, - QVariant::fromValue< Tomahawk::InfoSystem::InfoCustomData >( trackInfo ), Tomahawk::InfoSystem::InfoCustomData() );*/ + Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( + s_tmInfoIdentifier, Tomahawk::InfoSystem::InfoAlbumCoverArt, + QVariant::fromValue< Tomahawk::InfoSystem::InfoCustomData >( trackInfo ), Tomahawk::InfoSystem::InfoCustomData() ); } if ( crows.second > 0 ) @@ -517,7 +542,7 @@ void TreeModel::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ) { qDebug() << Q_FUNC_INFO; - if ( caller != s_infoIdentifier || type != Tomahawk::InfoSystem::InfoAlbumCoverArt ) + if ( caller != s_tmInfoIdentifier || type != Tomahawk::InfoSystem::InfoAlbumCoverArt ) { qDebug() << "Info of wrong type or not with our identifier"; return; @@ -529,6 +554,7 @@ TreeModel::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, return; } + Tomahawk::InfoSystem::InfoCustomData pptr = input.value< Tomahawk::InfoSystem::InfoCustomData >(); Tomahawk::InfoSystem::InfoCustomData returnedData = output.value< Tomahawk::InfoSystem::InfoCustomData >(); const QByteArray ba = returnedData["imgbytes"].toByteArray(); if ( ba.length() ) @@ -536,13 +562,15 @@ TreeModel::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QPixmap pm; pm.loadFromData( ba ); - qlonglong pptr = input.toLongLong(); - TreeModelItem* ai = reinterpret_cast(pptr); + qlonglong p = pptr["pptr"].toLongLong(); + TreeModelItem* ai = reinterpret_cast(p); if ( pm.isNull() || returnedData["url"].toString().startsWith( LASTFM_DEFAULT_COVER ) ) ai->cover = m_defaultCover; else ai->cover = pm; + + emit dataChanged( ai->index, ai->index.sibling( ai->index.row(), columnCount( QModelIndex() ) - 1 ) ); } } diff --git a/src/libtomahawk/playlist/treemodel.h b/src/libtomahawk/playlist/treemodel.h index 6062c37cb..68f23bd98 100644 --- a/src/libtomahawk/playlist/treemodel.h +++ b/src/libtomahawk/playlist/treemodel.h @@ -28,7 +28,7 @@ #include "database/databasecommand_allartists.h" #include "treemodelitem.h" -#include "tomahawk/infosystem.h" +#include "infosystem/infosystem.h" #include "dllmacro.h" @@ -39,6 +39,17 @@ class DLLEXPORT TreeModel : public QAbstractItemModel Q_OBJECT public: + enum Columns { + Name = 0, + Duration, + Bitrate, + Age, + Year, + Filesize, + Origin, + AlbumPosition + }; + explicit TreeModel( QObject* parent = 0 ); virtual ~TreeModel(); diff --git a/src/libtomahawk/playlist/treeproxymodel.cpp b/src/libtomahawk/playlist/treeproxymodel.cpp index 357596ed0..3f8b86b16 100644 --- a/src/libtomahawk/playlist/treeproxymodel.cpp +++ b/src/libtomahawk/playlist/treeproxymodel.cpp @@ -99,6 +99,12 @@ TreeProxyModel::lessThan( const QModelIndex& left, const QModelIndex& right ) co if ( !p2 ) return false; + if ( !p1->result().isNull() ) + { + if ( p1->result()->albumpos() != p2->result()->albumpos() ) + return p1->result()->albumpos() < p2->result()->albumpos(); + } + return QString::localeAwareCompare( textForItem( p1 ), textForItem( p2 ) ) < 0; } diff --git a/src/scanmanager.cpp b/src/scanmanager.cpp index 27f134e01..acca5dc90 100644 --- a/src/scanmanager.cpp +++ b/src/scanmanager.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -26,7 +26,7 @@ #include "musicscanner.h" #include "tomahawksettings.h" -#include "tomahawkutils.h" +#include "utils/tomahawkutils.h" #include "database/database.h" #include "database/databasecommand_dirmtimes.h" @@ -60,15 +60,15 @@ ScanManager::ScanManager( QObject* parent ) m_deferredScanTimer->setSingleShot( false ); m_deferredScanTimer->setInterval( 1000 ); m_dirWatcher = new QFileSystemWatcher( this ); - + connect( TomahawkSettings::instance(), SIGNAL( changed() ), SLOT( onSettingsChanged() ) ); connect( m_queuedScanTimer, SIGNAL( timeout() ), SLOT( queuedScanTimeout() ) ); connect( m_deferredScanTimer, SIGNAL( timeout() ), SLOT( deferredScanTimeout() ) ); connect( m_dirWatcher, SIGNAL( directoryChanged( const QString & ) ), SLOT( handleChangedDir( const QString & ) ) ); - + if ( TomahawkSettings::instance()->hasScannerPaths() ) m_currScannerPaths = TomahawkSettings::instance()->scannerPaths(); - + qDebug() << "loading initial directories to watch"; QTimer::singleShot( 1000, this, SLOT( startupWatchPaths() ) ); m_deferredScanTimer->start(); @@ -78,11 +78,11 @@ ScanManager::ScanManager( QObject* parent ) ScanManager::~ScanManager() { qDebug() << Q_FUNC_INFO; - + if( m_musicScannerThreadController ) { m_musicScannerThreadController->quit(); - + while( !m_musicScannerThreadController->isFinished() ) { QCoreApplication::processEvents( QEventLoop::AllEvents, 200 ); @@ -94,7 +94,7 @@ ScanManager::~ScanManager() delete m_scanner; m_scanner = 0; } - + delete m_musicScannerThreadController; m_musicScannerThreadController = 0; } @@ -112,7 +112,7 @@ ScanManager::onSettingsChanged() m_dirWatcher->addPaths( m_currScannerPaths ); runManualScan( m_currScannerPaths ); } - + if( TomahawkSettings::instance()->watchForChanges() && !m_queuedChangedDirs.isEmpty() ) runManualScan( m_queuedChangedDirs, false ); @@ -123,13 +123,13 @@ void ScanManager::startupWatchPaths() { qDebug() << Q_FUNC_INFO; - + if( !Database::instance() || ( Database::instance() && !Database::instance()->isReady() ) ) { QTimer::singleShot( 1000, this, SLOT( startupWatchPaths() ) ); return; } - + DatabaseCommand_DirMtimes* cmd = new DatabaseCommand_DirMtimes( m_currScannerPaths ); connect( cmd, SIGNAL( done( QMap< QString, unsigned int > ) ), SLOT( setInitialPaths( QMap< QString, unsigned int > ) ) ); @@ -155,7 +155,7 @@ void ScanManager::runManualScan( const QStringList& paths, bool recursive ) { qDebug() << Q_FUNC_INFO; - + if ( !m_musicScannerThreadController && !m_scanner ) //still running if these are not zero { m_musicScannerThreadController = new QThread( this ); @@ -185,7 +185,7 @@ ScanManager::runManualScan( const QStringList& paths, bool recursive ) m_deferredDirs[recursive] << path; } } - } + } } @@ -244,7 +244,7 @@ ScanManager::deferredScanTimeout() runManualScan( m_deferredDirs[true], true ); } else if( !m_deferredDirs[false].isEmpty() ) - { + { qDebug() << "Running scan for deferred non-recursive paths"; runManualScan( m_deferredDirs[false], false ); } diff --git a/src/scrobbler.cpp b/src/scrobbler.cpp index 2968d5196..74ad40ae8 100644 --- a/src/scrobbler.cpp +++ b/src/scrobbler.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -26,10 +26,9 @@ #include "typedefs.h" #include "audio/audioengine.h" #include "tomahawksettings.h" -#include "tomahawk/tomahawkapp.h" -#include "tomahawk/infosystem.h" +#include "infosystem/infosystem.h" -static QString s_infoIdentifier = QString("SCROBBLER"); +static QString s_scInfoIdentifier = QString( "SCROBBLER" ); Scrobbler::Scrobbler( QObject* parent ) : QObject( parent ) @@ -37,13 +36,11 @@ Scrobbler::Scrobbler( QObject* parent ) { connect( AudioEngine::instance(), SIGNAL( timerSeconds( unsigned int ) ), SLOT( engineTick( unsigned int ) ), Qt::QueuedConnection ); - - connect( TomahawkApp::instance()->infoSystem(), + + connect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ), SLOT( infoSystemInfo( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ) ); - connect( TomahawkApp::instance()->infoSystem(), SIGNAL( finished( QString ) ), SLOT( infoSystemFinished( QString ) ) ); - connect( AudioEngine::instance(), SIGNAL( started( const Tomahawk::result_ptr& ) ), SLOT( trackStarted( const Tomahawk::result_ptr& ) ), Qt::QueuedConnection ); @@ -55,6 +52,8 @@ Scrobbler::Scrobbler( QObject* parent ) connect( AudioEngine::instance(), SIGNAL( stopped() ), SLOT( trackStopped() ), Qt::QueuedConnection ); + + connect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( finished( QString ) ), SLOT( infoSystemFinished( QString ) ) ); } @@ -63,7 +62,7 @@ Scrobbler::~Scrobbler() } -void +void Scrobbler::trackStarted( const Tomahawk::result_ptr& track ) { Q_ASSERT( QThread::currentThread() == thread() ); @@ -76,34 +75,34 @@ Scrobbler::trackStarted( const Tomahawk::result_ptr& track ) } Tomahawk::InfoSystem::InfoCustomData trackInfo; - + trackInfo["title"] = QVariant::fromValue< QString >( track->track() ); trackInfo["artist"] = QVariant::fromValue< QString >( track->artist()->name() ); trackInfo["album"] = QVariant::fromValue< QString >( track->album()->name() ); trackInfo["duration"] = QVariant::fromValue< uint >( track->duration() ); - TomahawkApp::instance()->infoSystem()->getInfo( - s_infoIdentifier, Tomahawk::InfoSystem::InfoMiscSubmitNowPlaying, + Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( + s_scInfoIdentifier, Tomahawk::InfoSystem::InfoMiscSubmitNowPlaying, QVariant::fromValue< Tomahawk::InfoSystem::InfoCustomData >( trackInfo ), Tomahawk::InfoSystem::InfoCustomData() ); - + m_scrobblePoint = ScrobblePoint( track->duration() / 2 ); } -void +void Scrobbler::trackPaused() { Q_ASSERT( QThread::currentThread() == thread() ); } -void +void Scrobbler::trackResumed() { Q_ASSERT( QThread::currentThread() == thread() ); } -void +void Scrobbler::trackStopped() { Q_ASSERT( QThread::currentThread() == thread() ); @@ -128,19 +127,20 @@ void Scrobbler::scrobble() { Q_ASSERT( QThread::currentThread() == thread() ); - - TomahawkApp::instance()->infoSystem()->getInfo( - s_infoIdentifier, Tomahawk::InfoSystem::InfoMiscSubmitScrobble, + + Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( + s_scInfoIdentifier, Tomahawk::InfoSystem::InfoMiscSubmitScrobble, QVariant(), Tomahawk::InfoSystem::InfoCustomData() ); } + void Scrobbler::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ) { Q_UNUSED( input ); Q_UNUSED( output ); Q_UNUSED( customData ); - if ( caller == s_infoIdentifier ) + if ( caller == s_scInfoIdentifier ) { qDebug() << Q_FUNC_INFO; if ( type == Tomahawk::InfoSystem::InfoMiscSubmitNowPlaying ) @@ -150,10 +150,11 @@ Scrobbler::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, } } -void + +void Scrobbler::infoSystemFinished( QString target ) { - if ( target == s_infoIdentifier ) + if ( target == s_scInfoIdentifier ) { qDebug() << Q_FUNC_INFO; qDebug() << "Scrobbler received done signal from InfoSystem"; diff --git a/src/scrobbler.h b/src/scrobbler.h index 11741beec..f2c484aa9 100644 --- a/src/scrobbler.h +++ b/src/scrobbler.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -23,7 +23,7 @@ #include "lastfm/ScrobblePoint" -#include "tomahawk/infosystem.h" +#include "infosystem/infosystem.h" #include @@ -37,20 +37,20 @@ class Scrobbler : public QObject public: Scrobbler( QObject* parent = 0 ); virtual ~Scrobbler(); - + public slots: void trackStarted( const Tomahawk::result_ptr& ); void trackPaused(); void trackResumed(); void trackStopped(); void engineTick( unsigned int secondsElapsed ); - + void infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ); void infoSystemFinished( QString target ); - + private: void scrobble(); - + bool m_reachedScrobblePoint; ScrobblePoint m_scrobblePoint; }; diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index 365414b81..1c64fa8de 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -32,7 +32,7 @@ #include "artist.h" #include "album.h" #include "collection.h" -#include "tomahawk/infosystem.h" +#include "infosystem/infosystem.h" #include "database/database.h" #include "database/databasecollection.h" #include "database/databasecommand_collectionstats.h" @@ -152,7 +152,6 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] ) , m_shortcutHandler( 0 ) , m_scrubFriendlyName( false ) , m_mainwindow( 0 ) - , m_infoSystem( 0 ) { qDebug() << "TomahawkApp thread:" << this->thread(); setOrganizationName( QLatin1String( ORGANIZATION_NAME ) ); @@ -176,7 +175,6 @@ TomahawkApp::init() #endif registerMetaTypes(); - setupLogfile(); Echonest::Config::instance()->setAPIKey( "JRIHWEP6GPOER2QQ6" ); @@ -217,7 +215,7 @@ TomahawkApp::init() } qDebug() << "Init InfoSystem."; - m_infoSystem = new Tomahawk::InfoSystem::InfoSystem( this ); + new Tomahawk::InfoSystem::InfoSystem( this ); #ifdef LIBLASTFM_FOUND qDebug() << "Init Scrobbler."; @@ -304,7 +302,7 @@ TomahawkApp::~TomahawkApp() delete m_mainwindow; delete m_audioEngine; #endif - delete m_infoSystem; +// delete m_infoSystem; delete m_database; } diff --git a/src/web/api_v1.h b/src/web/api_v1.h index f7476990e..cc065a41a 100644 --- a/src/web/api_v1.h +++ b/src/web/api_v1.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -38,8 +38,7 @@ #include #include "network/servent.h" -#include "tomahawkutils.h" -#include "tomahawk/tomahawkapp.h" +#include "utils/tomahawkutils.h" #include #include #include diff --git a/src/xmppbot/xmppbot.cpp b/src/xmppbot/xmppbot.cpp index 464e09ede..404d64fd2 100644 --- a/src/xmppbot/xmppbot.cpp +++ b/src/xmppbot/xmppbot.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -18,8 +18,7 @@ #include "xmppbot.h" -#include "tomahawk/tomahawkapp.h" -#include "tomahawk/infosystem.h" +#include "infosystem/infosystem.h" #include "album.h" #include "typedefs.h" #include "tomahawksettings.h" @@ -36,7 +35,7 @@ using namespace gloox; using namespace Tomahawk::InfoSystem; -static QString s_infoIdentifier = QString("XMPPBot"); +static QString s_botInfoIdentifier = QString( "XMPPBot" ); XMPPBot::XMPPBot(QObject *parent) : QObject(parent) @@ -50,7 +49,7 @@ XMPPBot::XMPPBot(QObject *parent) int port = settings->xmppBotPort(); if (jidstring.isEmpty() || password.isEmpty()) return; - + JID jid(jidstring.toStdString()); jid.setResource( QString( "tomahawkbot%1" ).arg( qrand() ).toStdString() ); @@ -66,11 +65,11 @@ XMPPBot::XMPPBot(QObject *parent) connect(AudioEngine::instance(), SIGNAL(started(const Tomahawk::result_ptr &)), SLOT(newTrackSlot(const Tomahawk::result_ptr &))); - connect(TomahawkApp::instance()->infoSystem(), + connect(InfoSystem::instance(), SIGNAL(info(QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData)), SLOT(infoReturnedSlot(QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData))); - - connect(TomahawkApp::instance()->infoSystem(), SIGNAL(finished(QString)), SLOT(infoFinishedSlot(QString))); + + connect(InfoSystem::instance(), SIGNAL(finished(QString)), SLOT(infoFinishedSlot(QString))); bool success = m_client.data()->gloox::Client::connect(false); if (success) @@ -149,7 +148,7 @@ void XMPPBot::handleMessage(const Message& msg, MessageSession* session) //TODO: implement "properly" with MessageSessions, if the bot is to be multi-user if (msg.subtype() != Message::Chat || msg.from().full().empty() || msg.to().full().empty()) return; - + QString body = QString::fromStdString( msg.body() ).toLower().trimmed(); QString originatingJid = QString::fromStdString( msg.from().full() ); @@ -192,7 +191,7 @@ void XMPPBot::handleMessage(const Message& msg, MessageSession* session) qDebug() << "jid from:" << QString::fromStdString(msg.from().full()) << ", jid to:" << QString::fromStdString(msg.to().full()); qDebug() << "Operating on tokens:" << tokens; - + if (m_currTrack.isNull() || m_currTrack->artist()->name().isEmpty() || m_currTrack->track().isEmpty()) { qDebug() << "XMPPBot can't figure out track"; @@ -201,8 +200,8 @@ void XMPPBot::handleMessage(const Message& msg, MessageSession* session) m_client.data()->send(retMsg); return; } - - InfoMap infoMap; + + InfoMap infoMap; Q_FOREACH(QString token, tokens) { if (token == "biography") @@ -221,7 +220,7 @@ void XMPPBot::handleMessage(const Message& msg, MessageSession* session) infoMap[InfoTrackLyrics] = QVariant::fromValue(myhash); } } - + if (infoMap.isEmpty()) { qDebug() << "XMPPBot can't figure out track"; @@ -229,38 +228,38 @@ void XMPPBot::handleMessage(const Message& msg, MessageSession* session) Message retMsg(Message::Chat, JID(originatingJid.toStdString()), m_currReturnMessage.toStdString()); m_client.data()->send(retMsg); return; - } - + } + m_currInfoMap.unite(infoMap); QString waitMsg("Please wait..."); Message retMsg(Message::Chat, JID(originatingJid.toStdString()), waitMsg.toStdString()); m_client.data()->send(retMsg); Tomahawk::InfoSystem::InfoCustomData hash; hash["XMPPBotSendToJID"] = originatingJid; - TomahawkApp::instance()->infoSystem()->getInfo(s_infoIdentifier, infoMap, hash); + InfoSystem::instance()->getInfo(s_botInfoIdentifier, infoMap, hash); } void XMPPBot::infoReturnedSlot(QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData) { qDebug() << Q_FUNC_INFO; - - if (caller != s_infoIdentifier || + + if (caller != s_botInfoIdentifier || input.isNull() || !input.isValid() || !customData.contains("XMPPBotSendToJID") ) { qDebug() << "Not the right object, custom data is null, or don't have a set JID"; return; - } - + } + if (!m_currInfoMap.contains(type)) { qDebug() << "not in currInfoMap"; return; } - else + else m_currInfoMap.remove(type); - + QString jid = customData["XMPPBotSendToJID"].toString(); if (!m_currReturnJid.isEmpty() && m_currReturnJid != jid && !m_currReturnMessage.isEmpty()) { @@ -269,7 +268,7 @@ void XMPPBot::infoReturnedSlot(QString caller, Tomahawk::InfoSystem::InfoType ty m_currReturnMessage = QString("\n"); } m_currReturnJid = jid; - + switch(type) { case InfoArtistBiography: @@ -287,7 +286,7 @@ void XMPPBot::infoReturnedSlot(QString caller, Tomahawk::InfoSystem::InfoType ty m_currReturnMessage += QString("\nBiographies for %1\n").arg(artist); Q_FOREACH(QString source, bmap.keys()) { - m_currReturnMessage += (bmap[source]["attribution"].isEmpty() ? + m_currReturnMessage += (bmap[source]["attribution"].isEmpty() ? QString("From %1:\n").arg(bmap[source]["site"]) : QString("From %1 at %2:\n").arg(bmap[source]["attribution"]).arg(bmap[source]["site"])); m_currReturnMessage += bmap[source]["text"] + QString("\n"); @@ -381,15 +380,15 @@ void XMPPBot::infoReturnedSlot(QString caller, Tomahawk::InfoSystem::InfoType ty default: break; } - + if (m_currReturnMessage.isEmpty()) { qDebug() << "Empty message, not sending anything back"; return; } - + qDebug() << "Going to send message: " << m_currReturnMessage << " to " << jid; - + //gloox::Message msg(Message::Chat, JID(jid.toStdString()), m_currReturnMessage.toStdString()); //m_client.data()->send(msg); } @@ -398,10 +397,10 @@ void XMPPBot::infoFinishedSlot(QString caller) { qDebug() << Q_FUNC_INFO; qDebug() << "current return message is" << m_currReturnMessage; - qDebug() << "id is" << caller << "and our id is" << s_infoIdentifier; - if (m_currReturnMessage.isEmpty() || caller != s_infoIdentifier) + qDebug() << "id is" << caller << "and our id is" << s_botInfoIdentifier; + if (m_currReturnMessage.isEmpty() || caller != s_botInfoIdentifier) return; - + qDebug() << "Sending message to JID" << m_currReturnJid; gloox::Message msg(Message::Chat, JID(m_currReturnJid.toStdString()), m_currReturnMessage.toStdString()); m_client.data()->send(msg); diff --git a/src/xmppbot/xmppbot.h b/src/xmppbot/xmppbot.h index ee5a2b38a..e22a564ae 100644 --- a/src/xmppbot/xmppbot.h +++ b/src/xmppbot/xmppbot.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -20,7 +20,7 @@ #define XMPPBOT_H #include -#include +#include #include #include @@ -42,12 +42,12 @@ class XMPPBotClient public: XMPPBotClient(QObject* parent, gloox::JID &jid, std::string password, int port); virtual ~XMPPBotClient(); - + void run(); - + private slots: void recvSlot(); - + private: QTimer m_timer; }; @@ -59,7 +59,7 @@ class XMPPBot , public gloox::MessageHandler { Q_OBJECT - + public: XMPPBot(QObject *parent); virtual ~XMPPBot(); @@ -68,16 +68,16 @@ public slots: virtual void newTrackSlot(const Tomahawk::result_ptr &track); virtual void infoReturnedSlot(QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData); virtual void infoFinishedSlot(QString caller); - + protected: // ConnectionListener virtual void onConnect(); virtual void onDisconnect(gloox::ConnectionError e); virtual bool onTLSConnect(const gloox::CertInfo &info); - + // SubscriptionHandler virtual void handleSubscription(const gloox::Subscription &subscription); - + // MessageHandler virtual void handleMessage(const gloox::Message &msg, gloox::MessageSession *session = 0); From e3c90784e1077bcb78ebcafde01a403089241463 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Thu, 14 Apr 2011 04:40:04 +0200 Subject: [PATCH 44/75] * Properly shutdown InfoSystem again. * Default sizes & restoring of TreeHeader columns. * Fix square cover painting in TreeItemDelegate. --- include/tomahawk/tomahawkapp.h | 5 +++++ src/libtomahawk/infosystem/infosystem.h | 6 ++++-- src/libtomahawk/playlist/albummodel.cpp | 1 - src/libtomahawk/playlist/artistview.cpp | 8 ++++++++ src/libtomahawk/playlist/artistview.h | 4 ++++ src/libtomahawk/playlist/treeheader.cpp | 8 ++++---- src/libtomahawk/playlist/treeitemdelegate.cpp | 2 +- src/libtomahawk/playlist/treemodel.cpp | 2 +- src/libtomahawk/source.cpp | 12 +++++++++++- src/libtomahawk/source.h | 8 ++++---- src/tomahawkapp.cpp | 4 ++-- 11 files changed, 44 insertions(+), 16 deletions(-) diff --git a/include/tomahawk/tomahawkapp.h b/include/tomahawk/tomahawkapp.h index 5e7a7db7f..b03e17ab6 100644 --- a/include/tomahawk/tomahawkapp.h +++ b/include/tomahawk/tomahawkapp.h @@ -52,6 +52,10 @@ class XMPPBot; namespace Tomahawk { class ShortcutHandler; + namespace InfoSystem + { + class InfoSystem; + } } #ifdef LIBLASTFM_FOUND @@ -119,6 +123,7 @@ private: AudioEngine* m_audioEngine; SipHandler* m_sipHandler; Servent* m_servent; + Tomahawk::InfoSystem::InfoSystem* m_infoSystem; XMPPBot* m_xmppBot; Tomahawk::ShortcutHandler* m_shortcutHandler; bool m_scrubFriendlyName; diff --git a/src/libtomahawk/infosystem/infosystem.h b/src/libtomahawk/infosystem/infosystem.h index 7f883e20f..75e674f49 100644 --- a/src/libtomahawk/infosystem/infosystem.h +++ b/src/libtomahawk/infosystem/infosystem.h @@ -29,6 +29,8 @@ #include #include +#include "dllmacro.h" + namespace Tomahawk { namespace InfoSystem { @@ -97,7 +99,7 @@ typedef QMap< QString, QMap< QString, QString > > InfoGenericMap; typedef QHash< QString, QVariant > InfoCustomData; typedef QHash< QString, QString > InfoCacheCriteria; -class InfoPlugin : public QObject +class DLLEXPORT InfoPlugin : public QObject { Q_OBJECT @@ -134,7 +136,7 @@ protected: typedef QWeakPointer< InfoPlugin > InfoPluginPtr; -class InfoSystem : public QObject +class DLLEXPORT InfoSystem : public QObject { Q_OBJECT diff --git a/src/libtomahawk/playlist/albummodel.cpp b/src/libtomahawk/playlist/albummodel.cpp index bf4ea4c05..7e28d655d 100644 --- a/src/libtomahawk/playlist/albummodel.cpp +++ b/src/libtomahawk/playlist/albummodel.cpp @@ -274,7 +274,6 @@ AlbumModel::addFilteredCollection( const collection_ptr& collection, unsigned in void AlbumModel::onAlbumsAdded( const QList& albums ) { - Q_UNUSED( collection ); if ( !albums.count() ) return; diff --git a/src/libtomahawk/playlist/artistview.cpp b/src/libtomahawk/playlist/artistview.cpp index 88f83dc08..2c8412057 100644 --- a/src/libtomahawk/playlist/artistview.cpp +++ b/src/libtomahawk/playlist/artistview.cpp @@ -149,6 +149,14 @@ ArtistView::paintEvent( QPaintEvent* event ) } +void +ArtistView::resizeEvent( QResizeEvent* event ) +{ + QTreeView::resizeEvent( event ); + m_header->checkState(); +} + + void ArtistView::onFilterChanged( const QString& ) { diff --git a/src/libtomahawk/playlist/artistview.h b/src/libtomahawk/playlist/artistview.h index d272df314..6f9b94b1f 100644 --- a/src/libtomahawk/playlist/artistview.h +++ b/src/libtomahawk/playlist/artistview.h @@ -52,10 +52,13 @@ public: virtual QString title() const { return m_model->title(); } virtual QString description() const { return m_model->description(); } + virtual bool showStatsBar() const { return false; } virtual bool showModes() const { return true; } virtual bool jumpToCurrentTrack() { return false; } + QString guid() const { return QString( "ArtistView" ); } + public slots: void onItemActivated( const QModelIndex& index ); @@ -64,6 +67,7 @@ protected: virtual void dragEnterEvent( QDragEnterEvent* event ); virtual void dragMoveEvent( QDragMoveEvent* event ); virtual void dropEvent( QDropEvent* event ); + virtual void resizeEvent( QResizeEvent* event ); void paintEvent( QPaintEvent* event ); diff --git a/src/libtomahawk/playlist/treeheader.cpp b/src/libtomahawk/playlist/treeheader.cpp index 12ca97c04..72bc75192 100644 --- a/src/libtomahawk/playlist/treeheader.cpp +++ b/src/libtomahawk/playlist/treeheader.cpp @@ -60,7 +60,7 @@ TreeHeader::onSectionResized() if ( !m_init ) return; -// TomahawkSettings::instance()->setPlaylistColumnSizes( m_parent->guid(), saveState() ); + TomahawkSettings::instance()->setPlaylistColumnSizes( m_parent->guid(), saveState() ); } @@ -77,13 +77,13 @@ TreeHeader::checkState() if ( !count() || m_init ) return; -/* QByteArray state = TomahawkSettings::instance()->playlistColumnSizes( m_parent->guid() ); + QByteArray state = TomahawkSettings::instance()->playlistColumnSizes( m_parent->guid() ); if ( !state.isEmpty() ) restoreState( state ); else { QList< double > m_columnWeights; - m_columnWeights << 0.21 << 0.22 << 0.20 << 0.05 << 0.05 << 0.05 << 0.05 << 0.05; // << 0.12; + m_columnWeights << 0.50 << 0.07 << 0.07 << 0.07 << 0.07 << 0.07; // << 0.12; for ( int i = 0; i < count() - 1; i++ ) { @@ -96,7 +96,7 @@ TreeHeader::checkState() } } - m_init = true;*/ + m_init = true; } diff --git a/src/libtomahawk/playlist/treeitemdelegate.cpp b/src/libtomahawk/playlist/treeitemdelegate.cpp index 51704d7e8..fa080c980 100644 --- a/src/libtomahawk/playlist/treeitemdelegate.cpp +++ b/src/libtomahawk/playlist/treeitemdelegate.cpp @@ -85,7 +85,7 @@ TreeItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, painter->setRenderHint( QPainter::Antialiasing ); painter->setPen( opt.palette.color( QPalette::Text ) ); - QRect r = option.rect.adjusted( 4, 4, -option.rect.width() + option.rect.height() - 8, -4 ); + QRect r = option.rect.adjusted( 4, 4, -option.rect.width() + option.rect.height() - 4, -4 ); // painter->drawPixmap( option.rect.adjusted( 4, 4, -4, -38 ), QPixmap( RESPATH "images/cover-shadow.png" ) ); painter->drawPixmap( r, item->cover ); diff --git a/src/libtomahawk/playlist/treemodel.cpp b/src/libtomahawk/playlist/treemodel.cpp index d95f10240..ea8feb1c7 100644 --- a/src/libtomahawk/playlist/treemodel.cpp +++ b/src/libtomahawk/playlist/treemodel.cpp @@ -396,7 +396,7 @@ TreeModel::addCollection( const collection_ptr& collection ) Database::instance()->enqueue( QSharedPointer( cmd ) ); - m_title = tr( "All artists from %1" ).arg( collection->source()->friendlyName() ); + m_title = tr( "All Artists from %1" ).arg( collection->source()->friendlyName() ); } diff --git a/src/libtomahawk/source.cpp b/src/libtomahawk/source.cpp index 29715c966..d825a7724 100644 --- a/src/libtomahawk/source.cpp +++ b/src/libtomahawk/source.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -222,6 +222,16 @@ Source::onStateChanged( DBSyncConnection::State newstate, DBSyncConnection::Stat } +unsigned int +Source::trackCount() const +{ + if ( m_stats.contains( "numfiles" ) ) + return m_stats.value( "numfiles" ).toUInt(); + else + return 0; +} + + void Source::onPlaybackStarted( const Tomahawk::query_ptr& query ) { diff --git a/src/libtomahawk/source.h b/src/libtomahawk/source.h index 8ab4de2e5..ed48dfd1b 100644 --- a/src/libtomahawk/source.h +++ b/src/libtomahawk/source.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -65,11 +65,11 @@ public: void scanningProgress( unsigned int files ); void scanningFinished( unsigned int files ); - + void setOffline(); void setOnline(); - unsigned int trackCount() const { return m_stats.value( "numfiles" ).toUInt(); } + unsigned int trackCount() const; Tomahawk::query_ptr currentTrack() const { return m_currentTrack; } QString textStatus() const { return m_textStatus; } @@ -102,7 +102,7 @@ private slots: void onStateChanged( DBSyncConnection::State newstate, DBSyncConnection::State oldstate, const QString& info ); void onPlaybackStarted( const Tomahawk::query_ptr& query ); void onPlaybackFinished( const Tomahawk::query_ptr& query ); - + private: bool m_isLocal; bool m_online; diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index 1c64fa8de..541068403 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -215,7 +215,7 @@ TomahawkApp::init() } qDebug() << "Init InfoSystem."; - new Tomahawk::InfoSystem::InfoSystem( this ); + m_infoSystem = new Tomahawk::InfoSystem::InfoSystem( this ); #ifdef LIBLASTFM_FOUND qDebug() << "Init Scrobbler."; @@ -302,7 +302,7 @@ TomahawkApp::~TomahawkApp() delete m_mainwindow; delete m_audioEngine; #endif -// delete m_infoSystem; + delete m_infoSystem; delete m_database; } From f5219525b4c60784f3bb24730279101d745fd4cf Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Thu, 14 Apr 2011 05:00:27 +0200 Subject: [PATCH 45/75] * Added alphaBlend method to TomahawkUtils. DRY. --- .../playlist/playlistitemdelegate.cpp | 18 +++++------------ src/libtomahawk/playlist/treeitemdelegate.cpp | 16 +++++++++++++-- src/libtomahawk/utils/tomahawkutils.cpp | 20 ++++++++++++++++--- src/libtomahawk/utils/tomahawkutils.h | 8 +++++--- 4 files changed, 41 insertions(+), 21 deletions(-) diff --git a/src/libtomahawk/playlist/playlistitemdelegate.cpp b/src/libtomahawk/playlist/playlistitemdelegate.cpp index 174001fc7..e06bdb9c4 100644 --- a/src/libtomahawk/playlist/playlistitemdelegate.cpp +++ b/src/libtomahawk/playlist/playlistitemdelegate.cpp @@ -76,24 +76,16 @@ PlaylistItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& opti return; float opacity = 0.0; - painter->save(); if ( item->query()->results().count() ) opacity = item->query()->results().first()->score(); - QColor textcol, bgcol; - textcol = option.palette.color( QPalette::Foreground ); - bgcol = option.palette.color( QPalette::Background ); - opacity = qMax( (float)0.3, opacity ); - int r = textcol.red(), g = textcol.green(), b = textcol.blue(); - r = opacity * r + ( 1 - opacity ) * bgcol.red(); - g = opacity * g + ( 1 - opacity ) * bgcol.green(); - b = opacity * b + ( 1 - opacity ) * bgcol.blue(); - textcol = QColor( r, g, b ); + QColor textColor = TomahawkUtils::alphaBlend( option.palette.color( QPalette::Foreground ), option.palette.color( QPalette::Background ), opacity ); if ( item->isPlaying() ) { // painter->setRenderHint( QPainter::Antialiasing ); + painter->save(); { QRect r = option.rect.adjusted( 3, 0, 0, 0 ); @@ -120,18 +112,18 @@ PlaylistItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& opti painter->setPen( pen ); painter->drawRoundedRect( r, 3.0, 3.0 ); } + + painter->restore(); } else { if ( const QStyleOptionViewItem *vioption = qstyleoption_cast(&option)) { QStyleOptionViewItemV4 o( *vioption ); - o.palette.setColor( QPalette::Text, textcol ); + o.palette.setColor( QPalette::Text, textColor ); QStyledItemDelegate::paint( painter, o, index ); } else QStyledItemDelegate::paint( painter, option, index ); } - - painter->restore(); } diff --git a/src/libtomahawk/playlist/treeitemdelegate.cpp b/src/libtomahawk/playlist/treeitemdelegate.cpp index fa080c980..fcb453f73 100644 --- a/src/libtomahawk/playlist/treeitemdelegate.cpp +++ b/src/libtomahawk/playlist/treeitemdelegate.cpp @@ -66,7 +66,19 @@ TreeItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, } else if ( !item->result().isNull() ) { - return QStyledItemDelegate::paint( painter, option, index ); + float opacity = item->result()->score(); + + opacity = qMax( (float)0.3, opacity ); + QColor textColor = TomahawkUtils::alphaBlend( option.palette.color( QPalette::Foreground ), option.palette.color( QPalette::Background ), opacity ); + + if ( const QStyleOptionViewItem *vioption = qstyleoption_cast(&option)) + { + QStyleOptionViewItemV4 o( *vioption ); + o.palette.setColor( QPalette::Text, textColor ); + return QStyledItemDelegate::paint( painter, o, index ); + } + else + return QStyledItemDelegate::paint( painter, option, index ); } QStyleOptionViewItemV4 opt = option; @@ -99,7 +111,7 @@ TreeItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, text = painter->fontMetrics().elidedText( text, Qt::ElideRight, r.width() ); painter->drawText( r, text, to ); - painter->setFont( boldFont ); +// painter->setFont( boldFont ); painter->restore(); } diff --git a/src/libtomahawk/utils/tomahawkutils.cpp b/src/libtomahawk/utils/tomahawkutils.cpp index a551e39c6..e652f5e43 100644 --- a/src/libtomahawk/utils/tomahawkutils.cpp +++ b/src/libtomahawk/utils/tomahawkutils.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -19,6 +19,7 @@ #include "tomahawkutils.h" #include +#include #include #include #include @@ -265,6 +266,19 @@ extensionToMimetype( const QString& extension ) } +QColor +alphaBlend( const QColor& colorFrom, const QColor& colorTo, float opacity ) +{ + opacity = qMax( (float)0.3, opacity ); + int r = colorFrom.red(), g = colorFrom.green(), b = colorFrom.blue(); + r = opacity * r + ( 1 - opacity ) * colorTo.red(); + g = opacity * g + ( 1 - opacity ) * colorTo.green(); + b = opacity * b + ( 1 - opacity ) * colorTo.blue(); + + return QColor( r, g, b ); +} + + QPixmap createDragPixmap( int itemCount ) { @@ -366,7 +380,7 @@ dnsResolver() { if( !s_dnsResolver ) s_dnsResolver = new DNSResolver(); - + return s_dnsResolver; } @@ -387,7 +401,7 @@ DNSResolver::resolve( QString &host, QString type ) { // For the moment, assume we are looking for XMPP... QString fullHost( "_xmpp-client._tcp." + host ); - + qDebug() << "Looking up SRV record for " << fullHost.toUtf8(); m_dnsSharedRequest->query( fullHost.toUtf8(), QJDns::Srv ); diff --git a/src/libtomahawk/utils/tomahawkutils.h b/src/libtomahawk/utils/tomahawkutils.h index 103e379ce..8490829f4 100644 --- a/src/libtomahawk/utils/tomahawkutils.h +++ b/src/libtomahawk/utils/tomahawkutils.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -25,6 +25,7 @@ #define RESPATH ":/data/" +class QColor; class QDir; class QDateTime; class QString; @@ -70,11 +71,11 @@ namespace TomahawkUtils { QThread::sleep( secs ); } - static void msleep( unsigned long msecs ) + static void msleep( unsigned long msecs ) { QThread::msleep( msecs ); } - static void usleep( unsigned long usecs ) + static void usleep( unsigned long usecs ) { QThread::usleep( usecs ); } @@ -89,6 +90,7 @@ namespace TomahawkUtils DLLEXPORT QString filesizeToString( unsigned int size ); DLLEXPORT QString extensionToMimetype( const QString& extension ); + DLLEXPORT QColor alphaBlend( const QColor& colorFrom, const QColor& colorTo, float opacity ); DLLEXPORT QPixmap createDragPixmap( int itemCount = 1 ); DLLEXPORT QNetworkAccessManager* nam(); From 3e05151008a4005debce0158e31d7c9c3a6e173b Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Thu, 14 Apr 2011 07:26:27 +0200 Subject: [PATCH 46/75] * Support showing tracks without an album tag in the TreeView. --- .../database/databasecommand_allalbums.cpp | 16 +++++++++---- .../database/databasecommand_alltracks.cpp | 6 +++++ src/libtomahawk/playlist/treeitemdelegate.cpp | 8 ++++--- src/libtomahawk/playlist/treemodel.cpp | 23 +++++++++++-------- 4 files changed, 36 insertions(+), 17 deletions(-) diff --git a/src/libtomahawk/database/databasecommand_allalbums.cpp b/src/libtomahawk/database/databasecommand_allalbums.cpp index 15aca3ed3..e0ab9b97e 100644 --- a/src/libtomahawk/database/databasecommand_allalbums.cpp +++ b/src/libtomahawk/database/databasecommand_allalbums.cpp @@ -44,10 +44,11 @@ DatabaseCommand_AllAlbums::execForArtist( DatabaseImpl* dbi ) QString sql = QString( "SELECT DISTINCT album.id, album.name " - "FROM album, file, file_join " + "FROM file, file_join " + "LEFT OUTER JOIN album " + "ON file_join.album = album.id " "WHERE file.id = file_join.file " - "AND file_join.album = album.id " - "AND album.artist = %1 " + "AND file_join.artist = %1 " "%2 " "%3 %4 %5" ).arg( m_artist->id() ) @@ -61,7 +62,14 @@ DatabaseCommand_AllAlbums::execForArtist( DatabaseImpl* dbi ) while( query.next() ) { - Tomahawk::album_ptr album = Tomahawk::Album::get( query.value( 0 ).toUInt(), query.value( 1 ).toString(), m_artist ); + unsigned int albumId = query.value( 0 ).toUInt(); + QString albumName; + if ( query.value( 0 ).isNull() ) + { + albumName = tr( "Unknown" ); + } + + Tomahawk::album_ptr album = Tomahawk::Album::get( albumId, albumName, m_artist ); al << album; } diff --git a/src/libtomahawk/database/databasecommand_alltracks.cpp b/src/libtomahawk/database/databasecommand_alltracks.cpp index 57ebf3afa..a6bcb7151 100644 --- a/src/libtomahawk/database/databasecommand_alltracks.cpp +++ b/src/libtomahawk/database/databasecommand_alltracks.cpp @@ -54,6 +54,12 @@ DatabaseCommand_AllTracks::exec( DatabaseImpl* dbi ) if ( !m_collection.isNull() ) sourceToken = QString( "AND file.source %1" ).arg( m_collection->source()->isLocal() ? "IS NULL" : QString( "= %1" ).arg( m_collection->source()->id() ) ); + if ( m_album && m_album->id() == 0 ) + { + m_artist = m_album->artist().data(); + m_album = 0; + } + QString sql = QString( "SELECT file.id, artist.name, album.name, track.name, file.size, " "file.duration, file.bitrate, file.url, file.source, file.mtime, file.mimetype, file_join.albumpos, artist.id, album.id, track.id " diff --git a/src/libtomahawk/playlist/treeitemdelegate.cpp b/src/libtomahawk/playlist/treeitemdelegate.cpp index fcb453f73..50ac99979 100644 --- a/src/libtomahawk/playlist/treeitemdelegate.cpp +++ b/src/libtomahawk/playlist/treeitemdelegate.cpp @@ -67,7 +67,6 @@ TreeItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, else if ( !item->result().isNull() ) { float opacity = item->result()->score(); - opacity = qMax( (float)0.3, opacity ); QColor textColor = TomahawkUtils::alphaBlend( option.palette.color( QPalette::Foreground ), option.palette.color( QPalette::Background ), opacity ); @@ -77,9 +76,12 @@ TreeItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, o.palette.setColor( QPalette::Text, textColor ); return QStyledItemDelegate::paint( painter, o, index ); } - else - return QStyledItemDelegate::paint( painter, option, index ); } + else + return; + + if ( text.trimmed().isEmpty() ) + text = tr( "Unknown" ); QStyleOptionViewItemV4 opt = option; initStyleOption( &opt, QModelIndex() ); diff --git a/src/libtomahawk/playlist/treemodel.cpp b/src/libtomahawk/playlist/treemodel.cpp index ea8feb1c7..247735999 100644 --- a/src/libtomahawk/playlist/treemodel.cpp +++ b/src/libtomahawk/playlist/treemodel.cpp @@ -96,8 +96,6 @@ TreeModel::canFetchMore( const QModelIndex& parent ) const void TreeModel::fetchMore( const QModelIndex& parent ) { - qDebug() << Q_FUNC_INFO; - TreeModelItem* parentItem = itemFromIndex( parent ); if ( !parentItem || parentItem->fetchingMore ) return; @@ -105,16 +103,16 @@ TreeModel::fetchMore( const QModelIndex& parent ) parentItem->fetchingMore = true; if ( !parentItem->artist().isNull() ) { - qDebug() << "Artist" << parentItem->artist()->name(); + qDebug() << Q_FUNC_INFO << "Loading Artist:" << parentItem->artist()->name(); addAlbums( parentItem->artist(), parent ); } else if ( !parentItem->album().isNull() ) { - qDebug() << "Artist" << parentItem->album()->name(); + qDebug() << Q_FUNC_INFO << "Loading Album:" << parentItem->album()->name(); addTracks( parentItem->album(), parent ); } else - qDebug() << "Something else"; + Q_ASSERT( false ); } @@ -183,8 +181,12 @@ TreeModel::data( const QModelIndex& index, int role ) const { return QSize( 128, 32 ); } + else if ( !entry->artist().isNull() ) + { + return QSize( 128, 44 ); + } - return QSize( 128, 44 ); + return QSize( 128, 0 ); } if ( role != Qt::DisplayRole ) // && role != Qt::ToolTipRole ) @@ -371,7 +373,6 @@ TreeModel::addTracks( const album_ptr& album, const QModelIndex& parent ) QList< QVariant > rows; rows << parent.row(); rows << parent.parent().row(); - cmd->setData( QVariant( rows ) ); connect( cmd, SIGNAL( tracks( QList, QVariant ) ), @@ -438,7 +439,6 @@ TreeModel::onArtistsAdded( const QList& artists ) TreeModelItem* artistitem; foreach( const artist_ptr& artist, artists ) { - qDebug() << artist->name(); artistitem = new TreeModelItem( artist, m_rootItem ); artistitem->cover = m_defaultCover; artistitem->index = createIndex( m_rootItem->children.count() - 1, 0, artistitem ); @@ -470,7 +470,7 @@ TreeModel::onAlbumsAdded( const QList& albums, const QVaria if ( crows.second > 0 ) emit beginInsertRows( parent, crows.first + 1, crows.second ); - TreeModelItem* albumitem; + TreeModelItem* albumitem = 0; foreach( const album_ptr& album, albums ) { albumitem = new TreeModelItem( album, parentItem ); @@ -518,7 +518,7 @@ TreeModel::onTracksAdded( const QList& tracks, const QVaria if ( crows.second > 0 ) emit beginInsertRows( parent, crows.first + 1, crows.second ); - TreeModelItem* item; + TreeModelItem* item = 0; foreach( const query_ptr& query, tracks ) { qDebug() << query->toString(); @@ -541,7 +541,9 @@ TreeModel::onTracksAdded( const QList& tracks, const QVaria void TreeModel::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ) { + Q_UNUSED( customData ); qDebug() << Q_FUNC_INFO; + if ( caller != s_tmInfoIdentifier || type != Tomahawk::InfoSystem::InfoAlbumCoverArt ) { qDebug() << "Info of wrong type or not with our identifier"; @@ -578,6 +580,7 @@ TreeModel::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, void TreeModel::infoSystemFinished( QString target ) { + Q_UNUSED( target ); qDebug() << Q_FUNC_INFO; } From 8231127a3b44c78ab3a78047cd93659120c22d05 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Thu, 14 Apr 2011 07:47:57 +0200 Subject: [PATCH 47/75] * Only show tracks without an album tag below the 'Unknown' album node in TreeModel. --- .../database/databasecommand_allalbums.cpp | 2 +- .../database/databasecommand_alltracks.cpp | 14 ++++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/libtomahawk/database/databasecommand_allalbums.cpp b/src/libtomahawk/database/databasecommand_allalbums.cpp index e0ab9b97e..55b2b7139 100644 --- a/src/libtomahawk/database/databasecommand_allalbums.cpp +++ b/src/libtomahawk/database/databasecommand_allalbums.cpp @@ -63,7 +63,7 @@ DatabaseCommand_AllAlbums::execForArtist( DatabaseImpl* dbi ) while( query.next() ) { unsigned int albumId = query.value( 0 ).toUInt(); - QString albumName; + QString albumName = query.value( 1 ).toString(); if ( query.value( 0 ).isNull() ) { albumName = tr( "Unknown" ); diff --git a/src/libtomahawk/database/databasecommand_alltracks.cpp b/src/libtomahawk/database/databasecommand_alltracks.cpp index a6bcb7151..01117751c 100644 --- a/src/libtomahawk/database/databasecommand_alltracks.cpp +++ b/src/libtomahawk/database/databasecommand_alltracks.cpp @@ -54,10 +54,16 @@ DatabaseCommand_AllTracks::exec( DatabaseImpl* dbi ) if ( !m_collection.isNull() ) sourceToken = QString( "AND file.source %1" ).arg( m_collection->source()->isLocal() ? "IS NULL" : QString( "= %1" ).arg( m_collection->source()->id() ) ); - if ( m_album && m_album->id() == 0 ) + QString albumToken; + if ( m_album ) { - m_artist = m_album->artist().data(); - m_album = 0; + if ( m_album->id() == 0 ) + { + m_artist = m_album->artist().data(); + albumToken = QString( "AND album.id IS NULL" ); + } + else + albumToken = QString( "AND album.id = %1" ).arg( m_album->id() ); } QString sql = QString( @@ -74,7 +80,7 @@ DatabaseCommand_AllTracks::exec( DatabaseImpl* dbi ) "%4 %5 %6" ).arg( sourceToken ) .arg( !m_artist ? QString() : QString( "AND artist.id = %1" ).arg( m_artist->id() ) ) - .arg( !m_album ? QString() : QString( "AND album.id = %1" ).arg( m_album->id() ) ) + .arg( !m_album ? QString() : albumToken ) .arg( m_sortOrder > 0 ? QString( "ORDER BY %1" ).arg( m_orderToken ) : QString() ) .arg( m_sortDescending ? "DESC" : QString() ) .arg( m_amount > 0 ? QString( "LIMIT 0, %1" ).arg( m_amount ) : QString() ); From 3ce41c50bc46b53e87f274bcb702bcdeac5ec212 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Thu, 14 Apr 2011 10:42:16 -0400 Subject: [PATCH 48/75] Don't assert if a scrobble failed, that's no fun. --- thirdparty/liblastfm2/src/scrobble/Audioscrobbler.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/thirdparty/liblastfm2/src/scrobble/Audioscrobbler.cpp b/thirdparty/liblastfm2/src/scrobble/Audioscrobbler.cpp index 3606bd1a4..0a98b7994 100644 --- a/thirdparty/liblastfm2/src/scrobble/Audioscrobbler.cpp +++ b/thirdparty/liblastfm2/src/scrobble/Audioscrobbler.cpp @@ -194,7 +194,8 @@ lastfm::Audioscrobbler::onTrackScrobbleReturn() } else { - Q_ASSERT(false); + qWarning() << "Got error in scrobble submission:" << lfm[ "error" ] << "and silently ignoring. Submission is cached."; + //Q_ASSERT(false); } } From 4b13467e4cae66fe990eaab74b19bcbaaba31110 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Thu, 14 Apr 2011 16:50:38 -0400 Subject: [PATCH 49/75] Don't add directories to the watcher if watch for changes is disabled --- src/scanmanager.cpp | 49 ++++++++++++++++----------------------------- src/scanmanager.h | 3 +-- 2 files changed, 18 insertions(+), 34 deletions(-) diff --git a/src/scanmanager.cpp b/src/scanmanager.cpp index acca5dc90..577da910d 100644 --- a/src/scanmanager.cpp +++ b/src/scanmanager.cpp @@ -67,10 +67,12 @@ ScanManager::ScanManager( QObject* parent ) connect( m_dirWatcher, SIGNAL( directoryChanged( const QString & ) ), SLOT( handleChangedDir( const QString & ) ) ); if ( TomahawkSettings::instance()->hasScannerPaths() ) + { m_currScannerPaths = TomahawkSettings::instance()->scannerPaths(); - - qDebug() << "loading initial directories to watch"; - QTimer::singleShot( 1000, this, SLOT( startupWatchPaths() ) ); + if ( TomahawkSettings::instance()->watchForChanges() ) + QTimer::singleShot( 1000, this, SLOT( runStartupScan() ) ); + } + m_deferredScanTimer->start(); } @@ -109,7 +111,6 @@ ScanManager::onSettingsChanged() { m_currScannerPaths = TomahawkSettings::instance()->scannerPaths(); m_dirWatcher->removePaths( m_dirWatcher->directories() ); - m_dirWatcher->addPaths( m_currScannerPaths ); runManualScan( m_currScannerPaths ); } @@ -119,35 +120,13 @@ ScanManager::onSettingsChanged() } -void -ScanManager::startupWatchPaths() +void ScanManager::runStartupScan() { qDebug() << Q_FUNC_INFO; - if( !Database::instance() || ( Database::instance() && !Database::instance()->isReady() ) ) - { - QTimer::singleShot( 1000, this, SLOT( startupWatchPaths() ) ); - return; - } - - DatabaseCommand_DirMtimes* cmd = new DatabaseCommand_DirMtimes( m_currScannerPaths ); - connect( cmd, SIGNAL( done( QMap< QString, unsigned int > ) ), - SLOT( setInitialPaths( QMap< QString, unsigned int > ) ) ); - Database::instance()->enqueue( QSharedPointer< DatabaseCommand >( cmd ) ); -} - - -void -ScanManager::setInitialPaths( QMap< QString, unsigned int > pathMap ) -{ - qDebug() << Q_FUNC_INFO; - foreach( QString path, pathMap.keys() ) - { - qDebug() << "Adding " << path << " to watcher"; - m_dirWatcher->addPath( path ); - } - if( TomahawkSettings::instance()->hasScannerPaths() && TomahawkSettings::instance()->watchForChanges() ) - runManualScan( TomahawkSettings::instance()->scannerPaths() ); + QTimer::singleShot( 1000, this, SLOT( runStartupScan() ) ); + else + runManualScan( m_currScannerPaths ); } @@ -156,6 +135,9 @@ ScanManager::runManualScan( const QStringList& paths, bool recursive ) { qDebug() << Q_FUNC_INFO; + if( !Database::instance() || ( Database::instance() && !Database::instance()->isReady() ) ) + return; + if ( !m_musicScannerThreadController && !m_scanner ) //still running if these are not zero { m_musicScannerThreadController = new QThread( this ); @@ -193,10 +175,13 @@ void ScanManager::addWatchedDirs( const QStringList& paths ) { qDebug() << Q_FUNC_INFO; + if ( !TomahawkSettings::instance()->watchForChanges() ) + return; + QStringList currentWatchedPaths = m_dirWatcher->directories(); - foreach( QString path, paths ) + foreach ( QString path, paths ) { - if( !currentWatchedPaths.contains( path ) ) + if ( !currentWatchedPaths.contains( path ) ) { qDebug() << "adding " << path << " to watched dirs"; m_dirWatcher->addPath( path ); diff --git a/src/scanmanager.h b/src/scanmanager.h index fdec0cf15..3cd57fd09 100644 --- a/src/scanmanager.h +++ b/src/scanmanager.h @@ -49,14 +49,13 @@ public slots: void handleChangedDir( const QString& path ); void addWatchedDirs( const QStringList& paths ); void removeWatchedDir( const QString& path ); - void setInitialPaths( QMap< QString, unsigned int > pathMap ); private slots: void scannerQuit(); void scannerFinished(); void scannerDestroyed( QObject* scanner ); - void startupWatchPaths(); + void runStartupScan(); void queuedScanTimeout(); void deferredScanTimeout(); From 714c306032cc82494909df9c26f16cd0bbcf78d9 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Tue, 12 Apr 2011 06:56:19 -0400 Subject: [PATCH 50/75] Refactor the resolver config UI for More Prettiness Allow resolvers to configure themselves and whatnot --- data/images/configure.png | Bin 0 -> 717 bytes include/tomahawk/tomahawkapp.h | 8 +- resources.qrc | 1 + src/CMakeLists.txt | 5 + src/libtomahawk/CMakeLists.txt | 2 + src/libtomahawk/functimeout.h | 10 +- src/libtomahawk/pipeline.cpp | 10 +- src/libtomahawk/resolver.cpp | 116 ++++++++++++++++++ src/libtomahawk/resolver.h | 17 ++- src/libtomahawk/tomahawksettings.cpp | 33 +++-- src/libtomahawk/tomahawksettings.h | 51 ++++---- src/resolverconfigdelegate.cpp | 176 +++++++++++++++++++++++++++ src/resolverconfigdelegate.h | 42 +++++++ src/resolverconfigwrapper.cpp | 0 src/resolverconfigwrapper.h | 68 +++++++++++ src/resolvers/qtscriptresolver.cpp | 5 +- src/resolvers/qtscriptresolver.h | 7 +- src/resolvers/scriptresolver.cpp | 53 +++++++- src/resolvers/scriptresolver.h | 6 + src/resolversmodel.cpp | 154 +++++++++++++++++++++++ src/resolversmodel.h | 55 +++++++++ src/settingsdialog.cpp | 80 ++++++------ src/settingsdialog.h | 9 +- src/settingsdialog.ui | 36 ++---- src/tomahawkapp.cpp | 34 +++--- 25 files changed, 835 insertions(+), 143 deletions(-) create mode 100644 data/images/configure.png create mode 100644 src/libtomahawk/resolver.cpp create mode 100644 src/resolverconfigdelegate.cpp create mode 100644 src/resolverconfigdelegate.h create mode 100644 src/resolverconfigwrapper.cpp create mode 100644 src/resolverconfigwrapper.h create mode 100644 src/resolversmodel.cpp create mode 100644 src/resolversmodel.h diff --git a/data/images/configure.png b/data/images/configure.png new file mode 100644 index 0000000000000000000000000000000000000000..5ce478b1adfefacc19d35d61e88a6c02ebe97454 GIT binary patch literal 717 zcmV;;0y6!HP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L02{9W02{9XUK)`c00007bV*G`2iXAx z12+)F5m%`I00K=(L_t(|+KrN3NRx3C#*f?DM%ip+yqb-i;h^3{#n{|Ose_>C#@NE# z7GW2nLRnqZRk>l z!E^IGoWld>6hQ%)Ob;ZrwY8lTqK?F3D=U#m#6CX$#%MA3twKK3jp{=S3-bwzqR{g1 zWn_6|PHT0V4^ml84HUxVD;?&gUq4YYxrThci3GMzVQs_8wx>aE7+A7!I1H&&3b@>z z8%!qi9rhAf2rzWW0VzB{sMRWCC={ZTLLqRr7qhDNRaNlz?0&5`==X~y;%hk@XtmlC z)z#Ho0)bh$({nG|qLN>Ej>p>@6bJ+}b93`2b1k5YM55;Lw?1I9w}RI{3DeUbfmgwU zk`fL#FdNvgKDCcf%4E{WJ?36(INk6~Szl-8a=AAFK#9fNG~C_Y#rJsJGrheQ zBv;6hcfyN?hOCn~Qef@KUgduny7b2#PFv(s$3;Yx5y)(Lh@2zNPdMU39%!A08&{uL z2UAU&vxvjtpqADa^wRZWsl2>Q3i-Hgymh^|--2{HEh0%0sm`d7%`u#mNW_}#x8;FB z5JX#iH3q4425MvyP%7)Gf&RxmQ&aDUagOpXV6s?qkSO9GJthS m_collections; - QList m_scriptResolvers; + QHash m_scriptResolvers; Database* m_database; ScanManager *m_scanManager; @@ -143,3 +144,4 @@ private: }; #endif // TOMAHAWKAPP_H + diff --git a/resources.qrc b/resources.qrc index ddbc46b96..9996e5cb0 100644 --- a/resources.qrc +++ b/resources.qrc @@ -74,6 +74,7 @@ ./data/images/back.png ./data/images/forward.png ./data/images/music-icon.png +./data/images/configure.png ./data/topbar-radiobuttons.css ./data/icons/tomahawk-icon-16x16.png ./data/icons/tomahawk-icon-32x32.png diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1b9a95e65..067558b19 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -63,6 +63,8 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui} tomahawktrayicon.cpp audiocontrols.cpp settingsdialog.cpp + resolverconfigdelegate.cpp + resolversmodel.cpp tomahawkwindow.cpp ) @@ -99,6 +101,9 @@ SET( tomahawkHeadersGui ${tomahawkHeadersGui} tomahawktrayicon.h audiocontrols.h settingsdialog.h + resolverconfigdelegate.h + resolversmodel.h + resolverconfigwrapper.h tomahawkwindow.h ) diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index ae7dc0350..33aaff411 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -4,6 +4,7 @@ SET( QT_USE_QTGUI TRUE ) SET( QT_USE_QTSQL TRUE ) SET( QT_USE_QTNETWORK TRUE ) SET( QT_USE_QTXML TRUE ) +SET(QT_USE_QTUITOOLS TRUE) include( ${QT_USE_FILE} ) @@ -21,6 +22,7 @@ set( libSources album.cpp collection.cpp playlist.cpp + resolver.cpp query.cpp result.cpp source.cpp diff --git a/src/libtomahawk/functimeout.h b/src/libtomahawk/functimeout.h index c66134311..bbb632f59 100644 --- a/src/libtomahawk/functimeout.h +++ b/src/libtomahawk/functimeout.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -22,6 +22,7 @@ #include #include #include +#include #include "boost/function.hpp" #include "boost/bind.hpp" @@ -43,8 +44,9 @@ class DLLEXPORT FuncTimeout : public QObject Q_OBJECT public: - FuncTimeout( int ms, boost::function func ) + FuncTimeout( int ms, boost::function func, QObject* besafe ) : m_func( func ) + , m_watch( QWeakPointer< QObject >( besafe ) ) { //qDebug() << Q_FUNC_INFO; QTimer::singleShot( ms, this, SLOT( exec() ) ); @@ -58,12 +60,14 @@ public: public slots: void exec() { - m_func(); + if( !m_watch.isNull() ) + m_func(); this->deleteLater(); }; private: boost::function m_func; + QWeakPointer< QObject > m_watch; }; }; // ns diff --git a/src/libtomahawk/pipeline.cpp b/src/libtomahawk/pipeline.cpp index b7d538a37..c3bab44d6 100644 --- a/src/libtomahawk/pipeline.cpp +++ b/src/libtomahawk/pipeline.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -134,7 +134,7 @@ Pipeline::resolve( const query_ptr& q, bool prioritized ) { if ( q.isNull() ) return; - + QList< query_ptr > qlist; qlist << q; resolve( qlist, prioritized ); @@ -292,7 +292,7 @@ Pipeline::shunt( const query_ptr& q ) { incQIDState( q ); // qDebug() << "Shunting in" << lasttimeout << "ms, q:" << q->toString(); - new FuncTimeout( lasttimeout, boost::bind( &Pipeline::shunt, this, q ) ); + new FuncTimeout( lasttimeout, boost::bind( &Pipeline::shunt, this, q ), this ); } } else @@ -311,8 +311,8 @@ Pipeline::shunt( const query_ptr& q ) bool Pipeline::resolverSorter( const Resolver* left, const Resolver* right ) { - if( left->weight() == right->weight() ) - return left->preference() > right->preference(); + if( left->weight() == right->weight() ) // TODO dispatch in parallel + return left; else return left->weight() > right->weight(); } diff --git a/src/libtomahawk/resolver.cpp b/src/libtomahawk/resolver.cpp new file mode 100644 index 000000000..4e6a757fe --- /dev/null +++ b/src/libtomahawk/resolver.cpp @@ -0,0 +1,116 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Christian Muehlhaeuser + * + * Tomahawk 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 3 of the License, or + * (at your option) any later version. + * + * Tomahawk 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#include "resolver.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +QVariant +Tomahawk::ExternalResolver::configMsgFromWidget( QWidget* w ) +{ + if( !w ) + return QVariant(); + + // generate a qvariantmap of all the widgets in the hierarchy, and for each one include the list of properties and values + QVariantMap widgetMap; + addChildProperties( w, widgetMap ); +// qDebug() << "Generated widget variant:" << widgetMap; + return widgetMap; +} + + +void +Tomahawk::ExternalResolver::addChildProperties( QObject* widget, QVariantMap& m ) +{ + // recursively add all properties of this widget to the map, then repeat on all children. + // bare QWidgets are boring---so skip them! They have no input that the user can set. + if( !widget || !widget->isWidgetType() ) + return; + + if( qstrcmp( widget->metaObject()->className(), "QWidget" ) != 0 ) + { +// qDebug() << "Adding properties for this:" << widget->metaObject()->className(); + // add this widget's properties + QVariantMap props; + for( int i = widget->metaObject()->propertyOffset(); i < widget->metaObject()->propertyCount(); i++ ) + { + QString prop = widget->metaObject()->property( i ).name(); + QVariant val = widget->property( prop.toLatin1() ); + // clean up for QJson.... + if( val.canConvert< QPixmap >() || val.canConvert< QImage >() || val.canConvert< QIcon >() ) + continue; + props[ prop ] = val; +// qDebug() << QString( "%1: %2" ).arg( prop ).arg( props[ prop ].toString() ); + } + m[ widget->objectName() ] = props; + } + // and recurse + foreach( QObject* child, widget->children() ) + addChildProperties( child, m ); +} + + +QWidget* +Tomahawk::ExternalResolver::widgetFromData( QByteArray& data, QWidget* parent ) +{ + if( data.isEmpty() ) + return 0; + + QUiLoader l; + QBuffer b( &data ); + QWidget* w = l.load( &b, parent ); + + return w; +} + +QByteArray +Tomahawk::ExternalResolver::fixDataImagePaths( const QByteArray& data, bool compressed, const QVariantMap& images ) +{ + // with a list of images and image data, write each to a temp file, replace the path in the .ui file with the temp file path + QString uiFile = QString::fromUtf8( data ); + foreach( const QString& filename, images.keys() ) + { + if( !uiFile.contains( filename ) ) // make sure the image is used + continue; + + QString fullPath = QDir::tempPath() + "/" + filename; + QFile imgF( fullPath ); + if( !imgF.open( QIODevice::WriteOnly ) ) + { + qWarning() << "Failed to write to temporary image in UI file:" << filename << fullPath; + continue; + } + QByteArray data = images[ filename ].toByteArray(); + qDebug() << "expanding data:" << data << compressed; + data = compressed ? qUncompress( QByteArray::fromBase64( data ) ) : QByteArray::fromBase64( data ); + imgF.write( data ); + imgF.close(); + + // replace the path to the image with the real path + uiFile.replace( filename, fullPath ); + } + return uiFile.toUtf8(); +} + diff --git a/src/libtomahawk/resolver.h b/src/libtomahawk/resolver.h index d1b526ffe..c3a3bae7e 100644 --- a/src/libtomahawk/resolver.h +++ b/src/libtomahawk/resolver.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -33,6 +33,9 @@ weighted resolver */ + +class QWidget; + namespace Tomahawk { @@ -45,12 +48,8 @@ public: virtual QString name() const = 0; virtual unsigned int weight() const = 0; - virtual unsigned int preference() const { return 100; }; virtual unsigned int timeout() const = 0; - //virtual QWidget * configUI() { return 0; }; - //etc - public slots: virtual void resolve( const Tomahawk::query_ptr& query ) = 0; }; @@ -64,10 +63,18 @@ public: virtual QString filePath() const { return m_filePath; } + virtual QWidget* configUI() const = 0; + virtual void saveConfig() = 0; public slots: virtual void stop() = 0; +protected: + QWidget* widgetFromData( QByteArray& data, QWidget* parent = 0 ); + QVariant configMsgFromWidget( QWidget* w ); + QByteArray fixDataImagePaths( const QByteArray& data, bool compressed, const QVariantMap& images ); private: + void addChildProperties( QObject* parent, QVariantMap& m ); + QString m_filePath; }; diff --git a/src/libtomahawk/tomahawksettings.cpp b/src/libtomahawk/tomahawksettings.cpp index 37a905cad..22ce4f548 100644 --- a/src/libtomahawk/tomahawksettings.cpp +++ b/src/libtomahawk/tomahawksettings.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -52,7 +52,7 @@ TomahawkSettings::TomahawkSettings( QObject* parent ) qDebug() << "Config version outdated, old:" << value( "configversion" ).toUInt() << "new:" << VERSION << "Doing upgrade, if any..."; - + // insert upgrade code here as required setValue( "configversion", VERSION ); } @@ -415,7 +415,7 @@ int TomahawkSettings::defaultPort() const { return 50210; -} +} int TomahawkSettings::externalPort() const @@ -485,7 +485,7 @@ TomahawkSettings::setTwitterScreenName( const QString& screenName ) { setValue( "twitter/ScreenName", screenName ); } - + QString TomahawkSettings::twitterOAuthToken() const { @@ -627,20 +627,33 @@ TomahawkSettings::setXmppBotPort( const int port ) setValue( "xmppBot/port", port ); } -void +void TomahawkSettings::addScriptResolver(const QString& resolver) { - setValue( "script/resolvers", scriptResolvers() << resolver ); + setValue( "script/resolvers", allScriptResolvers() << resolver ); } -QStringList -TomahawkSettings::scriptResolvers() const +QStringList +TomahawkSettings::allScriptResolvers() const { return value( "script/resolvers" ).toStringList(); } -void -TomahawkSettings::setScriptResolvers( const QStringList& resolver ) +void +TomahawkSettings::setAllScriptResolvers( const QStringList& resolver ) { setValue( "script/resolvers", resolver ); } + + +QStringList +TomahawkSettings::enabledScriptResolvers() const +{ + return value( "script/loadedresolvers" ).toStringList(); +} + +void +TomahawkSettings::setEnabledScriptResolvers( const QStringList& resolvers ) +{ + setValue( "script/loadedresolvers", resolvers ); +} diff --git a/src/libtomahawk/tomahawksettings.h b/src/libtomahawk/tomahawksettings.h index 42daa91e3..0b47ca685 100644 --- a/src/libtomahawk/tomahawksettings.h +++ b/src/libtomahawk/tomahawksettings.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -47,14 +47,14 @@ public: bool watchForChanges() const; void setWatchForChanges( bool watch ); - + bool acceptedLegalWarning() const; void setAcceptedLegalWarning( bool accept ); - + /// UI settings QByteArray mainWindowGeometry() const; void setMainWindowGeometry( const QByteArray& geom ); - + QByteArray mainWindowState() const; void setMainWindowState( const QByteArray& state ); @@ -71,24 +71,24 @@ public: /// Jabber settings bool jabberAutoConnect() const; /// true by default void setJabberAutoConnect( bool autoconnect = false ); - + QString jabberUsername() const; void setJabberUsername( const QString& username ); - + QString jabberPassword() const; void setJabberPassword( const QString& pw ); - + QString jabberServer() const; void setJabberServer( const QString& server ); - + unsigned int jabberPort() const; // default is 5222 void setJabberPort( int port ); - + /// Network settings enum ExternalAddressMode { Lan, Upnp }; ExternalAddressMode externalAddressMode() const; void setExternalAddressMode( ExternalAddressMode externalAddressMode ); - + bool preferStaticHostPort() const; void setPreferStaticHostPort( bool prefer ); @@ -120,42 +120,42 @@ public: /// ACL settings QStringList aclEntries() const; void setAclEntries( const QStringList &entries ); - + /// Last.fm settings bool scrobblingEnabled() const; /// false by default void setScrobblingEnabled( bool enable ); - + QString lastFmUsername() const; void setLastFmUsername( const QString& username ); - + QString lastFmPassword() const; void setLastFmPassword( const QString& password ); - + QByteArray lastFmSessionKey() const; void setLastFmSessionKey( const QByteArray& key ); - + /// Twitter settings QString twitterScreenName() const; void setTwitterScreenName( const QString& screenName ); - + QString twitterOAuthToken() const; void setTwitterOAuthToken( const QString& oauthtoken ); - + QString twitterOAuthTokenSecret() const; void setTwitterOAuthTokenSecret( const QString& oauthtokensecret ); qint64 twitterCachedFriendsSinceId() const; void setTwitterCachedFriendsSinceId( qint64 sinceid ); - + qint64 twitterCachedMentionsSinceId() const; void setTwitterCachedMentionsSinceId( qint64 sinceid ); - + qint64 twitterCachedDirectMessagesSinceId() const; void setTwitterCachedDirectMessagesSinceId( qint64 sinceid ); - + QHash twitterCachedPeers() const; void setTwitterCachedPeers( const QHash &cachedPeers ); - + /// XMPP Component Settings QString xmppBotServer() const; void setXmppBotServer( const QString &server ); @@ -168,11 +168,14 @@ public: int xmppBotPort() const; void setXmppBotPort( const int port ); - + /// Script resolver settings - QStringList scriptResolvers() const; - void setScriptResolvers( const QStringList& resolver ); + QStringList allScriptResolvers() const; + void setAllScriptResolvers( const QStringList& resolvers ); void addScriptResolver( const QString& resolver ); + QStringList enabledScriptResolvers() const; + void setEnabledScriptResolvers( const QStringList& resolvers ); + signals: void changed(); diff --git a/src/resolverconfigdelegate.cpp b/src/resolverconfigdelegate.cpp new file mode 100644 index 000000000..fb983c8ae --- /dev/null +++ b/src/resolverconfigdelegate.cpp @@ -0,0 +1,176 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Christian Muehlhaeuser + * + * Tomahawk 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 3 of the License, or + * (at your option) any later version. + * + * Tomahawk 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + + +#include "resolverconfigdelegate.h" + +#include "resolversmodel.h" +#include "tomahawk/tomahawkapp.h" + +#include +#include +#include + +#define PADDING 4 + +ResolverConfigDelegate::ResolverConfigDelegate( QObject* parent ) + : QStyledItemDelegate( parent ) + , m_configPressed( false ) +{ + +} + +void +ResolverConfigDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const +{ + QStyleOptionViewItemV4 opt = option; + initStyleOption( &opt, index ); + QRect itemRect = opt.rect; + int top = itemRect.top(); + + QFont name = opt.font; + name.setPointSize( name.pointSize() + 2 ); + name.setBold( true ); + + QFont path = opt.font; + path.setItalic( true ); + path.setPointSize( path.pointSize() - 1 ); + + + QFontMetrics bfm( name ); + QFontMetrics sfm( path ); + + // draw the background + const QWidget* w = opt.widget; + QStyle* style = w ? w->style() : QApplication::style(); + style->drawPrimitive( QStyle::PE_PanelItemViewItem, &opt, painter, w ); + + int rightSplit = itemRect.width(); + int rectW = opt.rect.height() - 4 * PADDING; + QRect confRect = QRect( rightSplit - rectW - 2 * PADDING, 2 * PADDING + top, rectW, rectW ); + // if the resolver has a config widget, paint it first (right-aligned) + if( index.data( ResolversModel::HasConfig ).toBool() ) { + // draw it the same size as the check belox + QStyleOptionToolButton topt; + topt.font = opt.font; + topt.icon = QIcon( RESPATH "images/configure.png" ); + topt.iconSize = QSize( 16, 16 ); + topt.rect = confRect; + topt.subControls = QStyle::SC_ToolButton; + topt.activeSubControls = QStyle::SC_None; + topt.features = QStyleOptionToolButton::None; + topt.pos = confRect.topLeft(); + topt.state = m_configPressed ? QStyle::State_On : QStyle::State_Raised; + if( opt.state & QStyle::State_MouseOver || m_configPressed ) + topt.state |= QStyle::State_HasFocus; + style->drawComplexControl( QStyle::CC_ToolButton, &topt, painter, w ); + } + + // draw check + confRect.moveTo( 2 * PADDING, 2 * PADDING + top ); + opt.rect = confRect; + opt.checkState == Qt::Checked ? opt.state |= QStyle::State_On : opt.state |= QStyle::State_Off; + style->drawPrimitive( QStyle::PE_IndicatorViewItemCheck, &opt, painter, w ); + itemRect.setX( opt.rect.topRight().x() + PADDING ); + + QString nameStr = bfm.elidedText( index.data( ResolversModel::ResolverName ).toString(),Qt::ElideRight, rightSplit ); + painter->save(); + painter->setFont( name ); + QRect textRect = itemRect.adjusted( PADDING, PADDING, -PADDING, -PADDING ); + textRect.setBottom( itemRect.height() / 2 + top ); + painter->drawText( textRect, nameStr ); + painter->restore(); + + QString pathStr = sfm.elidedText( index.data( ResolversModel::ResolverPath ).toString(),Qt::ElideMiddle, rightSplit ); + painter->save(); + painter->setFont( path ); + painter->setBrush( Qt::gray ); + textRect.moveTop( itemRect.height() / 2 + top ); + painter->drawText( textRect, pathStr ); + painter->restore(); + +} + +QSize +ResolverConfigDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const +{ + int width = QStyledItemDelegate::sizeHint( option, index ).width(); + + QStyleOptionViewItemV4 opt = option; + initStyleOption( &opt, index ); + + + QFont name = opt.font; + name.setPointSize( name.pointSize() + 2 ); + name.setBold( true ); + + QFont path = opt.font; + path.setItalic( true ); + path.setPointSize( path.pointSize() - 1 ); + + + QFontMetrics bfm( name ); + QFontMetrics sfm( path ); + return QSize( width, 3 * PADDING + bfm.height() + sfm.height() ); +} + +bool +ResolverConfigDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index) +{ +// qDebug() << "EDITOR EVENT!" << ( event->type() == QEvent::MouseButtonRelease ); + + QStyleOptionViewItemV4 viewOpt( option ); + initStyleOption( &viewOpt, index ); + const QWidget* w = viewOpt.widget; + QStyle* style = w ? w->style() : QApplication::style(); + int top = viewOpt.rect.top(); + + if( event->type() == QEvent::MouseButtonRelease || event->type() == QEvent::MouseButtonDblClick ) { + m_configPressed = false; + + int rectW = option.rect.height() - 4 * PADDING; + QRect checkRect = QRect( 2 * PADDING, 2 * PADDING + top, rectW, rectW ); + QMouseEvent* me = static_cast< QMouseEvent* >( event ); + if( me->button() != Qt::LeftButton || !checkRect.contains( me->pos() ) ) + return false; + + // eat the double click events inside the check rect + if( event->type() == QEvent::MouseButtonDblClick ) { + return true; + } + + Qt::CheckState curState = static_cast< Qt::CheckState >( index.data( Qt::CheckStateRole ).toInt() ); + Qt::CheckState newState = curState == Qt::Checked ? Qt::Unchecked : Qt::Checked; + return model->setData( index, newState, Qt::CheckStateRole ); + + } else if( event->type() == QEvent::MouseButtonPress ) { + int rightSplit = viewOpt.rect.width(); + int rectW = viewOpt.rect.height() - 4 * PADDING; + QRect confRect = QRect( rightSplit - rectW - 2 * PADDING, 2 * PADDING + top, rectW, rectW ); + + QMouseEvent* me = static_cast< QMouseEvent* >( event ); + if( me->button() == Qt::LeftButton && confRect.contains( me->pos() ) ) { + m_configPressed = true; + + emit openConfig( index.data( ResolversModel::ResolverPath ).toString() ); + return true; + } + } + + return QStyledItemDelegate::editorEvent( event, model, option, index ); +} diff --git a/src/resolverconfigdelegate.h b/src/resolverconfigdelegate.h new file mode 100644 index 000000000..280e63ccb --- /dev/null +++ b/src/resolverconfigdelegate.h @@ -0,0 +1,42 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Christian Muehlhaeuser + * + * Tomahawk 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 3 of the License, or + * (at your option) any later version. + * + * Tomahawk 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + + +#ifndef RESOLVERCONFIGDELEGATE_H +#define RESOLVERCONFIGDELEGATE_H + +#include + + +class ResolverConfigDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + explicit ResolverConfigDelegate(QObject* parent = 0); + virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; + virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const; + virtual bool editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index ); + +signals: + void openConfig( const QString& resolverPath ); + +private: + bool m_configPressed; +}; + +#endif // RESOLVERCONFIGDELEGATE_H diff --git a/src/resolverconfigwrapper.cpp b/src/resolverconfigwrapper.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/resolverconfigwrapper.h b/src/resolverconfigwrapper.h new file mode 100644 index 000000000..e43700e38 --- /dev/null +++ b/src/resolverconfigwrapper.h @@ -0,0 +1,68 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Christian Muehlhaeuser + * + * Tomahawk 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 3 of the License, or + * (at your option) any later version. + * + * Tomahawk 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ +#ifndef RESOLVER_CONFIG_WRAPPER +#define RESOLVER_CONFIG_WRAPPER + +#include +#include +#include + +class ResolverConfigWrapper : public QDialog +{ + Q_OBJECT +public: + ResolverConfigWrapper( QWidget* conf, const QString& title, QWidget* parent ) : QDialog( parent ), m_widget( conf ) + { + setWindowTitle( title ); + + QVBoxLayout* v = new QVBoxLayout( this ); + v->addWidget( m_widget ); + + QDialogButtonBox* buttons = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this ); + connect( buttons, SIGNAL( clicked( QAbstractButton*) ), this, SLOT( closed( QAbstractButton* ) ) ); + connect( this, SIGNAL( rejected() ), this, SLOT( rejected() ) ); + v->addWidget( buttons ); + + setLayout( v ); + } +public slots: + void closed( QAbstractButton* b ) + { + // let the config widget live to see another day + layout()->removeWidget( m_widget ); + m_widget->setParent( 0 ); + + QDialogButtonBox* buttons = qobject_cast< QDialogButtonBox* >( sender() ); + if( buttons->standardButton( b ) == QDialogButtonBox::Ok ) + done( QDialog::Accepted ); + else + done( QDialog::Rejected ); + } + + // we get a rejected() signal emitted if the user presses escape (and no clicked() signal ) + void rejected() + { + layout()->removeWidget( m_widget ); + m_widget->setParent( 0 ); + } + +private: + QWidget* m_widget; +}; + +#endif diff --git a/src/resolvers/qtscriptresolver.cpp b/src/resolvers/qtscriptresolver.cpp index 3d1773fe8..78375c522 100644 --- a/src/resolvers/qtscriptresolver.cpp +++ b/src/resolvers/qtscriptresolver.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -49,9 +49,8 @@ QtScriptResolver::QtScriptResolver( const QString& scriptPath ) m_name = m.value( "name" ).toString(); m_weight = m.value( "weight", 0 ).toUInt(); m_timeout = m.value( "timeout", 25 ).toUInt() * 1000; - m_preference = m.value( "preference", 0 ).toUInt(); - qDebug() << Q_FUNC_INFO << m_name << m_weight << m_timeout << m_preference; + qDebug() << Q_FUNC_INFO << m_name << m_weight << m_timeout; m_ready = true; Tomahawk::Pipeline::instance()->addResolver( this ); diff --git a/src/resolvers/qtscriptresolver.h b/src/resolvers/qtscriptresolver.h index a6850ac96..ed90f8261 100644 --- a/src/resolvers/qtscriptresolver.h +++ b/src/resolvers/qtscriptresolver.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -68,9 +68,10 @@ public: virtual QString name() const { return m_name; } virtual unsigned int weight() const { return m_weight; } - virtual unsigned int preference() const { return m_preference; } virtual unsigned int timeout() const { return m_timeout; } + virtual QWidget* configUI() const { return 0; } // TODO support properly for qtscript resolvers too! + virtual void saveConfig() {} public slots: virtual void resolve( const Tomahawk::query_ptr& query ); virtual void stop(); @@ -82,7 +83,7 @@ private: ScriptEngine* m_engine; QString m_name; - unsigned int m_weight, m_preference, m_timeout; + unsigned int m_weight, m_timeout; bool m_ready, m_stopped; }; diff --git a/src/resolvers/scriptresolver.cpp b/src/resolvers/scriptresolver.cpp index f84acf492..a713f186c 100644 --- a/src/resolvers/scriptresolver.cpp +++ b/src/resolvers/scriptresolver.cpp @@ -49,6 +49,9 @@ ScriptResolver::~ScriptResolver() stop(); Tomahawk::Pipeline::instance()->removeResolver( this ); + + if( !m_configWidget.isNull() ) + delete m_configWidget.data(); } @@ -94,8 +97,6 @@ ScriptResolver::sendMsg( const QByteArray& msg ) { qDebug() << Q_FUNC_INFO << m_ready << msg << msg.length(); - if( !m_ready ) return; - quint32 len; qToBigEndian( msg.length(), (uchar*) &len ); m_proc.write( (const char*) &len, 4 ); @@ -121,6 +122,9 @@ ScriptResolver::handleMsg( const QByteArray& msg ) { doSetup( m ); return; + } else if( msgtype == "confwidget" ) { + setupConfWidget( m ); + return; } if( msgtype == "results" ) @@ -212,7 +216,7 @@ ScriptResolver::resolve( const Tomahawk::query_ptr& query ) sendMsg( msg ); m_queryState.insert( query->id(), 1 ); - new Tomahawk::FuncTimeout( m_timeout, boost::bind( &ScriptResolver::onTimeout, this, query ) ); + new Tomahawk::FuncTimeout( m_timeout, boost::bind( &ScriptResolver::onTimeout, this, query ), this ); } @@ -223,17 +227,54 @@ ScriptResolver::doSetup( const QVariantMap& m ) m_name = m.value( "name" ).toString(); m_weight = m.value( "weight", 0 ).toUInt(); m_timeout = m.value( "timeout", 25 ).toUInt() * 1000; - m_preference = m.value( "preference", 0 ).toUInt(); qDebug() << "SCRIPT" << filePath() << "READY," << endl << "name" << m_name << endl << "weight" << m_weight << endl - << "timeout" << m_timeout << endl - << "preference" << m_preference; + << "timeout" << m_timeout; m_ready = true; Tomahawk::Pipeline::instance()->addResolver( this ); } +void +ScriptResolver::setupConfWidget( const QVariantMap& m ) +{ + bool compressed = m.value( "compressed", "false" ).toString() == "true"; + qDebug() << "Resolver has a preferences widget! compressed?" << compressed << m; + + QByteArray uiData = m[ "widget" ].toByteArray(); + if( compressed ) + uiData = qUncompress( QByteArray::fromBase64( uiData ) ); + else + uiData = QByteArray::fromBase64( uiData ); + + if( m.contains( "images" ) ) + uiData = fixDataImagePaths( uiData, compressed, m[ "images" ].toMap() ); + m_configWidget = QWeakPointer< QWidget >( widgetFromData( uiData, 0 ) ); +} + + +void +ScriptResolver::saveConfig() +{ + Q_ASSERT( !m_configWidget.isNull() ); + + QVariantMap m; + m.insert( "_msgtype", "setpref" ); + QVariant widgets = configMsgFromWidget( m_configWidget.data() ); + m.insert( "widgets", widgets ); + QByteArray data = m_serializer.serialize( m ); + sendMsg( data ); +} + +QWidget* ScriptResolver::configUI() const +{ + if( m_configWidget.isNull() ) + return 0; + else + return m_configWidget.data(); +} + void ScriptResolver::stop() diff --git a/src/resolvers/scriptresolver.h b/src/resolvers/scriptresolver.h index 60d636352..34e29fdd2 100644 --- a/src/resolvers/scriptresolver.h +++ b/src/resolvers/scriptresolver.h @@ -29,6 +29,7 @@ #include "query.h" #include "result.h" +class QWidget; class ScriptResolver : public Tomahawk::ExternalResolver { Q_OBJECT @@ -42,6 +43,9 @@ public: virtual unsigned int preference() const { return m_preference; } virtual unsigned int timeout() const { return m_timeout; } + virtual QWidget* configUI() const; + virtual void saveConfig(); + signals: void finished(); @@ -60,10 +64,12 @@ private: void handleMsg( const QByteArray& msg ); void sendMsg( const QByteArray& msg ); void doSetup( const QVariantMap& m ); + void setupConfWidget( const QVariantMap& m ); QProcess m_proc; QString m_name; unsigned int m_weight, m_preference, m_timeout, m_num_restarts; + QWeakPointer< QWidget > m_configWidget; quint32 m_msgsize; QByteArray m_msg; diff --git a/src/resolversmodel.cpp b/src/resolversmodel.cpp new file mode 100644 index 000000000..07e7c8aca --- /dev/null +++ b/src/resolversmodel.cpp @@ -0,0 +1,154 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Christian Muehlhaeuser + * + * Tomahawk 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 3 of the License, or + * (at your option) any later version. + * + * Tomahawk 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + + +#include "resolversmodel.h" +#include +#include +#include + + +ResolversModel::ResolversModel( const QStringList& allResolvers, const QStringList& enabledResolvers, QObject* parent ) + : QAbstractListModel( parent ) + , m_allResolvers( allResolvers ) + , m_enabledResolvers( enabledResolvers ) +{ + // do some sanity checking just in case + bool changed = false; + foreach( const QString& l, m_enabledResolvers ) { + if( !m_allResolvers.contains( l ) ) { + m_enabledResolvers.removeAll( l ); + changed = true; + } + } + if( changed ) + TomahawkSettings::instance()->setEnabledScriptResolvers( m_enabledResolvers ); + +} + + +ResolversModel::~ResolversModel() +{ + +} + +QVariant +ResolversModel::data( const QModelIndex& index, int role ) const +{ + if( !index.isValid() ) + return QVariant(); + + switch( role ) + { + case Qt::DisplayRole: + case ResolversModel::ResolverName: + { + QFileInfo info( m_allResolvers.at( index.row() ) ); + return info.baseName(); + } + case ResolversModel::ResolverPath: + return m_allResolvers.at( index.row() ); + case ResolversModel::HasConfig: + if( Tomahawk::ExternalResolver* r = TomahawkApp::instance()->resolverForPath( m_allResolvers.at( index.row() ) ) ) // if we have one, it means we are loaded too! + return r->configUI() != 0; + return false; + case Qt::CheckStateRole: + return m_enabledResolvers.contains( m_allResolvers.at( index.row() ) ) ? Qt::Checked : Qt::Unchecked; + default: + return QVariant(); + } +} + +bool +ResolversModel::setData( const QModelIndex& index, const QVariant& value, int role ) +{ + if( role == Qt::CheckStateRole ) { + Qt::CheckState state = static_cast< Qt::CheckState >( value.toInt() ); + QString resolver = m_allResolvers.at( index.row() ); + + if( state == Qt::Checked && !m_enabledResolvers.contains( resolver ) ) { + m_enabledResolvers.append( resolver ); + + TomahawkApp::instance()->enableScriptResolver( resolver ); + } else if( state == Qt::Unchecked ) { + m_enabledResolvers.removeAll( resolver ); + + TomahawkApp::instance()->disableScriptResolver( resolver ); + } + dataChanged( index, index ); + + return true; + } + return false; +} + + +int +ResolversModel::rowCount( const QModelIndex& parent ) const +{ + return m_allResolvers.size(); +} + +int +ResolversModel::columnCount(const QModelIndex& parent) const +{ + return 1; +} + +Qt::ItemFlags +ResolversModel::flags( const QModelIndex& index ) const +{ + return QAbstractItemModel::flags(index) | Qt::ItemIsUserCheckable; +} + + +void +ResolversModel::addResolver( const QString& resolver, bool enable ) +{ + beginInsertRows( QModelIndex(), m_allResolvers.count(), m_allResolvers.count() ); + m_allResolvers << resolver; + if( enable ) + m_enabledResolvers << resolver; + endInsertRows(); +} + +void +ResolversModel::removeResolver( const QString& resolver ) +{ + for( int i = 0; i < m_allResolvers.count(); i++ ) { + if( m_allResolvers.at( i ) == resolver ) { + beginRemoveRows( QModelIndex(), i, i ); + m_allResolvers.takeAt( i ); + endRemoveRows(); + } + } + m_enabledResolvers.removeAll( resolver ); +} + +QStringList +ResolversModel::allResolvers() const +{ + return m_allResolvers; +} + +QStringList +ResolversModel::enabledResolvers() const +{ + return m_enabledResolvers; +} + diff --git a/src/resolversmodel.h b/src/resolversmodel.h new file mode 100644 index 000000000..c6cf8fa73 --- /dev/null +++ b/src/resolversmodel.h @@ -0,0 +1,55 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Christian Muehlhaeuser + * + * Tomahawk 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 3 of the License, or + * (at your option) any later version. + * + * Tomahawk 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + + +#ifndef RESOLVERSMODEL_H +#define RESOLVERSMODEL_H + +#include +#include + + +class ResolversModel : public QAbstractListModel +{ +public: + enum Roles { + ResolverName = Qt::UserRole + 15, + ResolverPath = Qt::UserRole + 16, + HasConfig = Qt::UserRole + 17 + }; + + explicit ResolversModel( const QStringList& allResolvers, const QStringList& enabledResolvers, QObject* parent = 0 ); + virtual ~ResolversModel(); + + virtual QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const; + virtual int rowCount( const QModelIndex& parent = QModelIndex() ) const; + virtual int columnCount( const QModelIndex& parent ) const; + virtual Qt::ItemFlags flags(const QModelIndex& index) const; + virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole); + + void addResolver( const QString& resolver, bool enable = false ); + void removeResolver( const QString& resolver ); + + QStringList allResolvers() const; + QStringList enabledResolvers() const; +private: + QStringList m_allResolvers; + QStringList m_enabledResolvers; +}; + +#endif // RESOLVERSMODEL_H diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index 72bc4edbe..966f193d1 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -24,6 +24,7 @@ #include #include #include +#include #ifdef LIBLASTFM_FOUND #include @@ -39,6 +40,9 @@ #include "sip/SipHandler.h" #include #include "scanmanager.h" +#include "resolverconfigdelegate.h" +#include "resolversmodel.h" +#include "resolverconfigwrapper.h" static QString md5( const QByteArray& src ) @@ -47,7 +51,6 @@ md5( const QByteArray& src ) return QString::fromLatin1( digest.toHex() ).rightJustified( 32, '0' ); } - SettingsDialog::SettingsDialog( QWidget *parent ) : QDialog( parent ) , ui( new Ui::SettingsDialog ) @@ -96,18 +99,19 @@ SettingsDialog::SettingsDialog( QWidget *parent ) ui->lineEditLastfmUsername->setText( s->lastFmUsername() ); ui->lineEditLastfmPassword->setText(s->lastFmPassword() ); connect( ui->pushButtonTestLastfmLogin, SIGNAL( clicked( bool) ), this, SLOT( testLastFmLogin() ) ); - + // SCRIPT RESOLVER ui->removeScript->setEnabled( false ); - foreach( const QString& resolver, s->scriptResolvers() ) { - QFileInfo info( resolver ); - ui->scriptList->addTopLevelItem( new QTreeWidgetItem( QStringList() << info.baseName() << resolver ) ); - - } - connect( ui->scriptList, SIGNAL( itemClicked( QTreeWidgetItem*, int ) ), this, SLOT( scriptSelectionChanged() ) ); + ResolverConfigDelegate* del = new ResolverConfigDelegate( this ); + connect( del, SIGNAL( openConfig( QString ) ), this, SLOT( openResolverConfig( QString ) ) ); + ui->scriptList->setItemDelegate( del ); + m_resolversModel = new ResolversModel( s->allScriptResolvers(), s->enabledScriptResolvers(), this ); + ui->scriptList->setModel( m_resolversModel ); + + connect( ui->scriptList->selectionModel(), SIGNAL( selectionChanged( QItemSelection,QItemSelection ) ), this, SLOT( scriptSelectionChanged() ) ); connect( ui->addScript, SIGNAL( clicked( bool ) ), this, SLOT( addScriptResolver() ) ); connect( ui->removeScript, SIGNAL( clicked( bool ) ), this, SLOT( removeScriptResolver() ) ); - + connect( ui->buttonBrowse, SIGNAL( clicked() ), SLOT( showPathSelector() ) ); connect( ui->proxyButton, SIGNAL( clicked() ), SLOT( showProxySettings() ) ); connect( ui->checkBoxStaticPreferred, SIGNAL( toggled(bool) ), SLOT( toggleUpnp(bool) ) ); @@ -132,23 +136,19 @@ SettingsDialog::~SettingsDialog() s->setJabberPassword( ui->jabberPassword->text() ); s->setJabberServer( ui->jabberServer->text() ); s->setJabberPort( ui->jabberPort->value() ); - + s->setExternalHostname( ui->staticHostName->text() ); s->setExternalPort( ui->staticPort->value() ); s->setScannerPaths( QStringList( ui->lineEditMusicPath->text() ) ); s->setWatchForChanges( ui->checkBoxWatchForChanges->isChecked() ); - + s->setScrobblingEnabled( ui->checkBoxEnableLastfm->isChecked() ); s->setLastFmUsername( ui->lineEditLastfmUsername->text() ); s->setLastFmPassword( ui->lineEditLastfmPassword->text() ); - QStringList resolvers; - for( int i = 0; i < ui->scriptList->topLevelItemCount(); i++ ) - { - resolvers << ui->scriptList->topLevelItem( i )->data( 1, Qt::DisplayRole ).toString(); - } - s->setScriptResolvers( resolvers ); + s->setAllScriptResolvers( m_resolversModel->allResolvers() ); + s->setEnabledScriptResolvers( m_resolversModel->enabledResolvers() ); s->applyChanges(); } @@ -260,13 +260,13 @@ SettingsDialog::onLastFmFinished() ui->pushButtonTestLastfmLogin->setEnabled( false ); } break; - + case QNetworkReply::ContentOperationNotPermittedError: case QNetworkReply::AuthenticationRequiredError: ui->pushButtonTestLastfmLogin->setText( tr( "Failed" ) ); ui->pushButtonTestLastfmLogin->setEnabled( true ); break; - + default: qDebug() << "Couldn't get last.fm auth result"; ui->pushButtonTestLastfmLogin->setText( tr( "Could not contact server" ) ); @@ -336,38 +336,50 @@ ProxyDialog::saveSettings() } -void +void SettingsDialog::addScriptResolver() { QString resolver = QFileDialog::getOpenFileName( this, tr( "Load script resolver file" ), qApp->applicationDirPath() ); if( !resolver.isEmpty() ) { - QFileInfo info( resolver ); - ui->scriptList->addTopLevelItem( new QTreeWidgetItem( QStringList() << info.baseName() << resolver ) ); - - TomahawkApp::instance()->addScriptResolver( resolver ); + m_resolversModel->addResolver( resolver, true ); + TomahawkApp::instance()->enableScriptResolver( resolver ); } } -void +void SettingsDialog::removeScriptResolver() { // only one selection - if( !ui->scriptList->selectedItems().isEmpty() ) { - QString resolver = ui->scriptList->selectedItems().first()->data( 1, Qt::DisplayRole ).toString(); - delete ui->scriptList->takeTopLevelItem( ui->scriptList->indexOfTopLevelItem( ui->scriptList->selectedItems().first() ) ); - - TomahawkApp::instance()->removeScriptResolver( resolver ); + if( !ui->scriptList->selectionModel()->selectedIndexes().isEmpty() ) { + QString resolver = ui->scriptList->selectionModel()->selectedIndexes().first().data( ResolversModel::ResolverPath ).toString(); + m_resolversModel->removeResolver( resolver ); + + TomahawkApp::instance()->disableScriptResolver( resolver ); } } - -void +void SettingsDialog::scriptSelectionChanged() { - if( !ui->scriptList->selectedItems().isEmpty() ) { + if( !ui->scriptList->selectionModel()->selectedIndexes().isEmpty() ) { ui->removeScript->setEnabled( true ); } else { ui->removeScript->setEnabled( false ); } } + +void +SettingsDialog::openResolverConfig( const QString& resolver ) +{ + Tomahawk::ExternalResolver* r = TomahawkApp::instance()->resolverForPath( resolver ); + if( r && r->configUI() ) { + ResolverConfigWrapper dialog( r->configUI(), "Resolver Config", this ); + QWeakPointer< ResolverConfigWrapper > watcher( &dialog ); + int ret = dialog.exec(); + if( !watcher.isNull() && ret == QDialog::Accepted ) { + // send changed config to resolver + r->saveConfig(); + } + } +} diff --git a/src/settingsdialog.h b/src/settingsdialog.h index 02a3c608f..880c319da 100644 --- a/src/settingsdialog.h +++ b/src/settingsdialog.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -21,6 +21,7 @@ #include +class ResolversModel; class QNetworkReply; namespace Ui @@ -53,7 +54,7 @@ public: signals: void settingsChanged(); - + protected: void changeEvent( QEvent* e ); @@ -71,13 +72,15 @@ private slots: void addScriptResolver(); void scriptSelectionChanged(); void removeScriptResolver(); - + void openResolverConfig( const QString& ); + private: Ui::SettingsDialog* ui; ProxyDialog m_proxySettings; bool m_rejected; QNetworkReply* m_testLastFmQuery; + ResolversModel* m_resolversModel; }; #endif // SETTINGSDIALOG_H diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui index 0558568b6..292e7cf59 100644 --- a/src/settingsdialog.ui +++ b/src/settingsdialog.ui @@ -23,7 +23,7 @@ - 0 + 4 @@ -590,7 +590,7 @@ - + true @@ -600,40 +600,18 @@ false + + true + false true - - 2 + + true - - false - - - true - - - 150 - - - true - - - true - - - - 1 - - - - - 2 - - diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index 541068403..ea5311844 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -289,7 +289,7 @@ TomahawkApp::~TomahawkApp() qDebug() << Q_FUNC_INFO; // stop script resolvers - foreach( Tomahawk::ExternalResolver* r, m_scriptResolvers ) + foreach( Tomahawk::ExternalResolver* r, m_scriptResolvers.values() ) { delete r; } @@ -415,37 +415,41 @@ TomahawkApp::setupPipeline() Pipeline::instance()->addResolver( new DatabaseResolver( 100 ) ); // load script resolvers - foreach( QString resolver, TomahawkSettings::instance()->scriptResolvers() ) - addScriptResolver( resolver ); + foreach( QString resolver, TomahawkSettings::instance()->enabledScriptResolvers() ) + enableScriptResolver( resolver ); } void -TomahawkApp::addScriptResolver( const QString& path ) +TomahawkApp::enableScriptResolver( const QString& path ) { const QFileInfo fi( path ); if ( fi.suffix() == "js" || fi.suffix() == "script" ) - m_scriptResolvers << new QtScriptResolver( path ); + m_scriptResolvers.insert( path, new QtScriptResolver( path ) ); else - m_scriptResolvers << new ScriptResolver( path ); + m_scriptResolvers.insert( path, new ScriptResolver( path ) ); } void -TomahawkApp::removeScriptResolver( const QString& path ) +TomahawkApp::disableScriptResolver( const QString& path ) { - foreach( Tomahawk::ExternalResolver* r, m_scriptResolvers ) + if( m_scriptResolvers.contains( path ) ) { - if( r->filePath() == path ) - { - m_scriptResolvers.removeAll( r ); - connect( r, SIGNAL( finished() ), r, SLOT( deleteLater() ) ); - r->stop(); - return; - } + Tomahawk::ExternalResolver* r = m_scriptResolvers.take( path ); + + connect( r, SIGNAL( finished() ), r, SLOT( deleteLater() ) ); + r->stop(); + return; } } +Tomahawk::ExternalResolver* +TomahawkApp::resolverForPath( const QString& scriptPath ) +{ + return m_scriptResolvers.value( scriptPath, 0 ); +} + void TomahawkApp::initLocalCollection() From fe43c1dd01f1fc92f963d81913e4c4005437aa13 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Thu, 14 Apr 2011 20:06:34 -0400 Subject: [PATCH 51/75] Add config migration --- src/libtomahawk/tomahawksettings.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libtomahawk/tomahawksettings.cpp b/src/libtomahawk/tomahawksettings.cpp index 22ce4f548..f1670839f 100644 --- a/src/libtomahawk/tomahawksettings.cpp +++ b/src/libtomahawk/tomahawksettings.cpp @@ -26,7 +26,7 @@ #include #include -#define VERSION 1 +#define VERSION 2 TomahawkSettings* TomahawkSettings::s_instance = 0; @@ -55,6 +55,9 @@ TomahawkSettings::TomahawkSettings( QObject* parent ) // insert upgrade code here as required setValue( "configversion", VERSION ); + if( contains( "script/resolvers") ) { + setValue( "script/loadedresolvers", value( "script/resolvers" ) ); + } } } From ef1ded8636cb211360fc89bfa38b506358a5b213 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Thu, 14 Apr 2011 20:11:29 -0400 Subject: [PATCH 52/75] remove useless file --- src/resolverconfigwrapper.cpp | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/resolverconfigwrapper.cpp diff --git a/src/resolverconfigwrapper.cpp b/src/resolverconfigwrapper.cpp deleted file mode 100644 index e69de29bb..000000000 From ab964957d241340e09c05e89100cdc61e5b62be1 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Thu, 14 Apr 2011 20:26:08 -0400 Subject: [PATCH 53/75] elide --- src/resolverconfigdelegate.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/resolverconfigdelegate.cpp b/src/resolverconfigdelegate.cpp index fb983c8ae..0f98e49f8 100644 --- a/src/resolverconfigdelegate.cpp +++ b/src/resolverconfigdelegate.cpp @@ -88,19 +88,19 @@ ResolverConfigDelegate::paint( QPainter* painter, const QStyleOptionViewItem& op style->drawPrimitive( QStyle::PE_IndicatorViewItemCheck, &opt, painter, w ); itemRect.setX( opt.rect.topRight().x() + PADDING ); - QString nameStr = bfm.elidedText( index.data( ResolversModel::ResolverName ).toString(),Qt::ElideRight, rightSplit ); painter->save(); painter->setFont( name ); QRect textRect = itemRect.adjusted( PADDING, PADDING, -PADDING, -PADDING ); textRect.setBottom( itemRect.height() / 2 + top ); + QString nameStr = bfm.elidedText( index.data( ResolversModel::ResolverName ).toString(),Qt::ElideRight, textRect.width() ); painter->drawText( textRect, nameStr ); painter->restore(); - QString pathStr = sfm.elidedText( index.data( ResolversModel::ResolverPath ).toString(),Qt::ElideMiddle, rightSplit ); painter->save(); painter->setFont( path ); painter->setBrush( Qt::gray ); textRect.moveTop( itemRect.height() / 2 + top ); + QString pathStr = sfm.elidedText( index.data( ResolversModel::ResolverPath ).toString(),Qt::ElideMiddle, textRect.width() ); painter->drawText( textRect, pathStr ); painter->restore(); From f16277ac5f4d3db2bad120163c571c3405f549c4 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Thu, 14 Apr 2011 20:40:00 -0400 Subject: [PATCH 54/75] more assert fixes --- src/libtomahawk/widgets/newplaylistwidget.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libtomahawk/widgets/newplaylistwidget.cpp b/src/libtomahawk/widgets/newplaylistwidget.cpp index 869bfdb3e..bc633e6a2 100644 --- a/src/libtomahawk/widgets/newplaylistwidget.cpp +++ b/src/libtomahawk/widgets/newplaylistwidget.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -54,7 +54,7 @@ NewPlaylistWidget::NewPlaylistWidget( QWidget* parent ) connect( ui->buttonBox, SIGNAL( rejected() ), SLOT( cancel() ) ); m_suggestionsModel = new PlaylistModel( ui->suggestionsView ); - ui->suggestionsView->setModel( m_suggestionsModel ); + ui->suggestionsView->setPlaylistModel( m_suggestionsModel ); ui->suggestionsView->overlay()->setEnabled( false ); connect( &m_filterTimer, SIGNAL( timeout() ), SLOT( updateSuggestions() ) ); @@ -123,7 +123,7 @@ NewPlaylistWidget::suggestionsFound() delete m_suggestionsModel; m_suggestionsModel = new PlaylistModel( ui->suggestionsView ); - ui->suggestionsView->setModel( m_suggestionsModel ); + ui->suggestionsView->setPlaylistModel( m_suggestionsModel ); QList ql; foreach( const Tomahawk::plentry_ptr& entry, m_entries ) From df8a333aeeb7c836b9ccc7eb6214be0bbbf5e903 Mon Sep 17 00:00:00 2001 From: Frank Osterfeld Date: Thu, 14 Apr 2011 21:14:13 +0800 Subject: [PATCH 55/75] Convert QSet to QVector. This one possibly leaked, there is no need to use pointers here. --- src/sip/zeroconf/zeroconf.cpp | 13 +++++-------- src/sip/zeroconf/zeroconf.h | 2 +- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/sip/zeroconf/zeroconf.cpp b/src/sip/zeroconf/zeroconf.cpp index 9625f9abc..7e6bbf955 100644 --- a/src/sip/zeroconf/zeroconf.cpp +++ b/src/sip/zeroconf/zeroconf.cpp @@ -49,15 +49,12 @@ ZeroconfPlugin::connectPlugin( bool /*startup*/ ) m_zeroconf->advertise(); m_isOnline = true; - foreach( QStringList *currNode, m_cachedNodes ) + foreach( const QStringList& nodeSet, m_cachedNodes ) { - QStringList nodeSet = *currNode; if ( !Servent::instance()->connectedToSession( nodeSet[3] ) ) Servent::instance()->connectToPeer( nodeSet[0], nodeSet[1].toInt(), "whitelist", nodeSet[2], nodeSet[3] ); - - delete currNode; } - + m_cachedNodes.clear(); return true; } @@ -81,9 +78,9 @@ ZeroconfPlugin::lanHostFound( const QString& host, int port, const QString& name if ( !m_isOnline ) { qDebug() << "Not online, so not connecting."; - QStringList *nodeSet = new QStringList(); - *nodeSet << host << QString::number( port ) << name << nodeid; - m_cachedNodes.insert( nodeSet ); + QStringList nodeSet; + nodeSet << host << QString::number( port ) << name << nodeid; + m_cachedNodes.append( nodeSet ); return; } diff --git a/src/sip/zeroconf/zeroconf.h b/src/sip/zeroconf/zeroconf.h index 2d971ebb0..059f4727a 100644 --- a/src/sip/zeroconf/zeroconf.h +++ b/src/sip/zeroconf/zeroconf.h @@ -78,7 +78,7 @@ private slots: private: TomahawkZeroconf* m_zeroconf; bool m_isOnline; - QSet< QStringList* > m_cachedNodes; + QVector m_cachedNodes; }; #endif From 04d30913f9e02b2da39d013e7e94af0bfa6e230e Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Fri, 15 Apr 2011 07:35:42 +0200 Subject: [PATCH 56/75] * Show artist images in ArtistView (lazy-loading). * Added artist image api to LastFmPlugin. --- src/audiocontrols.cpp | 4 +- .../infosystem/infoplugins/lastfmplugin.cpp | 168 +++++++++++++++--- .../infosystem/infoplugins/lastfmplugin.h | 10 +- src/libtomahawk/playlist/artistview.cpp | 59 +++++- src/libtomahawk/playlist/artistview.h | 4 + src/libtomahawk/playlist/treemodel.cpp | 9 +- 6 files changed, 219 insertions(+), 35 deletions(-) diff --git a/src/audiocontrols.cpp b/src/audiocontrols.cpp index 93bfd71e7..d80efd846 100644 --- a/src/audiocontrols.cpp +++ b/src/audiocontrols.cpp @@ -28,8 +28,6 @@ #include "album.h" -#define LASTFM_DEFAULT_COVER "http://cdn.last.fm/flatness/catalogue/noimage" - static QString s_acInfoIdentifier = QString( "AUDIOCONTROLS" ); @@ -257,7 +255,7 @@ AudioControls::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType ty QPixmap pm; pm.loadFromData( ba ); - if ( pm.isNull() || returnedData["url"].toString().startsWith( LASTFM_DEFAULT_COVER ) ) + if ( pm.isNull() ) ui->coverImage->setPixmap( m_defaultCover ); else ui->coverImage->setPixmap( pm.scaled( ui->coverImage->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation ) ); diff --git a/src/libtomahawk/infosystem/infoplugins/lastfmplugin.cpp b/src/libtomahawk/infosystem/infoplugins/lastfmplugin.cpp index 0cb840265..f3a8f8b49 100644 --- a/src/libtomahawk/infosystem/infoplugins/lastfmplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/lastfmplugin.cpp @@ -47,7 +47,7 @@ LastFmPlugin::LastFmPlugin( QObject* parent ) , m_authJob( 0 ) { QSet< InfoType > supportedTypes; - supportedTypes << InfoMiscSubmitScrobble << InfoMiscSubmitNowPlaying << InfoAlbumCoverArt; + supportedTypes << InfoMiscSubmitScrobble << InfoMiscSubmitNowPlaying << InfoAlbumCoverArt << InfoArtistImages; qobject_cast< InfoSystem* >(parent)->registerInfoTypes(this, supportedTypes); /* @@ -81,6 +81,10 @@ LastFmPlugin::LastFmPlugin( QObject* parent ) } #endif + + m_badUrls << QUrl( "http://cdn.last.fm/flatness/catalogue/noimage" ) + << QUrl( "http://cdn.last.fm/flatness/catalogue/noimage/2/default_artist_medium.png" ); + connect( TomahawkSettings::instance(), SIGNAL( changed() ), SLOT( settingsChanged() ), Qt::QueuedConnection ); } @@ -91,6 +95,7 @@ LastFmPlugin::~LastFmPlugin() delete m_scrobbler; } + void LastFmPlugin::dataError( const QString &caller, const InfoType type, const QVariant& data, Tomahawk::InfoSystem::InfoCustomData &customData ) { @@ -98,20 +103,36 @@ LastFmPlugin::dataError( const QString &caller, const InfoType type, const QVari return; } + void LastFmPlugin::getInfo( const QString &caller, const InfoType type, const QVariant& data, Tomahawk::InfoSystem::InfoCustomData customData ) { qDebug() << Q_FUNC_INFO; - if ( type == InfoMiscSubmitNowPlaying ) - nowPlaying( caller, type, data, customData ); - else if ( type == InfoMiscSubmitScrobble ) - scrobble( caller, type, data, customData ); - else if ( type == InfoAlbumCoverArt ) - fetchCoverArt( caller, type, data, customData ); - else - dataError( caller, type, data, customData ); + + switch ( type ) + { + case InfoMiscSubmitNowPlaying: + nowPlaying( caller, type, data, customData ); + break; + + case InfoMiscSubmitScrobble: + scrobble( caller, type, data, customData ); + break; + + case InfoArtistImages: + fetchArtistImages( caller, type, data, customData ); + break; + + case InfoAlbumCoverArt: + fetchCoverArt( caller, type, data, customData ); + break; + + default: + dataError( caller, type, data, customData ); + } } + void LastFmPlugin::nowPlaying( const QString &caller, const InfoType type, const QVariant& data, Tomahawk::InfoSystem::InfoCustomData &customData ) { @@ -140,6 +161,7 @@ LastFmPlugin::nowPlaying( const QString &caller, const InfoType type, const QVar emit info( caller, type, data, QVariant(), customData ); } + void LastFmPlugin::scrobble( const QString &caller, const InfoType type, const QVariant& data, Tomahawk::InfoSystem::InfoCustomData &customData ) { @@ -158,6 +180,7 @@ LastFmPlugin::scrobble( const QString &caller, const InfoType type, const QVaria emit info( caller, type, data, QVariant(), customData ); } + void LastFmPlugin::fetchCoverArt( const QString &caller, const InfoType type, const QVariant& data, Tomahawk::InfoSystem::InfoCustomData &customData ) { @@ -181,30 +204,76 @@ LastFmPlugin::fetchCoverArt( const QString &caller, const InfoType type, const Q emit getCachedInfo( criteria, 2419200000, caller, type, data, customData ); } + +void +LastFmPlugin::fetchArtistImages( const QString &caller, const InfoType type, const QVariant& data, Tomahawk::InfoSystem::InfoCustomData &customData ) +{ + qDebug() << Q_FUNC_INFO; + if ( !data.canConvert< Tomahawk::InfoSystem::InfoCustomData >() ) + { + dataError( caller, type, data, customData ); + return; + } + InfoCustomData hash = data.value< Tomahawk::InfoSystem::InfoCustomData >(); + if ( !hash.contains( "artist" ) ) + { + dataError( caller, type, data, customData ); + return; + } + + Tomahawk::InfoSystem::InfoCacheCriteria criteria; + criteria["artist"] = hash["artist"].toString(); + + emit getCachedInfo( criteria, 2419200000, caller, type, data, customData ); +} + + void LastFmPlugin::notInCacheSlot( QHash criteria, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, Tomahawk::InfoSystem::InfoCustomData customData ) { qDebug() << Q_FUNC_INFO; - if ( type == InfoAlbumCoverArt ) + + switch ( type ) { - QString artistName = criteria["artist"]; - QString albumName = criteria["album"]; + case InfoAlbumCoverArt: + { + QString artistName = criteria["artist"]; + QString albumName = criteria["album"]; - QString imgurl = "http://ws.audioscrobbler.com/2.0/?method=album.imageredirect&artist=%1&album=%2&size=medium&api_key=7a90f6672a04b809ee309af169f34b8b"; - QNetworkRequest req( imgurl.arg( artistName ).arg( albumName ) ); - QNetworkReply* reply = TomahawkUtils::nam()->get( req ); - reply->setProperty( "customData", QVariant::fromValue( customData ) ); - reply->setProperty( "origData", input ); - reply->setProperty( "caller", caller ); - reply->setProperty( "type", (uint)(type) ); + QString imgurl = "http://ws.audioscrobbler.com/2.0/?method=album.imageredirect&artist=%1&album=%2&autocorrect=1&size=medium&api_key=7a90f6672a04b809ee309af169f34b8b"; + QNetworkRequest req( imgurl.arg( artistName ).arg( albumName ) ); + QNetworkReply* reply = TomahawkUtils::nam()->get( req ); + reply->setProperty( "customData", QVariant::fromValue( customData ) ); + reply->setProperty( "origData", input ); + reply->setProperty( "caller", caller ); + reply->setProperty( "type", (uint)(type) ); - connect( reply, SIGNAL( finished() ), SLOT( coverArtReturned() ) ); - return; + connect( reply, SIGNAL( finished() ), SLOT( coverArtReturned() ) ); + return; + } + + case InfoArtistImages: + { + QString artistName = criteria["artist"]; + + QString imgurl = "http://ws.audioscrobbler.com/2.0/?method=artist.imageredirect&artist=%1&autocorrect=1&size=medium&api_key=7a90f6672a04b809ee309af169f34b8b"; + QNetworkRequest req( imgurl.arg( artistName ) ); + QNetworkReply* reply = TomahawkUtils::nam()->get( req ); + reply->setProperty( "customData", QVariant::fromValue( customData ) ); + reply->setProperty( "origData", input ); + reply->setProperty( "caller", caller ); + reply->setProperty( "type", (uint)(type) ); + + connect( reply, SIGNAL( finished() ), SLOT( artistImagesReturned() ) ); + return; + } + + default: + qDebug() << "Couldn't figure out what to do with this type of request after cache miss"; } - else - qDebug() << "Couldn't figure out what to do with this type of request after cache miss"; } + void LastFmPlugin::coverArtReturned() { @@ -213,7 +282,10 @@ LastFmPlugin::coverArtReturned() QUrl redir = reply->attribute( QNetworkRequest::RedirectionTargetAttribute ).toUrl(); if ( redir.isEmpty() ) { - const QByteArray ba = reply->readAll(); + QByteArray ba = reply->readAll(); + if ( m_badUrls.contains( reply->url() ) ) + ba = QByteArray(); + InfoCustomData returnedData; returnedData["imgbytes"] = ba; returnedData["url"] = reply->url().toString(); @@ -249,6 +321,54 @@ LastFmPlugin::coverArtReturned() reply->deleteLater(); } + +void +LastFmPlugin::artistImagesReturned() +{ + qDebug() << Q_FUNC_INFO; + QNetworkReply* reply = qobject_cast( sender() ); + QUrl redir = reply->attribute( QNetworkRequest::RedirectionTargetAttribute ).toUrl(); + if ( redir.isEmpty() ) + { + QByteArray ba = reply->readAll(); + if ( m_badUrls.contains( reply->url() ) ) + ba = QByteArray(); + + InfoCustomData returnedData; + returnedData["imgbytes"] = ba; + returnedData["url"] = reply->url().toString(); + + InfoCustomData customData = reply->property( "customData" ).value< Tomahawk::InfoSystem::InfoCustomData >(); + InfoType type = (Tomahawk::InfoSystem::InfoType)(reply->property( "type" ).toUInt()); + emit info( + reply->property( "caller" ).toString(), + type, + reply->property( "origData" ), + returnedData, + customData + ); + + InfoCustomData origData = reply->property( "origData" ).value< Tomahawk::InfoSystem::InfoCustomData >(); + Tomahawk::InfoSystem::InfoCacheCriteria criteria; + criteria["artist"] = origData["artist"].toString(); + emit updateCache( criteria, 2419200000, type, returnedData ); + } + else + { + // Follow HTTP redirect + QNetworkRequest req( redir ); + QNetworkReply* newReply = TomahawkUtils::nam()->get( req ); + newReply->setProperty( "origData", reply->property( "origData" ) ); + newReply->setProperty( "customData", reply->property( "customData" ) ); + newReply->setProperty( "caller", reply->property( "caller" ) ); + newReply->setProperty( "type", reply->property( "type" ) ); + connect( newReply, SIGNAL( finished() ), SLOT( artistImagesReturned() ) ); + } + + reply->deleteLater(); +} + + void LastFmPlugin::settingsChanged() { diff --git a/src/libtomahawk/infosystem/infoplugins/lastfmplugin.h b/src/libtomahawk/infosystem/infoplugins/lastfmplugin.h index 00b27b15e..1b97b0e0c 100644 --- a/src/libtomahawk/infosystem/infoplugins/lastfmplugin.h +++ b/src/libtomahawk/infosystem/infoplugins/lastfmplugin.h @@ -47,21 +47,29 @@ public: public slots: void settingsChanged(); + void onAuthenticated(); void coverArtReturned(); + void artistImagesReturned(); + virtual void notInCacheSlot( Tomahawk::InfoSystem::InfoCacheCriteria criteria, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, Tomahawk::InfoSystem::InfoCustomData customData ); private: void fetchCoverArt( const QString &caller, const InfoType type, const QVariant& data, Tomahawk::InfoSystem::InfoCustomData &customData ); - void scrobble( const QString &caller, const InfoType type, const QVariant& data, InfoCustomData &customData ); + void fetchArtistImages( const QString &caller, const InfoType type, const QVariant& data, Tomahawk::InfoSystem::InfoCustomData &customData ); + void createScrobbler(); + void scrobble( const QString &caller, const InfoType type, const QVariant& data, InfoCustomData &customData ); void nowPlaying( const QString &caller, const InfoType type, const QVariant& data, InfoCustomData &customData ); + void dataError( const QString &caller, const InfoType type, const QVariant& data, InfoCustomData &customData ); lastfm::MutableTrack m_track; lastfm::Audioscrobbler* m_scrobbler; QString m_pw; + QList< QUrl > m_badUrls; + QNetworkReply* m_authJob; }; diff --git a/src/libtomahawk/playlist/artistview.cpp b/src/libtomahawk/playlist/artistview.cpp index 2c8412057..126f99ecd 100644 --- a/src/libtomahawk/playlist/artistview.cpp +++ b/src/libtomahawk/playlist/artistview.cpp @@ -31,14 +31,18 @@ #include "treeitemdelegate.h" #include "playlistmanager.h" +static QString s_tmInfoIdentifier = QString( "TREEMODEL" ); + +#define SCROLL_TIMEOUT 280 + using namespace Tomahawk; ArtistView::ArtistView( QWidget* parent ) : QTreeView( parent ) + , m_header( new TreeHeader( this ) ) , m_model( 0 ) , m_proxyModel( 0 ) - , m_header( new TreeHeader( this ) ) // , m_delegate( 0 ) { setAlternatingRowColors( true ); @@ -67,6 +71,12 @@ ArtistView::ArtistView( QWidget* parent ) setFont( f ); #endif + m_timer.setInterval( SCROLL_TIMEOUT ); + + connect( verticalScrollBar(), SIGNAL( rangeChanged( int, int ) ), SLOT( onViewChanged() ) ); + connect( verticalScrollBar(), SIGNAL( valueChanged( int ) ), SLOT( onViewChanged() ) ); + connect( &m_timer, SIGNAL( timeout() ), SLOT( onScrollTimeout() ) ); + connect( this, SIGNAL( doubleClicked( QModelIndex ) ), SLOT( onItemActivated( QModelIndex ) ) ); } @@ -168,12 +178,57 @@ ArtistView::onFilterChanged( const QString& ) void ArtistView::startDrag( Qt::DropActions supportedActions ) { + Q_UNUSED( supportedActions ); } -// Inspired from dolphin's draganddrophelper.cpp QPixmap ArtistView::createDragPixmap( int itemCount ) const { + Q_UNUSED( itemCount ); return QPixmap(); } + + +void +ArtistView::onViewChanged() +{ + if ( m_timer.isActive() ) + m_timer.stop(); + + m_timer.start(); +} + + +void +ArtistView::onScrollTimeout() +{ + qDebug() << Q_FUNC_INFO; + if ( m_timer.isActive() ) + m_timer.stop(); + + QModelIndex left = indexAt( viewport()->rect().topLeft() ); + while ( left.isValid() && left.parent().isValid() ) + left = left.parent(); + + QModelIndex right = indexAt( viewport()->rect().bottomLeft() ); + while ( right.isValid() && right.parent().isValid() ) + right = right.parent(); + + int max = m_proxyModel->trackCount(); + if ( right.isValid() ) + max = right.row() + 1; + + for ( int i = left.row(); i < max; i++ ) + { + TreeModelItem* item = m_model->itemFromIndex( m_proxyModel->mapToSource( m_proxyModel->index( i, 0 ) ) ); + + Tomahawk::InfoSystem::InfoCustomData trackInfo; + trackInfo["artist"] = QVariant::fromValue< QString >( item->artist()->name() ); + trackInfo["pptr"] = QVariant::fromValue< qlonglong >( (qlonglong)item ); + + Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( + s_tmInfoIdentifier, Tomahawk::InfoSystem::InfoArtistImages, + QVariant::fromValue< Tomahawk::InfoSystem::InfoCustomData >( trackInfo ), Tomahawk::InfoSystem::InfoCustomData() ); + } +} diff --git a/src/libtomahawk/playlist/artistview.h b/src/libtomahawk/playlist/artistview.h index 6f9b94b1f..e02107cbb 100644 --- a/src/libtomahawk/playlist/artistview.h +++ b/src/libtomahawk/playlist/artistview.h @@ -73,6 +73,8 @@ protected: private slots: void onFilterChanged( const QString& filter ); + void onViewChanged(); + void onScrollTimeout(); private: QPixmap createDragPixmap( int itemCount ) const; @@ -81,6 +83,8 @@ private: TreeModel* m_model; TreeProxyModel* m_proxyModel; // PlaylistItemDelegate* m_delegate; + + QTimer m_timer; }; #endif // ARTISTVIEW_H diff --git a/src/libtomahawk/playlist/treemodel.cpp b/src/libtomahawk/playlist/treemodel.cpp index 247735999..7d7974974 100644 --- a/src/libtomahawk/playlist/treemodel.cpp +++ b/src/libtomahawk/playlist/treemodel.cpp @@ -28,8 +28,6 @@ #include "database/database.h" #include "utils/tomahawkutils.h" -#define LASTFM_DEFAULT_COVER "http://cdn.last.fm/flatness/catalogue/noimage" - static QString s_tmInfoIdentifier = QString( "TREEMODEL" ); using namespace Tomahawk; @@ -369,6 +367,7 @@ TreeModel::addTracks( const album_ptr& album, const QModelIndex& parent ) DatabaseCommand_AllTracks* cmd = new DatabaseCommand_AllTracks( m_collection ); cmd->setAlbum( album.data() ); +// cmd->setArtist( album->artist().data() ); QList< QVariant > rows; rows << parent.row(); @@ -442,7 +441,6 @@ TreeModel::onArtistsAdded( const QList& artists ) artistitem = new TreeModelItem( artist, m_rootItem ); artistitem->cover = m_defaultCover; artistitem->index = createIndex( m_rootItem->children.count() - 1, 0, artistitem ); - connect( artistitem, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) ); } @@ -544,7 +542,8 @@ TreeModel::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, Q_UNUSED( customData ); qDebug() << Q_FUNC_INFO; - if ( caller != s_tmInfoIdentifier || type != Tomahawk::InfoSystem::InfoAlbumCoverArt ) + if ( caller != s_tmInfoIdentifier || + ( type != Tomahawk::InfoSystem::InfoAlbumCoverArt && type != Tomahawk::InfoSystem::InfoArtistImages ) ) { qDebug() << "Info of wrong type or not with our identifier"; return; @@ -567,7 +566,7 @@ TreeModel::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, qlonglong p = pptr["pptr"].toLongLong(); TreeModelItem* ai = reinterpret_cast(p); - if ( pm.isNull() || returnedData["url"].toString().startsWith( LASTFM_DEFAULT_COVER ) ) + if ( pm.isNull() ) ai->cover = m_defaultCover; else ai->cover = pm; From 9af6ff7911474490631016810bd87f6d53b4dec0 Mon Sep 17 00:00:00 2001 From: Frank Osterfeld Date: Wed, 13 Apr 2011 04:51:49 +0800 Subject: [PATCH 57/75] Do not crash when the collection folders contains cycles (symlinks). Example: /my/collection/subfolder/link -> /my/collection Use canonicalFilePath to detect cycles and also check m_newdirtimes for an existing timestamp before recursing into subfolders. --- src/musicscanner.cpp | 37 ++++++++++++++++++++----------------- src/musicscanner.h | 2 +- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/musicscanner.cpp b/src/musicscanner.cpp index 601d89288..7c38d37af 100644 --- a/src/musicscanner.cpp +++ b/src/musicscanner.cpp @@ -65,7 +65,7 @@ DirLister::go() void DirLister::scanDir( QDir dir, int depth, DirLister::Mode mode ) { - qDebug() << "DirLister::scanDir scanning: " << dir.absolutePath() << " with mode " << mode; + qDebug() << "DirLister::scanDir scanning: " << dir.canonicalPath() << " with mode " << mode; if( !dir.exists() ) { @@ -74,16 +74,16 @@ DirLister::scanDir( QDir dir, int depth, DirLister::Mode mode ) } QFileInfoList dirs; - const uint mtime = QFileInfo( dir.absolutePath() ).lastModified().toUTC().toTime_t(); - m_newdirmtimes.insert( dir.absolutePath(), mtime ); + const uint mtime = QFileInfo( dir.canonicalPath() ).lastModified().toUTC().toTime_t(); + m_newdirmtimes.insert( dir.canonicalPath(), mtime ); - if ( m_dirmtimes.contains( dir.absolutePath() ) && mtime == m_dirmtimes.value( dir.absolutePath() ) ) + if ( m_dirmtimes.contains( dir.canonicalPath() ) && mtime == m_dirmtimes.value( dir.canonicalPath() ) ) { // dont scan this dir, unchanged since last time. } else { - if( m_dirmtimes.contains( dir.absolutePath() ) || !m_recursive ) + if( m_dirmtimes.contains( dir.canonicalPath() ) || !m_recursive ) Database::instance()->enqueue( QSharedPointer( new DatabaseCommand_DeleteFiles( dir, SourceList::instance()->getLocal() ) ) ); dir.setFilter( QDir::Files | QDir::Readable | QDir::NoDotAndDotDot ); @@ -99,10 +99,13 @@ DirLister::scanDir( QDir dir, int depth, DirLister::Mode mode ) foreach( const QFileInfo& di, dirs ) { - qDebug() << "Considering dir " << di.absoluteFilePath(); - qDebug() << "m_dirmtimes contains it? " << (m_dirmtimes.contains( di.absoluteFilePath() ) ? "true" : "false"); - if( mode == DirLister::Recursive || !m_dirmtimes.contains( di.absoluteFilePath() ) ) - scanDir( di.absoluteFilePath(), depth + 1, DirLister::Recursive ); + const QString canonical = di.canonicalFilePath(); + qDebug() << "Considering dir " << canonical; + const bool haveDi = m_dirmtimes.contains( canonical ); + qDebug() << "m_dirmtimes contains it?" << haveDi; + if( !m_newdirmtimes.contains( canonical ) && ( mode == DirLister::Recursive || !haveDi ) ) { + scanDir( di.canonicalFilePath(), depth + 1, DirLister::Recursive ); + } } } @@ -317,20 +320,20 @@ MusicScanner::readFile( const QFileInfo& fi ) if( m_scanned % 3 == 0 ) SourceList::instance()->getLocal()->scanningProgress( m_scanned ); if( m_scanned % 100 == 0 ) - qDebug() << "SCAN" << m_scanned << fi.absoluteFilePath(); + qDebug() << "SCAN" << m_scanned << fi.canonicalFilePath(); #ifdef COMPLEX_TAGLIB_FILENAME - const wchar_t *encodedName = reinterpret_cast< const wchar_t * >( fi.absoluteFilePath().utf16() ); + const wchar_t *encodedName = reinterpret_cast< const wchar_t * >( fi.canonicalFilePath().utf16() ); #else - QByteArray fileName = QFile::encodeName( fi.absoluteFilePath() ); + QByteArray fileName = QFile::encodeName( fi.canonicalFilePath() ); const char *encodedName = fileName.constData(); #endif TagLib::FileRef f( encodedName ); if ( f.isNull() || !f.tag() ) { - // qDebug() << "Doesn't seem to be a valid audiofile:" << fi.absoluteFilePath(); - m_skippedFiles << fi.absoluteFilePath(); + // qDebug() << "Doesn't seem to be a valid audiofile:" << fi.canonicalFilePath(); + m_skippedFiles << fi.canonicalFilePath(); m_skipped++; return QVariantMap(); } @@ -351,8 +354,8 @@ MusicScanner::readFile( const QFileInfo& fi ) if ( artist.isEmpty() || track.isEmpty() ) { // FIXME: do some clever filename guessing - // qDebug() << "No tags found, skipping" << fi.absoluteFilePath(); - m_skippedFiles << fi.absoluteFilePath(); + // qDebug() << "No tags found, skipping" << fi.canonicalFilePath(); + m_skippedFiles << fi.canonicalFilePath(); m_skipped++; return QVariantMap(); } @@ -361,7 +364,7 @@ MusicScanner::readFile( const QFileInfo& fi ) QString url( "file://%1" ); QVariantMap m; - m["url"] = url.arg( fi.absoluteFilePath() ); + m["url"] = url.arg( fi.canonicalFilePath() ); m["mtime"] = fi.lastModified().toUTC().toTime_t(); m["size"] = (unsigned int)fi.size(); m["mimetype"] = mimetype; diff --git a/src/musicscanner.h b/src/musicscanner.h index 77fb62071..0944c2f90 100644 --- a/src/musicscanner.h +++ b/src/musicscanner.h @@ -46,7 +46,7 @@ public: MTimeOnly }; - DirLister( QStringList dirs, QMap& mtimes, bool recursive ) + DirLister( const QStringList& dirs, const QMap& mtimes, bool recursive ) : QObject(), m_dirs( dirs ), m_dirmtimes( mtimes ), m_recursive( recursive ) { qDebug() << Q_FUNC_INFO; From 66e3d07aee1ef0145191b170a2d947efa553ca31 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Fri, 15 Apr 2011 07:50:38 +0200 Subject: [PATCH 58/75] * Use canonicalPath() wherever dealing with file- & dir-paths. --- .../database/databasecommand_deletefiles.cpp | 16 ++++++++-------- .../database/databasecommand_dirmtimes.cpp | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/libtomahawk/database/databasecommand_deletefiles.cpp b/src/libtomahawk/database/databasecommand_deletefiles.cpp index 503d3887b..f3675369f 100644 --- a/src/libtomahawk/database/databasecommand_deletefiles.cpp +++ b/src/libtomahawk/database/databasecommand_deletefiles.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -78,18 +78,18 @@ DatabaseCommand_DeleteFiles::exec( DatabaseImpl* dbi ) delquery.prepare( QString( "DELETE FROM file WHERE source %1 AND id = ?" ) .arg( source()->isLocal() ? "IS NULL" : QString( "= %1" ).arg( source()->id() ) ) ); - dirquery.bindValue( 0, "file://" + m_dir.absolutePath() + "/%" ); + dirquery.bindValue( 0, "file://" + m_dir.canonicalPath() + "/%" ); dirquery.exec(); while ( dirquery.next() ) { QFileInfo fi( dirquery.value( 1 ).toString().mid( 7 ) ); // remove file:// - if ( fi.absolutePath() != m_dir.absolutePath() ) + if ( fi.canonicalPath() != m_dir.canonicalPath() ) { - if ( lastPath != fi.absolutePath() ) - qDebug() << "Skipping subdir:" << fi.absolutePath(); + if ( lastPath != fi.canonicalPath() ) + qDebug() << "Skipping subdir:" << fi.canonicalPath(); - lastPath = fi.absolutePath(); + lastPath = fi.canonicalPath(); continue; } @@ -133,11 +133,11 @@ DatabaseCommand_DeleteFiles::exec( DatabaseImpl* dbi ) << delquery.boundValues(); continue; } - + deleted++; } } - + qDebug() << "Deleted" << deleted << m_ids << m_files; emit done( m_files, source()->collection() ); diff --git a/src/libtomahawk/database/databasecommand_dirmtimes.cpp b/src/libtomahawk/database/databasecommand_dirmtimes.cpp index 07fbad637..c0ef4ffc5 100644 --- a/src/libtomahawk/database/databasecommand_dirmtimes.cpp +++ b/src/libtomahawk/database/databasecommand_dirmtimes.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -60,7 +60,7 @@ DatabaseCommand_DirMtimes::execSelectPath( DatabaseImpl *dbi, const QDir& path, "FROM dirs_scanned " "WHERE name LIKE :prefix" ) ); - query.bindValue( ":prefix", path.absolutePath() + "%" ); + query.bindValue( ":prefix", path.canonicalPath() + "%" ); query.exec(); while( query.next() ) From abd5c3c567d59a9bbd6b13486ba336e4714f92b9 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Fri, 15 Apr 2011 09:09:20 +0200 Subject: [PATCH 59/75] * Fixed bad url detection in last.fm plugin. --- .../infosystem/infoplugins/lastfmplugin.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libtomahawk/infosystem/infoplugins/lastfmplugin.cpp b/src/libtomahawk/infosystem/infoplugins/lastfmplugin.cpp index f3a8f8b49..9b96164a4 100644 --- a/src/libtomahawk/infosystem/infoplugins/lastfmplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/lastfmplugin.cpp @@ -82,8 +82,7 @@ LastFmPlugin::LastFmPlugin( QObject* parent ) #endif - m_badUrls << QUrl( "http://cdn.last.fm/flatness/catalogue/noimage" ) - << QUrl( "http://cdn.last.fm/flatness/catalogue/noimage/2/default_artist_medium.png" ); + m_badUrls << QUrl( "http://cdn.last.fm/flatness/catalogue/noimage" ); connect( TomahawkSettings::instance(), SIGNAL( changed() ), SLOT( settingsChanged() ), Qt::QueuedConnection ); @@ -283,8 +282,11 @@ LastFmPlugin::coverArtReturned() if ( redir.isEmpty() ) { QByteArray ba = reply->readAll(); - if ( m_badUrls.contains( reply->url() ) ) - ba = QByteArray(); + foreach ( const QUrl& url, m_badUrls ) + { + if ( reply->url().toString().startsWith( url.toString() ) ) + ba = QByteArray(); + } InfoCustomData returnedData; returnedData["imgbytes"] = ba; From 5e38fc572549e080e7fec4725dc7ffcfa57c16ad Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Fri, 15 Apr 2011 09:15:45 +0200 Subject: [PATCH 60/75] * Updated ChangeLog. --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 3a6c32a6c..f33fe5ebf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,5 @@ Version 0.1.0: + * You can now browse and play collections in a tree-view. * Watch folders for changes and automatically update your collection. This is on by default; you can turn it off on the Local Music tab in the settings dialog. Note that this triggers only on files or folders being From aad9dd4d759218a236a798a87505eca0856abb9b Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Fri, 15 Apr 2011 10:25:32 +0200 Subject: [PATCH 61/75] * Fixed rejecting default covers for artist images, too. --- src/libtomahawk/infosystem/infoplugins/lastfmplugin.cpp | 8 +++++--- src/settingsdialog.cpp | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libtomahawk/infosystem/infoplugins/lastfmplugin.cpp b/src/libtomahawk/infosystem/infoplugins/lastfmplugin.cpp index 9b96164a4..407031f1e 100644 --- a/src/libtomahawk/infosystem/infoplugins/lastfmplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/lastfmplugin.cpp @@ -81,7 +81,6 @@ LastFmPlugin::LastFmPlugin( QObject* parent ) } #endif - m_badUrls << QUrl( "http://cdn.last.fm/flatness/catalogue/noimage" ); connect( TomahawkSettings::instance(), SIGNAL( changed() ), @@ -333,8 +332,11 @@ LastFmPlugin::artistImagesReturned() if ( redir.isEmpty() ) { QByteArray ba = reply->readAll(); - if ( m_badUrls.contains( reply->url() ) ) - ba = QByteArray(); + foreach ( const QUrl& url, m_badUrls ) + { + if ( reply->url().toString().startsWith( url.toString() ) ) + ba = QByteArray(); + } InfoCustomData returnedData; returnedData["imgbytes"] = ba; diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index 966f193d1..ca481749c 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -105,7 +105,7 @@ SettingsDialog::SettingsDialog( QWidget *parent ) ResolverConfigDelegate* del = new ResolverConfigDelegate( this ); connect( del, SIGNAL( openConfig( QString ) ), this, SLOT( openResolverConfig( QString ) ) ); ui->scriptList->setItemDelegate( del ); - m_resolversModel = new ResolversModel( s->allScriptResolvers(), s->enabledScriptResolvers(), this ); + m_resolversModel = new ResolversModel( s->allScriptResolvers(), s->enabledScriptResolvers(), this ); ui->scriptList->setModel( m_resolversModel ); connect( ui->scriptList->selectionModel(), SIGNAL( selectionChanged( QItemSelection,QItemSelection ) ), this, SLOT( scriptSelectionChanged() ) ); From db4fc8bd03c80d5e0bc792cad5fbfee2046610b6 Mon Sep 17 00:00:00 2001 From: Frank Osterfeld Date: Thu, 14 Apr 2011 20:16:34 +0200 Subject: [PATCH 62/75] Fix compiler warnings. --- src/libtomahawk/database/fuzzyindex.cpp | 2 +- src/libtomahawk/network/controlconnection.cpp | 1 + src/libtomahawk/playlist/treemodelitem.cpp | 1 + thirdparty/liblastfm2/src/types/Track.cpp | 4 ++-- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/libtomahawk/database/fuzzyindex.cpp b/src/libtomahawk/database/fuzzyindex.cpp index 25719317c..31d4f5754 100644 --- a/src/libtomahawk/database/fuzzyindex.cpp +++ b/src/libtomahawk/database/fuzzyindex.cpp @@ -179,7 +179,7 @@ FuzzyIndex::search( const QString& table, const QString& name ) FuzzyQuery* qry = _CLNEW FuzzyQuery( _CLNEW Term( table.toStdWString().c_str(), DatabaseImpl::sortname( name ).toStdWString().c_str() ) ); hits = m_luceneSearcher->search( qry ); - for ( int i = 0; i < hits->length(); i++ ) + for ( uint i = 0; i < hits->length(); i++ ) { Document* d = &hits->doc( i ); diff --git a/src/libtomahawk/network/controlconnection.cpp b/src/libtomahawk/network/controlconnection.cpp index 24cc6af6d..b1c7a0b50 100644 --- a/src/libtomahawk/network/controlconnection.cpp +++ b/src/libtomahawk/network/controlconnection.cpp @@ -118,6 +118,7 @@ ControlConnection::registerSource() { qDebug() << Q_FUNC_INFO << m_source->id(); Source* source = (Source*) sender(); + Q_UNUSED( source ) Q_ASSERT( source == m_source.data() ); // .. but we'll use the shared pointer we've already made: diff --git a/src/libtomahawk/playlist/treemodelitem.cpp b/src/libtomahawk/playlist/treemodelitem.cpp index 9e1c03fa2..09688a56d 100644 --- a/src/libtomahawk/playlist/treemodelitem.cpp +++ b/src/libtomahawk/playlist/treemodelitem.cpp @@ -19,6 +19,7 @@ #include "treemodelitem.h" #include "utils/tomahawkutils.h" +#include "album.h" #include diff --git a/thirdparty/liblastfm2/src/types/Track.cpp b/thirdparty/liblastfm2/src/types/Track.cpp index cececee1b..64d8288d0 100644 --- a/thirdparty/liblastfm2/src/types/Track.cpp +++ b/thirdparty/liblastfm2/src/types/Track.cpp @@ -33,9 +33,9 @@ lastfm::TrackData::TrackData() rating( 0 ), fpid( -1 ), loved( false ), - null( false ), scrobbleStatus( Track::Null ), - scrobbleError( Track::None ) + scrobbleError( Track::None ), + null( false ) {} lastfm::Track::Track() From dde278a1cc522b1e0bf2f0c44ad44f379bfe63ee Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 15 Apr 2011 08:45:20 -0400 Subject: [PATCH 63/75] changielog --- ChangeLog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ChangeLog b/ChangeLog index f33fe5ebf..c816f71f4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,6 @@ Version 0.1.0: + * Resolvers can now be enabled and disabled, and some can be configured + directly in Tomahawk. * You can now browse and play collections in a tree-view. * Watch folders for changes and automatically update your collection. This is on by default; you can turn it off on the Local Music tab in the From 3671f35928e27e63a8fef8798dea818bbd5a6801 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 15 Apr 2011 14:00:11 -0400 Subject: [PATCH 64/75] don't crash if we try to feed QxT a result that we don't have a proper length for --- src/web/api_v1.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/web/api_v1.cpp b/src/web/api_v1.cpp index d0a3b0475..800935d4c 100644 --- a/src/web/api_v1.cpp +++ b/src/web/api_v1.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -71,7 +71,7 @@ Api_v1::auth_2( QxtWebRequestEvent* event, QString arg ) else qDebug() << "Failed parsing url parameters: " << part; } - + qDebug() << "has query items:" << pieces; if( !params.contains( "website" ) || !params.contains( "name" ) || !params.contains( "formtoken" ) ) { @@ -165,7 +165,8 @@ Api_v1::sid( QxtWebRequestEvent* event, QString unused ) QxtWebPageEvent* e = new QxtWebPageEvent( event->sessionID, event->requestID, iodev ); e->streaming = iodev->isSequential(); e->contentType = rp->mimetype().toAscii(); - e->headers.insert( "Content-Length", QString::number( rp->size() ) ); + if( rp->size() > 0 ) + e->headers.insert( "Content-Length", QString::number( rp->size() ) ); postEvent( e ); } @@ -341,7 +342,7 @@ Api_v1::sendWebpageWithArgs( QxtWebRequestEvent* event, const QString& filenameS // workaround for receiverurl if( !args.keys().contains( "URL" ) ) html.replace( QString( "<%URL%>" ).toLatin1(), QByteArray() ); - + QxtWebPageEvent* e = new QxtWebPageEvent( event->sessionID, event->requestID, html ); postEvent( e ); From e503f74db1ee59335dd0d951ec85ceeb8ffb0069 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 15 Apr 2011 14:01:07 -0400 Subject: [PATCH 65/75] update changelog --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index c816f71f4..46d9ee62f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -10,6 +10,7 @@ Version 0.1.0: music collection. Version 0.0.4: + * Fixed crash that could occur when playing a track from a browser. * Fixed a crash situation caused by sources going on- or offline. Version 0.0.3: From 1ecb7996942b5a0fe79654edf1a08048d1df2d13 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 15 Apr 2011 17:27:27 -0400 Subject: [PATCH 66/75] add a createdOn property to playlists, and sort sourcetree --- data/sql/dbmigrate-22_to_23.sql | 11 ++ resources.qrc | 1 + .../database/databasecollection.cpp | 11 +- .../databasecommand_createdynamicplaylist.cpp | 28 +-- .../databasecommand_createplaylist.cpp | 20 +- ...atabasecommand_loadalldynamicplaylists.cpp | 21 +- .../databasecommand_loadallplaylists.cpp | 5 +- src/libtomahawk/database/databaseimpl.cpp | 93 +++++++-- src/libtomahawk/database/databaseimpl.h | 8 +- src/libtomahawk/database/schema.sql | 17 +- src/libtomahawk/database/schema.sql.h | 9 +- src/libtomahawk/playlist.cpp | 67 ++++--- src/libtomahawk/playlist.h | 10 +- .../playlist/dynamic/DynamicPlaylist.cpp | 185 +++++++++--------- .../playlist/dynamic/DynamicPlaylist.h | 57 +++--- src/sourcetree/sourcesmodel.cpp | 47 ++++- src/sourcetree/sourcesmodel.h | 14 +- src/sourcetree/sourcesproxymodel.cpp | 5 +- src/sourcetree/sourcesproxymodel.h | 2 +- src/sourcetree/sourcetreeview.cpp | 3 + 20 files changed, 359 insertions(+), 255 deletions(-) create mode 100644 data/sql/dbmigrate-22_to_23.sql diff --git a/data/sql/dbmigrate-22_to_23.sql b/data/sql/dbmigrate-22_to_23.sql new file mode 100644 index 000000000..0ee92dd21 --- /dev/null +++ b/data/sql/dbmigrate-22_to_23.sql @@ -0,0 +1,11 @@ +-- Script to migate from db version 22 to 23. +-- Only change in this version is that playlists gained a createdOn date. +-- Set all playlists to created to now. +-- +-- Separate each command with %% + +ALTER TABLE playlist ADD COLUMN createdOn INTEGER NOT NULL DEFAULT 0; + +UPDATE playlist SET createdOn = strftime( '%s','now' ); + +UPDATE settings SET v = '23' WHERE k == 'schema_version'; diff --git a/resources.qrc b/resources.qrc index 9996e5cb0..7442790aa 100644 --- a/resources.qrc +++ b/resources.qrc @@ -88,5 +88,6 @@ ./data/www/auth.html ./data/www/auth.na.html ./data/www/tomahawk_banner_small.png +./data/sql/dbmigrate-22_to_23.sql diff --git a/src/libtomahawk/database/databasecollection.cpp b/src/libtomahawk/database/databasecollection.cpp index 23e36584d..bbcf6da79 100644 --- a/src/libtomahawk/database/databasecollection.cpp +++ b/src/libtomahawk/database/databasecollection.cpp @@ -143,11 +143,12 @@ void DatabaseCollection::dynamicPlaylistCreated( const source_ptr& source, const data[1].toString(), //title data[2].toString(), //info data[3].toString(), //creator - data[4].toString(), // dynamic type - static_cast(data[5].toInt()), // dynamic mode - data[6].toBool(), //shared - data[7].toInt(), //lastmod - data[8].toString() ) ); //GUID + data[4].toUInt(), // createdOn + data[5].toString(), // dynamic type + static_cast(data[6].toInt()), // dynamic mode + data[7].toBool(), //shared + data[8].toInt(), //lastmod + data[9].toString() ) ); //GUID addDynamicPlaylist( p ); } diff --git a/src/libtomahawk/database/databasecommand_createdynamicplaylist.cpp b/src/libtomahawk/database/databasecommand_createdynamicplaylist.cpp index f432f3a25..31b675119 100644 --- a/src/libtomahawk/database/databasecommand_createdynamicplaylist.cpp +++ b/src/libtomahawk/database/databasecommand_createdynamicplaylist.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -53,15 +53,15 @@ DatabaseCommand_CreateDynamicPlaylist::exec( DatabaseImpl* lib ) qDebug() << Q_FUNC_INFO; Q_ASSERT( !( m_playlist.isNull() && m_v.isNull() ) ); Q_ASSERT( !source().isNull() ); - + DatabaseCommand_CreatePlaylist::createPlaylist( lib, true ); qDebug() << "Created normal playlist, now creating additional dynamic info!"; - + TomahawkSqlQuery cre = lib->newquery(); cre.prepare( "INSERT INTO dynamic_playlist( guid, pltype, plmode ) " "VALUES( ?, ?, ? )" ); - + if( m_playlist.isNull() ) { QVariantMap m = m_v.toMap(); cre.addBindValue( m.value( "guid" ) ); @@ -73,22 +73,6 @@ DatabaseCommand_CreateDynamicPlaylist::exec( DatabaseImpl* lib ) cre.addBindValue( m_playlist->mode() ); } cre.exec(); - - // save the controls -- wait, no controls in a new playlist :P -// cre = lib->newquery(); -// cre.prepare( "INSERT INTO dynamic_playlist_controls( id, selectedType, match, input) " -// "VALUES( :id, :selectedType, :match, :input )" ); -// foreach( const dyncontrol_ptr& control, m_playlist->generator()->controls() ) { -// -// cre.bindValue( ":id", control->id() ); -// cre.bindValue( ":selectedType", control->selectedType() ); -// cre.bindValue( ":match", control->match() ); -// cre.bindValue( ":input", control->input() ); -// -// qDebug() << "CREATE DYNPLAYLIST CONTROL:" << cre.boundValues(); -// -// cre.exec(); -// } } @@ -101,10 +85,10 @@ DatabaseCommand_CreateDynamicPlaylist::postCommitHook() qDebug() << "Source has gone offline, not emitting to GUI."; return; } - + if( report() == false ) return; - + qDebug() << Q_FUNC_INFO << "..reporting.."; if( m_playlist.isNull() ) { source_ptr src = source(); diff --git a/src/libtomahawk/database/databasecommand_createplaylist.cpp b/src/libtomahawk/database/databasecommand_createplaylist.cpp index b5bd2ccc2..3f52bd95e 100644 --- a/src/libtomahawk/database/databasecommand_createplaylist.cpp +++ b/src/libtomahawk/database/databasecommand_createplaylist.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -75,25 +75,29 @@ DatabaseCommand_CreatePlaylist::postCommitHook() } else { m_playlist->reportCreated( m_playlist ); } - + if( source()->isLocal() ) Servent::instance()->triggerDBSync(); } -void +void DatabaseCommand_CreatePlaylist::createPlaylist( DatabaseImpl* lib, bool dynamic) { qDebug() << Q_FUNC_INFO; Q_ASSERT( !( m_playlist.isNull() && m_v.isNull() ) ); Q_ASSERT( !source().isNull() ); - + + uint now = QDateTime::currentDateTime().toTime_t(); + m_playlist->setCreatedOn( now ); + TomahawkSqlQuery cre = lib->newquery(); - cre.prepare( "INSERT INTO playlist( guid, source, shared, title, info, creator, lastmodified, dynplaylist) " - "VALUES( :guid, :source, :shared, :title, :info, :creator, :lastmodified, :dynplaylist )" ); - + cre.prepare( "INSERT INTO playlist( guid, source, shared, title, info, creator, lastmodified, dynplaylist, createdOn) " + "VALUES( :guid, :source, :shared, :title, :info, :creator, :lastmodified, :dynplaylist, :createdOn )" ); + cre.bindValue( ":source", source()->isLocal() ? QVariant(QVariant::Int) : source()->id() ); cre.bindValue( ":dynplaylist", dynamic ); + cre.bindValue( ":createdOn", now ); if( !m_playlist.isNull() ) { cre.bindValue( ":guid", m_playlist->guid() ); cre.bindValue( ":shared", m_playlist->shared() ); @@ -111,6 +115,6 @@ DatabaseCommand_CreatePlaylist::createPlaylist( DatabaseImpl* lib, bool dynamic) cre.bindValue( ":lastmodified", m.value( "lastmodified", 0 ) ); } qDebug() << "CREATE PLAYLIST:" << cre.boundValues(); - + cre.exec(); } diff --git a/src/libtomahawk/database/databasecommand_loadalldynamicplaylists.cpp b/src/libtomahawk/database/databasecommand_loadalldynamicplaylists.cpp index 333b596fd..8c5a1bd27 100644 --- a/src/libtomahawk/database/databasecommand_loadalldynamicplaylists.cpp +++ b/src/libtomahawk/database/databasecommand_loadalldynamicplaylists.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -29,28 +29,29 @@ using namespace Tomahawk; void DatabaseCommand_LoadAllDynamicPlaylists::exec( DatabaseImpl* dbi ) { TomahawkSqlQuery query = dbi->newquery(); - - query.exec( QString( "SELECT playlist.guid as guid, title, info, creator, lastmodified, shared, currentrevision, dynamic_playlist.pltype, dynamic_playlist.plmode " + + query.exec( QString( "SELECT playlist.guid as guid, title, info, creator, createdOn, lastmodified, shared, currentrevision, dynamic_playlist.pltype, dynamic_playlist.plmode " "FROM playlist, dynamic_playlist WHERE source %1 AND dynplaylist = 'true' AND playlist.guid = dynamic_playlist.guid" ) .arg( source()->isLocal() ? "IS NULL" : QString( "=%1" ).arg( source()->id() ) ) ); - + QList plists; while ( query.next() ) { - QVariantList data = QVariantList() << query.value(6).toString() //current rev + QVariantList data = QVariantList() << query.value(7).toString() //current rev << query.value(1).toString() //title << query.value(2).toString() //info << query.value(3).toString() //creator - << query.value(7).toString() // dynamic type - << static_cast(query.value(8).toInt()) // dynamic mode - << query.value(5).toBool() //shared - << query.value(4).toInt() //lastmod + << query.value(4).toString() //createdOn + << query.value(8).toString() // dynamic type + << static_cast(query.value(9).toInt()) // dynamic mode + << query.value(6).toBool() //shared + << query.value(5).toInt() //lastmod << query.value(0).toString(); //GUID emit playlistLoaded( source(), data ); } - + emit done(); } diff --git a/src/libtomahawk/database/databasecommand_loadallplaylists.cpp b/src/libtomahawk/database/databasecommand_loadallplaylists.cpp index db7865767..c2f0782bc 100644 --- a/src/libtomahawk/database/databasecommand_loadallplaylists.cpp +++ b/src/libtomahawk/database/databasecommand_loadallplaylists.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -30,7 +30,7 @@ void DatabaseCommand_LoadAllPlaylists::exec( DatabaseImpl* dbi ) { TomahawkSqlQuery query = dbi->newquery(); - query.exec( QString( "SELECT guid, title, info, creator, lastmodified, shared, currentrevision " + query.exec( QString( "SELECT guid, title, info, creator, lastmodified, shared, currentrevision, createdOn " "FROM playlist WHERE source %1 AND dynplaylist = 'false'" ) .arg( source()->isLocal() ? "IS NULL" : QString( "= %1" ).arg( source()->id() ) @@ -44,6 +44,7 @@ void DatabaseCommand_LoadAllPlaylists::exec( DatabaseImpl* dbi ) query.value(1).toString(), //title query.value(2).toString(), //info query.value(3).toString(), //creator + query.value(7).toInt(), //lastmod query.value(5).toBool(), //shared query.value(4).toInt(), //lastmod query.value(0).toString() //GUID diff --git a/src/libtomahawk/database/databaseimpl.cpp b/src/libtomahawk/database/databaseimpl.cpp index 85615f00e..2e2fa69ed 100644 --- a/src/libtomahawk/database/databaseimpl.cpp +++ b/src/libtomahawk/database/databaseimpl.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -30,6 +30,7 @@ #include "result.h" #include "artist.h" #include "album.h" +#include "utils/tomahawkutils.h" /* !!!! You need to manually generate schema.sql.h when the schema changes: cd src/libtomahawk/database @@ -37,7 +38,7 @@ */ #include "schema.sql.h" -#define CURRENT_SCHEMA_VERSION 22 +#define CURRENT_SCHEMA_VERSION 23 DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent ) @@ -63,21 +64,22 @@ DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent ) int v = qry.value( 0 ).toInt(); qDebug() << "Current schema is" << v << this->thread(); if ( v != CURRENT_SCHEMA_VERSION ) - { + { QString newname = QString("%1.v%2").arg(dbname).arg(v); qDebug() << endl << "****************************" << endl; qDebug() << "Schema version too old: " << v << ". Current version is:" << CURRENT_SCHEMA_VERSION; qDebug() << "Moving" << dbname << newname; + qDebug() << "If the migration fails, you can recover your DB by copying" << newname << "back to" << dbname; qDebug() << endl << "****************************" << endl; qry.clear(); qry.finish(); - + db.close(); db.removeDatabase( "tomahawk" ); - if( QFile::rename( dbname, newname ) ) + if( QFile::copy( dbname, newname ) ) { db = QSqlDatabase::addDatabase( "QSQLITE", "tomahawk" ); db.setDatabaseName( dbname ); @@ -87,6 +89,13 @@ DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent ) TomahawkSqlQuery query = newquery(); query.exec( "PRAGMA auto_vacuum = FULL" ); schemaUpdated = updateSchema( v ); + + if( !schemaUpdated ) + { + Q_ASSERT( false ); + QTimer::singleShot( 0, qApp, SLOT( quit() ) ); + } + } else { @@ -149,26 +158,70 @@ DatabaseImpl::updateSearchIndex() bool -DatabaseImpl::updateSchema( int currentver ) +DatabaseImpl::updateSchema( int oldVersion ) { - qDebug() << "Create tables... old version is" << currentver; - QString sql( get_tomahawk_sql() ); - QStringList statements = sql.split( ";", QString::SkipEmptyParts ); - db.transaction(); - - foreach( const QString& sl, statements ) + // we are called here with the old database. we must migrate it to the CURRENT_SCHEMA_VERSION from t7he oldVersion + if ( oldVersion == 0 ) // empty database, so create our tables and stuff { - QString s( sl.trimmed() ); - if( s.length() == 0 ) - continue; + qDebug() << "Create tables... old version is" << oldVersion; + QString sql( get_tomahawk_sql() ); + QStringList statements = sql.split( ";", QString::SkipEmptyParts ); + db.transaction(); - qDebug() << "Executing:" << s; - TomahawkSqlQuery query = newquery(); - query.exec( s ); + foreach( const QString& sl, statements ) + { + QString s( sl.trimmed() ); + if( s.length() == 0 ) + continue; + + qDebug() << "Executing:" << s; + TomahawkSqlQuery query = newquery(); + query.exec( s ); + } + + db.commit(); + return true; + } else // update in place! run the proper upgrade script + { + int cur = oldVersion; + db.transaction(); + while( cur < CURRENT_SCHEMA_VERSION ) { + cur++; + + QString path = QString( RESPATH "sql/dbmigrate-%1_to_%2.sql" ).arg( cur - 1 ).arg( cur ); + QFile script( path ); + if( !script.exists() || !script.open( QIODevice::ReadOnly ) ) + { + qWarning() << "Failed to find or open upgrade script from" << (cur-1) << "to" << cur << " (" << path << ")! Aborting upgrade.."; + return false; + } + QString sql = QString::fromUtf8( script.readAll() ).trimmed(); + QStringList statements = sql.split( ";", QString::SkipEmptyParts ); + + foreach( const QString& sql, statements ) + { + QString clean = cleanSql( sql ).trimmed(); + if( clean.isEmpty() ) + continue; + + qDebug() << "Executing upgrade statement:" << clean; + TomahawkSqlQuery q = newquery(); + q.exec( clean ); + } + } + db.commit(); + qDebug() << "DB Upgrade successful!"; + return true; } +} - db.commit(); - return true; +QString +DatabaseImpl::cleanSql( const QString& sql ) +{ + QString fixed = sql; + QRegExp r( "--[^\\n]*" ); + fixed.replace( r, QString() ); + return fixed.trimmed(); } diff --git a/src/libtomahawk/database/databaseimpl.h b/src/libtomahawk/database/databaseimpl.h index e2965f553..f3551b634 100644 --- a/src/libtomahawk/database/databaseimpl.h +++ b/src/libtomahawk/database/databaseimpl.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -84,9 +84,11 @@ signals: public slots: private: + QString cleanSql( const QString& sql ); + bool m_ready; - - bool updateSchema( int currentver ); + + bool updateSchema( int oldVersion ); QSqlDatabase db; diff --git a/src/libtomahawk/database/schema.sql b/src/libtomahawk/database/schema.sql index e35973508..e2f6ce90d 100644 --- a/src/libtomahawk/database/schema.sql +++ b/src/libtomahawk/database/schema.sql @@ -67,13 +67,14 @@ CREATE TABLE IF NOT EXISTS playlist ( creator TEXT, lastmodified INTEGER NOT NULL DEFAULT 0, currentrevision TEXT REFERENCES playlist_revision(guid) DEFERRABLE INITIALLY DEFERRED, - dynplaylist BOOLEAN DEFAULT false + dynplaylist BOOLEAN DEFAULT false, + createdOn INTEGER NOT NULL DEFAULT 0 ); ---INSERT INTO playlist(guid, title, info, currentrevision, dynplaylist) +--INSERT INTO playlist(guid, title, info, currentrevision, dynplaylist) --VALUES('dynamic_playlist-guid-1','Test Dynamic Playlist Dynamic','this playlist automatically created and used for testing','revisionguid-1', 1); ---INSERT INTO playlist(guid, title, info, currentrevision, dynplaylist) +--INSERT INTO playlist(guid, title, info, currentrevision, dynplaylist) --VALUES('dynamic_playlist-guid-2','Test Dynamic Playlist Static','this playlist automatically created and used for testing','revisionguid-11', 1); CREATE TABLE IF NOT EXISTS playlist_item ( @@ -129,8 +130,8 @@ CREATE TABLE IF NOT EXISTS dynamic_playlist_controls ( --INSERT INTO dynamic_playlist_controls(id, playlist, selectedType, match, input) -- VALUES('controlid-2', 'dynamic_playlist-guid-11', "artist", 0, "FooArtist" ); - - + + CREATE TABLE IF NOT EXISTS dynamic_playlist_revision ( guid TEXT PRIMARY KEY NOT NULL REFERENCES playlist_revision(guid) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED, controls TEXT, -- qlist( id, id, id ) @@ -148,7 +149,7 @@ CREATE TABLE IF NOT EXISTS dynamic_playlist_revision ( -- if source=null, file is local to this machine CREATE TABLE IF NOT EXISTS file ( - id INTEGER PRIMARY KEY AUTOINCREMENT, + id INTEGER PRIMARY KEY AUTOINCREMENT, source INTEGER REFERENCES source(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED, url TEXT NOT NULL, -- file:///music/foo/bar.mp3, size INTEGER NOT NULL, -- in bytes @@ -212,7 +213,7 @@ CREATE TABLE IF NOT EXISTS artist_tags ( ); CREATE INDEX artist_tags_tag ON artist_tags(tag); --- all other attributes. +-- all other attributes. -- like tags that have a value, eg: -- BPM=120, releaseyear=1980, key=Dminor, composer=Someone -- NB: since all values are text, numeric values should be zero-padded to a set amount @@ -263,4 +264,4 @@ CREATE TABLE IF NOT EXISTS settings ( v TEXT NOT NULL DEFAULT '' ); -INSERT INTO settings(k,v) VALUES('schema_version', '22'); +INSERT INTO settings(k,v) VALUES('schema_version', '23'); diff --git a/src/libtomahawk/database/schema.sql.h b/src/libtomahawk/database/schema.sql.h index dfd468cf8..864766dc6 100644 --- a/src/libtomahawk/database/schema.sql.h +++ b/src/libtomahawk/database/schema.sql.h @@ -1,5 +1,5 @@ /* - This file was automatically generated from ./schema.sql on Wed Mar 2 01:40:39 CET 2011. + This file was automatically generated from schema.sql on Fri Apr 15 15:55:52 EDT 2011. */ static const char * tomahawk_schema_sql = @@ -51,7 +51,8 @@ static const char * tomahawk_schema_sql = " creator TEXT," " lastmodified INTEGER NOT NULL DEFAULT 0," " currentrevision TEXT REFERENCES playlist_revision(guid) DEFERRABLE INITIALLY DEFERRED," -" dynplaylist BOOLEAN DEFAULT false" +" dynplaylist BOOLEAN DEFAULT false," +" createdOn INTEGER NOT NULL DEFAULT 0" ");" "CREATE TABLE IF NOT EXISTS playlist_item (" " guid TEXT PRIMARY KEY," @@ -86,8 +87,6 @@ static const char * tomahawk_schema_sql = " match TEXT," " input TEXT" ");" -"" -"" "CREATE TABLE IF NOT EXISTS dynamic_playlist_revision (" " guid TEXT PRIMARY KEY NOT NULL REFERENCES playlist_revision(guid) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED," " controls TEXT, " @@ -173,7 +172,7 @@ static const char * tomahawk_schema_sql = " k TEXT NOT NULL PRIMARY KEY," " v TEXT NOT NULL DEFAULT ''" ");" -"INSERT INTO settings(k,v) VALUES('schema_version', '22');" +"INSERT INTO settings(k,v) VALUES('schema_version', '23');" ; const char * get_tomahawk_sql() diff --git a/src/libtomahawk/playlist.cpp b/src/libtomahawk/playlist.cpp index bf65556da..4281f7265 100644 --- a/src/libtomahawk/playlist.cpp +++ b/src/libtomahawk/playlist.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -57,28 +57,28 @@ PlaylistEntry::queryVariant() const } -void +void PlaylistEntry::setQuery( const Tomahawk::query_ptr& q ) { m_query = q; } -const Tomahawk::query_ptr& +const Tomahawk::query_ptr& PlaylistEntry::query() const { return m_query; } -source_ptr +source_ptr PlaylistEntry::lastSource() const { return m_lastsource; } -void +void PlaylistEntry::setLastSource( source_ptr s ) { m_lastsource = s; @@ -99,6 +99,7 @@ Playlist::Playlist( const source_ptr& src, const QString& title, const QString& info, const QString& creator, + uint createdOn, bool shared, int lastmod, const QString& guid ) @@ -109,6 +110,7 @@ Playlist::Playlist( const source_ptr& src, , m_title( title ) , m_info( info ) , m_creator( creator ) + , m_createdOn( createdOn ) , m_lastmodified( lastmod ) , m_shared( shared ) { @@ -129,6 +131,7 @@ Playlist::Playlist( const source_ptr& author, , m_title( title ) , m_info ( info ) , m_creator( creator ) + , m_createdOn( 0 ) // will be set by db command , m_lastmodified( 0 ) , m_shared( shared ) { @@ -141,7 +144,7 @@ void Playlist::init() { m_locallyChanged = false; - connect( Pipeline::instance(), SIGNAL( idle() ), SLOT( onResolvingFinished() ) ); + connect( Pipeline::instance(), SIGNAL( idle() ), SLOT( onResolvingFinished() ) ); } @@ -229,7 +232,7 @@ Playlist::reportDeleted( const Tomahawk::playlist_ptr& self ) qDebug() << Q_FUNC_INFO; Q_ASSERT( self.data() == this ); m_source->collection()->deletePlaylist( self ); - + emit deleted( self ); } @@ -310,24 +313,24 @@ Playlist::setRevision( const QString& rev, ); return; } - + PlaylistRevision pr = setNewRevision( rev, neworderedguids, oldorderedguids, is_newest_rev, addedmap ); - + if( applied ) m_currentrevision = rev; pr.applied = applied; - + foreach( const plentry_ptr& entry, m_entries ) { connect( entry->query().data(), SIGNAL( resultsAdded( QList ) ), SLOT( onResultsFound( QList ) ), Qt::UniqueConnection ); - + } emit revisionLoaded( pr ); } -PlaylistRevision +PlaylistRevision Playlist::setNewRevision( const QString& rev, const QList& neworderedguids, const QList& oldorderedguids, @@ -340,10 +343,10 @@ Playlist::setNewRevision( const QString& rev, QMap entriesmap; foreach( const plentry_ptr& p, m_entries ) entriesmap.insert( p->guid(), p ); - - + + QList entries; - + foreach( const QString& id, neworderedguids ) { //qDebug() << "id:" << id; @@ -351,7 +354,7 @@ Playlist::setNewRevision( const QString& rev, //qDebug() << "entriesmap:" << entriesmap.count() << entriesmap; //qDebug() << "addedmap:" << addedmap.count() << addedmap; //qDebug() << "m_entries" << m_entries; - + if( entriesmap.contains( id ) ) { entries.append( entriesmap.value( id ) ); @@ -367,13 +370,13 @@ Playlist::setNewRevision( const QString& rev, Q_ASSERT( false ); // XXX } } - + //qDebug() << Q_FUNC_INFO << rev << entries.length() << applied; - + PlaylistRevision pr; pr.oldrevisionguid = m_currentrevision; pr.revisionguid = rev; - + // entries that have been removed: QSet removedguids = oldorderedguids.toSet().subtract( neworderedguids.toSet() ); //qDebug() << "Removedguids:" << removedguids << "oldorederedguids" << oldorderedguids << "newog" << neworderedguids; @@ -399,10 +402,10 @@ Playlist::setNewRevision( const QString& rev, } } } - + pr.added = addedmap.values(); - - + + pr.newlist = entries; return pr; } @@ -410,12 +413,12 @@ Playlist::setNewRevision( const QString& rev, source_ptr Playlist::author() const -{ - return m_source; +{ + return m_source; } -void +void Playlist::resolve() { QList< query_ptr > qlist; @@ -462,7 +465,7 @@ void Playlist::addEntries( const QList& queries, const QString& oldrev ) { //qDebug() << Q_FUNC_INFO; - + QList el = addEntriesInternal( queries ); QString newrev = uuid(); @@ -470,7 +473,7 @@ Playlist::addEntries( const QList& queries, const QString& oldrev ) } -QList +QList Playlist::addEntriesInternal( const QList& queries ) { QList el = entries(); @@ -478,16 +481,16 @@ Playlist::addEntriesInternal( const QList& queries ) { plentry_ptr e( new PlaylistEntry() ); e->setGuid( uuid() ); - + if ( query->results().count() ) e->setDuration( query->results().at( 0 )->duration() ); else e->setDuration( 0 ); - + e->setLastmodified( 0 ); e->setAnnotation( "" ); // FIXME e->setQuery( query ); - + el << e; } return el; @@ -500,14 +503,14 @@ Playlist::newEntries( const QList< plentry_ptr >& entries ) QSet currentguids; foreach( const plentry_ptr& p, m_entries ) currentguids.insert( p->guid() ); // could be cached as member? - + // calc list of newly added entries: QList added; foreach( const plentry_ptr& p, entries ) { if( !currentguids.contains( p->guid() ) ) added << p; - } + } return added; } diff --git a/src/libtomahawk/playlist.h b/src/libtomahawk/playlist.h index 5147a3d9b..cb81e1a19 100644 --- a/src/libtomahawk/playlist.h +++ b/src/libtomahawk/playlist.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -77,6 +77,7 @@ public: source_ptr lastSource() const; void setLastSource( source_ptr s ); + private: QString m_guid; Tomahawk::query_ptr m_query; @@ -107,6 +108,7 @@ Q_PROPERTY( QString currentrevision READ currentrevision WRITE setCurrentrevi Q_PROPERTY( QString title READ title WRITE setTitle ) Q_PROPERTY( QString info READ info WRITE setInfo ) Q_PROPERTY( QString creator READ creator WRITE setCreator ) +Q_PROPERTY( unsigned int createdon READ createdOn WRITE setCreatedOn ) Q_PROPERTY( bool shared READ shared WRITE setShared ) friend class ::DatabaseCommand_LoadAllPlaylists; @@ -139,6 +141,7 @@ public: QString guid() const { return m_guid; } bool shared() const { return m_shared; } unsigned int lastmodified() const { return m_lastmodified; } + uint createdOn() const { return m_createdOn; } const QList< plentry_ptr >& entries() { return m_entries; } virtual void addEntry( const Tomahawk::query_ptr& query, const QString& oldrev ); @@ -155,6 +158,7 @@ public: void setCreator( const QString& s ) { m_creator = s; } void setGuid( const QString& s ) { m_guid = s; } void setShared( bool b ) { m_shared = b; } + void setCreatedOn( uint createdOn ) { m_createdOn = createdOn; } // virtual QList tracks(); @@ -184,7 +188,7 @@ signals: /// was deleted, eh? void deleted( const Tomahawk::playlist_ptr& pl ); - + void repeatModeChanged( PlaylistInterface::RepeatMode mode ); void shuffleModeChanged( bool enabled ); @@ -214,6 +218,7 @@ protected: const QString& title, const QString& info, const QString& creator, + uint createdOn, bool shared, int lastmod, const QString& guid = "" ); // populate db @@ -247,6 +252,7 @@ private: QString m_currentrevision; QString m_guid, m_title, m_info, m_creator; unsigned int m_lastmodified; + unsigned int m_createdOn; bool m_shared; QList< plentry_ptr > m_entries; diff --git a/src/libtomahawk/playlist/dynamic/DynamicPlaylist.cpp b/src/libtomahawk/playlist/dynamic/DynamicPlaylist.cpp index 6186024ee..d81c27324 100644 --- a/src/libtomahawk/playlist/dynamic/DynamicPlaylist.cpp +++ b/src/libtomahawk/playlist/dynamic/DynamicPlaylist.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -43,17 +43,18 @@ DynamicPlaylist::~DynamicPlaylist() } // Called by loadAllPlaylists command -DynamicPlaylist::DynamicPlaylist ( const Tomahawk::source_ptr& src, +DynamicPlaylist::DynamicPlaylist ( const Tomahawk::source_ptr& src, const QString& currentrevision, - const QString& title, - const QString& info, - const QString& creator, - const QString& type, + const QString& title, + const QString& info, + const QString& creator, + uint createdOn, + const QString& type, GeneratorMode mode, - bool shared, - int lastmod, + bool shared, + int lastmod, const QString& guid ) - : Playlist( src, currentrevision, title, info, creator, shared, lastmod, guid ) + : Playlist( src, currentrevision, title, info, creator, createdOn, shared, lastmod, guid ) { qDebug() << "Creating Dynamic Playlist 1"; // TODO instantiate generator @@ -63,12 +64,12 @@ DynamicPlaylist::DynamicPlaylist ( const Tomahawk::source_ptr& src, // called when a new playlist is created (no currentrevision, new guid) -DynamicPlaylist::DynamicPlaylist ( const Tomahawk::source_ptr& author, - const QString& guid, - const QString& title, - const QString& info, - const QString& creator, - const QString& type, +DynamicPlaylist::DynamicPlaylist ( const Tomahawk::source_ptr& author, + const QString& guid, + const QString& title, + const QString& info, + const QString& creator, + const QString& type, bool shared ) : Playlist ( author, guid, title, info, creator, shared ) { @@ -76,31 +77,31 @@ DynamicPlaylist::DynamicPlaylist ( const Tomahawk::source_ptr& author, m_generator = geninterface_ptr( GeneratorFactory::create( type ) ); } -geninterface_ptr +geninterface_ptr DynamicPlaylist::generator() const { return m_generator; } -int +int DynamicPlaylist::mode() const { return m_generator->mode(); } -void +void DynamicPlaylist::setGenerator(const Tomahawk::geninterface_ptr& gen_ptr) { m_generator = gen_ptr; } -QString +QString DynamicPlaylist::type() const { return m_generator->type(); } -void +void DynamicPlaylist::setMode( int mode ) { m_generator->setMode( (GeneratorMode)mode ); @@ -108,27 +109,27 @@ DynamicPlaylist::setMode( int mode ) -dynplaylist_ptr -DynamicPlaylist::create( const Tomahawk::source_ptr& author, - const QString& guid, - const QString& title, - const QString& info, - const QString& creator, +dynplaylist_ptr +DynamicPlaylist::create( const Tomahawk::source_ptr& author, + const QString& guid, + const QString& title, + const QString& info, + const QString& creator, bool shared ) { // default generator QString type = ""; dynplaylist_ptr dynplaylist = dynplaylist_ptr( new DynamicPlaylist( author, guid, title, info, creator, type, shared ) ); - + DatabaseCommand_CreateDynamicPlaylist* cmd = new DatabaseCommand_CreateDynamicPlaylist( author, dynplaylist ); connect( cmd, SIGNAL(finished()), dynplaylist.data(), SIGNAL(created()) ); Database::instance()->enqueue( QSharedPointer(cmd) ); dynplaylist->reportCreated( dynplaylist ); return dynplaylist; - + } -void +void DynamicPlaylist::createNewRevision( const QString& newUuid ) { if( mode() == Static ) @@ -142,22 +143,22 @@ DynamicPlaylist::createNewRevision( const QString& newUuid ) // create a new revision that will be a static playlist, as it has entries -void -DynamicPlaylist::createNewRevision( const QString& newrev, - const QString& oldrev, - const QString& type, - const QList< dyncontrol_ptr>& controls, +void +DynamicPlaylist::createNewRevision( const QString& newrev, + const QString& oldrev, + const QString& type, + const QList< dyncontrol_ptr>& controls, const QList< plentry_ptr >& entries ) { // get the newly added tracks QList< plentry_ptr > added = newEntries( entries ); - + QStringList orderedguids; for( int i = 0; i < entries.size(); ++i ) orderedguids << entries.at(i)->guid(); - + // no conflict resolution or partial updating for controls. all or nothing baby - + // source making the change (local user in this case) source_ptr author = SourceList::instance()->getLocal(); // command writes new rev to DB and calls setRevision, which emits our signal @@ -176,10 +177,10 @@ DynamicPlaylist::createNewRevision( const QString& newrev, } // create a new revision that will be an ondemand playlist, as it has no entries -void -DynamicPlaylist::createNewRevision( const QString& newrev, - const QString& oldrev, - const QString& type, +void +DynamicPlaylist::createNewRevision( const QString& newrev, + const QString& oldrev, + const QString& type, const QList< dyncontrol_ptr>& controls ) { // can skip the entry stuff. just overwrite with new info @@ -196,13 +197,13 @@ DynamicPlaylist::createNewRevision( const QString& newrev, Database::instance()->enqueue( QSharedPointer( cmd ) ); } -void +void DynamicPlaylist::loadRevision( const QString& rev ) { qDebug() << Q_FUNC_INFO << "Loading with:" << ( rev.isEmpty() ? currentrevision() : rev ); - + DatabaseCommand_LoadDynamicPlaylist* cmd = new DatabaseCommand_LoadDynamicPlaylist( rev.isEmpty() ? currentrevision() : rev ); - + if( m_generator->mode() == OnDemand ) { connect( cmd, SIGNAL( done( QString, bool, @@ -230,22 +231,22 @@ DynamicPlaylist::loadRevision( const QString& rev ) QList< QVariantMap >, bool, QMap< QString, Tomahawk::plentry_ptr >, - bool ) ) ); - + bool ) ) ); + } Database::instance()->enqueue( QSharedPointer( cmd ) ); } -bool +bool DynamicPlaylist::remove( const Tomahawk::dynplaylist_ptr& playlist ) { DatabaseCommand_DeletePlaylist* cmd = new DatabaseCommand_DeleteDynamicPlaylist( playlist->author(), playlist->guid() ); Database::instance()->enqueue( QSharedPointer(cmd) ); - + return false; } -void +void DynamicPlaylist::reportCreated( const Tomahawk::dynplaylist_ptr& self ) { qDebug() << Q_FUNC_INFO; @@ -255,26 +256,26 @@ DynamicPlaylist::reportCreated( const Tomahawk::dynplaylist_ptr& self ) // will emit Collection::playlistCreated(...) // qDebug() << "Creating dynplaylist belonging to:" << author().data() << author().isNull(); // qDebug() << "REPORTING DYNAMIC PLAYLIST CREATED:" << this << author()->friendlyName(); - author()->collection()->addDynamicPlaylist( self ); + author()->collection()->addDynamicPlaylist( self ); } -void +void DynamicPlaylist::reportDeleted( const Tomahawk::dynplaylist_ptr& self ) { qDebug() << Q_FUNC_INFO; Q_ASSERT( self.data() == this ); // will emit Collection::playlistDeleted(...) - author()->collection()->deleteDynamicPlaylist( self ); - + author()->collection()->deleteDynamicPlaylist( self ); + emit deleted( self ); } void DynamicPlaylist::addEntries(const QList< query_ptr >& queries, const QString& oldrev) { Q_ASSERT( m_generator->mode() == Static ); - + QList el = addEntriesInternal( queries ); - + QString newrev = uuid(); createNewRevision( newrev, oldrev, m_generator->type(), m_generator->controls(), el ); } @@ -283,17 +284,17 @@ void DynamicPlaylist::addEntry(const Tomahawk::query_ptr& query, const QString& { QList queries; queries << query; - + addEntries( queries, oldrev ); } -void DynamicPlaylist::setRevision( const QString& rev, - const QList< QString >& neworderedguids, - const QList< QString >& oldorderedguids, - const QString& type, - const QList< dyncontrol_ptr >& controls, - bool is_newest_rev, - const QMap< QString, plentry_ptr >& addedmap, +void DynamicPlaylist::setRevision( const QString& rev, + const QList< QString >& neworderedguids, + const QList< QString >& oldorderedguids, + const QString& type, + const QList< dyncontrol_ptr >& controls, + bool is_newest_rev, + const QMap< QString, plentry_ptr >& addedmap, bool applied) { // we're probably being called by a database worker thread @@ -315,32 +316,32 @@ void DynamicPlaylist::setRevision( const QString& rev, if( m_generator->type() != type ) { // new generator needed m_generator = GeneratorFactory::create( type ); } - + m_generator->setControls( controls ); m_generator->setMode( Static ); - + DynamicPlaylistRevision dpr = setNewRevision( rev, neworderedguids, oldorderedguids, is_newest_rev, addedmap ); dpr.applied = applied; dpr.controls = controls; dpr.type = type; dpr.mode = Static; - + if( applied ) { setCurrentrevision( rev ); } // qDebug() << "EMITTING REVISION LOADED 1!"; - emit dynamicRevisionLoaded( dpr ); + emit dynamicRevisionLoaded( dpr ); } -void -DynamicPlaylist::setRevision( const QString& rev, - const QList< QString >& neworderedguids, - const QList< QString >& oldorderedguids, - const QString& type, - const QList< QVariantMap>& controlsV, - bool is_newest_rev, - const QMap< QString, Tomahawk::plentry_ptr >& addedmap, +void +DynamicPlaylist::setRevision( const QString& rev, + const QList< QString >& neworderedguids, + const QList< QString >& oldorderedguids, + const QString& type, + const QList< QVariantMap>& controlsV, + bool is_newest_rev, + const QMap< QString, Tomahawk::plentry_ptr >& addedmap, bool applied ) { if( QThread::currentThread() != thread() ) @@ -358,16 +359,16 @@ DynamicPlaylist::setRevision( const QString& rev, Q_ARG( bool, applied ) ); return; } - + QList controls = variantsToControl( controlsV ); setRevision( rev, neworderedguids, oldorderedguids, type, controls, is_newest_rev, addedmap, applied ); - + } -void DynamicPlaylist::setRevision( const QString& rev, - bool is_newest_rev, - const QString& type, - const QList< dyncontrol_ptr >& controls, +void DynamicPlaylist::setRevision( const QString& rev, + bool is_newest_rev, + const QString& type, + const QList< dyncontrol_ptr >& controls, bool applied ) { if( QThread::currentThread() != thread() ) @@ -385,30 +386,30 @@ void DynamicPlaylist::setRevision( const QString& rev, if( m_generator->type() != type ) { // new generator needed m_generator = geninterface_ptr( GeneratorFactory::create( type ) ); } - + m_generator->setControls( controls ); m_generator->setMode( OnDemand ); - + DynamicPlaylistRevision dpr; dpr.oldrevisionguid = currentrevision(); dpr.revisionguid = rev; dpr.controls = controls; dpr.type = type; dpr.mode = OnDemand; - + if( applied ) { setCurrentrevision( rev ); } // qDebug() << "EMITTING REVISION LOADED 2!"; - emit dynamicRevisionLoaded( dpr ); + emit dynamicRevisionLoaded( dpr ); } -void -DynamicPlaylist::setRevision( const QString& rev, - bool is_newest_rev, - const QString& type, - const QList< QVariantMap >& controlsV, +void +DynamicPlaylist::setRevision( const QString& rev, + bool is_newest_rev, + const QString& type, + const QList< QVariantMap >& controlsV, bool applied ) { if( QThread::currentThread() != thread() ) @@ -422,8 +423,8 @@ DynamicPlaylist::setRevision( const QString& rev, QGenericArgument( "QList< QVariantMap >" , (const void*)&controlsV ), Q_ARG( bool, applied ) ); return; - } - + } + QList controls = variantsToControl( controlsV ); setRevision( rev, is_newest_rev, type, controls, applied ); } diff --git a/src/libtomahawk/playlist/dynamic/DynamicPlaylist.h b/src/libtomahawk/playlist/dynamic/DynamicPlaylist.h index 04cd2119e..4312d67b9 100644 --- a/src/libtomahawk/playlist/dynamic/DynamicPlaylist.h +++ b/src/libtomahawk/playlist/dynamic/DynamicPlaylist.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -35,7 +35,7 @@ class DatabaseCommand_CreateDynamicPlaylist; class DatabaseCollection; namespace Tomahawk { - + /** * Subclass of playlist that adds the information needed to store a dynamic playlist. * It uses normal PlaylistEntries but also has a mode, a generator, and a list of controls @@ -46,35 +46,35 @@ struct DLLEXPORT DynamicPlaylistRevision : PlaylistRevision QList< dyncontrol_ptr > controls; Tomahawk::GeneratorMode mode; QString type; - - DynamicPlaylistRevision( const PlaylistRevision& other ) - { - revisionguid = other.revisionguid; - oldrevisionguid = other.oldrevisionguid; + + DynamicPlaylistRevision( const PlaylistRevision& other ) + { + revisionguid = other.revisionguid; + oldrevisionguid = other.oldrevisionguid; newlist = other.newlist; added = other.added; removed = other.removed; - applied = other.applied; + applied = other.applied; } - + DynamicPlaylistRevision() {} }; class DLLEXPORT DynamicPlaylist : public Playlist { Q_OBJECT - + // :-( int becuase qjson chokes on my enums Q_PROPERTY( int mode WRITE setMode READ mode ) Q_PROPERTY( QString type WRITE setType READ type ) - + friend class ::DatabaseCommand_SetDynamicPlaylistRevision; friend class ::DatabaseCommand_CreateDynamicPlaylist; friend class ::DatabaseCollection; /// :-( - -public: + +public: virtual ~DynamicPlaylist(); - + /// Generate an empty dynamic playlist with default generator static Tomahawk::dynplaylist_ptr create( const source_ptr& author, const QString& guid, @@ -84,21 +84,21 @@ public: bool shared ); static bool remove( const dynplaylist_ptr& playlist ); - + virtual void loadRevision( const QString& rev = "" ); - + // :-( int becuase qjson chokes on my enums int mode() const; QString type() const; geninterface_ptr generator() const; - + // Creates a new revision from the playlist in memory. Use this is you change the controls or // mode of a playlist and want to save it to db/others. void createNewRevision( const QString& uuid = QString() ); - + virtual void addEntries( const QList< query_ptr >& queries, const QString& oldrev ); virtual void addEntry( const Tomahawk::query_ptr& query, const QString& oldrev ); - + // // these need to exist and be public for the json serialization stuff // you SHOULD NOT call them. They are used for an alternate CTOR method from json. @@ -108,13 +108,13 @@ public: void setType( const QString& /*type*/ ) { /** TODO */; } void setGenerator( const geninterface_ptr& gen_ptr ); // - + signals: /// emitted when the playlist revision changes (whenever the playlist changes) void dynamicRevisionLoaded( Tomahawk::DynamicPlaylistRevision ); - + void deleted( const Tomahawk::dynplaylist_ptr& pl ); - + public slots: // want to update the playlist from the model? // generate a newrev using uuid() and call this: @@ -122,10 +122,10 @@ public slots: void createNewRevision( const QString& newrev, const QString& oldrev, const QString& type, const QList< dyncontrol_ptr>& controls, const QList< plentry_ptr >& entries ); // if it is ondemand, no entries are needed implicitly sets mode to ondemand void createNewRevision( const QString& newrev, const QString& oldrev, const QString& type, const QList< dyncontrol_ptr>& controls ); - + void reportCreated( const Tomahawk::dynplaylist_ptr& self ); void reportDeleted( const Tomahawk::dynplaylist_ptr& self ); - + // called from setdynamicplaylistrevision db cmd // 4 options, because dbcmds can't create qwidgets: // static version, qvariant controls @@ -147,7 +147,7 @@ public slots: const QList< Tomahawk::dyncontrol_ptr >& controls, bool is_newest_rev, const QMap< QString, Tomahawk::plentry_ptr >& addedmap, - bool applied ); + bool applied ); // ondemand version void setRevision( const QString& rev, bool is_newest_rev, @@ -166,12 +166,13 @@ private: const QString& title, const QString& info, const QString& creator, + uint createdOn, const QString& type, GeneratorMode mode, bool shared, int lastmod, const QString& guid = "" ); // populate db - + // called when creating new playlist explicit DynamicPlaylist( const source_ptr& author, const QString& guid, @@ -180,11 +181,11 @@ private: const QString& creator, const QString& type, bool shared ); - + private: QList< dyncontrol_ptr > variantsToControl( const QList< QVariantMap >& controlsV ); geninterface_ptr m_generator; - + }; }; // namespace diff --git a/src/sourcetree/sourcesmodel.cpp b/src/sourcetree/sourcesmodel.cpp index 76f1d233d..a27b457f5 100644 --- a/src/sourcetree/sourcesmodel.cpp +++ b/src/sourcetree/sourcesmodel.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -38,6 +38,7 @@ SourcesModel::SourcesModel( SourceTreeView* parent ) , m_parent( parent ) { setColumnCount( 1 ); + setSortRole( SortRole ); onSourceAdded( SourceList::instance()->sources() ); connect( SourceList::instance(), SIGNAL( sourceAdded( Tomahawk::source_ptr ) ), SLOT( onSourceAdded( Tomahawk::source_ptr ) ) ); @@ -97,6 +98,32 @@ SourcesModel::data( const QModelIndex& index, int role ) const if ( role == Qt::SizeHintRole ) { return QSize( 0, 18 ); + } else if ( role == SortRole ) + { + if ( indexType( index ) == PlaylistSource ) + { + playlist_ptr playlist = indexToPlaylist( index ); + if ( !playlist.isNull() ) + return playlist->createdOn(); + } else if ( indexType( index ) == DynamicPlaylistSource ) + { + dynplaylist_ptr playlist = indexToDynamicPlaylist( index ); + if ( !playlist.isNull() ) + return playlist->createdOn(); + } else if( indexType( index ) == CollectionSource ) + { + source_ptr source = indexToTreeItem( index )->source(); + if( source.isNull() ) + return 0; // Super Collection is first + else if( source->isLocal() ) + return 1; // Then Local collection + else // then all the rest + return 5; + } else + { + qDebug() << "RETURNING NULL SORT DATA!"; + return QVariant(); + } } return QStandardItemModel::data( index, role ); @@ -152,7 +179,7 @@ SourcesModel::appendItem( const source_ptr& source ) connect( source.data(), SIGNAL( playbackStarted( Tomahawk::query_ptr ) ), SLOT( onSourceChanged() ) ); connect( source.data(), SIGNAL( stateChanged() ), SLOT( onSourceChanged() ) ); } - + return true; // FIXME } @@ -246,7 +273,7 @@ SourcesModel::indexToDynamicPlaylist( const QModelIndex& index ) dynplaylist_ptr res; if ( !index.isValid() ) return res; - + if ( indexType( index ) == DynamicPlaylistSource ) { QModelIndex idx = index.model()->index( index.row(), 0, index.parent() ); @@ -255,7 +282,7 @@ SourcesModel::indexToDynamicPlaylist( const QModelIndex& index ) if ( playlist ) return *playlist; } - + return res; } @@ -311,12 +338,12 @@ SourcesModel::dynamicPlaylistToIndex( const Tomahawk::dynplaylist_ptr& playlist for ( int i = 0; i < rowCount(); i++ ) { QModelIndex pidx = index( i, 0 ); - + for ( int j = 0; j < rowCount( pidx ); j++ ) { QModelIndex idx = index( j, 0, pidx ); SourcesModel::SourceType type = SourcesModel::indexType( idx ); - + if ( type == SourcesModel::DynamicPlaylistSource ) { playlist_ptr p = SourcesModel::indexToDynamicPlaylist( idx ); @@ -325,7 +352,7 @@ SourcesModel::dynamicPlaylistToIndex( const Tomahawk::dynplaylist_ptr& playlist } } } - + return QModelIndex(); } @@ -367,11 +394,11 @@ SourcesModel::setData( const QModelIndex& index, const QVariant& value, int role { playlist = indexToDynamicPlaylist( index ).staticCast< Playlist >(); } - + if ( !playlist.isNull() ) { playlist->rename( value.toString() ); - QStandardItemModel::setData( index, value, Qt::DisplayRole ); + QStandardItemModel::setData( index, value, Qt::DisplayRole ); return true; } @@ -383,7 +410,7 @@ void SourcesModel::onSourceChanged() { Source* src = qobject_cast< Source* >( sender() ); - + for ( int i = 0; i < rowCount(); i++ ) { QModelIndex idx = index( i, 0 ); diff --git a/src/sourcetree/sourcesmodel.h b/src/sourcetree/sourcesmodel.h index a9ad5d74b..79d12382e 100644 --- a/src/sourcetree/sourcesmodel.h +++ b/src/sourcetree/sourcesmodel.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -31,15 +31,19 @@ class SourcesModel : public QStandardItemModel { Q_OBJECT -public: +public: enum SourceType { Invalid = -1, - + CollectionSource = 0, PlaylistSource = 1, DynamicPlaylistSource = 2 }; - + + enum ExtraRoles { + SortRole = Qt::UserRole + 20, + }; + explicit SourcesModel( SourceTreeView* parent = 0 ); virtual QStringList mimeTypes() const; @@ -58,7 +62,7 @@ public: QModelIndex playlistToIndex( const Tomahawk::playlist_ptr& playlist ); QModelIndex dynamicPlaylistToIndex( const Tomahawk::dynplaylist_ptr& playlist ); QModelIndex collectionToIndex( const Tomahawk::collection_ptr& collection ); - + signals: void clicked( const QModelIndex& ); diff --git a/src/sourcetree/sourcesproxymodel.cpp b/src/sourcetree/sourcesproxymodel.cpp index d93cf098e..a53967c58 100644 --- a/src/sourcetree/sourcesproxymodel.cpp +++ b/src/sourcetree/sourcesproxymodel.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -32,6 +32,7 @@ SourcesProxyModel::SourcesProxyModel( SourcesModel* model, QObject* parent ) { setDynamicSortFilter( true ); + setSortRole( SourcesModel::SortRole ); setSourceModel( model ); } @@ -63,7 +64,7 @@ SourcesProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex& sourcePar { if ( !m_filtered ) return true; - + SourceTreeItem* sti = m_model->indexToTreeItem( sourceModel()->index( sourceRow, 0, sourceParent ) ); if ( sti ) { diff --git a/src/sourcetree/sourcesproxymodel.h b/src/sourcetree/sourcesproxymodel.h index add57b257..52b9b6960 100644 --- a/src/sourcetree/sourcesproxymodel.h +++ b/src/sourcetree/sourcesproxymodel.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify diff --git a/src/sourcetree/sourcetreeview.cpp b/src/sourcetree/sourcetreeview.cpp index 4935b8d0e..6693bd106 100644 --- a/src/sourcetree/sourcetreeview.cpp +++ b/src/sourcetree/sourcetreeview.cpp @@ -80,6 +80,9 @@ SourceTreeView::SourceTreeView( QWidget* parent ) setIndentation( 16 ); setAnimated( true ); + setSortingEnabled( true ); + sortByColumn( 1, Qt::AscendingOrder ); + setItemDelegate( new SourceDelegate( this ) ); setContextMenuPolicy( Qt::CustomContextMenu ); From dca94f864d0f9a4a40219a060a9d31bec90791e4 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sat, 16 Apr 2011 00:18:20 +0200 Subject: [PATCH 67/75] * Fixed style / typo. --- src/libtomahawk/database/databaseimpl.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/libtomahawk/database/databaseimpl.cpp b/src/libtomahawk/database/databaseimpl.cpp index 2e2fa69ed..e052368f0 100644 --- a/src/libtomahawk/database/databaseimpl.cpp +++ b/src/libtomahawk/database/databaseimpl.cpp @@ -160,7 +160,7 @@ DatabaseImpl::updateSearchIndex() bool DatabaseImpl::updateSchema( int oldVersion ) { - // we are called here with the old database. we must migrate it to the CURRENT_SCHEMA_VERSION from t7he oldVersion + // we are called here with the old database. we must migrate it to the CURRENT_SCHEMA_VERSION from the oldVersion if ( oldVersion == 0 ) // empty database, so create our tables and stuff { qDebug() << "Create tables... old version is" << oldVersion; @@ -181,11 +181,13 @@ DatabaseImpl::updateSchema( int oldVersion ) db.commit(); return true; - } else // update in place! run the proper upgrade script + } + else // update in place! run the proper upgrade script { int cur = oldVersion; db.transaction(); - while( cur < CURRENT_SCHEMA_VERSION ) { + while ( cur < CURRENT_SCHEMA_VERSION ) + { cur++; QString path = QString( RESPATH "sql/dbmigrate-%1_to_%2.sql" ).arg( cur - 1 ).arg( cur ); @@ -195,9 +197,9 @@ DatabaseImpl::updateSchema( int oldVersion ) qWarning() << "Failed to find or open upgrade script from" << (cur-1) << "to" << cur << " (" << path << ")! Aborting upgrade.."; return false; } + QString sql = QString::fromUtf8( script.readAll() ).trimmed(); QStringList statements = sql.split( ";", QString::SkipEmptyParts ); - foreach( const QString& sql, statements ) { QString clean = cleanSql( sql ).trimmed(); @@ -215,6 +217,7 @@ DatabaseImpl::updateSchema( int oldVersion ) } } + QString DatabaseImpl::cleanSql( const QString& sql ) { From ab72ee2302e93296f92e05a72d27bdfa6adfa9bb Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 15 Apr 2011 19:12:40 -0400 Subject: [PATCH 68/75] if we are created remotely, use their creation date --- .../database/databasecommand_createplaylist.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/libtomahawk/database/databasecommand_createplaylist.cpp b/src/libtomahawk/database/databasecommand_createplaylist.cpp index 3f52bd95e..9a9f32697 100644 --- a/src/libtomahawk/database/databasecommand_createplaylist.cpp +++ b/src/libtomahawk/database/databasecommand_createplaylist.cpp @@ -88,8 +88,16 @@ DatabaseCommand_CreatePlaylist::createPlaylist( DatabaseImpl* lib, bool dynamic) Q_ASSERT( !( m_playlist.isNull() && m_v.isNull() ) ); Q_ASSERT( !source().isNull() ); - uint now = QDateTime::currentDateTime().toTime_t(); - m_playlist->setCreatedOn( now ); + uint now = 0; + if( m_playlist.isNull() ) + { + now = m_v.toMap()[ "createdon" ].toUInt(); + } + else + { + now = QDateTime::currentDateTime().toTime_t(); + m_playlist->setCreatedOn( now ); + } TomahawkSqlQuery cre = lib->newquery(); cre.prepare( "INSERT INTO playlist( guid, source, shared, title, info, creator, lastmodified, dynplaylist, createdOn) " From fe08bf2175b07559a146247c87a37ef422acd944 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 15 Apr 2011 19:13:54 -0400 Subject: [PATCH 69/75] and set properly --- src/libtomahawk/database/databasecommand_createplaylist.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libtomahawk/database/databasecommand_createplaylist.cpp b/src/libtomahawk/database/databasecommand_createplaylist.cpp index 9a9f32697..8971674bc 100644 --- a/src/libtomahawk/database/databasecommand_createplaylist.cpp +++ b/src/libtomahawk/database/databasecommand_createplaylist.cpp @@ -96,8 +96,8 @@ DatabaseCommand_CreatePlaylist::createPlaylist( DatabaseImpl* lib, bool dynamic) else { now = QDateTime::currentDateTime().toTime_t(); - m_playlist->setCreatedOn( now ); } + m_playlist->setCreatedOn( now ); TomahawkSqlQuery cre = lib->newquery(); cre.prepare( "INSERT INTO playlist( guid, source, shared, title, info, creator, lastmodified, dynplaylist, createdOn) " From ed2c1513a84f5d3eceb9f593108df925028b632f Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 15 Apr 2011 19:14:48 -0400 Subject: [PATCH 70/75] wasn't meant to commit that --- src/libtomahawk/database/databasecommand_createplaylist.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libtomahawk/database/databasecommand_createplaylist.cpp b/src/libtomahawk/database/databasecommand_createplaylist.cpp index 8971674bc..9a9f32697 100644 --- a/src/libtomahawk/database/databasecommand_createplaylist.cpp +++ b/src/libtomahawk/database/databasecommand_createplaylist.cpp @@ -96,8 +96,8 @@ DatabaseCommand_CreatePlaylist::createPlaylist( DatabaseImpl* lib, bool dynamic) else { now = QDateTime::currentDateTime().toTime_t(); + m_playlist->setCreatedOn( now ); } - m_playlist->setCreatedOn( now ); TomahawkSqlQuery cre = lib->newquery(); cre.prepare( "INSERT INTO playlist( guid, source, shared, title, info, creator, lastmodified, dynplaylist, createdOn) " From cdd3684dbaca0c8d7b86a10830b6a3fafa8dbf83 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sat, 16 Apr 2011 01:31:08 +0200 Subject: [PATCH 71/75] * Fixed style. --- src/libtomahawk/playlist.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libtomahawk/playlist.h b/src/libtomahawk/playlist.h index cb81e1a19..e905517b2 100644 --- a/src/libtomahawk/playlist.h +++ b/src/libtomahawk/playlist.h @@ -108,7 +108,7 @@ Q_PROPERTY( QString currentrevision READ currentrevision WRITE setCurrentrevi Q_PROPERTY( QString title READ title WRITE setTitle ) Q_PROPERTY( QString info READ info WRITE setInfo ) Q_PROPERTY( QString creator READ creator WRITE setCreator ) -Q_PROPERTY( unsigned int createdon READ createdOn WRITE setCreatedOn ) +Q_PROPERTY( unsigned int createdon READ createdOn WRITE setCreatedOn ) Q_PROPERTY( bool shared READ shared WRITE setShared ) friend class ::DatabaseCommand_LoadAllPlaylists; @@ -141,7 +141,7 @@ public: QString guid() const { return m_guid; } bool shared() const { return m_shared; } unsigned int lastmodified() const { return m_lastmodified; } - uint createdOn() const { return m_createdOn; } + uint createdOn() const { return m_createdOn; } const QList< plentry_ptr >& entries() { return m_entries; } virtual void addEntry( const Tomahawk::query_ptr& query, const QString& oldrev ); From 9202113a43cff2407302cdc2eb2535af5ac836f5 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Sat, 16 Apr 2011 03:03:59 -0400 Subject: [PATCH 72/75] Attempt to speed up infosystemcache loading on startup --- src/libtomahawk/infosystem/infosystemcache.cpp | 8 ++++---- src/libtomahawk/infosystem/infosystemcache.h | 9 +++++---- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/libtomahawk/infosystem/infosystemcache.cpp b/src/libtomahawk/infosystem/infosystemcache.cpp index 9ecdc7435..7a247d281 100644 --- a/src/libtomahawk/infosystem/infosystemcache.cpp +++ b/src/libtomahawk/infosystem/infosystemcache.cpp @@ -43,7 +43,7 @@ InfoSystemCache::InfoSystemCache( QObject* parent ) QString cacheFile = cacheDir + '/' + QString::number( i ); QDir dir( cacheDir ); if( dir.exists() && QFile::exists( cacheFile ) ) - loadCache( type, cacheFile ); + QMetaObject::invokeMethod( this, "loadCache", Qt::AutoConnection, Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QString, cacheFile ) ); } } @@ -122,7 +122,7 @@ InfoSystemCache::updateCacheSlot( Tomahawk::InfoSystem::InfoCacheCriteria criter void -InfoSystemCache::loadCache( InfoType type, const QString &cacheFile ) +InfoSystemCache::loadCache( Tomahawk::InfoSystem::InfoType type, const QString &cacheFile ) { qDebug() << Q_FUNC_INFO; QSettings cachedSettings( cacheFile, QSettings::IniFormat ); @@ -157,7 +157,7 @@ InfoSystemCache::loadCache( InfoType type, const QString &cacheFile ) void -InfoSystemCache::saveCache( InfoType type, const QString &cacheDir ) +InfoSystemCache::saveCache( Tomahawk::InfoSystem::InfoType type, const QString &cacheDir ) { qDebug() << Q_FUNC_INFO; QDir dir( cacheDir ); @@ -201,4 +201,4 @@ InfoSystemCache::saveCache( InfoType type, const QString &cacheDir ) } //namespace InfoSystem -} //namespace Tomahawk \ No newline at end of file +} //namespace Tomahawk diff --git a/src/libtomahawk/infosystem/infosystemcache.h b/src/libtomahawk/infosystem/infosystemcache.h index 20307eab8..38e626878 100644 --- a/src/libtomahawk/infosystem/infosystemcache.h +++ b/src/libtomahawk/infosystem/infosystemcache.h @@ -48,10 +48,11 @@ public slots: void getCachedInfoSlot( Tomahawk::InfoSystem::InfoCacheCriteria criteria, qint64 newMaxAge, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, Tomahawk::InfoSystem::InfoCustomData customData ); void updateCacheSlot( Tomahawk::InfoSystem::InfoCacheCriteria criteria, qint64 maxAge, Tomahawk::InfoSystem::InfoType type, QVariant output ); -private: - void loadCache( InfoType type, const QString &cacheFile ); - void saveCache( InfoType type, const QString &cacheDir ); +private slots: + void loadCache( Tomahawk::InfoSystem::InfoType type, const QString &cacheFile ); + void saveCache( Tomahawk::InfoSystem::InfoType type, const QString &cacheDir ); +private: QHash< InfoType, QHash< InfoCacheCriteria, QVariant > > m_dataCache; QHash< InfoType, QHash< InfoCacheCriteria, QDateTime > > m_insertTimeCache; QHash< InfoType, QHash< InfoCacheCriteria, QDateTime > > m_maxTimeCache; @@ -62,4 +63,4 @@ private: } //namespace Tomahawk -#endif //TOMAHAWK_INFOSYSTEMCACHE_H \ No newline at end of file +#endif //TOMAHAWK_INFOSYSTEMCACHE_H From 5334dbf0376ae81765ab1d45489db5ebd014fda1 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Sat, 16 Apr 2011 03:31:40 -0400 Subject: [PATCH 73/75] Whoops. C'mon, do what I mean, not what I tell you to do. --- src/libtomahawk/infosystem/infosystemcache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libtomahawk/infosystem/infosystemcache.cpp b/src/libtomahawk/infosystem/infosystemcache.cpp index 7a247d281..17d0ac906 100644 --- a/src/libtomahawk/infosystem/infosystemcache.cpp +++ b/src/libtomahawk/infosystem/infosystemcache.cpp @@ -43,7 +43,7 @@ InfoSystemCache::InfoSystemCache( QObject* parent ) QString cacheFile = cacheDir + '/' + QString::number( i ); QDir dir( cacheDir ); if( dir.exists() && QFile::exists( cacheFile ) ) - QMetaObject::invokeMethod( this, "loadCache", Qt::AutoConnection, Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QString, cacheFile ) ); + QMetaObject::invokeMethod( this, "loadCache", Qt::QueuedConnection, Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QString, cacheFile ) ); } } From f7c440ed4f206508f84059e3e5ce44ec24e22eda Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Sat, 16 Apr 2011 03:40:15 -0400 Subject: [PATCH 74/75] Don't let cache requests go through until the cache is fully loaded --- src/libtomahawk/infosystem/infosystemcache.cpp | 12 ++++++++++++ src/libtomahawk/infosystem/infosystemcache.h | 1 + 2 files changed, 13 insertions(+) diff --git a/src/libtomahawk/infosystem/infosystemcache.cpp b/src/libtomahawk/infosystem/infosystemcache.cpp index 17d0ac906..7b89539c1 100644 --- a/src/libtomahawk/infosystem/infosystemcache.cpp +++ b/src/libtomahawk/infosystem/infosystemcache.cpp @@ -33,6 +33,7 @@ namespace InfoSystem InfoSystemCache::InfoSystemCache( QObject* parent ) : QObject(parent) + , m_cacheRemainingToLoad( 0 ) { qDebug() << Q_FUNC_INFO; QString cacheBaseDir = QDesktopServices::storageLocation( QDesktopServices::CacheLocation ); @@ -43,7 +44,10 @@ InfoSystemCache::InfoSystemCache( QObject* parent ) QString cacheFile = cacheDir + '/' + QString::number( i ); QDir dir( cacheDir ); if( dir.exists() && QFile::exists( cacheFile ) ) + { + m_cacheRemainingToLoad++; QMetaObject::invokeMethod( this, "loadCache", Qt::QueuedConnection, Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QString, cacheFile ) ); + } } } @@ -74,6 +78,13 @@ InfoSystemCache::getCachedInfoSlot( Tomahawk::InfoSystem::InfoCacheCriteria crit emit notInCache( criteria, caller, type, input, customData ); return; } + + if ( m_cacheRemainingToLoad > 0 ) + { + qDebug() << "Cache not fully loaded, punting request for a bit"; + QMetaObject::invokeMethod( this, "getCachedInfoSlot", Qt::QueuedConnection, Q_ARG( Tomahawk::InfoSystem::InfoCacheCriteria, criteria ), Q_ARG( qint64, newMaxAge ), Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( Tomahawk::InfoSystem::InfoCustomData, customData ) ); + return; + } QHash< InfoCacheCriteria, QDateTime > typemaxtimecache = m_maxTimeCache[type]; @@ -153,6 +164,7 @@ InfoSystemCache::loadCache( Tomahawk::InfoSystem::InfoType type, const QString & m_insertTimeCache[type] = insertDateHash; m_maxTimeCache[type] = maxDateHash; } + m_cacheRemainingToLoad--; } diff --git a/src/libtomahawk/infosystem/infosystemcache.h b/src/libtomahawk/infosystem/infosystemcache.h index 38e626878..bf712c8d0 100644 --- a/src/libtomahawk/infosystem/infosystemcache.h +++ b/src/libtomahawk/infosystem/infosystemcache.h @@ -57,6 +57,7 @@ private: QHash< InfoType, QHash< InfoCacheCriteria, QDateTime > > m_insertTimeCache; QHash< InfoType, QHash< InfoCacheCriteria, QDateTime > > m_maxTimeCache; QSet< InfoType > m_dirtySet; + int m_cacheRemainingToLoad; }; } //namespace InfoSystem From 7f570c325d342433cd6695638ba1ca0d9b657721 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sat, 16 Apr 2011 13:36:09 +0200 Subject: [PATCH 75/75] * Updates README and ChangeLog. --- ChangeLog | 3 +- README | 108 ++++++++---------------------------------------------- 2 files changed, 17 insertions(+), 94 deletions(-) diff --git a/ChangeLog b/ChangeLog index 46d9ee62f..8393fc358 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,8 @@ Version 0.1.0: * Resolvers can now be enabled and disabled, and some can be configured directly in Tomahawk. - * You can now browse and play collections in a tree-view. + * Browse and play collections in our snappy tree-view, which also shows + images for artists and albums. * Watch folders for changes and automatically update your collection. This is on by default; you can turn it off on the Local Music tab in the settings dialog. Note that this triggers only on files or folders being diff --git a/README b/README index f33c4f948..2483da2f6 100644 --- a/README +++ b/README @@ -1,82 +1,23 @@ -Quickstart on Ubuntu --------------------- - - $ sudo apt-get install build-essential cmake libtag1c2a libtag1-dev libqt4-dev libqt4-sql-sqlite \ - libvorbis-dev libmad0-dev libflac++-dev libasound2-dev libboost-dev zlib1g-dev \ - libgnutls-dev pkg-config - - -Gloox 1.0 (XMPP library) ------------------------- - On Ubuntu 10.10 (and higher): - $ sudo apt-get install libgloox-dev - - Otherwise see: http://camaya.net/glooxdownload - You need to build gloox 1.0 from source, Ubuntu 10.04 only packages version 0.9. - - Download and unpack tarball: - $ ./configure --without-openssl --with-gnutls --without-libidn --with-zlib --without-examples --without-tests - $ CXXFLAGS=-fPIC make - $ sudo make install - -QJson (Qt JSON library) ------------------------ - On Ubuntu 10.04 (and higher): - $ sudo apt-get install libqjson-dev - - Otherwise see: http://sourceforge.net/projects/qjson/files/ (developed using version 0.7.1) - - Download and unpack tarball: - $ ./configure && make - $ sudo make install - -libEchonest 1.1.4 ---------------- - See: http://projects.kde.org/projects/playground/libs/libechonest/ - - Download and unpack tarball: - $ mkdir build && cd build - $ cmake .. - $ make - $ sudo make install - -CLucene 0.9.23 ---------------- - See: http://clucene.sourceforge.net/download.shtml - - Clone from git and build CLucene: - $ git clone git://clucene.git.sourceforge.net/gitroot/clucene/clucene - $ cd clucene && mkdir build && cd build - $ cmake .. - $ make - $ sudo make install - - -Quickstart on OS X +Compiling Tomahawk ------------------ - Install homebrew - $ ruby -e "$(curl -fsSL https://gist.github.com/raw/323731/install_homebrew.rb)" - $ brew install cmake qt qjson gloox libmad libvorbis flac taglib boost - - Install libEchnoest & CLucene as per the above instructions. - - If liblastfm gives problems, do the below: - $ brew edit liblastfm - Change the url to https://github.com/davidsansome/liblastfm/tarball/0.3.1 - $ brew install liblastfm - Copy the md5 hash it returns. - $ brew edit liblastfm - Replace the md5 hash with the new one you copied. - $ brew install liblastfm - - -Now compile Tomahawk --------------------- $ mkdir build && cd build $ cmake .. $ make + + Start the application on Linux: $ ./tomahawk + Start the application on OS X: + $ open tomahawk.app + + +Detailed building instructions for Ubuntu +----------------------------------------- + See: http://wiki.tomahawk-player.org/mediawiki/index.php/Building_Ubuntu_Binary_on_Maverick_(10.10) + +Detailed building instructions for OS X +--------------------------------------- + See: http://wiki.tomahawk-player.org/mediawiki/index.php/Building_OS_X_Application_Bundle_on_Snow_Leopard_(10.6) Dependencies @@ -85,7 +26,7 @@ Dependencies CMake 2.8.0 http://www.cmake.org/ Qt 4.7.0 http://qt.nokia.com/ QJson 0.7.1 http://qjson.sourceforge.net/ - Gloox 1.0 (0.9.x will fail) http://camaya.net/gloox/ + Gloox 1.0 http://camaya.net/gloox/ SQLite 3.6.22 http://www.sqlite.org/ TagLib 1.6.2 http://developer.kde.org/~wheeler/taglib.html Boost 1.3x http://www.boost.org/ @@ -102,23 +43,4 @@ Dependencies MiniUPnP http://miniupnp.free.fr/ liblastfm 0.4.0 http://github.com/jonocole/liblastfm/ - -To build the app: ------------------ - $ mkdir build && cd build - $ cmake .. - $ make - -To run the app: ---------------- - Only run the next two commands if you installed any of the dependencies from source on Linux. - $ export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH - $ sudo ldconfig -v - - Start the application on Linux: - $ ./tomahawk - - Start the application on OS X: - $ open tomahawk.app - Enjoy!