From f2d5a9dadca5e50c1ecce4bece99776eec424b07 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Thu, 23 Jun 2011 08:54:29 -0400 Subject: [PATCH 01/86] Make SipPlugin reset pure virtual and implement --- src/libtomahawk/sip/SipPlugin.h | 3 ++- src/sip/jabber/jabber.h | 2 ++ src/sip/twitter/twitter.cpp | 12 ++++++++++++ src/sip/twitter/twitter.h | 1 + src/sip/zeroconf/zeroconf.h | 2 ++ 5 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/libtomahawk/sip/SipPlugin.h b/src/libtomahawk/sip/SipPlugin.h index 002f9b242..4a882b3d4 100644 --- a/src/libtomahawk/sip/SipPlugin.h +++ b/src/libtomahawk/sip/SipPlugin.h @@ -94,7 +94,8 @@ public slots: // so plugins can clean up after themselves virtual void deletePlugin(); - virtual void reset() {} + //called when there is a new database + virtual void reset() = 0; signals: void error( int, const QString& ); diff --git a/src/sip/jabber/jabber.h b/src/sip/jabber/jabber.h index f77d6bda3..bbdbab73c 100644 --- a/src/sip/jabber/jabber.h +++ b/src/sip/jabber/jabber.h @@ -97,6 +97,8 @@ public slots: void refreshProxy(); void showAddFriendDialog(); + virtual void reset() {} + protected: virtual QString defaultSuffix() const; diff --git a/src/sip/twitter/twitter.cpp b/src/sip/twitter/twitter.cpp index 4fb5befbe..50791ef3a 100644 --- a/src/sip/twitter/twitter.cpp +++ b/src/sip/twitter/twitter.cpp @@ -785,6 +785,18 @@ TwitterPlugin::checkSettings() connectPlugin( false ); } + +void +TwitterPlugin::reset() +{ + qDebug() << Q_FUNC_INFO; + setTwitterCachedDirectMessagesSinceId( 0 ); + setTwitterCachedFriendsSinceId( 0 ); + setTwitterCachedMentionsSinceId( 0 ); + setTwitterCachedPeers( QHash< QString, QVariant >() ); +} + + QString TwitterPlugin::twitterScreenName() const { diff --git a/src/sip/twitter/twitter.h b/src/sip/twitter/twitter.h index 508cacceb..470bbb386 100644 --- a/src/sip/twitter/twitter.h +++ b/src/sip/twitter/twitter.h @@ -78,6 +78,7 @@ signals: public slots: virtual bool connectPlugin( bool startup ); void disconnectPlugin(); + virtual void reset(); void checkSettings(); void refreshProxy(); void deletePlugin(); diff --git a/src/sip/zeroconf/zeroconf.h b/src/sip/zeroconf/zeroconf.h index c60e43698..d345d524c 100644 --- a/src/sip/zeroconf/zeroconf.h +++ b/src/sip/zeroconf/zeroconf.h @@ -67,6 +67,8 @@ public slots: virtual bool connectPlugin( bool startup ); void disconnectPlugin(); + virtual void reset() {} + void sendMsg( const QString& , const QString& ) {} void broadcastMsg( const QString & ) {} void addContact( const QString &, const QString& ) {} From 660176477a79a5cc6fac39c86f44d193a7d0236c Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Thu, 23 Jun 2011 09:16:33 -0400 Subject: [PATCH 02/86] Remove reset; handle dbid changes locally in twitter sip --- src/libtomahawk/sip/SipPlugin.h | 3 --- src/sip/jabber/jabber.h | 2 -- src/sip/twitter/twitter.cpp | 28 ++++++++++++++++++++++------ src/sip/twitter/twitter.h | 3 ++- src/sip/zeroconf/zeroconf.h | 2 -- 5 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/libtomahawk/sip/SipPlugin.h b/src/libtomahawk/sip/SipPlugin.h index 4a882b3d4..6e803c154 100644 --- a/src/libtomahawk/sip/SipPlugin.h +++ b/src/libtomahawk/sip/SipPlugin.h @@ -94,9 +94,6 @@ public slots: // so plugins can clean up after themselves virtual void deletePlugin(); - //called when there is a new database - virtual void reset() = 0; - signals: void error( int, const QString& ); void stateChanged( SipPlugin::ConnectionState state ); diff --git a/src/sip/jabber/jabber.h b/src/sip/jabber/jabber.h index bbdbab73c..f77d6bda3 100644 --- a/src/sip/jabber/jabber.h +++ b/src/sip/jabber/jabber.h @@ -97,8 +97,6 @@ public slots: void refreshProxy(); void showAddFriendDialog(); - virtual void reset() {} - protected: virtual QString defaultSuffix() const; diff --git a/src/sip/twitter/twitter.cpp b/src/sip/twitter/twitter.cpp index 50791ef3a..83cd36169 100644 --- a/src/sip/twitter/twitter.cpp +++ b/src/sip/twitter/twitter.cpp @@ -67,6 +67,19 @@ TwitterPlugin::TwitterPlugin( const QString& pluginId ) , m_state( Disconnected ) { qDebug() << Q_FUNC_INFO; + + if ( !Database::instance() || Database::instance()->dbid() != twitterSavedDbid() ) + { + if ( !twitterSavedDbid().isEmpty() ) //remove eventually (post 0.2), here for migration purposes + { + setTwitterCachedDirectMessagesSinceId( 0 ); + setTwitterCachedFriendsSinceId( 0 ); + setTwitterCachedMentionsSinceId( 0 ); + setTwitterCachedPeers( QHash< QString, QVariant >() ); + } + setTwitterSavedDbid( Database::instance()->dbid() ); + } + m_checkTimer.setInterval( 150000 ); m_checkTimer.setSingleShot( false ); connect( &m_checkTimer, SIGNAL( timeout() ), SLOT( checkTimerFired() ) ); @@ -787,13 +800,16 @@ TwitterPlugin::checkSettings() void -TwitterPlugin::reset() +TwitterPlugin::setTwitterSavedDbid( const QString& dbid ) { - qDebug() << Q_FUNC_INFO; - setTwitterCachedDirectMessagesSinceId( 0 ); - setTwitterCachedFriendsSinceId( 0 ); - setTwitterCachedMentionsSinceId( 0 ); - setTwitterCachedPeers( QHash< QString, QVariant >() ); + TomahawkSettings::instance()->setValue( pluginId() + "/saveddbid", dbid ); +} + + +QString +TwitterPlugin::twitterSavedDbid() const +{ + return TomahawkSettings::instance()->value( pluginId() + "/saveddbid", QString() ).toString(); } diff --git a/src/sip/twitter/twitter.h b/src/sip/twitter/twitter.h index 470bbb386..1846e0b8a 100644 --- a/src/sip/twitter/twitter.h +++ b/src/sip/twitter/twitter.h @@ -78,7 +78,6 @@ signals: public slots: virtual bool connectPlugin( bool startup ); void disconnectPlugin(); - virtual void reset(); void checkSettings(); void refreshProxy(); void deletePlugin(); @@ -123,6 +122,8 @@ private: bool refreshTwitterAuth(); void parseGotTomahawk( const QRegExp ®ex, const QString &screenName, const QString &text ); // handle per-plugin config + QString twitterSavedDbid() const; + void setTwitterSavedDbid( const QString& dbid ); QString twitterScreenName() const; void setTwitterScreenName( const QString& screenName ); QString twitterOAuthToken() const; diff --git a/src/sip/zeroconf/zeroconf.h b/src/sip/zeroconf/zeroconf.h index d345d524c..c60e43698 100644 --- a/src/sip/zeroconf/zeroconf.h +++ b/src/sip/zeroconf/zeroconf.h @@ -67,8 +67,6 @@ public slots: virtual bool connectPlugin( bool startup ); void disconnectPlugin(); - virtual void reset() {} - void sendMsg( const QString& , const QString& ) {} void broadcastMsg( const QString & ) {} void addContact( const QString &, const QString& ) {} From dca4a7c591a88297a77d24ce255dac1a7b465746 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Thu, 23 Jun 2011 16:54:27 +0200 Subject: [PATCH 03/86] * Fixed TWK-226. Never advertise ourselves with an unroutable / internal-only IP address. --- src/libtomahawk/network/servent.cpp | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/libtomahawk/network/servent.cpp b/src/libtomahawk/network/servent.cpp index 0ed05161d..da0a8550b 100644 --- a/src/libtomahawk/network/servent.cpp +++ b/src/libtomahawk/network/servent.cpp @@ -195,13 +195,28 @@ Servent::createConnectionKey( const QString& name, const QString &nodeid, const void Servent::setExternalAddress( QHostAddress ha, unsigned int port ) { - m_externalAddress = ha; - m_externalPort = port; - - if( m_externalPort == 0 || m_externalAddress.toString().isEmpty() ) + QString ip = ha.toString(); + if ( !qApp->arguments().contains( "--lanhack" ) ) { - if( !TomahawkSettings::instance()->externalHostname().isEmpty() && - !TomahawkSettings::instance()->externalPort() == 0 ) + if ( ip.startsWith( "10." ) || ip.startsWith( "172.16." ) || ip.startsWith( "192.168." ) ) + { + qDebug() << Q_FUNC_INFO << "Tried to set an invalid ip as external address!"; + return; + } + + m_externalAddress = ha; + m_externalPort = port; + } + else + { + m_externalAddress = ha; + m_externalPort = port; + } + + if ( m_externalPort == 0 || m_externalAddress.toString().isEmpty() ) + { + if ( !TomahawkSettings::instance()->externalHostname().isEmpty() && + !TomahawkSettings::instance()->externalPort() == 0 ) { qDebug() << "UPnP failed, have external address/port -- falling back"; m_externalHostname = TomahawkSettings::instance()->externalHostname(); From 1a4ed2e551c9ac37897049c9427f5f21061c5b41 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Thu, 23 Jun 2011 17:42:52 +0200 Subject: [PATCH 04/86] * Never word-wrap in the short-mode PlaylistItemDelegate. --- src/libtomahawk/playlist/playlistitemdelegate.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libtomahawk/playlist/playlistitemdelegate.cpp b/src/libtomahawk/playlist/playlistitemdelegate.cpp index c91a3ac72..b6d7b4f88 100644 --- a/src/libtomahawk/playlist/playlistitemdelegate.cpp +++ b/src/libtomahawk/playlist/playlistitemdelegate.cpp @@ -202,13 +202,14 @@ PlaylistItemDelegate::paintShort( QPainter* painter, const QStyleOptionViewItem& r.adjust( ir.width() + 12, 0, 0, 0 ); QTextOption to( Qt::AlignTop ); - QString text = painter->fontMetrics().elidedText( upperText, Qt::ElideRight, r.width() - 3 ); + to.setWrapMode( QTextOption::NoWrap ); painter->setFont( boldFont ); + QString text = painter->fontMetrics().elidedText( upperText, Qt::ElideRight, r.width() - 3 ); painter->drawText( r.adjusted( 0, 1, 0, 0 ), text, to ); to.setAlignment( Qt::AlignBottom ); - text = painter->fontMetrics().elidedText( lowerText, Qt::ElideRight, r.width() - 3 ); painter->setFont( opt.font ); + text = painter->fontMetrics().elidedText( lowerText, Qt::ElideRight, r.width() - 3 ); painter->drawText( r.adjusted( 0, 1, 0, 0 ), text, to ); } painter->restore(); From 337c4e6e9cbfd82a852fc72810ee14a846dca9d2 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Thu, 23 Jun 2011 18:02:09 +0200 Subject: [PATCH 05/86] * Recalculate collection stats after finish scanning. --- src/musicscanner.cpp | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/src/musicscanner.cpp b/src/musicscanner.cpp index 3123f5ca4..c65966370 100644 --- a/src/musicscanner.cpp +++ b/src/musicscanner.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,6 +26,7 @@ #include "database/database.h" #include "database/databasecommand_dirmtimes.h" #include "database/databasecommand_filemtimes.h" +#include "database/databasecommand_collectionstats.h" #include "database/databasecommand_addfiles.h" #include "database/databasecommand_deletefiles.h" @@ -59,7 +60,7 @@ DirLister::go() } m_newdirmtimes = m_dirmtimes; } - + foreach( QString dir, m_dirs ) { m_opcount++; @@ -76,12 +77,12 @@ DirLister::scanDir( QDir dir, int depth, DirLister::Mode mode ) m_opcount--; if ( m_opcount == 0 ) emit finished( m_newdirmtimes ); - + return; } - + //qDebug() << "DirLister::scanDir scanning: " << dir.canonicalPath() << " with mode " << mode; - + if( !dir.exists() ) { qDebug() << "Dir no longer exists, not scanning"; @@ -89,10 +90,10 @@ DirLister::scanDir( QDir dir, int depth, DirLister::Mode mode ) m_opcount--; if ( m_opcount == 0 ) emit finished( m_newdirmtimes ); - + return; } - + QFileInfoList dirs; const uint mtime = QFileInfo( dir.canonicalPath() ).lastModified().toUTC().toTime_t(); m_newdirmtimes.insert( dir.canonicalPath(), mtime ); @@ -120,7 +121,7 @@ DirLister::scanDir( QDir dir, int depth, DirLister::Mode mode ) } dir.setFilter( QDir::Dirs | QDir::Readable | QDir::NoDotAndDotDot ); dirs = dir.entryInfoList(); - + foreach( const QFileInfo& di, dirs ) { const QString canonical = di.canonicalFilePath(); @@ -132,7 +133,7 @@ DirLister::scanDir( QDir dir, int depth, DirLister::Mode mode ) QMetaObject::invokeMethod( this, "scanDir", Qt::QueuedConnection, Q_ARG( QDir, di.canonicalFilePath() ), Q_ARG( int, depth + 1 ), Q_ARG( DirLister::Mode, DirLister::Recursive ) ); } } - + m_opcount--; if ( m_opcount == 0 ) emit finished( m_newdirmtimes ); @@ -232,7 +233,7 @@ MusicScanner::scan() SLOT( commitBatch( QVariantList, QVariantList ) ), Qt::DirectConnection ); m_dirListerThreadController = new QThread( this ); - + m_dirLister = QWeakPointer< DirLister >( new DirLister( m_dirs, m_dirmtimes, m_mode, m_manualFull, m_recursive ) ); m_dirLister.data()->moveToThread( m_dirListerThreadController ); @@ -242,7 +243,7 @@ MusicScanner::scan() // queued, so will only fire after all dirs have been scanned: connect( m_dirLister.data(), SIGNAL( finished( QMap ) ), SLOT( listerFinished( QMap ) ), Qt::QueuedConnection ); - + m_dirListerThreadController->start(); QMetaObject::invokeMethod( m_dirLister.data(), "go" ); } @@ -277,12 +278,20 @@ MusicScanner::listerFinished( const QMap& newmtimes ) foreach( const QString& s, m_skippedFiles ) qDebug() << s; - // save mtimes, then quit thread - DatabaseCommand_DirMtimes* cmd = new DatabaseCommand_DirMtimes( newmtimes ); - connect( cmd, SIGNAL( finished() ), SIGNAL( finished() ) ); + { + DatabaseCommand_DirMtimes* cmd = new DatabaseCommand_DirMtimes( newmtimes ); + connect( cmd, SIGNAL( finished() ), SIGNAL( finished() ) ); + Database::instance()->enqueue( QSharedPointer(cmd) ); + } - Database::instance()->enqueue( QSharedPointer(cmd) ); + // re-calculate source stats + { + DatabaseCommand_CollectionStats* cmd = new DatabaseCommand_CollectionStats( SourceList::instance()->getLocal() ); + connect( cmd, SIGNAL( done( QVariantMap ) ), + SourceList::instance()->getLocal().data(), SLOT( setStats( QVariantMap ) ), Qt::QueuedConnection ); + Database::instance()->enqueue( QSharedPointer( cmd ) ); + } if ( !m_dirLister.isNull() ) { @@ -332,7 +341,7 @@ MusicScanner::scanFile( const QFileInfo& fi ) m_filesToDelete << m_filemtimes.value( "file://" + fi.canonicalFilePath() ).keys().first(); } - + QVariant m = readFile( fi ); if ( m.toMap().isEmpty() ) return; @@ -419,7 +428,7 @@ MusicScanner::readFile( const QFileInfo& fi ) m["albumpos"] = tag->track(); m["year"] = tag->year(); m["hash"] = ""; // TODO - + m_scanned++; return m; } From 2ef67f5b286140eb50d414113c9cc32187a2e58e Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Thu, 23 Jun 2011 19:25:59 +0200 Subject: [PATCH 06/86] * Mark the now playing item in the TreeView, just like we do in the TrackView. --- src/libtomahawk/playlist/treeitemdelegate.cpp | 8 ++++ src/libtomahawk/playlist/treemodel.cpp | 40 +++++++++++++++++++ src/libtomahawk/playlist/treemodel.h | 5 +++ src/libtomahawk/playlist/treemodelitem.cpp | 4 ++ src/libtomahawk/playlist/treemodelitem.h | 5 +++ 5 files changed, 62 insertions(+) diff --git a/src/libtomahawk/playlist/treeitemdelegate.cpp b/src/libtomahawk/playlist/treeitemdelegate.cpp index 3d499649d..3ad8e2cc8 100644 --- a/src/libtomahawk/playlist/treeitemdelegate.cpp +++ b/src/libtomahawk/playlist/treeitemdelegate.cpp @@ -74,6 +74,14 @@ TreeItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, { QStyleOptionViewItemV4 o( *vioption ); o.palette.setColor( QPalette::Text, textColor ); + + if ( item->isPlaying() ) + { + o.palette.setColor( QPalette::Highlight, o.palette.color( QPalette::Mid ) ); + o.palette.setColor( QPalette::Text, o.palette.color( QPalette::HighlightedText ) ); + o.state |= QStyle::State_Selected; + } + return QStyledItemDelegate::paint( painter, o, index ); } } diff --git a/src/libtomahawk/playlist/treemodel.cpp b/src/libtomahawk/playlist/treemodel.cpp index eaa83f07a..020a21a78 100644 --- a/src/libtomahawk/playlist/treemodel.cpp +++ b/src/libtomahawk/playlist/treemodel.cpp @@ -23,6 +23,7 @@ #include #include +#include "audio/audioengine.h" #include "database/databasecommand_allalbums.h" #include "database/databasecommand_alltracks.h" #include "database/database.h" @@ -42,6 +43,9 @@ TreeModel::TreeModel( QObject* parent ) m_defaultCover = QPixmap( RESPATH "images/no-album-art-placeholder.png" ) .scaled( QSize( 120, 120 ), Qt::IgnoreAspectRatio, Qt::SmoothTransformation ); + connect( AudioEngine::instance(), SIGNAL( finished( Tomahawk::result_ptr ) ), SLOT( onPlaybackFinished( Tomahawk::result_ptr ) ), Qt::DirectConnection ); + connect( AudioEngine::instance(), SIGNAL( stopped() ), SLOT( onPlaybackStopped() ), Qt::DirectConnection ); + 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 ) ) ); @@ -60,10 +64,17 @@ 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 { @@ -204,6 +215,12 @@ TreeModel::data( const QModelIndex& index, int role ) const return QSize( 128, 0 ); } + if ( role == Qt::DecorationRole ) + { + if ( entry->isPlaying() && index.column() == 0 ) + return QPixmap( RESPATH "images/now-playing-speaker.png" ); + } + if ( role != Qt::DisplayRole ) // && role != Qt::ToolTipRole ) return QVariant(); @@ -618,6 +635,29 @@ TreeModel::infoSystemFinished( QString target ) } +void +TreeModel::onPlaybackFinished( const Tomahawk::result_ptr& result ) +{ + TreeModelItem* oldEntry = itemFromIndex( m_currentIndex ); + qDebug() << oldEntry->result().data() << result.data(); + if ( oldEntry && !oldEntry->result().isNull() && oldEntry->result().data() == result.data() ) + { + oldEntry->setIsPlaying( false ); + } +} + + +void +TreeModel::onPlaybackStopped() +{ + TreeModelItem* oldEntry = itemFromIndex( m_currentIndex ); + if ( oldEntry ) + { + oldEntry->setIsPlaying( false ); + } +} + + void TreeModel::onDataChanged() { diff --git a/src/libtomahawk/playlist/treemodel.h b/src/libtomahawk/playlist/treemodel.h index 5e9379406..b1dae2de8 100644 --- a/src/libtomahawk/playlist/treemodel.h +++ b/src/libtomahawk/playlist/treemodel.h @@ -91,7 +91,9 @@ public: TreeModelItem* itemFromIndex( const QModelIndex& index ) const { if ( index.isValid() ) + { return static_cast( index.internalPointer() ); + } else { return m_rootItem; @@ -125,6 +127,9 @@ private slots: void infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ); void infoSystemFinished( QString target ); + void onPlaybackFinished( const Tomahawk::result_ptr& result ); + void onPlaybackStopped(); + void onDataChanged(); private: diff --git a/src/libtomahawk/playlist/treemodelitem.cpp b/src/libtomahawk/playlist/treemodelitem.cpp index 09688a56d..5406be52f 100644 --- a/src/libtomahawk/playlist/treemodelitem.cpp +++ b/src/libtomahawk/playlist/treemodelitem.cpp @@ -48,6 +48,7 @@ TreeModelItem::TreeModelItem( TreeModelItem* parent, QAbstractItemModel* model ) childCount = 0; toberemoved = false; fetchingMore = false; + m_isPlaying = false; if ( parent ) { @@ -62,6 +63,7 @@ TreeModelItem::TreeModelItem( const Tomahawk::album_ptr& album, TreeModelItem* p { this->parent = parent; fetchingMore = false; + m_isPlaying = false; if ( parent ) { @@ -88,6 +90,7 @@ TreeModelItem::TreeModelItem( const Tomahawk::artist_ptr& artist, TreeModelItem* { this->parent = parent; fetchingMore = false; + m_isPlaying = false; if ( parent ) { @@ -114,6 +117,7 @@ TreeModelItem::TreeModelItem( const Tomahawk::result_ptr& result, TreeModelItem* { this->parent = parent; fetchingMore = false; + m_isPlaying = false; if ( parent ) { diff --git a/src/libtomahawk/playlist/treemodelitem.h b/src/libtomahawk/playlist/treemodelitem.h index 16538727b..01f3b226e 100644 --- a/src/libtomahawk/playlist/treemodelitem.h +++ b/src/libtomahawk/playlist/treemodelitem.h @@ -44,6 +44,9 @@ public: const Tomahawk::album_ptr& album() const { return m_album; }; const Tomahawk::result_ptr& result() const { return m_result; }; + bool isPlaying() { return m_isPlaying; } + void setIsPlaying( bool b ) { m_isPlaying = b; emit dataChanged(); } + void setCover( const QPixmap& cover ) { this->cover = cover; emit dataChanged(); } TreeModelItem* parent; @@ -64,6 +67,8 @@ private: Tomahawk::artist_ptr m_artist; Tomahawk::album_ptr m_album; Tomahawk::result_ptr m_result; + + bool m_isPlaying; }; #endif // TREEMODELITEM_H From d5266f71474f675491ad3133f7bc783ee2c96153 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Thu, 23 Jun 2011 20:02:26 +0200 Subject: [PATCH 07/86] * Fix the styling of the now playing row in the TreeView. --- .../playlist/playlistitemdelegate.cpp | 4 +-- src/libtomahawk/playlist/treeitemdelegate.cpp | 26 +++++++++++++++++-- src/libtomahawk/playlist/treeitemdelegate.h | 7 +++-- src/libtomahawk/playlist/treemodel.cpp | 6 ----- 4 files changed, 31 insertions(+), 12 deletions(-) diff --git a/src/libtomahawk/playlist/playlistitemdelegate.cpp b/src/libtomahawk/playlist/playlistitemdelegate.cpp index b6d7b4f88..dd9a4ef16 100644 --- a/src/libtomahawk/playlist/playlistitemdelegate.cpp +++ b/src/libtomahawk/playlist/playlistitemdelegate.cpp @@ -258,8 +258,8 @@ PlaylistItemDelegate::paintDetailed( QPainter* painter, const QStyleOptionViewIt if ( m_view->header()->visualIndex( index.column() ) == 0 ) { r.adjust( 0, 0, 0, -3 ); - painter->drawPixmap( r.adjusted( 3, 3, 18 - r.width(), 0 ), m_nowPlayingIcon ); - r.adjust( 22, 0, 0, 3 ); + painter->drawPixmap( r.adjusted( 3, 1, 18 - r.width(), 1 ), m_nowPlayingIcon ); + r.adjust( 25, 0, 0, 3 ); } painter->setPen( opt.palette.text().color() ); diff --git a/src/libtomahawk/playlist/treeitemdelegate.cpp b/src/libtomahawk/playlist/treeitemdelegate.cpp index 3ad8e2cc8..c42b51ee6 100644 --- a/src/libtomahawk/playlist/treeitemdelegate.cpp +++ b/src/libtomahawk/playlist/treeitemdelegate.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include "query.h" #include "result.h" @@ -30,13 +31,15 @@ #include "treemodelitem.h" #include "treeproxymodel.h" +#include "artistview.h" -TreeItemDelegate::TreeItemDelegate( QAbstractItemView* parent, TreeProxyModel* proxy ) +TreeItemDelegate::TreeItemDelegate( ArtistView* parent, TreeProxyModel* proxy ) : QStyledItemDelegate( (QObject*)parent ) , m_view( parent ) , m_model( proxy ) { + m_nowPlayingIcon = QPixmap( RESPATH "images/now-playing-speaker.png" ); } @@ -82,8 +85,27 @@ TreeItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, o.state |= QStyle::State_Selected; } - return QStyledItemDelegate::paint( painter, o, index ); + qApp->style()->drawControl( QStyle::CE_ItemViewItem, &o, painter ); + + { + QRect r = o.rect.adjusted( 3, 0, 0, 0 ); + + // Paint Now Playing Speaker Icon + if ( item->isPlaying() && m_view->header()->visualIndex( index.column() ) == 0 ) + { + r.adjust( 0, 0, 0, -3 ); + painter->drawPixmap( r.adjusted( 3, 1, 18 - r.width(), 1 ), m_nowPlayingIcon ); + r.adjust( 25, 0, 0, 3 ); + } + + painter->setPen( o.palette.text().color() ); + + QTextOption to( Qt::AlignVCenter ); + QString text = painter->fontMetrics().elidedText( index.data().toString(), Qt::ElideRight, r.width() - 3 ); + painter->drawText( r.adjusted( 0, 1, 0, 0 ), text, to ); + } } + return; } else return; diff --git a/src/libtomahawk/playlist/treeitemdelegate.h b/src/libtomahawk/playlist/treeitemdelegate.h index 234b0d326..5074305e0 100644 --- a/src/libtomahawk/playlist/treeitemdelegate.h +++ b/src/libtomahawk/playlist/treeitemdelegate.h @@ -23,6 +23,7 @@ #include "dllmacro.h" +class ArtistView; class TreeProxyModel; class DLLEXPORT TreeItemDelegate : public QStyledItemDelegate @@ -30,7 +31,7 @@ class DLLEXPORT TreeItemDelegate : public QStyledItemDelegate Q_OBJECT public: - TreeItemDelegate( QAbstractItemView* parent = 0, TreeProxyModel* proxy = 0 ); + TreeItemDelegate( ArtistView* parent = 0, TreeProxyModel* proxy = 0 ); protected: void paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const; @@ -39,8 +40,10 @@ protected: // QWidget* createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const; private: - QAbstractItemView* m_view; + ArtistView* m_view; TreeProxyModel* m_model; + + QPixmap m_nowPlayingIcon; }; #endif // TREEITEMDELEGATE_H diff --git a/src/libtomahawk/playlist/treemodel.cpp b/src/libtomahawk/playlist/treemodel.cpp index 020a21a78..c57d17b94 100644 --- a/src/libtomahawk/playlist/treemodel.cpp +++ b/src/libtomahawk/playlist/treemodel.cpp @@ -215,12 +215,6 @@ TreeModel::data( const QModelIndex& index, int role ) const return QSize( 128, 0 ); } - if ( role == Qt::DecorationRole ) - { - if ( entry->isPlaying() && index.column() == 0 ) - return QPixmap( RESPATH "images/now-playing-speaker.png" ); - } - if ( role != Qt::DisplayRole ) // && role != Qt::ToolTipRole ) return QVariant(); From d455270c05ba956dfa7802f621c391b4918f62ed Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Thu, 23 Jun 2011 15:12:06 -0400 Subject: [PATCH 08/86] Add (if verbose is turned on in config) play/stop notifications --- src/libtomahawk/audio/audioengine.cpp | 42 +++++++++++++++++++++------ src/libtomahawk/tomahawksettings.cpp | 14 +++++++++ src/libtomahawk/tomahawksettings.h | 3 ++ 3 files changed, 50 insertions(+), 9 deletions(-) diff --git a/src/libtomahawk/audio/audioengine.cpp b/src/libtomahawk/audio/audioengine.cpp index e86a9b6d1..79fe2242c 100644 --- a/src/libtomahawk/audio/audioengine.cpp +++ b/src/libtomahawk/audio/audioengine.cpp @@ -22,6 +22,7 @@ #include "playlistinterface.h" #include "sourceplaylistinterface.h" +#include "tomahawksettings.h" #include "database/database.h" #include "database/databasecommand_logplayback.h" @@ -153,8 +154,20 @@ AudioEngine::stop( bool sendNotification ) emit stopped(); if ( sendNotification ) + { + Tomahawk::InfoSystem::InfoMap map; + map[ Tomahawk::InfoSystem::InfoNowStopped ] = QVariant(); + + if ( TomahawkSettings::instance()->verboseNotifications() ) + { + Tomahawk::InfoSystem::InfoCriteriaHash stopInfo; + stopInfo["message"] = QString( "Tomahawk is stopped." ); + map[ Tomahawk::InfoSystem::InfoNotifyUser ] = QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( stopInfo ); + } + Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( - s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNowStopped, QVariant() ); + s_aeInfoIdentifier, map ); + } } @@ -305,15 +318,26 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result ) DatabaseCommand_LogPlayback* cmd = new DatabaseCommand_LogPlayback( m_currentTrack, DatabaseCommand_LogPlayback::Started ); Database::instance()->enqueue( QSharedPointer(cmd) ); - Tomahawk::InfoSystem::InfoCriteriaHash trackInfo; - - trackInfo["title"] = m_currentTrack->track(); - trackInfo["artist"] = m_currentTrack->artist()->name(); - trackInfo["album"] = m_currentTrack->album()->name(); - Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( - s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNowPlaying, - QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ) ); + Tomahawk::InfoSystem::InfoMap map; + Tomahawk::InfoSystem::InfoCriteriaHash trackInfo; + trackInfo["title"] = m_currentTrack->track(); + trackInfo["artist"] = m_currentTrack->artist()->name(); + trackInfo["album"] = m_currentTrack->album()->name(); + map[ Tomahawk::InfoSystem::InfoNowPlaying ] = QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ); + + if ( TomahawkSettings::instance()->verboseNotifications() ) + { + Tomahawk::InfoSystem::InfoCriteriaHash playInfo; + playInfo["message"] = QString( "Tomahawk is playing \"%1\" by %2 on album %3." ) + .arg( m_currentTrack->track() ) + .arg( m_currentTrack->artist()->name() ) + .arg( m_currentTrack->album()->name() ); + map[ Tomahawk::InfoSystem::InfoNotifyUser ] = QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( playInfo ); + } + + Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( + s_aeInfoIdentifier, map ); } } diff --git a/src/libtomahawk/tomahawksettings.cpp b/src/libtomahawk/tomahawksettings.cpp index bc8a5d824..f92ee98c1 100644 --- a/src/libtomahawk/tomahawksettings.cpp +++ b/src/libtomahawk/tomahawksettings.cpp @@ -420,6 +420,20 @@ TomahawkSettings::setMainWindowSplitterState( const QByteArray& state ) } +bool +TomahawkSettings::verboseNotifications() const +{ + return value( "ui/notifications/verbose", false ).toBool(); +} + + +void +TomahawkSettings::setVerboseNotifications( bool notifications ) +{ + setValue( "ui/notifications/verbose", notifications ); +} + + QByteArray TomahawkSettings::playlistColumnSizes( const QString& playlistid ) const { diff --git a/src/libtomahawk/tomahawksettings.h b/src/libtomahawk/tomahawksettings.h index aaedcbb08..1ee60c975 100644 --- a/src/libtomahawk/tomahawksettings.h +++ b/src/libtomahawk/tomahawksettings.h @@ -66,6 +66,9 @@ public: QByteArray mainWindowSplitterState() const; void setMainWindowSplitterState( const QByteArray& state ); + bool verboseNotifications() const; + void setVerboseNotifications( bool notifications ); + /// Playlist stuff QByteArray playlistColumnSizes( const QString& playlistid ) const; void setPlaylistColumnSizes( const QString& playlistid, const QByteArray& state ); From 555adeaac737873ef23ab7ddae7080c71de76058 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Thu, 23 Jun 2011 15:15:31 -0400 Subject: [PATCH 09/86] Cleanup --- src/libtomahawk/audio/audioengine.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/libtomahawk/audio/audioengine.cpp b/src/libtomahawk/audio/audioengine.cpp index 79fe2242c..fd3f42de1 100644 --- a/src/libtomahawk/audio/audioengine.cpp +++ b/src/libtomahawk/audio/audioengine.cpp @@ -134,8 +134,7 @@ AudioEngine::pause() m_mediaObject->pause(); emit paused(); - Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( - s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNowPaused, QVariant() ); + Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNowPaused, QVariant() ); } @@ -165,8 +164,7 @@ AudioEngine::stop( bool sendNotification ) map[ Tomahawk::InfoSystem::InfoNotifyUser ] = QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( stopInfo ); } - Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( - s_aeInfoIdentifier, map ); + Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( s_aeInfoIdentifier, map ); } } @@ -336,8 +334,7 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result ) map[ Tomahawk::InfoSystem::InfoNotifyUser ] = QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( playInfo ); } - Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( - s_aeInfoIdentifier, map ); + Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( s_aeInfoIdentifier, map ); } } From bf015d241ac73122e148b268299f1bc18350e9ce Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Thu, 23 Jun 2011 16:03:24 -0400 Subject: [PATCH 10/86] Rip out retry timer and move to a push solution. Untested, will test later. --- src/libtomahawk/album.h | 2 + src/libtomahawk/artist.h | 2 + src/libtomahawk/audio/audioengine.cpp | 55 ++++++++++----------- src/libtomahawk/audio/audioengine.h | 4 +- src/libtomahawk/playlist.h | 2 + src/libtomahawk/playlist/albumproxymodel.h | 2 + src/libtomahawk/playlist/trackproxymodel.h | 2 + src/libtomahawk/playlist/treeproxymodel.h | 2 + src/libtomahawk/playlistinterface.h | 2 + src/libtomahawk/sourceplaylistinterface.cpp | 3 +- src/libtomahawk/sourceplaylistinterface.h | 5 +- 11 files changed, 49 insertions(+), 32 deletions(-) diff --git a/src/libtomahawk/album.h b/src/libtomahawk/album.h index 96b901b0e..12b7a41e3 100644 --- a/src/libtomahawk/album.h +++ b/src/libtomahawk/album.h @@ -70,6 +70,8 @@ signals: void tracksAdded( const QList& tracks ); void trackCountChanged( unsigned int tracks ); void sourceTrackCountChanged( unsigned int tracks ); + + void nextTrackReady(); private slots: void onTracksAdded( const QList& tracks ); diff --git a/src/libtomahawk/artist.h b/src/libtomahawk/artist.h index f1b631d81..d30cc57a9 100644 --- a/src/libtomahawk/artist.h +++ b/src/libtomahawk/artist.h @@ -71,6 +71,8 @@ signals: void trackCountChanged( unsigned int tracks ); void sourceTrackCountChanged( unsigned int tracks ); + void nextTrackReady(); + private slots: void onTracksAdded( const QList& tracks ); diff --git a/src/libtomahawk/audio/audioengine.cpp b/src/libtomahawk/audio/audioengine.cpp index fd3f42de1..b1e0c3b1a 100644 --- a/src/libtomahawk/audio/audioengine.cpp +++ b/src/libtomahawk/audio/audioengine.cpp @@ -52,6 +52,7 @@ AudioEngine::AudioEngine() , m_queue( 0 ) , m_timeElapsed( 0 ) , m_expectStop( false ) + , m_waitingOnNewTrack( false ) { s_instance = this; qDebug() << "Init AudioEngine"; @@ -75,17 +76,12 @@ AudioEngine::AudioEngine() // Since it's indendent, we'll set it to 75% since that's nicer setVolume( 75 ); #endif - - m_retryTimer.setInterval( 10000 ); - m_retryTimer.setSingleShot( false ); - connect( &m_retryTimer, SIGNAL( timeout() ), SLOT( loadNextTrack() ) ); } AudioEngine::~AudioEngine() { qDebug() << Q_FUNC_INFO; - m_retryTimer.stop(); m_mediaObject->stop(); // stop(); @@ -144,8 +140,7 @@ AudioEngine::stop( bool sendNotification ) qDebug() << Q_FUNC_INFO; m_mediaObject->stop(); - m_retryTimer.stop(); - + if ( m_playlist ) m_playlist->reset(); @@ -255,8 +250,6 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result ) { qDebug() << Q_FUNC_INFO << thread() << result; - m_retryTimer.stop(); - bool err = false; { @@ -344,6 +337,7 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result ) return false; } + m_waitingOnNewTrack = false; return true; } @@ -352,8 +346,6 @@ AudioEngine::loadPreviousTrack() { qDebug() << Q_FUNC_INFO; - m_retryTimer.stop(); - if ( !m_playlist ) { stop(); @@ -373,9 +365,6 @@ AudioEngine::loadNextTrack() { qDebug() << Q_FUNC_INFO; - bool wasRetrying = m_retryTimer.isActive(); - m_retryTimer.stop(); - Tomahawk::result_ptr result; if ( m_queue && m_queue->trackCount() ) @@ -395,16 +384,12 @@ AudioEngine::loadNextTrack() stop( false ); if ( m_playlist && m_playlist->retryMode() == Tomahawk::PlaylistInterface::Retry ) { - if ( !wasRetrying ) - { - Tomahawk::InfoSystem::InfoCriteriaHash retryInfo; - retryInfo["message"] = QString( "The current track could not be resolved. Tomahawk will keep trying..." ); - Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( - s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNotifyUser, - QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( retryInfo ) ); - } - m_retryTimer.setInterval( m_playlist->retryInterval() ); - m_retryTimer.start(); + m_waitingOnNewTrack = true; + Tomahawk::InfoSystem::InfoCriteriaHash retryInfo; + retryInfo["message"] = QString( "The current track could not be resolved. Tomahawk will pick back up with the next resolvable track..." ); + Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( + s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNotifyUser, + QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( retryInfo ) ); } } } @@ -417,7 +402,7 @@ AudioEngine::playItem( Tomahawk::PlaylistInterface* playlist, const Tomahawk::re if ( m_playlist ) m_playlist->reset(); - + setPlaylist( playlist ); m_currentTrackPlaylist = playlist; @@ -425,17 +410,27 @@ AudioEngine::playItem( Tomahawk::PlaylistInterface* playlist, const Tomahawk::re loadTrack( result ); else if ( m_playlist->retryMode() == PlaylistInterface::Retry ) { + m_waitingOnNewTrack = true; Tomahawk::InfoSystem::InfoCriteriaHash retryInfo; - retryInfo["message"] = QString( "The current track could not be resolved. Tomahawk will keep trying..." ); + retryInfo["message"] = QString( "The current track could not be resolved. Tomahawk will pick back up with the next resolvable track..." ); Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNotifyUser, QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( retryInfo ) ); - m_retryTimer.setInterval( playlist->retryInterval() ); - m_retryTimer.start(); } } +void +AudioEngine::playlistNextTrackReady() +{ + if ( !m_waitingOnNewTrack ) + return; + + m_waitingOnNewTrack = false; + next(); +} + + void AudioEngine::onAboutToFinish() { @@ -498,6 +493,10 @@ AudioEngine::setPlaylist( PlaylistInterface* playlist ) if ( m_playlist ) m_playlist->reset(); m_playlist = playlist; + + if ( m_playlist->retryMode() == PlaylistInterface::Retry ) + connect( m_playlist->object(), SIGNAL( nextTrackReady() ), SLOT( playlistNextTrackReady() ) ); + emit playlistChanged( playlist ); } diff --git a/src/libtomahawk/audio/audioengine.h b/src/libtomahawk/audio/audioengine.h index 92f687518..c92b9df70 100644 --- a/src/libtomahawk/audio/audioengine.h +++ b/src/libtomahawk/audio/audioengine.h @@ -83,6 +83,8 @@ public slots: void onTrackAboutToFinish(); + void playlistNextTrackReady(); + signals: void loading( const Tomahawk::result_ptr& track ); void started( const Tomahawk::result_ptr& track ); @@ -131,7 +133,7 @@ private: unsigned int m_timeElapsed; bool m_expectStop; - QTimer m_retryTimer; + bool m_waitingOnNewTrack; static AudioEngine* s_instance; }; diff --git a/src/libtomahawk/playlist.h b/src/libtomahawk/playlist.h index 76bab9b74..a74729f7d 100644 --- a/src/libtomahawk/playlist.h +++ b/src/libtomahawk/playlist.h @@ -208,6 +208,8 @@ signals: void trackCountChanged( unsigned int tracks ); void sourceTrackCountChanged( unsigned int tracks ); + void nextTrackReady(); + public slots: // want to update the playlist from the model? // generate a newrev using uuid() and call this: diff --git a/src/libtomahawk/playlist/albumproxymodel.h b/src/libtomahawk/playlist/albumproxymodel.h index 8b9d5e1f6..991ec6b57 100644 --- a/src/libtomahawk/playlist/albumproxymodel.h +++ b/src/libtomahawk/playlist/albumproxymodel.h @@ -65,6 +65,8 @@ signals: void filterChanged( const QString& filter ); + void nextTrackReady(); + public slots: virtual void setRepeatMode( RepeatMode mode ) { m_repeatMode = mode; emit repeatModeChanged( mode ); } virtual void setShuffled( bool enabled ) { m_shuffled = enabled; emit shuffleModeChanged( enabled ); } diff --git a/src/libtomahawk/playlist/trackproxymodel.h b/src/libtomahawk/playlist/trackproxymodel.h index 3ddb35779..76381b117 100644 --- a/src/libtomahawk/playlist/trackproxymodel.h +++ b/src/libtomahawk/playlist/trackproxymodel.h @@ -74,6 +74,8 @@ signals: void filterChanged( const QString& filter ); + void nextTrackReady(); + public slots: virtual void setRepeatMode( RepeatMode mode ) { m_repeatMode = mode; emit repeatModeChanged( mode ); } virtual void setShuffled( bool enabled ) { m_shuffled = enabled; emit shuffleModeChanged( enabled ); } diff --git a/src/libtomahawk/playlist/treeproxymodel.h b/src/libtomahawk/playlist/treeproxymodel.h index 66efc7668..5e33ddcb3 100644 --- a/src/libtomahawk/playlist/treeproxymodel.h +++ b/src/libtomahawk/playlist/treeproxymodel.h @@ -70,6 +70,8 @@ signals: void filterChanged( const QString& filter ); + void nextTrackReady(); + public slots: virtual void setRepeatMode( RepeatMode mode ) { m_repeatMode = mode; emit repeatModeChanged( mode ); } virtual void setShuffled( bool enabled ) { m_shuffled = enabled; emit shuffleModeChanged( enabled ); } diff --git a/src/libtomahawk/playlistinterface.h b/src/libtomahawk/playlistinterface.h index ad93a8a03..01f9f3126 100644 --- a/src/libtomahawk/playlistinterface.h +++ b/src/libtomahawk/playlistinterface.h @@ -32,6 +32,7 @@ namespace Tomahawk class DLLEXPORT PlaylistInterface { + public: enum RepeatMode { NoRepeat, RepeatOne, RepeatAll }; enum ViewMode { Unknown, Tree, Flat, Album }; @@ -78,6 +79,7 @@ signals: virtual void shuffleModeChanged( bool enabled ) = 0; virtual void trackCountChanged( unsigned int tracks ) = 0; virtual void sourceTrackCountChanged( unsigned int tracks ) = 0; + virtual void nextTrackReady() = 0; private: QObject* m_object; diff --git a/src/libtomahawk/sourceplaylistinterface.cpp b/src/libtomahawk/sourceplaylistinterface.cpp index c8023baf2..a3d794937 100644 --- a/src/libtomahawk/sourceplaylistinterface.cpp +++ b/src/libtomahawk/sourceplaylistinterface.cpp @@ -114,7 +114,8 @@ SourcePlaylistInterface::resolveResultsAdded( const QList& } void -SourcePlaylistInterface::resolvingFinished( bool hasResults ) const +SourcePlaylistInterface::resolvingFinished( bool hasResults ) { qDebug() << Q_FUNC_INFO << " and has results? : " << (hasResults ? "true" : "false"); + emit nextTrackReady(); } \ No newline at end of file diff --git a/src/libtomahawk/sourceplaylistinterface.h b/src/libtomahawk/sourceplaylistinterface.h index 56d8bebfa..7eb8d179d 100644 --- a/src/libtomahawk/sourceplaylistinterface.h +++ b/src/libtomahawk/sourceplaylistinterface.h @@ -70,11 +70,12 @@ signals: void shuffleModeChanged( bool enabled ); void trackCountChanged( unsigned int tracks ); void sourceTrackCountChanged( unsigned int tracks ); - + void nextTrackReady(); + private slots: void onSourcePlaybackStarted( const Tomahawk::query_ptr& query ); void resolveResultsAdded( const QList& results ) const; - void resolvingFinished( bool hasResults ) const; + void resolvingFinished( bool hasResults ); private: Tomahawk::source_ptr m_source; From a639b89ebcc3074a31c2a7e3e6c61f6dddf36455 Mon Sep 17 00:00:00 2001 From: Alejandro Wainzinger Date: Thu, 23 Jun 2011 19:41:01 -0700 Subject: [PATCH 11/86] Add reference to Doxygen docs in README. --- README | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README b/README index 3f9e69324..4357bb7b9 100644 --- a/README +++ b/README @@ -19,6 +19,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) +Doxygen Documentation +--------------------- + See: http://dev.tomahawk-player.org/api/classes.html + Dependencies ------------ From 1ecab22b4dd12624bfbed731e2cdca95d4969467 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Fri, 24 Jun 2011 04:47:50 +0200 Subject: [PATCH 12/86] * Added new helper class ContextMenu. Made it easy to support context-menus in the TreeView, too. --- src/libtomahawk/CMakeLists.txt | 2 + src/libtomahawk/contextMenu.cpp | 122 ++++++++++++++++++++ src/libtomahawk/contextMenu.h | 65 +++++++++++ src/libtomahawk/playlist/artistview.cpp | 45 ++++++++ src/libtomahawk/playlist/artistview.h | 6 + src/libtomahawk/playlist/collectionview.cpp | 39 ------- src/libtomahawk/playlist/collectionview.h | 12 -- src/libtomahawk/playlist/playlistview.cpp | 73 +++--------- src/libtomahawk/playlist/playlistview.h | 13 +-- src/libtomahawk/playlist/trackview.cpp | 82 +++++++------ src/libtomahawk/playlist/trackview.h | 8 +- src/libtomahawk/sourceplaylistinterface.cpp | 4 +- 12 files changed, 315 insertions(+), 156 deletions(-) create mode 100644 src/libtomahawk/contextMenu.cpp create mode 100644 src/libtomahawk/contextMenu.h diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index 52ba39e66..c80ed6547 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -31,6 +31,7 @@ set( libSources viewpage.cpp viewmanager.cpp globalactionmanager.cpp + contextMenu.cpp sip/SipPlugin.cpp sip/SipHandler.cpp @@ -194,6 +195,7 @@ set( libHeaders viewpage.h viewmanager.h globalactionmanager.h + contextMenu.h artist.h album.h diff --git a/src/libtomahawk/contextMenu.cpp b/src/libtomahawk/contextMenu.cpp new file mode 100644 index 000000000..29cccd326 --- /dev/null +++ b/src/libtomahawk/contextMenu.cpp @@ -0,0 +1,122 @@ +/* === 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 "contextMenu.h" + +#include + +#include "globalactionmanager.h" +#include "pipeline.h" +#include "playlistview.h" +#include "viewmanager.h" + +using namespace Tomahawk; + + +ContextMenu::ContextMenu( QWidget* parent ) + : QMenu( parent ) +{ + m_sigmap = new QSignalMapper( this ); + connect( m_sigmap, SIGNAL( mapped( int ) ), SLOT( onTriggered( int ) ) ); + + m_supportedActions = ActionPlay | ActionQueue | ActionCopyLink; +} + + +void +ContextMenu::setQueries( const QList& queries ) +{ + clear(); + m_queries.clear(); + m_queries << queries; + + if ( m_supportedActions & ActionPlay ) + m_sigmap->setMapping( addAction( tr( "&Play" ) ), ActionPlay ); + + if ( m_supportedActions & ActionQueue ) + m_sigmap->setMapping( addAction( tr( "Add to &Queue" ) ), ActionQueue ); + + //m_sigmap->setMapping( addAction( tr( "&Add to Playlist" ) ), ActionAddToPlaylist ); + + addSeparator(); + + if ( m_supportedActions & ActionCopyLink ) + m_sigmap->setMapping( addAction( tr( "Copy Track Link" ) ), ActionCopyLink ); + + addSeparator(); + + if ( m_supportedActions & ActionDelete ) + m_sigmap->setMapping( addAction( queries.count() > 1 ? tr( "&Delete Items" ) : tr( "&Delete Item" ) ), ActionDelete ); + + foreach ( QAction* action, actions() ) + { + connect( action, SIGNAL( triggered() ), m_sigmap, SLOT( map() ) ); + } +} + + +void +ContextMenu::setQuery( const Tomahawk::query_ptr& query ) +{ + QList queries; + queries << query; + setQueries( queries ); +} + + +void +ContextMenu::onTriggered( int action ) +{ + switch ( action ) + { + case ActionQueue: + addToQueue(); + break; + + case ActionCopyLink: + copyLink(); + break; + + default: + emit triggered( action ); + } +} + + +void ContextMenu::addToQueue() +{ + foreach ( const query_ptr& query, m_queries ) + { + if ( !query->resolvingFinished() ) + Pipeline::instance()->resolve( query ); + + ViewManager::instance()->queue()->model()->append( query ); + } + + ViewManager::instance()->showQueue(); +} + + +void +ContextMenu::copyLink() +{ + if ( m_queries.count() ) + { + GlobalActionManager::instance()->copyToClipboard( m_queries.first() ); + } +} diff --git a/src/libtomahawk/contextMenu.h b/src/libtomahawk/contextMenu.h new file mode 100644 index 000000000..7153064b5 --- /dev/null +++ b/src/libtomahawk/contextMenu.h @@ -0,0 +1,65 @@ +/* === 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 CONTEXTMENU_H +#define CONTEXTMENU_H + +#include +#include + +#include "typedefs.h" + +#include "dllmacro.h" + +namespace Tomahawk +{ + +class DLLEXPORT ContextMenu : public QMenu +{ +Q_OBJECT + +public: + enum MenuActions + { ActionPlay = 1, ActionQueue = 2, ActionDelete = 4, ActionCopyLink = 8 }; + + explicit ContextMenu( QWidget* parent = 0 ); + + int supportedActions() const { return m_supportedActions; } + void setSupportedActions( int actions ) { m_supportedActions = actions; } + + void setQuery( const Tomahawk::query_ptr& query ); + void setQueries( const QList& queries ); + +signals: + void triggered( int action ); + +private slots: + void onTriggered( int action ); + + void copyLink(); + void addToQueue(); + +private: + QSignalMapper* m_sigmap; + int m_supportedActions; + QList m_queries; +}; + +}; // ns + +#endif diff --git a/src/libtomahawk/playlist/artistview.cpp b/src/libtomahawk/playlist/artistview.cpp index a584d9a91..54f25fbff 100644 --- a/src/libtomahawk/playlist/artistview.cpp +++ b/src/libtomahawk/playlist/artistview.cpp @@ -46,6 +46,7 @@ ArtistView::ArtistView( QWidget* parent ) , m_proxyModel( 0 ) // , m_delegate( 0 ) , m_loadingSpinner( new LoadingSpinner( this ) ) + , m_contextMenu( new ContextMenu( this ) ) , m_showModes( true ) { setAlternatingRowColors( true ); @@ -59,6 +60,7 @@ ArtistView::ArtistView( QWidget* parent ) setAllColumnsShowFocus( true ); setSelectionMode( QAbstractItemView::ExtendedSelection ); setSelectionBehavior( QAbstractItemView::SelectRows ); + setContextMenuPolicy( Qt::CustomContextMenu ); setHeader( m_header ); setProxyModel( new TreeProxyModel( this ) ); @@ -81,6 +83,8 @@ ArtistView::ArtistView( QWidget* parent ) connect( &m_timer, SIGNAL( timeout() ), SLOT( onScrollTimeout() ) ); connect( this, SIGNAL( doubleClicked( QModelIndex ) ), SLOT( onItemActivated( QModelIndex ) ) ); + connect( this, SIGNAL( customContextMenuRequested( const QPoint& ) ), SLOT( onCustomContextMenu( const QPoint& ) ) ); + connect( m_contextMenu, SIGNAL( triggered( int ) ), SLOT( onMenuTriggered( int ) ) ); } @@ -250,6 +254,47 @@ ArtistView::onScrollTimeout() } +void +ArtistView::onCustomContextMenu( const QPoint& pos ) +{ + QModelIndex idx = indexAt( pos ); + idx = idx.sibling( idx.row(), 0 ); + m_contextMenuIndex = idx; + + if ( !idx.isValid() ) + return; + + QList queries; + foreach ( const QModelIndex& index, selectedIndexes() ) + { + if ( index.column() ) + continue; + + TreeModelItem* item = m_proxyModel->itemFromIndex( m_proxyModel->mapToSource( index ) ); + if ( item && !item->result().isNull() ) + queries << item->result()->toQuery(); + } + + m_contextMenu->setQueries( queries ); + m_contextMenu->exec( mapToGlobal( pos ) ); +} + + +void +ArtistView::onMenuTriggered( int action ) +{ + switch ( action ) + { + case ContextMenu::ActionPlay: + onItemActivated( m_contextMenuIndex ); + break; + + default: + break; + } +} + + bool ArtistView::jumpToCurrentTrack() { diff --git a/src/libtomahawk/playlist/artistview.h b/src/libtomahawk/playlist/artistview.h index a32b430a6..c60b863e5 100644 --- a/src/libtomahawk/playlist/artistview.h +++ b/src/libtomahawk/playlist/artistview.h @@ -22,6 +22,7 @@ #include #include +#include "contextMenu.h" #include "treemodel.h" #include "treeproxymodel.h" #include "viewpage.h" @@ -79,6 +80,9 @@ private slots: void onViewChanged(); void onScrollTimeout(); + void onCustomContextMenu( const QPoint& pos ); + void onMenuTriggered( int action ); + private: TreeHeader* m_header; TreeModel* m_model; @@ -86,6 +90,8 @@ private: // PlaylistItemDelegate* m_delegate; LoadingSpinner* m_loadingSpinner; + QModelIndex m_contextMenuIndex; + Tomahawk::ContextMenu* m_contextMenu; bool m_showModes; QTimer m_timer; diff --git a/src/libtomahawk/playlist/collectionview.cpp b/src/libtomahawk/playlist/collectionview.cpp index 55ff115b3..96e8cda41 100644 --- a/src/libtomahawk/playlist/collectionview.cpp +++ b/src/libtomahawk/playlist/collectionview.cpp @@ -38,9 +38,6 @@ CollectionView::CollectionView( QWidget* parent ) setDragDropMode( QAbstractItemView::DragOnly ); setAcceptDrops( false ); - - setContextMenuPolicy( Qt::CustomContextMenu ); - connect( this, SIGNAL( customContextMenuRequested( const QPoint& ) ), SLOT( onCustomContextMenu( const QPoint& ) ) ); } @@ -80,42 +77,6 @@ CollectionView::dragEnterEvent( QDragEnterEvent* event ) } -void -CollectionView::setupMenus() -{ - m_itemMenu.clear(); - - m_playItemAction = m_itemMenu.addAction( tr( "&Play" ) ); - m_addItemsToQueueAction = m_itemMenu.addAction( tr( "Add to &Queue" ) ); - m_itemMenu.addSeparator(); - - foreach( QAction* a, actions() ) - m_itemMenu.addAction( a ); -// m_addItemsToPlaylistAction = m_itemMenu.addAction( tr( "&Add to Playlist" ) ); - - connect( m_playItemAction, SIGNAL( triggered() ), SLOT( playItem() ) ); - connect( m_addItemsToQueueAction, SIGNAL( triggered() ), SLOT( addItemsToQueue() ) ); -// connect( m_addItemsToPlaylistAction, SIGNAL( triggered() ), SLOT( addItemsToPlaylist() ) ); -} - - -void -CollectionView::onCustomContextMenu( const QPoint& pos ) -{ - qDebug() << Q_FUNC_INFO; - setupMenus(); - - QModelIndex idx = indexAt( pos ); - idx = idx.sibling( idx.row(), 0 ); - setContextMenuIndex( idx ); - - if ( !idx.isValid() ) - return; - - m_itemMenu.exec( mapToGlobal( pos ) ); -} - - void CollectionView::onTrackCountChanged( unsigned int tracks ) { diff --git a/src/libtomahawk/playlist/collectionview.h b/src/libtomahawk/playlist/collectionview.h index e19c80d28..a3893b270 100644 --- a/src/libtomahawk/playlist/collectionview.h +++ b/src/libtomahawk/playlist/collectionview.h @@ -19,8 +19,6 @@ #ifndef COLLECTIONVIEW_H #define COLLECTIONVIEW_H -#include - #include "trackproxymodel.h" #include "trackmodel.h" #include "trackview.h" @@ -52,20 +50,10 @@ public: virtual bool jumpToCurrentTrack(); private slots: - void onCustomContextMenu( const QPoint& pos ); void onTrackCountChanged( unsigned int tracks ); protected: virtual void dragEnterEvent( QDragEnterEvent* event ); - -private: - void setupMenus(); - - QMenu m_itemMenu; - - QAction* m_playItemAction; - QAction* m_addItemsToQueueAction; - QAction* m_addItemsToPlaylistAction; }; #endif // COLLECTIONVIEW_H diff --git a/src/libtomahawk/playlist/playlistview.cpp b/src/libtomahawk/playlist/playlistview.cpp index 210558a4b..5a8ce4a9f 100644 --- a/src/libtomahawk/playlist/playlistview.cpp +++ b/src/libtomahawk/playlist/playlistview.cpp @@ -32,16 +32,10 @@ using namespace Tomahawk; PlaylistView::PlaylistView( QWidget* parent ) : TrackView( parent ) , m_model( 0 ) - , m_itemMenu( 0 ) - , m_playItemAction( 0 ) - , m_addItemsToQueueAction( 0 ) - , m_addItemsToPlaylistAction( 0 ) - , m_deleteItemsAction( 0 ) { setProxyModel( new PlaylistProxyModel( this ) ); - setContextMenuPolicy( Qt::CustomContextMenu ); - connect( this, SIGNAL( customContextMenuRequested( const QPoint& ) ), SLOT( onCustomContextMenu( const QPoint& ) ) ); + connect( contextMenu(), SIGNAL( triggered( int ) ), SLOT( onMenuTriggered( int ) ) ); } @@ -81,54 +75,6 @@ PlaylistView::setPlaylistModel( PlaylistModel* model ) } -void -PlaylistView::setupMenus() -{ - m_itemMenu.clear(); - - unsigned int i = 0; - foreach( const QModelIndex& idx, selectedIndexes() ) - if ( idx.column() == 0 ) - i++; - - m_playItemAction = m_itemMenu.addAction( tr( "&Play" ) ); - m_addItemsToQueueAction = m_itemMenu.addAction( tr( "Add to &Queue" ) ); - m_itemMenu.addSeparator(); - - foreach( QAction* a, actions() ) - m_itemMenu.addAction( a ); - -// m_addItemsToPlaylistAction = m_itemMenu.addAction( tr( "&Add to Playlist" ) ); -// m_itemMenu.addSeparator(); - m_deleteItemsAction = m_itemMenu.addAction( i > 1 ? tr( "&Delete Items" ) : tr( "&Delete Item" ) ); - - if ( model() ) - m_deleteItemsAction->setEnabled( !model()->isReadOnly() ); - - connect( m_playItemAction, SIGNAL( triggered() ), SLOT( playItem() ) ); - connect( m_addItemsToQueueAction, SIGNAL( triggered() ), SLOT( addItemsToQueue() ) ); -// connect( m_addItemsToPlaylistAction, SIGNAL( triggered() ), SLOT( addItemsToPlaylist() ) ); - connect( m_deleteItemsAction, SIGNAL( triggered() ), SLOT( deleteItems() ) ); -} - - -void -PlaylistView::onCustomContextMenu( const QPoint& pos ) -{ - qDebug() << Q_FUNC_INFO; - setupMenus(); - - QModelIndex idx = indexAt( pos ); - idx = idx.sibling( idx.row(), 0 ); - setContextMenuIndex( idx ); - - if ( !idx.isValid() ) - return; - - m_itemMenu.exec( mapToGlobal( pos ) ); -} - - void PlaylistView::keyPressEvent( QKeyEvent* event ) { @@ -152,6 +98,7 @@ PlaylistView::deleteItems() proxyModel()->removeIndexes( selectedIndexes() ); } + void PlaylistView::onTrackCountChanged( unsigned int tracks ) { @@ -196,3 +143,19 @@ PlaylistView::isTemporaryPage() const { return ( m_model && m_model->isTemporary() ); } + + +void +PlaylistView::onMenuTriggered( int action ) +{ + switch ( action ) + { + case ContextMenu::ActionDelete: + deleteItems(); + break; + + default: + TrackView::onMenuTriggered( action ); + break; + } +} diff --git a/src/libtomahawk/playlist/playlistview.h b/src/libtomahawk/playlist/playlistview.h index 4bc19650a..945a0d613 100644 --- a/src/libtomahawk/playlist/playlistview.h +++ b/src/libtomahawk/playlist/playlistview.h @@ -19,8 +19,6 @@ #ifndef PLAYLISTVIEW_H #define PLAYLISTVIEW_H -#include - #include "playlist/trackproxymodel.h" #include "playlist/playlistmodel.h" #include "trackview.h" @@ -62,26 +60,19 @@ protected: void keyPressEvent( QKeyEvent* event ); private slots: - void onCustomContextMenu( const QPoint& pos ); void onTrackCountChanged( unsigned int tracks ); + void onMenuTriggered( int action ); void deleteItems(); void onDeleted(); void onChanged(); -private: - void setupMenus(); +private: PlaylistModel* m_model; - QMenu m_itemMenu; QString m_customTitle; QString m_customDescripton; - - QAction* m_playItemAction; - QAction* m_addItemsToQueueAction; - QAction* m_addItemsToPlaylistAction; - QAction* m_deleteItemsAction; }; #endif // PLAYLISTVIEW_H diff --git a/src/libtomahawk/playlist/trackview.cpp b/src/libtomahawk/playlist/trackview.cpp index 3b1f4b5ed..ddd006d54 100644 --- a/src/libtomahawk/playlist/trackview.cpp +++ b/src/libtomahawk/playlist/trackview.cpp @@ -34,7 +34,6 @@ #include "trackmodel.h" #include "trackproxymodel.h" #include "track.h" -#include "globalactionmanager.h" using namespace Tomahawk; @@ -49,6 +48,7 @@ TrackView::TrackView( QWidget* parent ) , m_loadingSpinner( new LoadingSpinner( this ) ) , m_resizing( false ) , m_dragging( false ) + , m_contextMenu( new ContextMenu( this ) ) { setAlternatingRowColors( true ); setSelectionMode( QAbstractItemView::ExtendedSelection ); @@ -67,6 +67,7 @@ TrackView::TrackView( QWidget* parent ) setHeader( m_header ); setSortingEnabled( true ); sortByColumn( -1 ); + setContextMenuPolicy( Qt::CustomContextMenu ); #ifndef Q_WS_WIN QFont f = font(); @@ -79,11 +80,9 @@ TrackView::TrackView( QWidget* parent ) setFont( f ); #endif - QAction* createLinkAction = new QAction( tr( "Copy Track Link" ), this ); - connect( createLinkAction, SIGNAL( triggered( bool ) ), this, SLOT( copyLink() ) ); - addAction( createLinkAction ); - connect( this, SIGNAL( doubleClicked( QModelIndex ) ), SLOT( onItemActivated( QModelIndex ) ) ); + connect( this, SIGNAL( customContextMenuRequested( const QPoint& ) ), SLOT( onCustomContextMenu( const QPoint& ) ) ); + connect( m_contextMenu, SIGNAL( triggered( int ) ), SLOT( onMenuTriggered( int ) ) ); } @@ -200,24 +199,6 @@ TrackView::playItem() } -void -TrackView::addItemsToQueue() -{ - foreach( const QModelIndex& idx, selectedIndexes() ) - { - if ( idx.column() ) - continue; - - TrackModelItem* item = model()->itemFromIndex( proxyModel()->mapToSource( idx ) ); - if ( item && item->query()->numResults() ) - { - ViewManager::instance()->queue()->model()->append( item->query() ); - ViewManager::instance()->showQueue(); - } - } -} - - void TrackView::resizeEvent( QResizeEvent* event ) { @@ -374,17 +355,6 @@ TrackView::onFilterChanged( const QString& ) } -void -TrackView::copyLink() -{ - TrackModelItem* item = model()->itemFromIndex( proxyModel()->mapToSource( contextMenuIndex() ) ); - if ( item && !item->query().isNull() ) - { - GlobalActionManager::instance()->copyToClipboard( item->query() ); - } -} - - void TrackView::startDrag( Qt::DropActions supportedActions ) { @@ -419,3 +389,47 @@ TrackView::startDrag( Qt::DropActions supportedActions ) m_proxyModel->removeIndexes( pindexes ); } } + + +void +TrackView::onCustomContextMenu( const QPoint& pos ) +{ + QModelIndex idx = indexAt( pos ); + idx = idx.sibling( idx.row(), 0 ); + setContextMenuIndex( idx ); + + if ( !idx.isValid() ) + return; + + if ( model() && !model()->isReadOnly() ) + m_contextMenu->setSupportedActions( m_contextMenu->supportedActions() | ContextMenu::ActionDelete ); + + QList queries; + foreach ( const QModelIndex& index, selectedIndexes() ) + { + if ( index.column() ) + continue; + + TrackModelItem* item = proxyModel()->itemFromIndex( proxyModel()->mapToSource( index ) ); + if ( item && !item->query().isNull() ) + queries << item->query(); + } + + m_contextMenu->setQueries( queries ); + m_contextMenu->exec( mapToGlobal( pos ) ); +} + + +void +TrackView::onMenuTriggered( int action ) +{ + switch ( action ) + { + case ContextMenu::ActionPlay: + onItemActivated( m_contextMenuIndex ); + break; + + default: + break; + } +} diff --git a/src/libtomahawk/playlist/trackview.h b/src/libtomahawk/playlist/trackview.h index 05546442e..d2ad0de82 100644 --- a/src/libtomahawk/playlist/trackview.h +++ b/src/libtomahawk/playlist/trackview.h @@ -22,6 +22,7 @@ #include #include +#include "contextMenu.h" #include "playlistitemdelegate.h" #include "dllmacro.h" @@ -53,6 +54,7 @@ explicit TrackView( QWidget* parent = 0 ); PlaylistItemDelegate* delegate() const { return m_delegate; } TrackHeader* header() const { return m_header; } OverlayWidget* overlay() const { return m_overlay; } + Tomahawk::ContextMenu* contextMenu() const { return m_contextMenu; } QModelIndex contextMenuIndex() const { return m_contextMenuIndex; } void setContextMenuIndex( const QModelIndex& idx ) { m_contextMenuIndex = idx; } @@ -61,7 +63,7 @@ public slots: void onItemActivated( const QModelIndex& index ); void playItem(); - void addItemsToQueue(); + void onMenuTriggered( int action ); protected: virtual void resizeEvent( QResizeEvent* event ); @@ -77,10 +79,9 @@ protected: private slots: void onItemResized( const QModelIndex& index ); - void onFilterChanged( const QString& filter ); - void copyLink(); + void onCustomContextMenu( const QPoint& pos ); private: QString m_guid; @@ -96,6 +97,7 @@ private: QRect m_dropRect; QModelIndex m_contextMenuIndex; + Tomahawk::ContextMenu* m_contextMenu; }; #endif // TRACKVIEW_H diff --git a/src/libtomahawk/sourceplaylistinterface.cpp b/src/libtomahawk/sourceplaylistinterface.cpp index a3d794937..c25e53583 100644 --- a/src/libtomahawk/sourceplaylistinterface.cpp +++ b/src/libtomahawk/sourceplaylistinterface.cpp @@ -70,7 +70,7 @@ SourcePlaylistInterface::hasNextItem() { if ( m_source.isNull() || m_source->currentTrack().isNull() || m_source->currentTrack()->results().isEmpty() ) return false; - + return m_gotNextItem; } @@ -109,7 +109,7 @@ SourcePlaylistInterface::resolveResultsAdded( const QList& qDebug() << Q_FUNC_INFO; foreach ( Tomahawk::result_ptr ptr, results ) { - qDebug() << "Found result: " << ptr->track(); +// qDebug() << "Found result:" << ptr->track(); } } From 251599e36e920d98cc87a04f80d86738caafed3c Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Fri, 24 Jun 2011 04:52:30 +0200 Subject: [PATCH 13/86] * Removed silly debug which slowed down sorting massively. --- src/libtomahawk/playlist/trackproxymodel.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libtomahawk/playlist/trackproxymodel.cpp b/src/libtomahawk/playlist/trackproxymodel.cpp index c1e1c34a2..abb54a01f 100644 --- a/src/libtomahawk/playlist/trackproxymodel.cpp +++ b/src/libtomahawk/playlist/trackproxymodel.cpp @@ -300,8 +300,6 @@ TrackProxyModel::removeIndexes( const QList& indexes ) bool TrackProxyModel::lessThan( const QModelIndex& left, const QModelIndex& right ) const { - qDebug() << Q_FUNC_INFO; - TrackModelItem* p1 = itemFromIndex( left ); TrackModelItem* p2 = itemFromIndex( right ); From b65d9d5809e3de6facc0bf16ca8f8f2442c2c359 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Fri, 24 Jun 2011 05:46:08 +0200 Subject: [PATCH 14/86] * Guard AudioEngine against null-ptr PlaylistInterfaces. --- src/libtomahawk/audio/audioengine.cpp | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/libtomahawk/audio/audioengine.cpp b/src/libtomahawk/audio/audioengine.cpp index b1e0c3b1a..b82ffe18b 100644 --- a/src/libtomahawk/audio/audioengine.cpp +++ b/src/libtomahawk/audio/audioengine.cpp @@ -140,10 +140,10 @@ AudioEngine::stop( bool sendNotification ) qDebug() << Q_FUNC_INFO; m_mediaObject->stop(); - + if ( m_playlist ) m_playlist->reset(); - + setCurrentTrack( Tomahawk::result_ptr() ); emit stopped(); @@ -158,7 +158,7 @@ AudioEngine::stop( bool sendNotification ) stopInfo["message"] = QString( "Tomahawk is stopped." ); map[ Tomahawk::InfoSystem::InfoNotifyUser ] = QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( stopInfo ); } - + Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( s_aeInfoIdentifier, map ); } } @@ -171,7 +171,7 @@ AudioEngine::previous() if ( !m_playlist ) return; - + if ( m_playlist->skipRestrictions() == PlaylistInterface::NoSkip || m_playlist->skipRestrictions() == PlaylistInterface::NoSkipBackwards ) return; @@ -187,7 +187,7 @@ AudioEngine::next() if ( !m_playlist ) return; - + if ( m_playlist->skipRestrictions() == PlaylistInterface::NoSkip || m_playlist->skipRestrictions() == PlaylistInterface::NoSkipForwards ) return; @@ -209,10 +209,10 @@ AudioEngine::seek( int ms ) { if ( !m_playlist ) return; - + if ( m_playlist->seekRestrictions() == PlaylistInterface::NoSeek ) return; - + if ( isPlaying() || isPaused() ) { qDebug() << Q_FUNC_INFO << ms; @@ -316,7 +316,7 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result ) trackInfo["artist"] = m_currentTrack->artist()->name(); trackInfo["album"] = m_currentTrack->album()->name(); map[ Tomahawk::InfoSystem::InfoNowPlaying ] = QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ); - + if ( TomahawkSettings::instance()->verboseNotifications() ) { Tomahawk::InfoSystem::InfoCriteriaHash playInfo; @@ -326,7 +326,7 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result ) .arg( m_currentTrack->album()->name() ); map[ Tomahawk::InfoSystem::InfoNotifyUser ] = QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( playInfo ); } - + Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( s_aeInfoIdentifier, map ); } } @@ -345,7 +345,7 @@ void AudioEngine::loadPreviousTrack() { qDebug() << Q_FUNC_INFO; - + if ( !m_playlist ) { stop(); @@ -492,11 +492,12 @@ AudioEngine::setPlaylist( PlaylistInterface* playlist ) { if ( m_playlist ) m_playlist->reset(); + m_playlist = playlist; - if ( m_playlist->retryMode() == PlaylistInterface::Retry ) + if ( m_playlist && m_playlist->retryMode() == PlaylistInterface::Retry ) connect( m_playlist->object(), SIGNAL( nextTrackReady() ), SLOT( playlistNextTrackReady() ) ); - + emit playlistChanged( playlist ); } From 1c820a2bebf0d07954fdffe247400d13c2932a7c Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Fri, 24 Jun 2011 05:49:20 +0200 Subject: [PATCH 15/86] * Guard some more. --- src/libtomahawk/audio/audioengine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libtomahawk/audio/audioengine.cpp b/src/libtomahawk/audio/audioengine.cpp index b82ffe18b..d598ab02a 100644 --- a/src/libtomahawk/audio/audioengine.cpp +++ b/src/libtomahawk/audio/audioengine.cpp @@ -495,7 +495,7 @@ AudioEngine::setPlaylist( PlaylistInterface* playlist ) m_playlist = playlist; - if ( m_playlist && m_playlist->retryMode() == PlaylistInterface::Retry ) + if ( m_playlist && m_playlist->object() && m_playlist->retryMode() == PlaylistInterface::Retry ) connect( m_playlist->object(), SIGNAL( nextTrackReady() ), SLOT( playlistNextTrackReady() ) ); emit playlistChanged( playlist ); From 4abb52d1982b34b2bd2c45e669508a5f6c23f823 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Fri, 24 Jun 2011 08:08:33 +0200 Subject: [PATCH 16/86] * Added context menus for Artists & Albums, too. --- src/libtomahawk/contextMenu.cpp | 110 ++++++++++++++++-- src/libtomahawk/contextMenu.h | 13 +++ src/libtomahawk/playlist/artistview.cpp | 15 ++- .../playlist/collectionflatmodel.h | 2 + src/libtomahawk/playlist/playlistmodel.cpp | 11 +- src/libtomahawk/playlist/trackmodel.h | 2 + src/libtomahawk/playlist/trackview.cpp | 2 + 7 files changed, 144 insertions(+), 11 deletions(-) diff --git a/src/libtomahawk/contextMenu.cpp b/src/libtomahawk/contextMenu.cpp index 29cccd326..2c86595b2 100644 --- a/src/libtomahawk/contextMenu.cpp +++ b/src/libtomahawk/contextMenu.cpp @@ -21,7 +21,6 @@ #include #include "globalactionmanager.h" -#include "pipeline.h" #include "playlistview.h" #include "viewmanager.h" @@ -38,10 +37,24 @@ ContextMenu::ContextMenu( QWidget* parent ) } +void +ContextMenu::clear() +{ + QMenu::clear(); + + m_queries.clear(); + m_albums.clear(); + m_artists.clear(); +} + + void ContextMenu::setQueries( const QList& queries ) { - clear(); + if ( queries.isEmpty() ) + return; + + QMenu::clear(); m_queries.clear(); m_queries << queries; @@ -55,8 +68,8 @@ ContextMenu::setQueries( const QList& queries ) addSeparator(); - if ( m_supportedActions & ActionCopyLink ) - m_sigmap->setMapping( addAction( tr( "Copy Track Link" ) ), ActionCopyLink ); + if ( m_supportedActions & ActionCopyLink && itemCount() == 1 ) + m_sigmap->setMapping( addAction( tr( "Copy Track &Link" ) ), ActionCopyLink ); addSeparator(); @@ -79,6 +92,84 @@ ContextMenu::setQuery( const Tomahawk::query_ptr& query ) } +void +ContextMenu::setAlbums( const QList& albums ) +{ + if ( albums.isEmpty() ) + return; + + QMenu::clear(); + m_albums.clear(); + m_albums << albums; + + if ( m_supportedActions & ActionPlay ) + m_sigmap->setMapping( addAction( tr( "&Play" ) ), ActionPlay ); + + if ( m_supportedActions & ActionQueue ) + m_sigmap->setMapping( addAction( tr( "Add to &Queue" ) ), ActionQueue ); + + //m_sigmap->setMapping( addAction( tr( "&Add to Playlist" ) ), ActionAddToPlaylist ); + + addSeparator(); + +/* if ( m_supportedActions & ActionCopyLink && itemCount() == 1 ) + m_sigmap->setMapping( addAction( tr( "Copy Album &Link" ) ), ActionCopyLink ); */ + + foreach ( QAction* action, actions() ) + { + connect( action, SIGNAL( triggered() ), m_sigmap, SLOT( map() ) ); + } +} + + +void +ContextMenu::setAlbum( const Tomahawk::album_ptr& album ) +{ + QList albums; + albums << album; + setAlbums( albums ); +} + + +void +ContextMenu::setArtists( const QList& artists ) +{ + if ( artists.isEmpty() ) + return; + + QMenu::clear(); + m_artists.clear(); + m_artists << artists; + + if ( m_supportedActions & ActionPlay ) + m_sigmap->setMapping( addAction( tr( "&Play" ) ), ActionPlay ); + + if ( m_supportedActions & ActionQueue ) + m_sigmap->setMapping( addAction( tr( "Add to &Queue" ) ), ActionQueue ); + + //m_sigmap->setMapping( addAction( tr( "&Add to Playlist" ) ), ActionAddToPlaylist ); + + addSeparator(); + +/* if ( m_supportedActions & ActionCopyLink && itemCount() == 1 ) + m_sigmap->setMapping( addAction( tr( "Copy Artist &Link" ) ), ActionCopyLink ); */ + + foreach ( QAction* action, actions() ) + { + connect( action, SIGNAL( triggered() ), m_sigmap, SLOT( map() ) ); + } +} + + +void +ContextMenu::setArtist( const Tomahawk::artist_ptr& artist ) +{ + QList artists; + artists << artist; + setArtists( artists ); +} + + void ContextMenu::onTriggered( int action ) { @@ -102,11 +193,16 @@ void ContextMenu::addToQueue() { foreach ( const query_ptr& query, m_queries ) { - if ( !query->resolvingFinished() ) - Pipeline::instance()->resolve( query ); - ViewManager::instance()->queue()->model()->append( query ); } + foreach ( const artist_ptr& artist, m_artists ) + { + ViewManager::instance()->queue()->model()->append( artist ); + } + foreach ( const album_ptr& album, m_albums ) + { + ViewManager::instance()->queue()->model()->append( album ); + } ViewManager::instance()->showQueue(); } diff --git a/src/libtomahawk/contextMenu.h b/src/libtomahawk/contextMenu.h index 7153064b5..f217d3581 100644 --- a/src/libtomahawk/contextMenu.h +++ b/src/libtomahawk/contextMenu.h @@ -45,6 +45,16 @@ public: void setQuery( const Tomahawk::query_ptr& query ); void setQueries( const QList& queries ); + void setArtist( const Tomahawk::artist_ptr& artist ); + void setArtists( const QList& artists ); + + void setAlbum( const Tomahawk::album_ptr& album ); + void setAlbums( const QList& albums ); + + void clear(); + + unsigned int itemCount() const { return m_queries.count() + m_artists.count() + m_albums.count(); } + signals: void triggered( int action ); @@ -57,7 +67,10 @@ private slots: private: QSignalMapper* m_sigmap; int m_supportedActions; + QList m_queries; + QList m_artists; + QList m_albums; }; }; // ns diff --git a/src/libtomahawk/playlist/artistview.cpp b/src/libtomahawk/playlist/artistview.cpp index 54f25fbff..c6fa45c9e 100644 --- a/src/libtomahawk/playlist/artistview.cpp +++ b/src/libtomahawk/playlist/artistview.cpp @@ -257,6 +257,8 @@ ArtistView::onScrollTimeout() void ArtistView::onCustomContextMenu( const QPoint& pos ) { + m_contextMenu->clear(); + QModelIndex idx = indexAt( pos ); idx = idx.sibling( idx.row(), 0 ); m_contextMenuIndex = idx; @@ -265,17 +267,28 @@ ArtistView::onCustomContextMenu( const QPoint& pos ) return; QList queries; + QList artists; + QList albums; + foreach ( const QModelIndex& index, selectedIndexes() ) { - if ( index.column() ) + if ( index.column() || selectedIndexes().contains( index.parent() ) ) continue; TreeModelItem* item = m_proxyModel->itemFromIndex( m_proxyModel->mapToSource( index ) ); + if ( item && !item->result().isNull() ) queries << item->result()->toQuery(); + if ( item && !item->artist().isNull() ) + artists << item->artist(); + if ( item && !item->album().isNull() ) + albums << item->album(); } m_contextMenu->setQueries( queries ); + m_contextMenu->setArtists( artists ); + m_contextMenu->setAlbums( albums ); + m_contextMenu->exec( mapToGlobal( pos ) ); } diff --git a/src/libtomahawk/playlist/collectionflatmodel.h b/src/libtomahawk/playlist/collectionflatmodel.h index fbf489975..cc1d5c79e 100644 --- a/src/libtomahawk/playlist/collectionflatmodel.h +++ b/src/libtomahawk/playlist/collectionflatmodel.h @@ -55,6 +55,8 @@ 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::artist_ptr& /*artist*/ ) {} + virtual void append( const Tomahawk::album_ptr& /*album*/ ) {} signals: void repeatModeChanged( Tomahawk::PlaylistInterface::RepeatMode mode ); diff --git a/src/libtomahawk/playlist/playlistmodel.cpp b/src/libtomahawk/playlist/playlistmodel.cpp index 3d9942c86..e7c712591 100644 --- a/src/libtomahawk/playlist/playlistmodel.cpp +++ b/src/libtomahawk/playlist/playlistmodel.cpp @@ -23,7 +23,7 @@ #include #include "album.h" - +#include "pipeline.h" #include "database/database.h" #include "database/databasecommand_playbackhistory.h" #include "dynamic/GeneratorInterface.h" @@ -188,6 +188,9 @@ PlaylistModel::append( const Tomahawk::query_ptr& query ) QList< Tomahawk::query_ptr > ql; ql << query; + if ( !query->resolvingFinished() ) + Pipeline::instance()->resolve( query ); + onTracksAdded( ql ); } @@ -201,7 +204,8 @@ PlaylistModel::append( const Tomahawk::album_ptr& album ) connect( album.data(), SIGNAL( tracksAdded( QList ) ), SLOT( onTracksAdded( QList ) ) ); - if( rowCount( QModelIndex() ) == 0 ) { + if ( rowCount( QModelIndex() ) == 0 ) + { setTitle( album->name() ); setDescription( tr( "All tracks by %1 on album %2" ).arg( album->artist()->name() ).arg( album->name() ) ); m_isTemporary = true; @@ -220,7 +224,8 @@ PlaylistModel::append( const Tomahawk::artist_ptr& artist ) connect( artist.data(), SIGNAL( tracksAdded( QList ) ), SLOT( onTracksAdded( QList ) ) ); - if( rowCount( QModelIndex() ) == 0 ) { + if ( rowCount( QModelIndex() ) == 0 ) + { setTitle( artist->name() ); setDescription( tr( "All tracks by %1" ).arg( artist->name() ) ); m_isTemporary = true; diff --git a/src/libtomahawk/playlist/trackmodel.h b/src/libtomahawk/playlist/trackmodel.h index 6f3e4cca1..ce67e0375 100644 --- a/src/libtomahawk/playlist/trackmodel.h +++ b/src/libtomahawk/playlist/trackmodel.h @@ -89,6 +89,8 @@ public: virtual void ensureResolved(); virtual void append( const Tomahawk::query_ptr& query ) = 0; + virtual void append( const Tomahawk::artist_ptr& artist ) = 0; + virtual void append( const Tomahawk::album_ptr& album ) = 0; TrackModelItem* itemFromIndex( const QModelIndex& index ) const; diff --git a/src/libtomahawk/playlist/trackview.cpp b/src/libtomahawk/playlist/trackview.cpp index ddd006d54..d8bf6c0a1 100644 --- a/src/libtomahawk/playlist/trackview.cpp +++ b/src/libtomahawk/playlist/trackview.cpp @@ -394,6 +394,8 @@ TrackView::startDrag( Qt::DropActions supportedActions ) void TrackView::onCustomContextMenu( const QPoint& pos ) { + m_contextMenu->clear(); + QModelIndex idx = indexAt( pos ); idx = idx.sibling( idx.row(), 0 ); setContextMenuIndex( idx ); From 903617fd50cf1cbf4c65d2d07914b6e26b289971 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Fri, 24 Jun 2011 08:12:43 +0200 Subject: [PATCH 17/86] Add Tomahawk object to resolver scope, currently offers a readFile method --- src/resolvers/qtscriptresolver.cpp | 25 +++++++++++++++++++++++++ src/resolvers/qtscriptresolver.h | 14 ++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/resolvers/qtscriptresolver.cpp b/src/resolvers/qtscriptresolver.cpp index a069ab5cf..a32466245 100644 --- a/src/resolvers/qtscriptresolver.cpp +++ b/src/resolvers/qtscriptresolver.cpp @@ -24,6 +24,30 @@ #include "sourcelist.h" #include "utils/tomahawkutils.h" +QtScriptResolverHelper::QtScriptResolverHelper( const QString& scriptPath, QObject* parent ): QObject(parent) +{ + m_scriptPath = scriptPath; +} + +QString +QtScriptResolverHelper::readFile( const QString& fileName ) +{ + QString path = QFileInfo( m_scriptPath ).absolutePath(); + // remove directories + QString cleanedFileName = QFileInfo( fileName ).fileName(); + + QString absoluteFilePath = path.append( "/" ).append( cleanedFileName ); + + QFile file( absoluteFilePath ); + if( !file.exists() ) + { + return QString(); + } + + file.open( QIODevice::ReadOnly ); + return file.readAll(); +} + QtScriptResolver::QtScriptResolver( const QString& scriptPath ) : Tomahawk::ExternalResolver( scriptPath ) @@ -43,6 +67,7 @@ QtScriptResolver::QtScriptResolver( const QString& scriptPath ) m_engine->mainFrame()->setHtml( "" ); m_engine->mainFrame()->evaluateJavaScript( scriptFile.readAll() ); + m_engine->mainFrame()->addToJavaScriptWindowObject( "Tomahawk", new QtScriptResolverHelper( scriptPath, this ) ); scriptFile.close(); QVariantMap m = m_engine->mainFrame()->evaluateJavaScript( "getSettings();" ).toMap(); diff --git a/src/resolvers/qtscriptresolver.h b/src/resolvers/qtscriptresolver.h index 51d457c1b..02c7f096f 100644 --- a/src/resolvers/qtscriptresolver.h +++ b/src/resolvers/qtscriptresolver.h @@ -33,6 +33,20 @@ class QtScriptResolver; +class QtScriptResolverHelper : public QObject +{ + Q_OBJECT + +public: + QtScriptResolverHelper(const QString& scriptPath, QObject* parent ); + +public slots: + QString readFile(const QString& fileName); + +private: + QString m_scriptPath; +}; + class ScriptEngine : public QWebPage { Q_OBJECT From 3f4140e023ef22b2625bb0e9b5ccc38f5f5b40ef Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Fri, 24 Jun 2011 08:18:13 +0200 Subject: [PATCH 18/86] * Don't offer a play action if the user selected multiple items. --- src/libtomahawk/contextMenu.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libtomahawk/contextMenu.cpp b/src/libtomahawk/contextMenu.cpp index 2c86595b2..82053fba2 100644 --- a/src/libtomahawk/contextMenu.cpp +++ b/src/libtomahawk/contextMenu.cpp @@ -58,7 +58,7 @@ ContextMenu::setQueries( const QList& queries ) m_queries.clear(); m_queries << queries; - if ( m_supportedActions & ActionPlay ) + if ( m_supportedActions & ActionPlay && itemCount() == 1 ) m_sigmap->setMapping( addAction( tr( "&Play" ) ), ActionPlay ); if ( m_supportedActions & ActionQueue ) @@ -102,7 +102,7 @@ ContextMenu::setAlbums( const QList& albums ) m_albums.clear(); m_albums << albums; - if ( m_supportedActions & ActionPlay ) + if ( m_supportedActions & ActionPlay && itemCount() == 1 ) m_sigmap->setMapping( addAction( tr( "&Play" ) ), ActionPlay ); if ( m_supportedActions & ActionQueue ) @@ -141,7 +141,7 @@ ContextMenu::setArtists( const QList& artists ) m_artists.clear(); m_artists << artists; - if ( m_supportedActions & ActionPlay ) + if ( m_supportedActions & ActionPlay && itemCount() == 1 ) m_sigmap->setMapping( addAction( tr( "&Play" ) ), ActionPlay ); if ( m_supportedActions & ActionQueue ) From cbd8caa1715a0a8449d867e4d4622688f6b43868 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Fri, 24 Jun 2011 08:18:41 +0200 Subject: [PATCH 19/86] Add compress-method to Tomahawk-Object in QtScriptResolvers --- src/resolvers/qtscriptresolver.cpp | 8 ++++++++ src/resolvers/qtscriptresolver.h | 5 +++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/resolvers/qtscriptresolver.cpp b/src/resolvers/qtscriptresolver.cpp index a32466245..815e2c0ff 100644 --- a/src/resolvers/qtscriptresolver.cpp +++ b/src/resolvers/qtscriptresolver.cpp @@ -48,6 +48,14 @@ QtScriptResolverHelper::readFile( const QString& fileName ) return file.readAll(); } +QString +QtScriptResolverHelper::compress( const QString& data ) +{ + QByteArray comp = qCompress( data.toLatin1(), 9 ); + return comp.toBase64(); +} + + QtScriptResolver::QtScriptResolver( const QString& scriptPath ) : Tomahawk::ExternalResolver( scriptPath ) diff --git a/src/resolvers/qtscriptresolver.h b/src/resolvers/qtscriptresolver.h index 02c7f096f..f77c93c02 100644 --- a/src/resolvers/qtscriptresolver.h +++ b/src/resolvers/qtscriptresolver.h @@ -38,10 +38,11 @@ class QtScriptResolverHelper : public QObject Q_OBJECT public: - QtScriptResolverHelper(const QString& scriptPath, QObject* parent ); + QtScriptResolverHelper( const QString& scriptPath, QObject* parent ); public slots: - QString readFile(const QString& fileName); + QString readFile( const QString& fileName ); + QString compress( const QString& data ); private: QString m_scriptPath; From e0cd07c442d2ca5cf353f91471ef1edc0f9867ec Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Fri, 24 Jun 2011 08:22:39 +0200 Subject: [PATCH 20/86] * Giving domme a style-lesson ;-) --- src/resolvers/qtscriptresolver.cpp | 8 +++++--- src/resolvers/qtscriptresolver.h | 13 +++++++------ 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/resolvers/qtscriptresolver.cpp b/src/resolvers/qtscriptresolver.cpp index a32466245..aad4fe721 100644 --- a/src/resolvers/qtscriptresolver.cpp +++ b/src/resolvers/qtscriptresolver.cpp @@ -24,22 +24,24 @@ #include "sourcelist.h" #include "utils/tomahawkutils.h" -QtScriptResolverHelper::QtScriptResolverHelper( const QString& scriptPath, QObject* parent ): QObject(parent) + +QtScriptResolverHelper::QtScriptResolverHelper( const QString& scriptPath, QObject* parent ) + : QObject( parent ) { m_scriptPath = scriptPath; } + QString QtScriptResolverHelper::readFile( const QString& fileName ) { QString path = QFileInfo( m_scriptPath ).absolutePath(); // remove directories QString cleanedFileName = QFileInfo( fileName ).fileName(); - QString absoluteFilePath = path.append( "/" ).append( cleanedFileName ); QFile file( absoluteFilePath ); - if( !file.exists() ) + if ( !file.exists() ) { return QString(); } diff --git a/src/resolvers/qtscriptresolver.h b/src/resolvers/qtscriptresolver.h index 02c7f096f..773679875 100644 --- a/src/resolvers/qtscriptresolver.h +++ b/src/resolvers/qtscriptresolver.h @@ -35,13 +35,13 @@ class QtScriptResolver; class QtScriptResolverHelper : public QObject { - Q_OBJECT +Q_OBJECT public: - QtScriptResolverHelper(const QString& scriptPath, QObject* parent ); + QtScriptResolverHelper( const QString& scriptPath, QObject* parent ); public slots: - QString readFile(const QString& fileName); + QString readFile( const QString& fileName ); private: QString m_scriptPath; @@ -86,12 +86,13 @@ public: explicit QtScriptResolver( const QString& scriptPath ); virtual ~QtScriptResolver(); - virtual QString name() const { return m_name; } - virtual unsigned int weight() const { return m_weight; } - virtual unsigned int timeout() const { return m_timeout; } + virtual QString name() const { return m_name; } + virtual unsigned int weight() const { return m_weight; } + 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(); From 9758324128e9e39fd20c00b0cd468fa5e0ec78f3 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Fri, 24 Jun 2011 09:24:41 +0200 Subject: [PATCH 21/86] * Fixed broken database schema for dynamic_playlist table. --- data/sql/dbmigrate-24_to_25.sql | 18 ++++++++++++++++++ resources.qrc | 1 + src/libtomahawk/database/databaseimpl.cpp | 2 +- src/libtomahawk/database/schema.sql | 4 ++-- src/libtomahawk/database/schema.sql.h | 6 +++--- 5 files changed, 25 insertions(+), 6 deletions(-) create mode 100644 data/sql/dbmigrate-24_to_25.sql diff --git a/data/sql/dbmigrate-24_to_25.sql b/data/sql/dbmigrate-24_to_25.sql new file mode 100644 index 000000000..181df2705 --- /dev/null +++ b/data/sql/dbmigrate-24_to_25.sql @@ -0,0 +1,18 @@ +-- Script to migate from db version 24 to 25. +-- Added the social_attributes table. +-- +-- Separate each command with %% + +ALTER TABLE dynamic_playlist RENAME TO tmp_dynamic_playlist; + +CREATE TABLE IF NOT EXISTS dynamic_playlist ( + guid TEXT NOT NULL REFERENCES playlist(guid) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED, + pltype TEXT, -- the generator type + plmode INTEGER -- the mode of this playlist +); + +INSERT INTO dynamic_playlist( guid, pltype, plmode ) SELECT guid, pltype, plmode FROM tmp_dynamic_playlist; + +DROP TABLE tmp_dynamic_playlist; + +UPDATE settings SET v = '25' WHERE k == 'schema_version'; diff --git a/resources.qrc b/resources.qrc index 38dbcb60a..4afb8151f 100644 --- a/resources.qrc +++ b/resources.qrc @@ -96,5 +96,6 @@ ./data/www/tomahawk_banner_small.png ./data/sql/dbmigrate-22_to_23.sql ./data/sql/dbmigrate-23_to_24.sql + ./data/sql/dbmigrate-24_to_25.sql diff --git a/src/libtomahawk/database/databaseimpl.cpp b/src/libtomahawk/database/databaseimpl.cpp index d8c21b024..93ebf952c 100644 --- a/src/libtomahawk/database/databaseimpl.cpp +++ b/src/libtomahawk/database/databaseimpl.cpp @@ -38,7 +38,7 @@ */ #include "schema.sql.h" -#define CURRENT_SCHEMA_VERSION 24 +#define CURRENT_SCHEMA_VERSION 25 DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent ) diff --git a/src/libtomahawk/database/schema.sql b/src/libtomahawk/database/schema.sql index 1f5e5593b..723943106 100644 --- a/src/libtomahawk/database/schema.sql +++ b/src/libtomahawk/database/schema.sql @@ -106,7 +106,7 @@ CREATE TABLE IF NOT EXISTS playlist_revision ( -- VALUES('revisionguid-11', 'dynamic_playlist-guid-2', '[]'); CREATE TABLE IF NOT EXISTS dynamic_playlist ( - guid TEXT PRIMARY KEY, + guid TEXT NOT NULL REFERENCES playlist(guid) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED, pltype TEXT, -- the generator type plmode INTEGER -- the mode of this playlist ); @@ -282,4 +282,4 @@ CREATE TABLE IF NOT EXISTS settings ( v TEXT NOT NULL DEFAULT '' ); -INSERT INTO settings(k,v) VALUES('schema_version', '24'); +INSERT INTO settings(k,v) VALUES('schema_version', '25'); diff --git a/src/libtomahawk/database/schema.sql.h b/src/libtomahawk/database/schema.sql.h index bd085067a..b9ff40493 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 Sun Jun 12 05:17:25 CEST 2011. + This file was automatically generated from ./schema.sql on Fri Jun 24 09:10:23 CEST 2011. */ static const char * tomahawk_schema_sql = @@ -76,7 +76,7 @@ static const char * tomahawk_schema_sql = " previous_revision TEXT REFERENCES playlist_revision(guid) DEFERRABLE INITIALLY DEFERRED" ");" "CREATE TABLE IF NOT EXISTS dynamic_playlist (" -" guid TEXT PRIMARY KEY," +" guid TEXT NOT NULL REFERENCES playlist(guid) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED," " pltype TEXT, " " plmode INTEGER " ");" @@ -183,7 +183,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', '24');" +"INSERT INTO settings(k,v) VALUES('schema_version', '25');" ; const char * get_tomahawk_sql() From 26e12157f287e649442ff162ab30359ceeb0f979 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Fri, 24 Jun 2011 09:31:52 +0200 Subject: [PATCH 22/86] * Silly whitespace cleanup. --- src/libtomahawk/database/databaseimpl.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libtomahawk/database/databaseimpl.cpp b/src/libtomahawk/database/databaseimpl.cpp index 93ebf952c..f80578475 100644 --- a/src/libtomahawk/database/databaseimpl.cpp +++ b/src/libtomahawk/database/databaseimpl.cpp @@ -149,10 +149,10 @@ DatabaseImpl::updateSchema( int oldVersion ) QStringList statements = sql.split( ";", QString::SkipEmptyParts ); db.transaction(); - foreach( const QString& sl, statements ) + foreach ( const QString& sl, statements ) { QString s( sl.trimmed() ); - if( s.length() == 0 ) + if ( s.length() == 0 ) continue; qDebug() << "Executing:" << s; @@ -173,18 +173,18 @@ DatabaseImpl::updateSchema( int oldVersion ) 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 ) ) + if ( !script.exists() || !script.open( QIODevice::ReadOnly ) ) { - qWarning() << "Failed to find or open upgrade script from" << (cur-1) << "to" << cur << " (" << path << ")! Aborting upgrade.."; + 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 ) + foreach ( const QString& sql, statements ) { QString clean = cleanSql( sql ).trimmed(); - if( clean.isEmpty() ) + if ( clean.isEmpty() ) continue; qDebug() << "Executing upgrade statement:" << clean; From 4674ed35f09e7c44b6a18b968410a89987223ccf Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Fri, 24 Jun 2011 11:38:15 +0200 Subject: [PATCH 23/86] * Fixed the warning mess. Hope I didn't break anything :-) --- src/CMakeLists.txt | 1 + src/libtomahawk/CMakeLists.txt | 19 ++++++++++--------- .../kdtoolsglobal.cpp | 2 +- src/libtomahawk/playlist/albumproxymodel.cpp | 2 ++ src/libtomahawk/playlist/artistview.cpp | 2 +- .../playlist/dynamic/DynamicModel.h | 6 +++++- src/libtomahawk/playlist/queueproxymodel.cpp | 5 ++--- src/libtomahawk/playlist/queueproxymodel.h | 4 +++- src/libtomahawk/playlist/treeproxymodel.cpp | 14 +++++++++++--- src/libtomahawk/playlist/treeproxymodel.h | 3 ++- src/sip/jabber/CMakeLists.txt | 2 -- src/sip/jabber/googlewrapper/CMakeLists.txt | 2 -- src/sip/jabber/jabber.h | 2 ++ 13 files changed, 40 insertions(+), 24 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2a6c9b127..e9940b50a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -264,4 +264,5 @@ IF( UNIX AND NOT APPLE AND KDE4_INSTALLED ) #install protocol file ENDIF() INSTALL( FILES ${CMAKE_BINARY_DIR}/tomahawk.protocol DESTINATION ${PROTOCOL_INSTALL_DIR} ) ENDIF() + #INCLUDE( "CPack.txt" ) diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index c80ed6547..ee138e099 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -192,7 +192,6 @@ set( libHeaders result.h source.h sourceplaylistinterface.h - viewpage.h viewmanager.h globalactionmanager.h contextMenu.h @@ -306,7 +305,6 @@ set( libHeaders playlist/dynamic/DynamicPlaylist.h playlist/dynamic/DynamicControl.h - playlist/dynamic/GeneratorFactory.h playlist/dynamic/GeneratorInterface.h playlist/dynamic/DynamicView.h playlist/dynamic/DynamicModel.h @@ -322,7 +320,6 @@ set( libHeaders playlist/dynamic/widgets/DynamicSetupWidget.h playlist/dynamic/widgets/LoadingSpinner.h - utils/tomahawkutils.h utils/querylabel.h utils/elidedlabel.h utils/animatedcounterlabel.h @@ -342,14 +339,19 @@ set( libHeaders widgets/infowidgets/sourceinfowidget.h kdsingleapplicationguard/kdsingleapplicationguard.h - kdsingleapplicationguard/kdsharedmemorylocker.h - kdsingleapplicationguard/kdtoolsglobal.h - kdsingleapplicationguard/kdlockedsharedmemorypointer.h ) set( libHeaders_NoMOC - playlist/dynamic/GeneratorInterface.h + viewpage.h + + infosystem/infoplugins/unix/imageconverter.h + + playlist/dynamic/GeneratorInterface.h + playlist/dynamic/GeneratorFactory.h + + utils/tomahawkutils.h ) + set( libUI ${libUI} widgets/playlisttypeselectordlg.ui widgets/newplaylistwidget.ui @@ -384,8 +386,7 @@ IF( UNIX AND NOT APPLE ) infosystem/infoplugins/unix/imageconverter.cpp ) SET( libHeaders ${libHeaders} - infosystem/infoplugins/unix/fdonotifyplugin.h - infosystem/infoplugins/unix/imageconverter.h ) + infosystem/infoplugins/unix/fdonotifyplugin.h ) ENDIF( UNIX AND NOT APPLE ) IF( WIN32 ) diff --git a/src/libtomahawk/kdsingleapplicationguard/kdtoolsglobal.cpp b/src/libtomahawk/kdsingleapplicationguard/kdtoolsglobal.cpp index 5997fe64c..b057614d7 100644 --- a/src/libtomahawk/kdsingleapplicationguard/kdtoolsglobal.cpp +++ b/src/libtomahawk/kdsingleapplicationguard/kdtoolsglobal.cpp @@ -19,7 +19,7 @@ namespace { } static Version kdParseQtVersion( const char * const version ) { - if ( !version || qstrlen( version ) < 5 || version[1] != '.' || version[3] != '.' || version[5] != 0 && version[5] != '.' && version[5] != '-' ) + if ( !version || qstrlen( version ) < 5 || version[1] != '.' || version[3] != '.' || ( version[5] != 0 && version[5] != '.' && version[5] != '-' ) ) return Version(); // parse error const Version result = { { version[0] - '0', version[2] - '0', version[4] - '0' } }; return result; diff --git a/src/libtomahawk/playlist/albumproxymodel.cpp b/src/libtomahawk/playlist/albumproxymodel.cpp index 90541d5df..6bafcdce5 100644 --- a/src/libtomahawk/playlist/albumproxymodel.cpp +++ b/src/libtomahawk/playlist/albumproxymodel.cpp @@ -40,6 +40,7 @@ AlbumProxyModel::AlbumProxyModel( QObject* parent ) setSourceAlbumModel( 0 ); } + void AlbumProxyModel::setSourceModel( QAbstractItemModel* sourceModel ) { @@ -48,6 +49,7 @@ AlbumProxyModel::setSourceModel( QAbstractItemModel* sourceModel ) Q_ASSERT( false ); } + void AlbumProxyModel::setSourceAlbumModel( AlbumModel* sourceModel ) { diff --git a/src/libtomahawk/playlist/artistview.cpp b/src/libtomahawk/playlist/artistview.cpp index c6fa45c9e..d2502fd95 100644 --- a/src/libtomahawk/playlist/artistview.cpp +++ b/src/libtomahawk/playlist/artistview.cpp @@ -120,7 +120,7 @@ ArtistView::setTreeModel( TreeModel* model ) if ( m_proxyModel ) { - m_proxyModel->setSourceModel( model ); + m_proxyModel->setSourceTreeModel( model ); m_proxyModel->sort( 0 ); } diff --git a/src/libtomahawk/playlist/dynamic/DynamicModel.h b/src/libtomahawk/playlist/dynamic/DynamicModel.h index ed8f6feeb..5c56d613f 100644 --- a/src/libtomahawk/playlist/dynamic/DynamicModel.h +++ b/src/libtomahawk/playlist/dynamic/DynamicModel.h @@ -27,7 +27,6 @@ namespace Tomahawk class StationModelItem; - /** * Extends PlaylistModel with support for handling stations */ @@ -55,6 +54,9 @@ public: // a batchof static tracks wre generated void tracksGenerated( const QList< query_ptr > entries, int limitResolvedTo = -1 ); + + using PlaylistModel::loadPlaylist; + signals: void collapseFromTo( int startRow, int num ); void checkForOverflow(); @@ -62,6 +64,7 @@ signals: void trackGenerationFailure( const QString& msg ); void tracksAdded(); + private slots: void newTrackGenerated( const Tomahawk::query_ptr& query ); @@ -69,6 +72,7 @@ private slots: void newTrackLoading(); void filteringTrackResolved( bool successful ); + private: void filterUnresolved( const QList< query_ptr >& entries ); void addToPlaylist( const QList< query_ptr >& entries, bool clearFirst ); diff --git a/src/libtomahawk/playlist/queueproxymodel.cpp b/src/libtomahawk/playlist/queueproxymodel.cpp index c52fb2c88..8fbff81b9 100644 --- a/src/libtomahawk/playlist/queueproxymodel.cpp +++ b/src/libtomahawk/playlist/queueproxymodel.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 @@ -47,13 +47,12 @@ QueueProxyModel::siblingItem( int itemsAway ) setCurrentIndex( QModelIndex() ); Tomahawk::result_ptr res = PlaylistProxyModel::siblingItem( itemsAway ); - qDebug() << "new rowcount:" << rowCount( QModelIndex() ); - removeIndex( currentIndex() ); return res; } + void QueueProxyModel::onTrackCountChanged( unsigned int count ) { diff --git a/src/libtomahawk/playlist/queueproxymodel.h b/src/libtomahawk/playlist/queueproxymodel.h index e7fc1826d..16dd5273e 100644 --- a/src/libtomahawk/playlist/queueproxymodel.h +++ b/src/libtomahawk/playlist/queueproxymodel.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,6 +35,8 @@ public: virtual Tomahawk::result_ptr siblingItem( int itemsAway ); + using PlaylistProxyModel::siblingItem; + private slots: void onTrackCountChanged( unsigned int count ); }; diff --git a/src/libtomahawk/playlist/treeproxymodel.cpp b/src/libtomahawk/playlist/treeproxymodel.cpp index 2f04dcb84..b1e3450b5 100644 --- a/src/libtomahawk/playlist/treeproxymodel.cpp +++ b/src/libtomahawk/playlist/treeproxymodel.cpp @@ -37,19 +37,27 @@ TreeProxyModel::TreeProxyModel( QObject* parent ) setSortCaseSensitivity( Qt::CaseInsensitive ); setDynamicSortFilter( true ); - setSourceModel( 0 ); + setSourceTreeModel( 0 ); } void -TreeProxyModel::setSourceModel( TreeModel* sourceModel ) +TreeProxyModel::setSourceModel( QAbstractItemModel* sourceModel ) +{ + Q_UNUSED( sourceModel ); + qDebug() << "Explicitly use setSourceTreeModel instead"; + Q_ASSERT( false ); +} + + +void +TreeProxyModel::setSourceTreeModel( TreeModel* sourceModel ) { m_model = sourceModel; if ( m_model && m_model->metaObject()->indexOfSignal( "trackCountChanged(uint)" ) > -1 ) connect( m_model, SIGNAL( trackCountChanged( unsigned int ) ), SIGNAL( sourceTrackCountChanged( unsigned int ) ) ); - QSortFilterProxyModel::setSourceModel( sourceModel ); } diff --git a/src/libtomahawk/playlist/treeproxymodel.h b/src/libtomahawk/playlist/treeproxymodel.h index 5e33ddcb3..68deab1be 100644 --- a/src/libtomahawk/playlist/treeproxymodel.h +++ b/src/libtomahawk/playlist/treeproxymodel.h @@ -34,7 +34,8 @@ public: explicit TreeProxyModel( QObject* parent = 0 ); virtual TreeModel* sourceModel() const { return m_model; } - virtual void setSourceModel( TreeModel* sourceModel ); + virtual void setSourceTreeModel( TreeModel* sourceModel ); + virtual void setSourceModel( QAbstractItemModel* sourceModel ); virtual QPersistentModelIndex currentIndex() const { return mapFromSource( m_model->currentItem() ); } virtual void setCurrentIndex( const QModelIndex& index ) { m_model->setCurrentItem( mapToSource( index ) ); } diff --git a/src/sip/jabber/CMakeLists.txt b/src/sip/jabber/CMakeLists.txt index a7cd6992e..98815219c 100644 --- a/src/sip/jabber/CMakeLists.txt +++ b/src/sip/jabber/CMakeLists.txt @@ -16,8 +16,6 @@ set( jabberSources set( jabberHeaders jabber.h - tomahawksipmessage.h - tomahawksipmessagefactory.h avatarmanager.h xmlconsole.h ) diff --git a/src/sip/jabber/googlewrapper/CMakeLists.txt b/src/sip/jabber/googlewrapper/CMakeLists.txt index 3ebd653e0..6f9e310c7 100644 --- a/src/sip/jabber/googlewrapper/CMakeLists.txt +++ b/src/sip/jabber/googlewrapper/CMakeLists.txt @@ -3,8 +3,6 @@ set( googleHeaders ../jabber.h - ../tomahawksipmessage.h - ../tomahawksipmessagefactory.h ../avatarmanager.h ../xmlconsole.h googlewrapper.h ) diff --git a/src/sip/jabber/jabber.h b/src/sip/jabber/jabber.h index f77d6bda3..8462b1092 100644 --- a/src/sip/jabber/jabber.h +++ b/src/sip/jabber/jabber.h @@ -133,6 +133,8 @@ private: bool presenceMeansOnline( Jreen::Presence::Type p ); void handlePeerStatus( const Jreen::JID &jid, Jreen::Presence::Type presenceType ); + using SipPlugin::errorMessage; + QMenu* m_menu; XmlConsole* m_xmlConsole; QString m_currentUsername; From 6be00f832dd56ad946ce8057351045a58ef003a2 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Fri, 24 Jun 2011 11:48:44 +0200 Subject: [PATCH 24/86] * Removed un-moc-able headers in thirdparty/qtweetlib. --- thirdparty/qtweetlib/CMakeLists.txt | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/thirdparty/qtweetlib/CMakeLists.txt b/thirdparty/qtweetlib/CMakeLists.txt index 8057ae945..952404ee2 100644 --- a/thirdparty/qtweetlib/CMakeLists.txt +++ b/thirdparty/qtweetlib/CMakeLists.txt @@ -94,17 +94,14 @@ set(TOMAHAWK_QTWEETLIB_HEADERS QTweetLib/src/oauth.h QTweetLib/src/oauthtwitter.h QTweetLib/src/qtweetfriendstimeline.h - QTweetLib/src/qtweetlib_global.h QTweetLib/src/qtweethometimeline.h QTweetLib/src/qtweetmentions.h QTweetLib/src/qtweetnetbase.h QTweetLib/src/qtweetretweetbyme.h QTweetLib/src/qtweetretweetsofme.h QTweetLib/src/qtweetretweettome.h - QTweetLib/src/qtweetstatus.h QTweetLib/src/qtweetstatusshow.h QTweetLib/src/qtweetstatusupdate.h - QTweetLib/src/qtweetuser.h QTweetLib/src/qtweetusertimeline.h QTweetLib/src/qtweetstatusdestroy.h QTweetLib/src/qtweetstatusretweet.h @@ -113,11 +110,9 @@ set(TOMAHAWK_QTWEETLIB_HEADERS QTweetLib/src/qtweetuserlookup.h QTweetLib/src/qtweetdirectmessages.h QTweetLib/src/qtweetuserstream.h - QTweetLib/src/qtweetdmstatus.h QTweetLib/src/qtweetusersearch.h QTweetLib/src/qtweetuserstatusesfriends.h QTweetLib/src/qtweetuserstatusesfollowers.h - QTweetLib/src/qtweetlist.h QTweetLib/src/qtweetlistcreate.h QTweetLib/src/qtweetlistupdate.h QTweetLib/src/qtweetlistgetlists.h @@ -145,20 +140,11 @@ set(TOMAHAWK_QTWEETLIB_HEADERS QTweetLib/src/qtweetfavoritescreate.h QTweetLib/src/qtweetfavoritesdestroy.h QTweetLib/src/qtweetsearch.h - QTweetLib/src/qtweetsearchresult.h - QTweetLib/src/qtweetsearchpageresults.h - QTweetLib/src/qtweetplace.h QTweetLib/src/qtweetgeoreversegeocode.h QTweetLib/src/qtweetgeosearch.h QTweetLib/src/qtweetgeosimilarplaces.h QTweetLib/src/qtweetgeoplaceid.h QTweetLib/src/qtweetgeoplacecreate.h - QTweetLib/src/qtweetgeocoord.h - QTweetLib/src/qtweetgeoboundingbox.h - QTweetLib/src/qtweetconvert.h - QTweetLib/src/qtweetentityurl.h - QTweetLib/src/qtweetentityhashtag.h - QTweetLib/src/qtweetentityusermentions.h QTweetLib/src/qtweetblocksblocking.h QTweetLib/src/qtweetblocksblockingids.h QTweetLib/src/qtweetblockscreate.h From f3ba4beffce99171b5daba0e2e9d15013457c9e0 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Fri, 24 Jun 2011 12:26:44 -0400 Subject: [PATCH 25/86] Only emit if there are actually results --- src/libtomahawk/sourceplaylistinterface.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libtomahawk/sourceplaylistinterface.cpp b/src/libtomahawk/sourceplaylistinterface.cpp index c25e53583..bf1836228 100644 --- a/src/libtomahawk/sourceplaylistinterface.cpp +++ b/src/libtomahawk/sourceplaylistinterface.cpp @@ -117,5 +117,6 @@ void SourcePlaylistInterface::resolvingFinished( bool hasResults ) { qDebug() << Q_FUNC_INFO << " and has results? : " << (hasResults ? "true" : "false"); - emit nextTrackReady(); + if ( hasResults ) + emit nextTrackReady(); } \ No newline at end of file From 3b0292d9d9af59ab4395706ed27fc4f94b794b5a Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Fri, 24 Jun 2011 12:57:42 -0400 Subject: [PATCH 26/86] Cleanup --- src/libtomahawk/audio/audioengine.cpp | 53 +++++++++++++-------------- src/libtomahawk/audio/audioengine.h | 5 ++- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/libtomahawk/audio/audioengine.cpp b/src/libtomahawk/audio/audioengine.cpp index d598ab02a..f3f6362b6 100644 --- a/src/libtomahawk/audio/audioengine.cpp +++ b/src/libtomahawk/audio/audioengine.cpp @@ -135,7 +135,7 @@ AudioEngine::pause() void -AudioEngine::stop( bool sendNotification ) +AudioEngine::stop() { qDebug() << Q_FUNC_INFO; @@ -147,20 +147,19 @@ AudioEngine::stop( bool sendNotification ) setCurrentTrack( Tomahawk::result_ptr() ); emit stopped(); - if ( sendNotification ) + Tomahawk::InfoSystem::InfoMap map; + map[ Tomahawk::InfoSystem::InfoNowStopped ] = QVariant(); + + if ( m_waitingOnNewTrack ) + sendWaitingNotification(); + else if ( TomahawkSettings::instance()->verboseNotifications() ) { - Tomahawk::InfoSystem::InfoMap map; - map[ Tomahawk::InfoSystem::InfoNowStopped ] = QVariant(); - - if ( TomahawkSettings::instance()->verboseNotifications() ) - { - Tomahawk::InfoSystem::InfoCriteriaHash stopInfo; - stopInfo["message"] = QString( "Tomahawk is stopped." ); - map[ Tomahawk::InfoSystem::InfoNotifyUser ] = QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( stopInfo ); - } - - Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( s_aeInfoIdentifier, map ); + Tomahawk::InfoSystem::InfoCriteriaHash stopInfo; + stopInfo["message"] = QString( "Tomahawk is stopped." ); + map[ Tomahawk::InfoSystem::InfoNotifyUser ] = QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( stopInfo ); } + + Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( s_aeInfoIdentifier, map ); } @@ -238,6 +237,17 @@ AudioEngine::mute() } +void +AudioEngine::sendWaitingNotification() const +{ + Tomahawk::InfoSystem::InfoCriteriaHash retryInfo; + retryInfo["message"] = QString( "The current track could not be resolved. Tomahawk will pick back up with the next resolvable track from this source." ); + Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( + s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNotifyUser, + QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( retryInfo ) ); +} + + void AudioEngine::onTrackAboutToFinish() { @@ -381,16 +391,9 @@ AudioEngine::loadNextTrack() loadTrack( result ); else { - stop( false ); if ( m_playlist && m_playlist->retryMode() == Tomahawk::PlaylistInterface::Retry ) - { m_waitingOnNewTrack = true; - Tomahawk::InfoSystem::InfoCriteriaHash retryInfo; - retryInfo["message"] = QString( "The current track could not be resolved. Tomahawk will pick back up with the next resolvable track..." ); - Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( - s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNotifyUser, - QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( retryInfo ) ); - } + stop(); } } @@ -408,14 +411,10 @@ AudioEngine::playItem( Tomahawk::PlaylistInterface* playlist, const Tomahawk::re if ( !result.isNull() ) loadTrack( result ); - else if ( m_playlist->retryMode() == PlaylistInterface::Retry ) + else if ( m_playlist && m_playlist->retryMode() == PlaylistInterface::Retry ) { m_waitingOnNewTrack = true; - Tomahawk::InfoSystem::InfoCriteriaHash retryInfo; - retryInfo["message"] = QString( "The current track could not be resolved. Tomahawk will pick back up with the next resolvable track..." ); - Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( - s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNotifyUser, - QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( retryInfo ) ); + stop(); } } diff --git a/src/libtomahawk/audio/audioengine.h b/src/libtomahawk/audio/audioengine.h index c92b9df70..dea60d648 100644 --- a/src/libtomahawk/audio/audioengine.h +++ b/src/libtomahawk/audio/audioengine.h @@ -60,12 +60,12 @@ public: Tomahawk::PlaylistInterface* playlist() const { return m_playlist; } Tomahawk::result_ptr currentTrack() const { return m_currentTrack; } - + public slots: void playPause(); void play(); void pause(); - void stop( bool sendNotification = true ); + void stop(); void previous(); void next(); @@ -117,6 +117,7 @@ private slots: private: bool isHttpResult( const QString& ) const; bool isLocalResult( const QString& ) const; + void sendWaitingNotification() const; bool m_isPlayingHttp; QSharedPointer m_input; From 2dad4fbe2ca364f4a0d0a6fb0187ad7c7bb40004 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sat, 25 Jun 2011 01:39:35 +0200 Subject: [PATCH 27/86] * Fixed broken splitter-handle on OS X. --- src/libtomahawk/widgets/welcomewidget.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libtomahawk/widgets/welcomewidget.cpp b/src/libtomahawk/widgets/welcomewidget.cpp index fd40744fb..f288f6714 100644 --- a/src/libtomahawk/widgets/welcomewidget.cpp +++ b/src/libtomahawk/widgets/welcomewidget.cpp @@ -47,6 +47,8 @@ WelcomeWidget::WelcomeWidget( QWidget* parent ) { ui->setupUi( this ); + ui->splitter->setHandleWidth( 1 ); + WelcomePlaylistModel* model = new WelcomePlaylistModel( this ); model->setMaxPlaylists( HISTORY_PLAYLIST_ITEMS ); From 54296986618f9965179e71257ed96d845ec5d76a Mon Sep 17 00:00:00 2001 From: Jason Herskowitz Date: Fri, 24 Jun 2011 20:16:37 -0400 Subject: [PATCH 28/86] Icon for home screen/dashboard. Needs to be wired up. --- data/images/dashboard.png | Bin 0 -> 6535 bytes resource.qrc | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 data/images/dashboard.png create mode 100644 resource.qrc diff --git a/data/images/dashboard.png b/data/images/dashboard.png new file mode 100644 index 0000000000000000000000000000000000000000..643cab3272f47b98697b84eda37920b867262b79 GIT binary patch literal 6535 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 Date: Wed, 22 Jun 2011 00:49:52 -0500 Subject: [PATCH 29/86] Database command for loading social actions. Used for allowing a result to be aware of whether or not it has various social attributes. e.g. loved. --- src/audiocontrols.cpp | 34 +++++++-- src/audiocontrols.h | 2 +- src/libtomahawk/CMakeLists.txt | 2 + src/libtomahawk/database/databasecommand.cpp | 1 + .../databasecommand_loadsocialactions.cpp | 74 +++++++++++++++++++ .../databasecommand_loadsocialactions.h | 73 ++++++++++++++++++ src/libtomahawk/result.cpp | 49 ++++++++++++ src/libtomahawk/result.h | 24 +++++- 8 files changed, 252 insertions(+), 7 deletions(-) create mode 100644 src/libtomahawk/database/databasecommand_loadsocialactions.cpp create mode 100644 src/libtomahawk/database/databasecommand_loadsocialactions.h diff --git a/src/audiocontrols.cpp b/src/audiocontrols.cpp index b6c77d682..42cc30ad7 100644 --- a/src/audiocontrols.cpp +++ b/src/audiocontrols.cpp @@ -80,6 +80,7 @@ AudioControls::AudioControls( QWidget* parent ) ui->volumeLowButton->setPixmap( RESPATH "images/volume-icon-muted.png" ); ui->volumeHighButton->setPixmap( RESPATH "images/volume-icon-full.png" ); ui->loveButton->setPixmap( RESPATH "images/not-loved.png" ); + ui->loveButton->setCheckable( true ); ui->ownerLabel->setForegroundRole( QPalette::Dark ); ui->metaDataArea->setStyleSheet( "QWidget#metaDataArea {\nborder-width: 4px;\nborder-image: url(" RESPATH "images/now-playing-panel.png) 4 4 4 4 stretch stretch; }" ); @@ -151,7 +152,7 @@ AudioControls::AudioControls( QWidget* parent ) connect( ui->artistTrackLabel, SIGNAL( clickedArtist() ), SLOT( onArtistClicked() ) ); connect( ui->artistTrackLabel, SIGNAL( clickedTrack() ), SLOT( onTrackClicked() ) ); connect( ui->albumLabel, SIGNAL( clickedAlbum() ), SLOT( onAlbumClicked() ) ); - connect( ui->loveButton, SIGNAL( clicked() ), SLOT( onLoveButtonClicked() ) ); + connect( ui->loveButton, SIGNAL( clicked( bool ) ), SLOT( onLoveButtonClicked( bool ) ) ); // connect( AudioEngine::instance(), SIGNAL( loading( Tomahawk::result_ptr ) ), SLOT( onPlaybackLoading( Tomahawk::result_ptr ) ) ); @@ -282,7 +283,6 @@ AudioControls::onPlaybackLoading( const Tomahawk::result_ptr& result ) ui->albumLabel->setResult( result ); ui->ownerLabel->setText( result->friendlySource() ); ui->coverImage->setPixmap( m_defaultCover ); - ui->loveButton->setVisible( true ); ui->timeLabel->setText( TomahawkUtils::timeToString( 0 ) ); ui->timeLeftLabel->setText( "-" + TomahawkUtils::timeToString( result->duration() ) ); @@ -298,6 +298,19 @@ AudioControls::onPlaybackLoading( const Tomahawk::result_ptr& result ) ui->pauseButton->setVisible( true ); ui->playPauseButton->setVisible( false ); ui->playPauseButton->setEnabled( false ); + + result->loadSocialActions(); + ui->loveButton->setVisible( true ); + if ( result->loved() ) + { + ui->loveButton->setPixmap( RESPATH "images/loved.png" ); + ui->loveButton->setChecked( true ); + } + else + { + ui->loveButton->setPixmap( RESPATH "images/not-loved.png" ); + ui->loveButton->setChecked( false ); + } } @@ -346,6 +359,7 @@ AudioControls::onPlaybackStopped() ui->pauseButton->setEnabled( false ); ui->playPauseButton->setEnabled( true ); ui->playPauseButton->setVisible( true ); + ui->loveButton->setVisible( false ); /* m_pauseAction->setEnabled( false ); m_playAction->setEnabled( true ); */ @@ -489,7 +503,7 @@ AudioControls::onTrackClicked() void -AudioControls::onLoveButtonClicked() +AudioControls::onLoveButtonClicked( bool checked ) { Tomahawk::InfoSystem::InfoCriteriaHash trackInfo; trackInfo["title"] = m_currentTrack->track(); @@ -500,7 +514,17 @@ AudioControls::onLoveButtonClicked() s_acInfoIdentifier, Tomahawk::InfoSystem::InfoLove, QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ) ); - DatabaseCommand_SocialAction* cmd = new DatabaseCommand_SocialAction( m_currentTrack, QString( "Love" ) ); - Database::instance()->enqueue( QSharedPointer(cmd) ); + if ( checked ) + { + DatabaseCommand_SocialAction* cmd = new DatabaseCommand_SocialAction( m_currentTrack, QString( "Love" ), QString( "true") ); + Database::instance()->enqueue( QSharedPointer(cmd) ); + ui->loveButton->setPixmap( RESPATH "images/loved.png" ); + } + else + { + DatabaseCommand_SocialAction* cmd = new DatabaseCommand_SocialAction( m_currentTrack, QString( "Love" ), QString( "false" ) ); + Database::instance()->enqueue( QSharedPointer(cmd) ); + ui->loveButton->setPixmap( RESPATH "images/not-loved.png" ); + } } diff --git a/src/audiocontrols.h b/src/audiocontrols.h index a74bd4925..74e611e2e 100644 --- a/src/audiocontrols.h +++ b/src/audiocontrols.h @@ -65,7 +65,7 @@ private slots: void onArtistClicked(); void onAlbumClicked(); void onTrackClicked(); - void onLoveButtonClicked(); + void onLoveButtonClicked( bool ); void infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ); void infoSystemFinished( QString target ); diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index ee138e099..da15df272 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -82,6 +82,7 @@ set( libSources database/databasecommand_addclientauth.cpp database/databasecommand_clientauthvalid.cpp database/databasecommand_socialaction.cpp + database/databasecommand_loadsocialactions.cpp database/database.cpp infosystem/infosystemcache.cpp @@ -250,6 +251,7 @@ set( libHeaders database/databasecommand_addclientauth.h database/databasecommand_clientauthvalid.h database/databasecommand_socialaction.h + database/databasecommand_loadsocialactions.h infosystem/infosystem.h infosystem/infosystemworker.h diff --git a/src/libtomahawk/database/databasecommand.cpp b/src/libtomahawk/database/databasecommand.cpp index 92843b4f8..7537bd121 100644 --- a/src/libtomahawk/database/databasecommand.cpp +++ b/src/libtomahawk/database/databasecommand.cpp @@ -31,6 +31,7 @@ #include "databasecommand_deletedynamicplaylist.h" #include "databasecommand_setdynamicplaylistrevision.h" #include "databasecommand_socialaction.h" +#include "databasecommand_loadsocialactions.h" DatabaseCommand::DatabaseCommand( QObject* parent ) diff --git a/src/libtomahawk/database/databasecommand_loadsocialactions.cpp b/src/libtomahawk/database/databasecommand_loadsocialactions.cpp new file mode 100644 index 000000000..61b949bea --- /dev/null +++ b/src/libtomahawk/database/databasecommand_loadsocialactions.cpp @@ -0,0 +1,74 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Christopher Reichert + * + * 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_loadsocialactions.h" + +#include + +#include "database/database.h" +#include "databaseimpl.h" +#include "network/servent.h" +#include "result.h" + +using namespace Tomahawk; + + +void +DatabaseCommand_LoadSocialActions::exec( DatabaseImpl* dbi ) +{ + qDebug() << Q_FUNC_INFO; + Q_ASSERT( !source().isNull() ); + + TomahawkSqlQuery query = dbi->newquery(); + + QVariant srcid = source()->isLocal() ? QVariant( QVariant::Int ) : source()->id(); + + bool isnew; + int artid = dbi->artistId( m_artist, isnew ); + if( artid < 1 ) + return; + + int trkid = dbi->trackId( artid, m_track, isnew ); + if( trkid < 1 ) + return; + + QString whereToken; + whereToken = QString( "WHERE id IS %1" ).arg( trkid ); + + QString sql = QString( + "SELECT k, v, timestamp, source " + "FROM social_attributes %1 " + "ORDER BY timestamp ASC" ).arg( whereToken ); + + query.prepare( sql ); + query.exec(); + + QList< Tomahawk::SocialAction > allSocialActions; + while ( query.next() ) { + Tomahawk::SocialAction action; + action.action = query.value( 0 ); // action + action.value = query.value( 1 ); // comment + action.timestamp = query.value( 2 ); // timestamp + action.source = query.value( 3 ); // source + + allSocialActions.append( action ); + } + + m_result->setAllSocialActions( allSocialActions ); +} + diff --git a/src/libtomahawk/database/databasecommand_loadsocialactions.h b/src/libtomahawk/database/databasecommand_loadsocialactions.h new file mode 100644 index 000000000..7d80bcd89 --- /dev/null +++ b/src/libtomahawk/database/databasecommand_loadsocialactions.h @@ -0,0 +1,73 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2011, Christopher Reichert + * + * 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_LOADSOCIALACTIONS_H +#define DATABASECOMMAND_LOADSOCIALACTIONS_H + +#include +#include +#include "database/databasecommand.h" + +#include "sourcelist.h" +#include "typedefs.h" +#include "artist.h" +#include "result.h" + +#include "dllmacro.h" + + +class DLLEXPORT DatabaseCommand_LoadSocialActions : public DatabaseCommand +{ +Q_OBJECT + +public: + + explicit DatabaseCommand_LoadSocialActions( QObject* parent = 0 ) + : DatabaseCommand( parent ) + {} + + + explicit DatabaseCommand_LoadSocialActions( Tomahawk::Result* result, QObject* parent = 0 ) + : DatabaseCommand( parent ), m_result( result ) + { + setSource( SourceList::instance()->getLocal() ); + setArtist( result->artist()->name() ); + setTrack( result->track() ); + } + + virtual QString commandname() const { return "loadsocialactions"; } + + virtual void exec( DatabaseImpl* ); + + QString artist() const { return m_artist; } + void setArtist( const QString& s ) { m_artist = s; } + + QString track() const { return m_track; } + void setTrack( const QString& s ) { m_track = s; } + +signals: + void done( QList< Tomahawk::SocialAction >& allSocialActions ); + +private: + Tomahawk::Result* m_result; + QString m_artist; + QString m_track; + +}; + +#endif // DATABASECOMMAND_LOADSOCIALACTIONS_H diff --git a/src/libtomahawk/result.cpp b/src/libtomahawk/result.cpp index 9bfae38f7..1336834c5 100644 --- a/src/libtomahawk/result.cpp +++ b/src/libtomahawk/result.cpp @@ -20,10 +20,12 @@ #include "album.h" #include "collection.h" +#include "database/database.h" #include "database/databasecommand_resolve.h" #include "database/databasecommand_alltracks.h" #include "database/databasecommand_addfiles.h" #include "database/databasecommand_loadfile.h" +#include "database/databasecommand_loadsocialactions.h" using namespace Tomahawk; @@ -166,6 +168,53 @@ Result::onOffline() } +void +Result::loadSocialActions() +{ + DatabaseCommand_LoadSocialActions* cmd = new DatabaseCommand_LoadSocialActions( this ); + connect( cmd, SIGNAL( finished() ), SLOT( onSocialActionsLoaded() )); + Database::instance()->enqueue( QSharedPointer(cmd) ); +} + + +void Result::onSocialActionsLoaded() +{ + parseSocialActions(); +} + + +void +Result::setAllSocialActions(QList< SocialAction > socialActions) +{ + m_allSocialActions = socialActions; +} + + +QList< SocialAction > +Result::allSocialActions() +{ + return m_allSocialActions; +} + + +void +Result::parseSocialActions() +{ + QListIterator< Tomahawk::SocialAction > it( m_allSocialActions ); + unsigned int highestTimestamp = 0; + + while ( it.hasNext() ) + { + Tomahawk::SocialAction socialAction; + socialAction = it.next(); + if ( socialAction.timestamp.toUInt() > highestTimestamp ) + { + m_currentSocialActions[ socialAction.action.toString() ] = socialAction.value.toBool(); + } + } +} + + void Result::setArtist( const Tomahawk::artist_ptr& artist ) { diff --git a/src/libtomahawk/result.h b/src/libtomahawk/result.h index ed4e5cbfd..928319720 100644 --- a/src/libtomahawk/result.h +++ b/src/libtomahawk/result.h @@ -36,6 +36,16 @@ class DatabaseCommand_LoadFile; namespace Tomahawk { + +struct SocialAction +{ + QVariant action; + QVariant value; + QVariant timestamp; + QVariant source; +}; + + class DLLEXPORT Result : public QObject { Q_OBJECT @@ -71,6 +81,8 @@ public: unsigned int albumpos() const { return m_albumpos; } unsigned int modificationTime() const { return m_modtime; } int year() const { return m_year; } + bool loved() { return m_currentSocialActions[ "Love" ].toBool(); } + QList< Tomahawk::SocialAction > allSocialActions(); void setScore( float score ) { m_score = score; } void setId( unsigned int id ) { m_id = id; } @@ -88,12 +100,18 @@ public: void setAlbumPos( unsigned int albumpos ) { m_albumpos = albumpos; } void setModificationTime( unsigned int modtime ) { m_modtime = modtime; } void setYear( unsigned int year ) { m_year = year; } - + void setLoved( bool loved ) { m_currentSocialActions[ "Loved" ] = loved; } + void setAllSocialActions( QList< Tomahawk::SocialAction > socialActions ); + + void loadSocialActions(); QVariantMap attributes() const { return m_attributes; } void setAttributes( const QVariantMap& map ) { m_attributes = map; updateAttributes(); } unsigned int dbid() const { return m_id; } +public slots: + void onSocialActionsLoaded(); + signals: // emitted when the collection this result comes from is going offline/online: void statusChanged(); @@ -104,6 +122,7 @@ private slots: private: void updateAttributes(); + void parseSocialActions(); mutable RID m_rid; collection_ptr m_collection; @@ -126,6 +145,9 @@ private: QVariantMap m_attributes; unsigned int m_id; + + QHash< QString, QVariant > m_currentSocialActions; + QList< SocialAction > m_allSocialActions; }; }; //ns From 8e99dbf01ee5c726f4f0db131f49e193e49fd584 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sat, 25 Jun 2011 04:12:16 +0200 Subject: [PATCH 30/86] * Show when a track was played in the recently played tracks history. --- .../database/databasecommand_logplayback.cpp | 2 +- .../databasecommand_playbackhistory.cpp | 4 +-- .../playlist/playlistitemdelegate.cpp | 15 ++++++---- src/libtomahawk/query.cpp | 8 +++++ src/libtomahawk/query.h | 6 ++-- src/libtomahawk/result.cpp | 4 ++- src/libtomahawk/utils/tomahawkutils.cpp | 29 ++++++++++--------- 7 files changed, 42 insertions(+), 26 deletions(-) diff --git a/src/libtomahawk/database/databasecommand_logplayback.cpp b/src/libtomahawk/database/databasecommand_logplayback.cpp index b14ab6e3c..e34ea7809 100644 --- a/src/libtomahawk/database/databasecommand_logplayback.cpp +++ b/src/libtomahawk/database/databasecommand_logplayback.cpp @@ -40,7 +40,7 @@ DatabaseCommand_LogPlayback::postCommitHook() // do not auto resolve this track Tomahawk::query_ptr q = Tomahawk::Query::get( m_artist, m_track, QString() ); - q->setPlayedBy( source() ); + q->setPlayedBy( source(), m_playtime ); if ( m_action == Finished ) { diff --git a/src/libtomahawk/database/databasecommand_playbackhistory.cpp b/src/libtomahawk/database/databasecommand_playbackhistory.cpp index a6c77e534..6e5c3af8d 100644 --- a/src/libtomahawk/database/databasecommand_playbackhistory.cpp +++ b/src/libtomahawk/database/databasecommand_playbackhistory.cpp @@ -67,11 +67,11 @@ DatabaseCommand_PlaybackHistory::exec( DatabaseImpl* dbi ) if ( query.value( 3 ).toUInt() == 0 ) { - q->setPlayedBy( SourceList::instance()->getLocal() ); + q->setPlayedBy( SourceList::instance()->getLocal(), query.value( 1 ).toUInt() ); } else { - q->setPlayedBy( SourceList::instance()->get( query.value( 3 ).toUInt() ) ); + q->setPlayedBy( SourceList::instance()->get( query.value( 3 ).toUInt() ), query.value( 1 ).toUInt() ); } ql << q; diff --git a/src/libtomahawk/playlist/playlistitemdelegate.cpp b/src/libtomahawk/playlist/playlistitemdelegate.cpp index dd9a4ef16..9bfc69445 100644 --- a/src/libtomahawk/playlist/playlistitemdelegate.cpp +++ b/src/libtomahawk/playlist/playlistitemdelegate.cpp @@ -37,6 +37,8 @@ #define PLAYING_ICON QString( RESPATH "images/now-playing-speaker.png" ) +using namespace Tomahawk; + PlaylistItemDelegate::PlaylistItemDelegate( TrackView* parent, TrackProxyModel* proxy ) : QStyledItemDelegate( (QObject*)parent ) @@ -147,6 +149,8 @@ PlaylistItemDelegate::paintShort( QPainter* painter, const QStyleOptionViewItem& QPixmap pixmap; QString artist, track, upperText, lowerText; + source_ptr source = item->query()->playedBy().first; + if ( item->query()->results().count() ) { artist = item->query()->results().first()->artist()->name(); @@ -158,7 +162,7 @@ PlaylistItemDelegate::paintShort( QPainter* painter, const QStyleOptionViewItem& track = item->query()->track(); } - if ( item->query()->playedBy().isNull() ) + if ( source.isNull() ) { upperText = artist; lowerText = track; @@ -166,13 +170,14 @@ PlaylistItemDelegate::paintShort( QPainter* painter, const QStyleOptionViewItem& else { upperText = QString( "%1 - %2" ).arg( artist ).arg( track ); + QString playtime = TomahawkUtils::ageToString( QDateTime::fromTime_t( item->query()->playedBy().second ) ); - if ( item->query()->playedBy() == SourceList::instance()->getLocal() ) - lowerText = QString( "played by you" ); + if ( source == SourceList::instance()->getLocal() ) + lowerText = QString( "played %1 ago by you" ).arg( playtime ); else - lowerText = QString( "played by %1" ).arg( item->query()->playedBy()->friendlyName() ); + lowerText = QString( "played %1 ago by %2" ).arg( playtime ).arg( source->friendlyName() ); - pixmap = item->query()->playedBy()->avatar(); + pixmap = source->avatar(); } if ( pixmap.isNull() ) diff --git a/src/libtomahawk/query.cpp b/src/libtomahawk/query.cpp index 7357bf42a..9281d86e0 100644 --- a/src/libtomahawk/query.cpp +++ b/src/libtomahawk/query.cpp @@ -202,6 +202,14 @@ Query::id() const } +void +Query::setPlayedBy( const Tomahawk::source_ptr& source, unsigned int playtime ) +{ + m_playedBy.first = source; + m_playedBy.second = playtime; +} + + bool Query::resultSorter( const result_ptr& left, const result_ptr& right ) { diff --git a/src/libtomahawk/query.h b/src/libtomahawk/query.h index c28d5bcfb..b0c1b7422 100644 --- a/src/libtomahawk/query.h +++ b/src/libtomahawk/query.h @@ -74,7 +74,7 @@ public: bool isFullTextQuery() const { return !m_fullTextQuery.isEmpty(); } bool resolvingFinished() const { return m_resolveFinished; } - Tomahawk::source_ptr playedBy() const { return m_playedBy; } + QPair< Tomahawk::source_ptr, unsigned int > playedBy() const { return m_playedBy; } Tomahawk::Resolver* currentResolver() const; QList< QWeakPointer< Tomahawk::Resolver > > resolvedBy() const { return m_resolvers; } @@ -94,7 +94,7 @@ public: int duration() const { return m_duration; } void setResolveFinished( bool resolved ) { m_resolveFinished = resolved; } - void setPlayedBy( const Tomahawk::source_ptr& source ) { m_playedBy = source; } + void setPlayedBy( const Tomahawk::source_ptr& source, unsigned int playtime ); signals: void resultsAdded( const QList& ); @@ -139,7 +139,7 @@ private: int m_duration; QString m_resultHint; - Tomahawk::source_ptr m_playedBy; + QPair< Tomahawk::source_ptr, unsigned int > m_playedBy; QList< QWeakPointer< Tomahawk::Resolver > > m_resolvers; mutable QMutex m_mutex; diff --git a/src/libtomahawk/result.cpp b/src/libtomahawk/result.cpp index 1336834c5..c9ceffeb1 100644 --- a/src/libtomahawk/result.cpp +++ b/src/libtomahawk/result.cpp @@ -91,7 +91,9 @@ Result::score() const RID Result::id() const { - Q_ASSERT( !m_rid.isEmpty() ); + if ( m_rid.isEmpty() ) + m_rid = uuid(); + return m_rid; } diff --git a/src/libtomahawk/utils/tomahawkutils.cpp b/src/libtomahawk/utils/tomahawkutils.cpp index 97ce2e572..939cd08a9 100644 --- a/src/libtomahawk/utils/tomahawkutils.cpp +++ b/src/libtomahawk/utils/tomahawkutils.cpp @@ -162,6 +162,7 @@ timeToString( int seconds ) .arg( secs < 10 ? "0" + QString::number( secs ) : QString::number( secs ) ); } + QString ageToString( const QDateTime& time ) { @@ -177,49 +178,49 @@ ageToString( const QDateTime& time ) if ( years ) { if ( years > 1 ) - return QString( "%1 years" ).arg( years ); + return QObject::tr( "%1 years" ).arg( years ); else - return QString( "%1 year" ).arg( years ); + return QObject::tr( "%1 year" ).arg( years ); } if ( months ) { if ( months > 1 ) - return QString( "%1 months" ).arg( months ); + return QObject::tr( "%1 months" ).arg( months ); else - return QString( "%1 month" ).arg( months ); + return QObject::tr( "%1 month" ).arg( months ); } if ( weeks ) { if ( weeks > 1 ) - return QString( "%1 weeks" ).arg( weeks ); + return QObject::tr( "%1 weeks" ).arg( weeks ); else - return QString( "%1 week" ).arg( weeks ); + return QObject::tr( "%1 week" ).arg( weeks ); } if ( days ) { if ( days > 1 ) - return QString( "%1 days" ).arg( days ); + return QObject::tr( "%1 days" ).arg( days ); else - return QString( "%1 day" ).arg( days ); + return QObject::tr( "%1 day" ).arg( days ); } if ( hours ) { if ( hours > 1 ) - return QString( "%1 hours" ).arg( hours ); + return QObject::tr( "%1 hours" ).arg( hours ); else - return QString( "%1 hour" ).arg( hours ); + return QObject::tr( "%1 hour" ).arg( hours ); } if ( mins ) { if ( mins > 1 ) - return QString( "%1 minutes" ).arg( mins ); + return QObject::tr( "%1 minutes" ).arg( mins ); else - return QString( "%1 minute" ).arg( mins ); + return QObject::tr( "%1 minute" ).arg( mins ); } return QString(); @@ -397,10 +398,10 @@ NetworkProxyFactory* proxyFactory() { // Don't use this anywhere! It's provided here for access reasons, but QNAM deletes this at will! - + if ( !s_proxyFactory ) s_proxyFactory = new NetworkProxyFactory(); - + return s_proxyFactory; } From f38031777599ca916a44e281aec4fc0f192a39b9 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sat, 25 Jun 2011 06:04:50 +0200 Subject: [PATCH 31/86] * Fixed ageToString() for time differences below 60 seconds. --- src/libtomahawk/utils/tomahawkutils.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/libtomahawk/utils/tomahawkutils.cpp b/src/libtomahawk/utils/tomahawkutils.cpp index 939cd08a9..8cb25944b 100644 --- a/src/libtomahawk/utils/tomahawkutils.cpp +++ b/src/libtomahawk/utils/tomahawkutils.cpp @@ -219,11 +219,9 @@ ageToString( const QDateTime& time ) { if ( mins > 1 ) return QObject::tr( "%1 minutes" ).arg( mins ); - else - return QObject::tr( "%1 minute" ).arg( mins ); } - return QString(); + return QObject::tr( "1 minute" ); } From bdf8a0a353a87daaa007d874e20d45b4037de212 Mon Sep 17 00:00:00 2001 From: Christopher Reichert Date: Sat, 25 Jun 2011 17:43:52 -0500 Subject: [PATCH 32/86] Moved the loveButton to a reasonable place in audiocontrols. Also changed the PlaylistTypeSelectorDlg to not be lop-sided. --- src/audiocontrols.ui | 45 +++++++++++++------ .../widgets/playlisttypeselectordlg.ui | 2 +- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/audiocontrols.ui b/src/audiocontrols.ui index 2a72910b5..76b077b87 100644 --- a/src/audiocontrols.ui +++ b/src/audiocontrols.ui @@ -250,20 +250,37 @@ - - - - - - 0 - 0 - - - - love - - - + + + + + + + + 0 + 0 + + + + love + + + + + + + Qt::Vertical + + + + 20 + 13 + + + + + + diff --git a/src/libtomahawk/widgets/playlisttypeselectordlg.ui b/src/libtomahawk/widgets/playlisttypeselectordlg.ui index bc4cb8e32..3ae6c25df 100644 --- a/src/libtomahawk/widgets/playlisttypeselectordlg.ui +++ b/src/libtomahawk/widgets/playlisttypeselectordlg.ui @@ -6,7 +6,7 @@ 0 0 - 554 + 482 169 From 62df210cdc3bf96c078764cdc4c2eb4145702b25 Mon Sep 17 00:00:00 2001 From: Jason Herskowitz Date: Sat, 25 Jun 2011 20:57:34 -0400 Subject: [PATCH 33/86] Make loved icon a bit darker red --- data/images/loved.png | Bin 4926 -> 3362 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/data/images/loved.png b/data/images/loved.png index 233b076ff605a0bf288c5e3b0d52b556c19f9745..8d735bc924634ad466d8126b05a7270d15ceb1f8 100644 GIT binary patch delta 3348 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 Date: Sat, 25 Jun 2011 21:08:40 -0400 Subject: [PATCH 34/86] Make loved icon right size --- data/images/loved.png | Bin 3362 -> 4926 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/data/images/loved.png b/data/images/loved.png index 8d735bc924634ad466d8126b05a7270d15ceb1f8..72d0b6b3e590fc7d08099442dfa7b1ec6a2097e6 100644 GIT binary patch literal 4926 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 bf&MRVM){48lLOyeLvwtOneJuN!`J^0EXek= delta 3347 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 d3H=rR1+e8nt7G1{Y5)KL07*qoL Date: Sat, 25 Jun 2011 21:03:45 -0500 Subject: [PATCH 35/86] Send UnLove track to LastFm. --- src/audiocontrols.cpp | 12 ++++++++---- .../infoplugins/generic/lastfmplugin.cpp | 19 ++++++++++++++----- .../infoplugins/generic/lastfmplugin.h | 2 +- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/audiocontrols.cpp b/src/audiocontrols.cpp index 42cc30ad7..3ecee5b18 100644 --- a/src/audiocontrols.cpp +++ b/src/audiocontrols.cpp @@ -510,18 +510,22 @@ AudioControls::onLoveButtonClicked( bool checked ) trackInfo["artist"] = m_currentTrack->artist()->name(); trackInfo["album"] = m_currentTrack->album()->name(); - Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( - s_acInfoIdentifier, Tomahawk::InfoSystem::InfoLove, - QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ) ); - if ( checked ) { + Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( + s_acInfoIdentifier, Tomahawk::InfoSystem::InfoLove, + QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ) ); + DatabaseCommand_SocialAction* cmd = new DatabaseCommand_SocialAction( m_currentTrack, QString( "Love" ), QString( "true") ); Database::instance()->enqueue( QSharedPointer(cmd) ); ui->loveButton->setPixmap( RESPATH "images/loved.png" ); } else { + Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( + s_acInfoIdentifier, Tomahawk::InfoSystem::InfoUnLove, + QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ) ); + DatabaseCommand_SocialAction* cmd = new DatabaseCommand_SocialAction( m_currentTrack, QString( "Love" ), QString( "false" ) ); Database::instance()->enqueue( QSharedPointer(cmd) ); ui->loveButton->setPixmap( RESPATH "images/not-loved.png" ); diff --git a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp index f01850b38..ded62fd51 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp @@ -45,8 +45,8 @@ LastFmPlugin::LastFmPlugin() : InfoPlugin() , m_scrobbler( 0 ) { - m_supportedGetTypes << InfoAlbumCoverArt << InfoArtistImages << InfoLove; - m_supportedPushTypes << InfoSubmitScrobble << InfoSubmitNowPlaying << InfoLove; + m_supportedGetTypes << InfoAlbumCoverArt << InfoArtistImages; + m_supportedPushTypes << InfoSubmitScrobble << InfoSubmitNowPlaying << InfoLove << InfoUnLove; /* Your API Key is 7194b85b6d1f424fe1668173a78c0c4a @@ -146,7 +146,8 @@ LastFmPlugin::pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoTy break; case InfoLove: - sendLoveSong( input ); + case InfoUnLove: + sendLoveSong( type, input ); break; default: @@ -201,7 +202,7 @@ LastFmPlugin::scrobble() void -LastFmPlugin::sendLoveSong( QVariant input ) +LastFmPlugin::sendLoveSong( const InfoType type, QVariant input ) { qDebug() << Q_FUNC_INFO; @@ -224,7 +225,15 @@ LastFmPlugin::sendLoveSong( QVariant input ) bool ok; track.setDuration( hash["duration"].toUInt( &ok ) ); track.setSource( lastfm::Track::Player ); - track.love(); + + if ( type == Tomahawk::InfoSystem::InfoLove ) + { + track.love(); + } + else if ( type == Tomahawk::InfoSystem::InfoUnLove ) + { + track.unlove(); + } } diff --git a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.h b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.h index ab194a5b1..597082638 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.h +++ b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.h @@ -67,7 +67,7 @@ private: void scrobble(); void dataError( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData ); - void sendLoveSong( QVariant input ); + void sendLoveSong( const InfoType type, QVariant input ); lastfm::MutableTrack m_track; lastfm::Audioscrobbler* m_scrobbler; From 7bff379d05d98271a60b92064a905fa222f958b1 Mon Sep 17 00:00:00 2001 From: Jason Herskowitz Date: Sat, 25 Jun 2011 22:23:07 -0400 Subject: [PATCH 36/86] Make gray outline of loved icons match source name color --- data/images/loved.png | Bin 4926 -> 4926 bytes data/images/not-loved.png | Bin 4926 -> 4926 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/data/images/loved.png b/data/images/loved.png index 72d0b6b3e590fc7d08099442dfa7b1ec6a2097e6..be660a4aaa69c5d43c530408c287631a0b851c59 100644 GIT binary patch delta 1215 zcmY*YYiJZ#6h3!$GbGvIZqk@ULlSh=))QJnzcac~@9vrN`p$RH zoO{QdW6rr1DVV8zlz(jhcjH9rj=D9W`elWpUcHeb%d&_Uw60I}XWe(9uxXlE1bJNx zk5DK?NPH}W_(Doq3EhM61;k&zj{#pP{4XK%ApMXlz;r{qOJog@-2=&5;q~4oMR_4J znHtJuR>`oGZJMSvG7zBiP`d!?6dq3(IZnAur#GR4P86>Kvvga;wms5uWJuG*P9onF zqJq;z1H)4Kx=iy0@*N;b0kd?rrui#`NHi0bjS-DsA{sT@+aHk-eZYjP1kk&%#Tm4r z>Xds>QF9L?lLL8`v6D^Tl6@Ji4Zv4{DLh5qtsb?2TlGOQj%^=rrsVg)jH1nhO!#|l zaAs>qW!11x4R9+Tth7DS&_eP$2iN^TRG*^;ZhU}%GhxT;Rt^owWcRZ+FWL*1S5)55 zqr5|~N#KXS1Wv$rysF>mn=+$JrToq1#U%%N<2xP>xT6R{u9ag^&$%8V22eA2bC z$Bxg34?4+@ck7MEPuD`bgknGi{cFc-AN2mJ;rQnxe?q~L^31lr9vZ&Yn4VA)cAT5w z0w$DX>eVGUYth$k4hoObi&tHYvDv`z z(2eS%ss)I_<&WJ)SqO5)EaG3Y$rvn0*XLHfwb|$RZq$6^I&XZVqiA_C hCnj$M00N@x6~&3}=c9X$HmqlS-P#RnZfZM^{0|8Ix#s`? delta 1215 zcmY*ZYiJZ#6h3!m986-|jl`%8Hr164?yg9Dv`zgXib4ZMf&_|+@c|XuYJvp(q1F{a zvGhloj98>%N*3x5p``8>U(_nvKmLdql8F&h;-ko>k*=E;ne6Q8cSbjw3vlv7H~S*?6Q z!(eUsy?_}U_Uln72Gxj>3D7VX`IuOE7*jOiWy zvenEFvMFZ_A~smte17(Zjm(sj^>b?V}I*X)(ZTF7`~Y4CpjHJ?2W%F<<$5Y zSNpFC(nk7ri?lDqPh9Q4{#NZ{iKQXY9w_@@wX99v2CNCVi#;z?x;2JVB{iDt8B&`5 z7^k!bm)8YH1J{nst6GWUk=KvVMOqB<=SF|;%ZfB9?HurL#6=2v&Rf>anH&B0mSgJ^#A|> diff --git a/data/images/not-loved.png b/data/images/not-loved.png index be57bb5377a78fe357841ff815d56d5bc79f9973..b2087de3723957bef12a42ba697b5948da23f0d3 100644 GIT binary patch delta 1228 zcmZ9MPe_ze6vf{gYBoi~Oj(Xulck1#B8EzY7Bzz|glMG%ZA?Ky!k|qXgMlETMa64E z2!zCCL9~nhFdxw(B5)BwEh>T{XbZDS7+@H0>=?BXuiXx*RJJ*z{)oPypl`27!b5m%RN+m5h2pOqD)CVvCn;JB$6bC0Rx5W`XKT5BgMUja?Y zgHzxo3s2yS{Sle=0dW;^GvXg=ALz{#Z^-!Vxz=r~3^Ow6p^DXunSM9FrKuOP zlwz+ra9tyqMYGth!zXb~{S@nOfi^Zg!&T^9&UN*YOhWZodf6L(9gVXfW>BjH?{8~- zbI9A(24lgmYnAV+8W{GA>mYEI|AaL46y&_tfZGZ8vwTzk(C|Z}N)(+;1b<^R8q=wR z*2lycUX?e5Z;EIU*E++!i~?vh17A}QuH-`+gY-eX=IW;5Bhv`JsUeM!7zFAfbqt<0 z3`v3ZoW6Q}p+{Z)lx;aew(OvuzU4)*kJGg4;fc@SBm5|@wSp&wx7wX69IpQY{h$>r zdeB*xgunG!^z&MeuC&IZ7m`|B`V>dH;7Oh9>uU0y#w*~kz_~p;7Iuy=j{NM=e;#IN L@btjL^0_PPe5{Fn delta 1227 zcmZXTO-NKx6vxjU2cZud{0Ki#r?4b*%t8<&3<@JOXr-$WMkqppiXhvxm?(%Ax_G$A zMV~OU3Z%^&Txrs(f+*hXA~D2WQM53$^!7XVy*Dnp@ZP=Woc}rJf6lpgp<|)r)#Bdv z+PaoKbMt;uq&hb=cxI%(#*9?I+>m0aEV|e|Z+|KlcU1XeDToo0wC*U99nMIhRPHe% z6R6t6+A_9B=vN|$!xa5;ix_)N#AL9qir6RF;qLb##tQx}chXu}Fh&Nf*hN%pMogDj zIbrigietl>u?YCgT03rx`G^d2+eqX=vcD5!PLcg@7|{<_0BrJgXD@Vbu)9ThX`i$EO zJjOf(JDXsB)70Al^_&JJqvv&Iv_j1ViBZ~<#xkX5C3i_#al;NcS@8$CaA8N-n?iH> zs+u)k-2dsw&>88m?G)|6{IpBpoJjICvSoj&3P`zF&Zs|tQyR38F9qi#g=?2iH;xXV z%GvzjG&&|9yihq_&OrsOnX7S&;{*04uJ- z{XYRfKVCGhyyT40PqU(X17$6AAhv;>`BKx|i!Grn7|?DAe1bgSdaJTiW p3z-Yl*AUK!cM>f+YS4LJYyG#^SB`b~Z=2OJbnfEd+}ZJa{{RA9jV1s9 From 3913611ffacb7ec120d02d7dcca19e9acf899e14 Mon Sep 17 00:00:00 2001 From: Jason Herskowitz Date: Sat, 25 Jun 2011 23:01:18 -0400 Subject: [PATCH 37/86] Temporary preference icon size fix, color tweaks, and added and icon for Post action --- data/images/account-settings.png | Bin 19778 -> 7434 bytes data/images/advanced-settings.png | Bin 19778 -> 7434 bytes data/images/lastfm-settings.png | Bin 19778 -> 7434 bytes data/images/list-add.png | Bin 19778 -> 13368 bytes data/images/list-remove.png | Bin 19778 -> 13368 bytes data/images/music-settings.png | Bin 19778 -> 7434 bytes data/images/post.png | Bin 0 -> 4926 bytes data/images/resolvers-settings.png | Bin 13368 -> 7434 bytes data/images/sipplugin-add.png | Bin 19778 -> 13368 bytes data/images/sipplugin-remove.png | Bin 19778 -> 13368 bytes resources.prc | 0 11 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 data/images/post.png create mode 100644 resources.prc diff --git a/data/images/account-settings.png b/data/images/account-settings.png index 4bef71bb061f768ba087f6667d4f6b26a42d6ca5..45b9e932a1a2811da4c91a0ed9b3b6367277ceaf 100644 GIT binary patch delta 2432 zcmY+Fe`u9u6vv?l=nv+`9Al3Z}Y%;&w0-Ip6_$c z^FHsrr@Fm&)|VaHwzaV!cTuh}rl9GG)OKvCG@8TnwT_NEN6J3RFIp6-DL-f?M~sPA zHKiJ!+7a_g<5zC_D+`lr_wL;b)R^w>ZiBx*olfs#xxw?i0{p+Rr&u2#|5ICAn_(@i zwKe|e(uEsU4$SoQ^r-wR{FLaB3+ONCGW21UA)iqC^gT3{{?!G^wL$qs$^~^W;X{FX zE4d@ATk(sasmH2|OY;+t)2;!l#^;BCn_iAGzcAsO70qT(Ao;MlTYmaAb-Q!!V=ZY6!y8T z(U4eXgp!zMmsDB1ELI^_5Lbh2{HRg{cFWR+wTZ$R!|VyzzVvNDgL^>%?h2qZ8VlAk zSqTX^(IhI|NhR@hBBM)_YjGbUav2>%3pw0z>^(wR5rIF{1AWJt);~~@u)W3EOREEb zsu@_nYJt6n`53*9E~c~%`#h@LI`C)I9af!OnqRhxoplIH&=KJK&~xZ-=ow-vy+Elh ztJWNre;~e`4ib$4lRCJM%m+}tAPDhN%w}`}`a61*@;`~s!MFJBSk>v1vvvt|^PZeR z_ZZo41d*`&E0p+|)&Eb*J6Ii51dL22xE}*rf4F*iJn+?0GZXdu+v{;z4Y} ze-T}d3NyeqU0}Y~h!Tw?31@H%lDzEd?T(em8Bpt7h6l+ZO!!H;Fs%BTVUv6YpmtpAex%1z|_=~*V@`@ zQmK@dS?TQTbpDAGCrn>oU$|3}V1|)S7JD9KtD9>Go}|?~YMGYO$BrHIhK7dB`1rVK zZ+9QHIehrAiN#{(+O=yALygWrzXHbH0SHRmugL0_R~4l9Z*@+nck9+IbN>8!GdMVy zef{_@rkpUU;YAJ0x|y+W5`P!#w-lGz-nmV)m6XtFALbdkkx0aoMx)Vb*0>QpaNT)} z_>dO5Ql1`k#t;9x6epbhK=5Z?NRyYBr@}PX$yt0gIZEw3kx6u&AgX&bykD8H(GSF5 zs0!SD6bYiV9+yKBn(;@gmioN~70ol7A-;f+~qyKd}-_Z|Nc+RotZOd&YW}R%zE$hM(>`HZqC)5 z8DnnIQQi6?4yWK~#&cErGp87H9hM#u(K|XKB49%1_z~%2(-?b}^C;I1w@?-pm!2_R z@?>mW#-z-?kzE6x9+VK^u%AiHiJ4h5#*$MePKbZ1M?bJ*(cL2gCW464Hn?+yamp10 zNA(T}u;Cvo<&`oaa}r~`H>g{rrcF#idM46ir%swc_#&izhmWDOWTbQ^1Vp+DrAI31 zCW1yuhf_LrTt+HrNahKt<5DTT6Y1BdOin}E5Qp@vDd}lbkv@cUy|I(Wr6XO6wC}jI z(C+i>-kFy=9n zvD^c8`uLH*jG8oQLc7q=sZ*zhq^G5XkU@2LB!N!(@Pu7^A=I93yMS(KBa$bNofJSu zO&LFS{N&7li4&4j(gK3-cjCWY(M~KoIhyoM8^NQai zjdJn4=OMj=tTZuwWB{Qf`t}P*nVdO=(iju;FfnK5!F*X&R+H6b4OuX2&f2i{n2fr! z7}ksRV}sZbmcmA{aV(QfWz*RVHjB++@3Ifr0`@7(Vk_Bdww7&R-?44%N4A$8WQW-a zR>;n=%dCjqVHVE019#&-yehB7>+{CEIS=EVcy}Jh`|?427$3$Zzs8$soB(zLLKbD1}O4QWq&!>L(4BMoP~})1;Zw+tNqU zQt3-6SK21+l@3dV(q*aGzzi-1KSOOpup!J4Vd!N@FpMx{8eTNaHq19HHLNylHtaSO z7zzzn40nxYqmMDb7;J2Bj578&rWl_wzG!^YxWM?iG1s`$SYSMDEHYY6Zl)Th#-?_r zXw%cCk*2ApS*H1><)$3dF4JMtIny1p+3aU-U~XfMG7mD3Ha~BE)4bTc#=O;>XFh8# zc5ra0>d@GsqeCx;WQR!(vm8El_|jpEL%zc~hf+ru$6Aif9eX$?IA%D$;yB-NmE#YN z`HtruEl!?J^_|)|^>Rvedd}$`r!1$&oEtcIbnfRo+IfcaN6xFAcRBy& ze9OhfrH)Hmmp(4(E-$-$>_ecN?~>sHraU2nO$xdpm~ zyCt|ya(mltrP~g-Q*Nd1KJFpz(eA14FS##t&vnmtzvkiOQQxDB#}JQc9`ilcc^vS# z;_2iW=o#Ue?D?YSLeEW}M?H(Ze7u@@_3|3$^`_Srz0afGz=J13n7a8BkQa zM(wEDlWTugdw*?9od$LK*LkJRnmQ-zI@b-WJEHEqy4&j()vHx6zTWhDU(`EZ->H6B z{ZaKltiQW{NnnG(fr0-D+z@!7L6rv44W>2tqQP$s-5Pdo_)Np44G%RkHwtSsrqSX? z2ZN-bRzahJ76u(?EH!T3IKA=W#(7OlP1-ieXtK1)(O}o$F2PfRzX(1Z;ujJZ@=C~t zkZYm!LK8yY3*8-RZQ82o*rr)cPc-vx7SrsNW}BPcY#!7+rTN0(D!$dfT5WGt(Yj6R%+{-0Uu;va&9F9$+8hn@4eK5DX4p?{O>Mij zeW~qtZSS^g-ELC5we7CA4{krE{i^mCIyC5z)*-9I*^YHOCU^X-V_~O&PQyAa=~URc zcIV{IOFN$luN$5kzC8SVmquMiclol*wXRLOW_Hc#S`yJN;)RH<-3;9#yUp&lzq@z$ z{@oXJKh>j7kC8pT=us5eD)RZrtx=|^*r@lSjz;@Or$n!eE{bUr^FqwdSl8I6Vi&}o zi3^I$jN2S9#mB_IAOBm=`aLsxZs^5&MfZBY*U8=udOy?q+dk$#z56We^Jm{?eW&-` z{glsBL!Vmp)SZ4^`@PfeME{2UC->hzz+*ttfRzJE26h`bcVOYup-;c?^xi?$2Bi<$ znBb5wAYpkzabowx4-(HMwMv?mbYyUY!OsrfGo;#(u|vKe>M=BV=(=I1VFQP)8djd% zD|u;h@$l&3i-s4aM5KI}ayd0TbzbVlw2o|$F3RYIBwXuO&Q)9V={J*uQ~qN@p%&(Pnb2K@R@ec zeDF+BW^Cs2iG1SVi5n;RVl%aGa>L25O+G!P)0Bl%N~aE(y6#!8XEUDN_gv6(Z#;K? zT90Yj&l{gld4Bu!+S6xDKm9_N7e0HDzc~EG?Jw1RY357kUXFbE^BK-F#?1KTm8P%E zedYG617F=d(|_j6Gta&j`Pvt=+-GIZI{L5n|N8WGzx?xT$#*ZcV0kINT~T5xz_*M(~q)mZe#qLRg_i}ODT z|77*2{-4hIv}{TGl4GAmewMp5aOwPI=4Dfs{h2i&Yj<{7_R8hemd{yUu_9wd;pcrn z-?_5Q%9X2Xta|4Q>5IuLWW%Y$Ea`)cFr;MJe4@mn+JYxeczuP=Qw?3*KNW7lq9 z7q)Ko`ugh^<@n^x&gHq!Z>a}TsRu<>BqgPZd@}8;?311+=bx%^YU%HdeqU4Ay72qc z-A?a2^VFFWXH(8z{$t`F<>zMp>GtRR^R>>eywLo@cNcqHJa{Sb(z(kME?ch5y6Sax z(Y1!x)?W|5zOU%%qH{MgZ^$>_yjAtqirX!3Z!hj$eCp1)JC>5!rBzEmzZ-UUciF(Q z^OmXQ4&@(JG^*HajkW$JkCWw+nYS#13pZnL%*?}MBfBw~{+4{d;(cJ8CPWRwj@reC z0%r>r(bnBzQgnQGhZAOR@6ej9_YJwgSOAOe)}@j^MB8x06#q;do@!gZ9v5b_Do{=lr(ZxiD~ zfm0wmSLLs@hxVy*Qp}Szgrqh2$QZ3_$}ih=5VE6}?3B;S$q(bQJPis>he9|zvQ{9f zkJuN14B&v^2sU))^W%&+09{wmj0EmwS&}Aa8b5dejL_u2VuZ&Z0+6Pho6%ET(v(N%n90X(C|+p zery9|=M=EPn2?fUn$S#+**U)&luAZ2n)Ft+BOMJ$gRiDJQ4@$xrpJTYEK_Lci6sW7 zWf&m=O4EEn6JLcDjnUte263|ft4u%La>O9tsfb3s7?Rc|moS7tJ&GsHa~_7Hss1Dw z+=PKDA&rTX(Xv7lW-nO!7sTrjU{0Cc#ov>L#}fAbMwjIl)PvHmqw-T!26w*-5iL-^ zGP+phiJa&#WP#LsPnItNL5h8kunYJ?Oe{CJ#N1J{4+zHt-w1&izt1E-BPps0`2Tm{ zZ+QSbo|Y@x;1HaJo~xkub*M=jpEk(*K@rki5U7t!i1UEULA-@k$j6gAC`cE^%MR|E?T zL3@On@B-(DGWv%Fk2JtNy{|N8M&vG%GNZ}qvVx`^;USJglAXD<5?f4Tm_XZBQ`+7w z;9b~Z@{2%U2O~ek-WWQxD*RXAkp_4`t278jJqU=gY}MB$+Rp(`iow zTUTnB$BLn}3bNH|#6;+afTOgSXXv6p_cE32iA9ezfYQ=EdfkF|pH)S!hVuGwdm-%O zTv|}iYrU@-HZk^|ncV|CY3(;-KCmMEj*+ELvROGt6_K9M^N|KnCPCZA1E;u4==tMz zCZQ#|alvcb;x%kk^IhSf8-H?VqfG$W*p}pH8hX?1F8lE6L(g6DUuQrOS zs*8~A0J7&*6gEYy-Nt?AZGH?ymU^S3(mXJ_p9Y@f1}0t6<3Yp>liz8C!|*KK1D@nA zkc9dhlOR|TxF40(M}mRNDKxQ<;sJ1 z0Pj99up*bt_8@()i`Y>=iR2?aKx@R_t<5HW3iuoZZ4VHQ^wa3Usv14**kqaRH=z;~ zU6zv%uP9K?^qAVAJeSLC?hJ!9M%_dN@+g7=7-{3+xDeWFV0q2wID%91iNa$W0IsMv zJfM3p?b0@&_j6SwdF&7j&{Qa?&j)Z_nI=Y~LE;7sZt8Xm77?2C(DQOqA4S*f_4!R; zka5^Y^w%4Kfid6g(DNw7jQGUiFSE?b$>T|}p~4#Il^!s{bV$_^G5*O{pyX%h^Cd~K zA&+$3Wt)#klEvB<#vKVB2?%tVLW5&9(ywE+*o&ApR}u{QU)c*h_8g!L0in0<3Q%%0 zgmZz&j!?Q4l=p?a6OnHKPxuCTTpzQ-GE3R@;k{c_>^X3oojQNU!75v^y~SzLQh_ng z;t*g!6=Zy|z}W|y@;X*4f5P!&d4NrMBFC_nt@rc@%KKuRk40e@As>;+;^haO|BoPZ z7RTXYSdI+tfii!P(DF%Rz*Dg(Rl+A5jLpTZ@HWa2(7d6&3xKi7JH!xDO8@y&wE8GE zbRTFxTVodIxX$H+?c5T>p$qtoK#0U#-~}ZGhz2;jfh;X$w5NAN8BTXpq7pIo2kNW? zVgV*k@)`l;`ebhyKqsWm&^A&U-9L#RX#o2MsW$-JULgC%vp3{dhfX~~5{0-W%4nyE zEG-7Q4yxXw=@ZEOjMO?N$r}@+Lv9HA`yP;i7n_RZ5#8I|SMtxZ4>f?;q^Re0YKD%n z;+>$~x($Q)K(A0Ru@reU*)gVr!VdVlz>|B^h9(dO@Ph$xIU)`<#W>;NxGNtA`-8ai z%foH+InhSWAvdg$?ND|{X4ZX!V?s*^Pe4Y%Fq11PD%jATO%>!5cs`Z^$P4JGYk!no zmYW|4MFxXGcgRtK_-hzwCGG=oNuogZy2CE$+3Ij(FJK&0HzAIXs+Wg0CE z9ta*opkpL(r1%<)_vKhJ>25&4a(E!UNx1>SF*u~D9;wd}8r@%s!RkN5()IaFk|emj z?VcSP?cqw)aMc2Sx9foUNZ%C3da?@o$oeC2nidF_0%VKQsb}Avjj*wfqK^`1Ko5zPhhuOhzF{XSA@DP&w(WJox zLA}Pp`?(My9ueW4V1EcW5lSjE6C_6-E=?1jxX=*1z!c+I9Gosey+4t^3e`%f5O|sw zXzx%Rc$zT%5X{sF2?P4Oc))htM0rADByLAb?^$`p`XMo)VhGWygifMr{|NL=5lw*9 zAT2k`Fa#7ba>*T- z>w{wceO1WHp=qN+yP^{n;k804`nu&opc_ED1Hem)`xq32plfK~-kHQwMH0PDk|Ky9 zOl1H;LNpYpoRESF7(uAu=?N12Q;ev*2gQV;kW+2!B4u_6wSGbRB%I<;5YtVOb~i~h zI^cF1Y31mI4wE%~FkICpbkchgx&bsS`ha$BqLF3m^D04V} zmnWek@jVN(V&^Jw0*@7hPOA2x8(| zK}j7>{j1RvArTQMDvL5v&!9F+hR2dBF9*dI9K5ay>iZrmHytx#bL0*t&Z3^oZu6pw zqQt~dL75aEs-GgWFrN_(339*kM64Ttx)BZI*c&1$gKKlj1_y;?+l)*<7xn?umr~w7q}!2C?rK1dtCCAMdJm zs8)$wgp8m)RJ^K}uA??O)M8OX&?xoE(n^uI3qaC>kc}RlJvb&<7hbE4RjDx)k3^kz z;8GuxNhOrIBDko-rxBTl4j3KYMUo@K%LJ>|=1GSH5=9 zaAXy6XQv%EvkP&YKP>eD`USMrOd;g>AqCzBfg^CL%xZ}e0ZFXXA`(s|6b+Cu?n7u< zR3dkuj!wu`S&1ks2WJXy9SWAT0)+^zHU2Ik+D9FZ5COTp*To=89n1T+XOc7G06b2y*(VkvY z$?G+X!1b$gi{S^I6B1c#4`OIqhoEc{;_=9ItFmMp9DvA?JVOyao{0%Zt;~Jox z>|sMFX+aGd(cd5!f5Z#ah&Vrp@a?ePL1LS%F_R_ngS*kl*Ah4kXsSZ(RnQg{!g;zm zu-era5zyHKN3Vd8hW-<^DH6GcAmhkt+1CU+pw;Hl%Q*?n$(C2 z#8S_IIi>Z0LM2UjqO=EvR->S4K@gLKfFgvQ=!{?Ot1Qbo)Ch!$z=>WFl(Yh&5_+0j z%B^(cEZ3;)E;nmfnNjes>`pj_GV%tJhpO59T4vqoBUh{vIE*QvUAfUEz8D6CzQ*xW zDP`Q#EUN)Aw86c(2jdkQp|DB-3=JCO^dO%?ZqJaICO0%DOE(nIF*^pNoirR`D38-5 zaYG^bklAeD-tJE5c}M1fKxyDa8PO0mfRn+L#ed{BeF z=k-Lm9|Q^yVd8t$A=OZ#RZ^O@H4eWN%G+@S>1B+e({?B(Rq)!#ha=DlQ2>}oTF;l4 zTjg?mJ!rLxptXhxQOToB1`T-vO_KL`B>2<>!|Vf+=!z>vLUX)CVdBB1uC~u_ti>TPVgYmI_t| z7boS)EER|=s8j%@ffI@g8kCcvs71T(#Y7=DMPhKwNx~uQzC)F`*FzIqwYYkOQ6&zKfEczvL`-|^A)U=3gn>Ngafyu*$4)* zP~O?m#7su9ffQm;8aSEe05j64BD{hcRQrum#I`bot3e43$N=KtgYkfm7CBY`vBOf7 z5OtKA#8gbf|E{~ey--834s|)%_>KkFdvJ9G z(9_wWMt1HIm&BMLy0T|ROhOcc6?ey&#OH9hu_3V)06l?{7c3Nnj?^h_cr9fs68uzF zN-33L1yU3s6i7_SIiNr+Wu$yrc?I)xa$$`Ee3-A7vr5DJ;70#zrh$*7}%Rlt4{R?}LMh*5_Yc;U2K za`oC?8Ys8L|=y6b7}{nw5*(P9AyY4g7yyT!2fCN3;n4Lzy)N^C`sk1djL3L zN5-i)Y9Y``iY5ta;vPLT1jQPtGrpG9V~tirAWtZ|?j~d3M4%z(hHx8!CgPKbeg{>6 zLW;3~J67sdBQ~r!{RzW3U?*q>PLmAfoOXf;vKhm}fUh&*1>~wU59xh{c8`I-cqNCJ zWv@GAyAi@NbR5?C5RGp@8TtsHbqE`)Gc_Vg32veXi3I>ST@p$P1Zs;U>VQ_%p}LAz z@H+iV(BDA@w^RWiP2()L1-WJj7>>k+-m6e$;)PiZdsp7T+<;TP%`XNQD9*i7}h5jX{EA;x!a-1J ze_XoB?pl<6)aC2=uP?A2rWv0c1%DVTs3*81X6#2Km*R%_gvj9`zJI_T$VmHP0uln1 zU~P~pUJtwB5B^KMsE|N+X-ZQ7S}CEH3Fy5RBBheRC|Ig1ibW^k0oM4laQUjSRH=&M zGf|WkI0&rU9X!#?+Jpd_A%bg-Qb*#>j;kO8Ek@Zf+ zCPAz|=#GzoXJH~pif_WQE*CKNGl@?H3PY7dC@rX|0{+CbqBfu#Mi@$|D~ceBmjB>%S$x|}83W8LG4@yZKX9FTA@<9(sb zKu8ykpu8|ef)pe}5Rl@EB5LR0a{>^2hoa9d<(9R{y_(YoOMH2T`!p*}s@g@c-7-id z|2v>F{*d@k8j5P?VPcL8q2uymd~iv(7zdzaQ}`wwm^=`ip*Y?95!^+f4HVIzfnDh5 z=ef8M&Z9ztC2J3mp{(@IQ%w8{S~Z-S`Tr%t1SMARggD!4tflMoyzrSpQ^*(w(KNxykjrYKbBj|^YL0unJj>y$q!}tm5c4QKhOf!zLB=I T)9ffQHln-t?6$h=uvh*M`Y?<# diff --git a/data/images/advanced-settings.png b/data/images/advanced-settings.png index 85caceeaee560584a97af09abf233224d88b8124..68238ba31a0733a031d0b65e215f15939ccc003b 100644 GIT binary patch delta 2632 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 diff --git a/data/images/lastfm-settings.png b/data/images/lastfm-settings.png index 7f4a4575ccfe516bd49987d69a1e5a881da5ed4f..d6e37184bf068ea5bda671afbdadca03b928fbf1 100644 GIT binary patch delta 2799 zcmZ9OYiv|S6vywj3vB6wKDO;{X`w5Gmr`v(iwH#9BG#6tBnT0rB29hKRQRCPP%%cM zpS(^ap^exGfdoZBiBS;~Ffk_33K~&}hVa4o0yM@7MqvH@XYaHZPIBg)Ij{ej*_pX} zq$l#~?9?ku7A?phT`}78y!_^SnwBA}#j%l$8@jsw-k;i*S6-1-JH9n>dY8)G0&cp68H-`)B5}JokBBXX5&3i*a50d4h^vy5E;uW1FFo3p7#^ zu8^gPBY=;ihcd^oPti&2OS%|{V=hoK;xNft&)grz8=G=?kAt^GfwoJfF;O|wo~$ul z$zt<#G7gtku{0Z#tsqLihL{E0O6+M#_ovKu!Uy5A@I=-#3Mq1%9hQ5s55Q$`eh`DO zt=PC3GiDSF3=Djt<0tCKh@oC>5Fp!G#2U|ky}0&a8oQgQk70G|;NGPBM}llCh|@{g zYL?cQbU%f*LEF{H!nF#Q<^a|LuuXZSO#yH@>InF2?0aO_4w8En6?fzu_R_$<8JUDT zu?>=c1bwc20j0g}Oj2W%3ax>4sClaG2%#Us-$0zpcDHQ`F{kKa3XW6wcPN1QGw7Rw z;1!@>Lf3w~70R_o$p6NHImz<9=V13pJt{*Q2s?Y`#MOnQl(PQK}!qwkEg?I%E|M*SzVArk+?I4_o`VVY(Uv?3(m$Mko zWu}=Cn7Y7u0G~-sPw*z@bfdp4JMF%Ma6i{F?1unM16VIV^ei`+f zF2t^fCETp^t5g`rI`<&|gzbSK{w4IGme5tUR|9pm@luB<-JMP!jevGDCY=eFX(ich zAlPhnZW4a&WDNUp?E6#(dk(hWvE?FH(ZR03zL9x8_IHW>Ca?`+(S{}F=b4rk`x=2m=|%sX8mLD#NQ4g%(Z@;<(Z z=}c7mebs*7C^IJ!%M<#(pny3MFRK*12t>8A7*&sxS`2c_m6%YXsGXpt0uiB`6NMFt z&|Hhx@!H4Hm~Wm;PGzSH3U#>_1A9?0NHeBoTBWiaJbIjrF5*-=*Z0RK27yy^FA{VC z>Gn1A2QJkZ)RM;%^8!+4Q)dDOeTno0=--syn=dHymu#W{+xM&D9d%8!PUh~`-%PK0 M{-UP$8XkP%e}M#?K>z>% literal 19778 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 LwC|g}C(iwU(v|Uh diff --git a/data/images/list-add.png b/data/images/list-add.png index 874ca23c662783f957d9f894ebef38ea93d18496..5fa31752b264befa0c21230527dc7bfc4c0b35fb 100644 GIT binary patch literal 13368 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 D_+nrb diff --git a/data/images/list-remove.png b/data/images/list-remove.png index 6ec777b0d5631772f6ebb2dd5cddc04fa823809f..bd54ca495ea431909d0acc9bd7e74b4a497fde80 100644 GIT binary patch literal 13368 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 TNrSc7aEgn0I=Y}+;*9?QmKclO delta 1644 zcmb7_&rcIU6vuaIw*uKxy0i)emR%tf!lq(k3YbbafxhX^?7TLVABWwh^Zm^Cy_tD$_S?g~*Sh;+ zrM#5vAMMvPEm?j;Mxxjx@WGR>2z^|c_bR>V+z|Q*eVNX}20!8tEKK2XjF$zTl{yyJ;&5m>-AcQ7 zw1%9kq2Q**F|irWdz&9o30M%I4@0#OdY4C8TF6=?ZQwaDcFN#6_0Wb>4_7wSF~`t( z#VI}2p&#+Lb}kF2;KkNUbKvnT_TlSqsLso+S%Ezx#_PNVI3lHRqu0!zi_3Z0354X1 z2*!_yoAMyAAZ{w-$vlJv*wtg0wVn5gx2`=vVvz4Nq@?xmm+D_$Qq^|0RbGaMcD`E; zn6wgaOYB})2is|WU369}K73J)ZfX{fssip-?_JvC*zGl_!X4P2hxayND1Km1N9|o1 zm?cbk6J|>Z-5hZ2>UKEzdg28XWk^^;xeUvm1|+&ApD5iy`hv80Aa(AGfPw^85ilPC vO=l$pHtY)m7&Y&|`o0g9bBli#pi`DI+dp>pCWiLk@OmmOmi5|Ayals4KBf(hZNqHW@n7+*}E zlowDFvp18N&|+<$)R2&pKv177Pdt`j{0c^tKmy@I4S@$qufI8aZhP@0vomMrKmVCC z=iI$8?S8zy{L#L#;kImV)^VJ+k-bCv(Ipix&F_0tQ}@r5XLCKhYpN}SYtC04$KO0M zG0&cc?a@K&7=DDcsA!PC zq6X;lfyKyTX_S;U^B((fW8K2 z7;b4cl`pj0kal)PZPLH8zD`4Jy7x=aoL4`sL|`H{t+?cV_jnuGjrJspIfS@~E@)h} zU)2p5ZKXL@n$K?31H-P}dB4NI)<2KeY7>OTA;mX z-7#uKYhhvrZcgkyA46?Vz4Y-Ghku5gW$d5PCy3or4vP)L^>MM6R-78wLw$p~4#9_L zy^%xMN0FPv%;;?o36duq^I`xifj)s@nO~Qeg}_UVQS)vX_QwUoxwL*G=KzuBMB-Pv z<+;AJKJciM$SL>}+}llq0nkx}BYH1JbGl!!uOxjM!+(IP9bs5mt(vN>egv!euTg9h zce9>6J#5Ua??>g$1P7hqc@~r|MN-JU0>fF_HnWB4Yy3AfU@<7CKfxl^U1?d^laYEp z)dycn0SecOcBQdpu-+#Ng`oKbWNMdfEC%TlIZW+Y^;7>HR2LG*wS^_EYo1B#Hnu0A zJ+5$;IVk(jN&SR<3(|p@!CH-SP9|Ds02KTSuO2cURjlt+@ytCJEz& z-o}1|giSW_2WrfM`=a*blKk9_Gm;_j_VshCUc zhcf=d_9(lI^qA<@r@WLFYskB!<6KEwUaLd)5BggI`mAKJ_Ox8x*}tWQ7MGOWf@~qj Y$^Q2G#ch*0{o`~-UKtxYy?gxVe?sc--v9sr literal 19778 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 diff --git a/data/images/post.png b/data/images/post.png new file mode 100644 index 0000000000000000000000000000000000000000..808a0737d363851e1eeca733db3357231fe1aaf5 GIT binary patch literal 4926 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 literal 0 HcmV?d00001 diff --git a/data/images/resolvers-settings.png b/data/images/resolvers-settings.png index ed67d5e381a6dab67ddee0176f63a06937fa9d87..80b2078280cf2efc3ae2e962c4becb6981a39967 100644 GIT binary patch delta 2652 zcmZXWe`wTo7{|YNZg;2d$Iacg+dRA54{B`HHYY-ZENyN(wR4kx(I4f4jT&N+7$K-B zL1Ynq_DzZnbOrrUp=FSTLX;JfC{q3rm=;!~QDT;*MR~p6pS#cct{!;4&*$^}ct6kQ z`TV$h@4+2CjZY8e`pf4u%<(+0JUh_42AL7ZB78S&+H`4OS= z_Ab5Sp4p*H{Ob!LV^S+eM@PMhi3!{bG%_-hWpq2-0XM^QVbO2!=};*2Ir42{-jz~B zj5j$s>7S{*F)2Ke!^F0e>6kGciI)gohvDyllfP|YQz}>l0gn^#lt4uOo~C9qRg%dw z4p~j%vx$t>sTl0%x*KeEml^#R`Fy?=_q;z`(Q2kD{TouT9*PKkiPN>h31-%OIz!Mv zNmsB%3#DYJrq5Ob&>sNB6jatlJ$bQiR^5D{DAiaq7I2`Rm2H^Zrmt^))sM?OMEE7HXJ* zO(j^is&2MGMv5Twk8m@8B@3}fP$UhGWV%tU)+8=eH^tSp*K3Ay&IAlhC*5SO6;P&T?( zy})@K#-qor1o;;pvy7>(a1Lp$Vo)*TjiqtnsW&2u*zXT^&*wupBnLfEE{h=kmMbmY96^p(GKUQIt9 zjP35qgMQw|TtkK0fhLf~(uwaUquyTib{1j))WzSZ6UT}tBbANDV1 z5=kamAYakRDAFFuLI)%F9Z_%h0;An_g~&l<=h#j&Zju5d>3T?4gB*Y>;1lR=N0p^` z-gRA98#BMwf>6d=TAuFVw^&kiy4K+5vR^ zvdgA@acGh&nEuELc(~2(MqU;D$P7G#d#8hP&=j@={xb+CGz+N#MhU^zBF<04nyFao zI54wZqqv-wNj@p!LE)@uRZ9W0TLKbeoJj!cfWAeJJ-zk$wacYqx=KjUXhLqER zCHpY;UCyWY-{s!}NHYC%;u56%^&M471!*}di1BV%g>2^?Z1q2gN7bd+7DeD;%!2W* z1^@fUhDEnwHE~_A{;`$8S79B&Q{d}$-UrI`!B9Tt#?&Vs{WSIQ-k)+Saq+UtbG>_) Ht=;|)P+pU+ literal 13368 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 diff --git a/data/images/sipplugin-add.png b/data/images/sipplugin-add.png index daf308c10767c50e77a8a2da26b30e6a793b259c..5fa31752b264befa0c21230527dc7bfc4c0b35fb 100644 GIT binary patch literal 13368 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 diff --git a/data/images/sipplugin-remove.png b/data/images/sipplugin-remove.png index d1528dc6cc7925f19e845957e2870f4ddd955bd4..bd54ca495ea431909d0acc9bd7e74b4a497fde80 100644 GIT binary patch literal 13368 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 TNrSc7aEgn0I=Y}+;*9?QmKclO delta 1651 zcmbuAL2DC16vuaKHa2C`G-;x3XqR0n#zKr0M2ZxNvf9K#Xr=UGkqwBL7Sa_wR47Hf z30{V|3CdLP;z1e(DR@Zm6L=6k>1Xg8=$oCLnU~O7#6vdO`Tyq4do%wxIe75-h3P$8 zZY-upiX(<$r0X^RHhfq4XE+JZx2=aiJKih%bZ-30`R?Y2ABN!?b^qGxwrN(Y-7dYD z@o3MjCEk4e`kRpQi95H-@t9BdJ)8b2r9k&1oi?4C0zzkA0im-XfR4M4fHDH+BoHEC z1_5OW>_~vHDWuOxeV4FNjpQXln2U&0lAz3+;zbZPp=265XQWP;ts~?yQjrJ^N)}~l zodC?gti*VeAP$~I+7o?8GwFDfRNq4dy z9&Mw@Eg^WBX-wP~^Ildabpkn9Acdi}fc7dV%Nz_MFvf0A(|RG=hPAP+(7>3p3*zMW*@9k^bQ^PLwffn}WtK=?9MDl#uxXI!OYE+& z!;>t(H3m(q_64-qlwM{Qk7^$e?5ygdBf3QC$9375UhdE?{dpc=aMLg5i(g)U`j*<*=6 Date: Sun, 26 Jun 2011 05:10:01 +0200 Subject: [PATCH 38/86] * Show a PointingHand cursor when hovering the love icon. --- src/audiocontrols.ui | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/audiocontrols.ui b/src/audiocontrols.ui index 76b077b87..872d5089f 100644 --- a/src/audiocontrols.ui +++ b/src/audiocontrols.ui @@ -261,6 +261,9 @@ 0 + + PointingHandCursor + love From 451713c946f91976eebc70e640a9d3460ee6d18d Mon Sep 17 00:00:00 2001 From: Jason Herskowitz Date: Sat, 25 Jun 2011 23:10:47 -0400 Subject: [PATCH 39/86] Make love icon not be invisibile on linux --- data/images/loved.png | Bin 4926 -> 4926 bytes data/images/not-loved.png | Bin 4926 -> 4926 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/data/images/loved.png b/data/images/loved.png index be660a4aaa69c5d43c530408c287631a0b851c59..41c6abce2b6d66c2a38c9f8c044d4fe33d4cbaeb 100644 GIT binary patch delta 1364 zcmY*ZYiJZ#6h8OvWTMH|P0|<*!3MKFNQ@M1YOJ)CingRsUqlS`M|^ZwvRPlH_(P>z zl(hJxk9E_CJF$Ui10h8el-A%QF-0_L3Z)d0{?Nt}k_v9JUAH^CGq>N_?xglIcka38 zeD^z#Id`rty0+;2fV;|-KWBJe?|LG=xnb>FjVp^qqu!Syzu!+hu!h64J{hJ4>Rd9)4^6se1j9?*z3R)e@zA3EM4bN3o$KeS;vD`{4g+aXGijzTACMq^sn&proo*)G>1!=j;qxw9J! z#-DUagy((y`idWu(!B*T5gv@}8+$vW=l4YNJe`=)v_7McbvcBCp_F`K^W#-@_h2i} zRxw#pl%XvoG}QKAuyQ1PPu2*ri+u=8Hu1{ZtY1b5(ohJCl@ghc&hH;wChhb9MS`AJ zs!)BBR_1!et&tj7$2f~l_t^NU0R7#|3W^MRmec?yuzMPy-0@U&VeWdTLUljRktC2YGzzc{n=JeW7=v(u|b@Fo`6&7RVnj zE&zB~2ivn!GqzyAQa>%ca5(`>1RPz=#RsMb+N+J*{7|B-^wn?MKD&D&zxXzyUIB&- zqmZzMcE7hb^|Y?(*eBH}!mqHkgKdw)A{~LRDGY}JXfB+1a_57VmV-E0FD&~6F#KUP zVOd`>*{(p#fgD+A53?b*EDw`RGqNVf+6~s_GLt#(+r9gTpdH`mGR^lfn}YUV2cWy` zN@uIDkbLk-~Ofc(n%|)Z-H$u%RC@Q21{Nm iWnnr(91z%t!}Ch3uMP*cP6Z|z+puo^+H-5RAN>dY5YDIo delta 1344 zcmY*ZTTB#Z6h8m#Faeji3nE?!kg#4V-~-<4gJuVPAhFss7^5`RVl-8;$_pBAn>5j+ z4_?MG8smjT6B}b;sCHeF%{(?6(;^*|3}Ji)gI}z6MU-2~z7kS}wQh#m+dk{rxUV?gwWOZ6093 zC)t6rrq+_uey`@|Rz6y3dtgH&$sZUD9V4pE()`yxV!#=;<2B3rdStTWQL~En0!76o zH*+ZGAZ!x&;48rs@Euk2T{$UbHGBsxY+($i0)|WG9E~P?QB+X4uS-6h=1wt(C{1fg zs9?I)S(q)Ty8!UbZVj%(n0t=YQE~DPdZhO z=t~8_`8U7)ezuY5Dg)AN^;MJug(F@!Qs#0ZcIOPUSnasXIDxhY?Q1&i_+0ozW}!bY zZU>x{LWxsD;65HO5U8#$#N`m( zEmp7aC|!8a1(>%D4!kh<?;Y{yI98B7;4N^L|1y|0iZs<5{GZXq z4g*_m~nlW4Xc_39IUl%@kn@j0~yzq1vNe&_IE+| zMXs@rnHtb7q!YqP)j(U@+lNvaLES@+4c~ByI8GrNt4$8HwVjpcMExd2VZETh01SoX zxC*{V)9v6Tu;TtuoUM-^Fm0}fuuM)2o>Z+0QHF{lNrC={Q-^k>fRq1xdmWjhkl!zt zAfP0UUxo9@N delta 1190 zcmZ9MPe@cz6vpozYFZ>boXi}u%s~zRw2(@Q7Bzz|glJ`iwJ-$*34=Cn3xBoob;FF*idh-Hz#&sL<`z>YAcmvdwAM~hz5tq1 z1V_Ph79Pfz_#-my9pZ1qjflUfeW15cye2;*FVo)-w&VG_=J1=ahkXVA2&!!s_Y|%h zxbkwrl@ykTNmOvO?u8(=34>ZCcz=8LIU#RR8;l3P-k5wB)xb~^ z*FoSa{|Ra8Dab{w0oPORXZfc7(C|a!Y8)R)g6n5xz{CVzlP834iqO!jo8!HV z0cbo2UsVsTX5_waq(*b1H;-dazg Date: Sun, 26 Jun 2011 05:13:02 +0200 Subject: [PATCH 40/86] * Fixed not disabling loveButton. --- src/audiocontrols.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/audiocontrols.cpp b/src/audiocontrols.cpp index 3ecee5b18..ce9dc0357 100644 --- a/src/audiocontrols.cpp +++ b/src/audiocontrols.cpp @@ -306,7 +306,7 @@ AudioControls::onPlaybackLoading( const Tomahawk::result_ptr& result ) ui->loveButton->setPixmap( RESPATH "images/loved.png" ); ui->loveButton->setChecked( true ); } - else + else { ui->loveButton->setPixmap( RESPATH "images/not-loved.png" ); ui->loveButton->setChecked( false ); @@ -353,12 +353,12 @@ AudioControls::onPlaybackStopped() ui->timeLeftLabel->setText( "" ); ui->coverImage->setPixmap( QPixmap() ); ui->seekSlider->setVisible( false ); - ui->loveButton->setVisible( false ); ui->pauseButton->setVisible( false ); ui->pauseButton->setEnabled( false ); ui->playPauseButton->setEnabled( true ); ui->playPauseButton->setVisible( true ); + ui->loveButton->setEnabled( false ); ui->loveButton->setVisible( false ); /* m_pauseAction->setEnabled( false ); @@ -525,7 +525,7 @@ AudioControls::onLoveButtonClicked( bool checked ) Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( s_acInfoIdentifier, Tomahawk::InfoSystem::InfoUnLove, QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ) ); - + DatabaseCommand_SocialAction* cmd = new DatabaseCommand_SocialAction( m_currentTrack, QString( "Love" ), QString( "false" ) ); Database::instance()->enqueue( QSharedPointer(cmd) ); ui->loveButton->setPixmap( RESPATH "images/not-loved.png" ); From e0c72c911a54717e665c2a4dd04e85e5281f018d Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sun, 26 Jun 2011 05:15:05 +0200 Subject: [PATCH 41/86] * Fixed loveButton not being re-enabled again. --- src/audiocontrols.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/audiocontrols.cpp b/src/audiocontrols.cpp index ce9dc0357..7961669f9 100644 --- a/src/audiocontrols.cpp +++ b/src/audiocontrols.cpp @@ -298,9 +298,11 @@ AudioControls::onPlaybackLoading( const Tomahawk::result_ptr& result ) ui->pauseButton->setVisible( true ); ui->playPauseButton->setVisible( false ); ui->playPauseButton->setEnabled( false ); + ui->loveButton->setEnabled( true ); + ui->loveButton->setVisible( true ); result->loadSocialActions(); - ui->loveButton->setVisible( true ); + if ( result->loved() ) { ui->loveButton->setPixmap( RESPATH "images/loved.png" ); From 80797d6538b04012cfe885f02a3d9ecad5c86cd2 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Sun, 26 Jun 2011 05:18:27 +0200 Subject: [PATCH 42/86] Add ConfigUi api to QtScriptResolver --- src/resolvers/qtscriptresolver.cpp | 173 ++++++++++++++++++++++++++++- src/resolvers/qtscriptresolver.h | 18 ++- 2 files changed, 188 insertions(+), 3 deletions(-) diff --git a/src/resolvers/qtscriptresolver.cpp b/src/resolvers/qtscriptresolver.cpp index 78508728a..e2e05ed45 100644 --- a/src/resolvers/qtscriptresolver.cpp +++ b/src/resolvers/qtscriptresolver.cpp @@ -24,6 +24,8 @@ #include "sourcelist.h" #include "utils/tomahawkutils.h" +#include + QtScriptResolverHelper::QtScriptResolverHelper( const QString& scriptPath, QObject* parent ) : QObject( parent ) @@ -57,12 +59,27 @@ QtScriptResolverHelper::compress( const QString& data ) return comp.toBase64(); } +QVariantMap +QtScriptResolverHelper::resolver() +{ + QVariantMap resolver; + resolver["config"] = m_resolverConfig; + resolver["scriptPath"] = m_scriptPath; + return resolver; +} + +void +QtScriptResolverHelper::setResolverConfig( QVariantMap config ) +{ + m_resolverConfig = config; +} QtScriptResolver::QtScriptResolver( const QString& scriptPath ) : Tomahawk::ExternalResolver( scriptPath ) , m_ready( false ) , m_stopped( false ) + , m_resolverHelper( new QtScriptResolverHelper( scriptPath, this ) ) { qDebug() << Q_FUNC_INFO << scriptPath; @@ -77,7 +94,7 @@ QtScriptResolver::QtScriptResolver( const QString& scriptPath ) m_engine->mainFrame()->setHtml( "" ); m_engine->mainFrame()->evaluateJavaScript( scriptFile.readAll() ); - m_engine->mainFrame()->addToJavaScriptWindowObject( "Tomahawk", new QtScriptResolverHelper( scriptPath, this ) ); + m_engine->mainFrame()->addToJavaScriptWindowObject( "Tomahawk", m_resolverHelper ); scriptFile.close(); QVariantMap m = m_engine->mainFrame()->evaluateJavaScript( "getSettings();" ).toMap(); @@ -85,6 +102,11 @@ QtScriptResolver::QtScriptResolver( const QString& scriptPath ) m_weight = m.value( "weight", 0 ).toUInt(); m_timeout = m.value( "timeout", 25 ).toUInt() * 1000; + // load config widget and apply settings + loadUi(); + QVariantMap config = m_engine->mainFrame()->evaluateJavaScript( "getConfig();" ).toMap(); + fillDataInWidgets( config ); + qDebug() << Q_FUNC_INFO << m_name << m_weight << m_timeout; m_ready = true; @@ -187,3 +209,152 @@ QtScriptResolver::stop() m_stopped = true; emit finished(); } + +void QtScriptResolver::loadUi() +{ + qDebug() << Q_FUNC_INFO; + + QVariantMap m = m_engine->mainFrame()->evaluateJavaScript( "getConfigUi();" ).toMap(); + + bool compressed = m.value( "compressed", "false" ).toBool(); + bool base64 = m.value( "base64", "false" ).toBool(); + + qDebug() << "Resolver has a preferences widget! compressed?" << compressed << m; + + QByteArray uiData = m[ "widget" ].toByteArray(); + if( base64 && compressed ) + uiData = qUncompress( QByteArray::fromBase64( uiData ) ); + else if( base64 ) + uiData = QByteArray::fromBase64( uiData ); + + if( m.contains( "images" ) ) + uiData = fixDataImagePaths( uiData, compressed, m[ "images" ].toMap() ); + + m_configWidget = QWeakPointer< QWidget >( widgetFromData( uiData, 0 ) ); + + m_dataWidgets = m_engine->mainFrame()->evaluateJavaScript( "getDataWidgets();" ).toList(); + + emit changed(); +} + + +QWidget* QtScriptResolver::configUI() const +{ + if( m_configWidget.isNull() ) + return 0; + else + return m_configWidget.data(); +} + +void QtScriptResolver::saveConfig() +{ + QVariant saveData = loadDataFromWidgets(); + qDebug() << Q_FUNC_INFO << saveData; + + m_resolverHelper->setResolverConfig( saveData.toMap() ); + m_engine->mainFrame()->evaluateJavaScript( "saveConfig();" ); +} + +QWidget* +QtScriptResolver::findWidget(QWidget* widget, const QStringList& widgetPath) +{ + qDebug() << Q_FUNC_INFO << widget->objectName() << widgetPath; + + if( !widget || !widget->isWidgetType() ) + return 0; + + if( widgetPath.isEmpty() ) + return widget; + + QString searchName = widgetPath.first(); + + foreach( QObject* child, widget->children() ) + { + if( child->isWidgetType() && child->objectName() == searchName ) + { + QStringList newWidgetPath = widgetPath; + newWidgetPath.removeFirst(); + return findWidget(qobject_cast< QWidget* >( child ), newWidgetPath); + } + } + + return 0; +} + + +QVariant QtScriptResolver::widgetData(QWidget* widget, const QString& property) +{ + for( int i = 0; i < widget->metaObject()->propertyCount(); i++ ) + { + if( widget->metaObject()->property( i ).name() == property ) + { + return widget->property( property.toLatin1() ); + } + } + + return QVariant(); +} + +void QtScriptResolver::setWidgetData(const QVariant& value, QWidget* widget, const QString& property) +{ + for( int i = 0; i < widget->metaObject()->propertyCount(); i++ ) + { + if( widget->metaObject()->property( i ).name() == property ) + { + widget->metaObject()->property( i ).write( widget, value); + return; + } + } +} + + +QVariantMap QtScriptResolver::loadDataFromWidgets() +{ + QVariantMap saveData; + foreach(const QVariant& dataWidget, m_dataWidgets) + { + QVariantMap data = dataWidget.toMap(); + + QStringList widgetPath; + foreach(const QVariant& pathItem, data["widget"].toList()) + { + widgetPath << pathItem.toString(); + } + + QWidget* widget= findWidget( m_configWidget.data(), widgetPath ); + + QString value = widgetData( widget, data["property"].toString() ).toString(); + + saveData[ data["name"].toString() ] = value; + } + + qDebug() << saveData; + + return saveData; +} + +void QtScriptResolver::fillDataInWidgets( const QVariantMap& data ) +{ + qDebug() << Q_FUNC_INFO << data; + foreach(const QVariant& dataWidget, m_dataWidgets) + { + QStringList widgetPath; + foreach(const QVariant& pathItem, dataWidget.toMap()["widget"].toList()) + { + widgetPath << pathItem.toString(); + } + + QWidget* widget= findWidget( m_configWidget.data(), widgetPath ); + if( !widget ) + { + qDebug() << Q_FUNC_INFO << "widget specified in resolver was not found:" << widgetPath; + Q_ASSERT(false); + return; + } + + QString propertyName = dataWidget.toMap()["property"].toString(); + QString name = dataWidget.toMap()["name"].toString(); + + setWidgetData( data[ name ], widget, propertyName ); + } +} diff --git a/src/resolvers/qtscriptresolver.h b/src/resolvers/qtscriptresolver.h index a9b439176..7e7966f36 100644 --- a/src/resolvers/qtscriptresolver.h +++ b/src/resolvers/qtscriptresolver.h @@ -39,13 +39,16 @@ Q_OBJECT public: QtScriptResolverHelper( const QString& scriptPath, QObject* parent ); + void setResolverConfig( QVariantMap config ); public slots: QString readFile( const QString& fileName ); QString compress( const QString& data ); + QVariantMap resolver(); private: QString m_scriptPath; + QVariantMap m_resolverConfig; }; class ScriptEngine : public QWebPage @@ -91,8 +94,8 @@ public: virtual unsigned int weight() const { return m_weight; } virtual unsigned int timeout() const { return m_timeout; } - virtual QWidget* configUI() const { return 0; } // TODO support properly for qtscript resolvers too! - virtual void saveConfig() {} + virtual QWidget* configUI() const; + virtual void saveConfig(); public slots: virtual void resolve( const Tomahawk::query_ptr& query ); @@ -102,12 +105,23 @@ signals: void finished(); private: + virtual void loadUi(); + QWidget* findWidget( QWidget* widget, const QStringList& widgetPath ); + void setWidgetData( const QVariant& value, QWidget* widget, const QString& property ); + QVariant widgetData( QWidget* widget, const QString& property ); + QVariantMap loadDataFromWidgets(); + void fillDataInWidgets( const QVariantMap& data ); + ScriptEngine* m_engine; QString m_name; unsigned int m_weight, m_timeout; bool m_ready, m_stopped; + + QtScriptResolverHelper* m_resolverHelper; + QWeakPointer< QWidget > m_configWidget; + QList< QVariant > m_dataWidgets; }; #endif // QTSCRIPTRESOLVER_H From de74c0c3fefd05f11ee9c32f441f20a4001e4352 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Sun, 26 Jun 2011 05:22:06 +0200 Subject: [PATCH 43/86] Add newlines for muesli being able to read the code --- src/resolvers/qtscriptresolver.cpp | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/resolvers/qtscriptresolver.cpp b/src/resolvers/qtscriptresolver.cpp index e2e05ed45..0f73d8f2b 100644 --- a/src/resolvers/qtscriptresolver.cpp +++ b/src/resolvers/qtscriptresolver.cpp @@ -52,6 +52,7 @@ QtScriptResolverHelper::readFile( const QString& fileName ) return file.readAll(); } + QString QtScriptResolverHelper::compress( const QString& data ) { @@ -59,6 +60,7 @@ QtScriptResolverHelper::compress( const QString& data ) return comp.toBase64(); } + QVariantMap QtScriptResolverHelper::resolver() { @@ -68,6 +70,7 @@ QtScriptResolverHelper::resolver() return resolver; } + void QtScriptResolverHelper::setResolverConfig( QVariantMap config ) { @@ -210,7 +213,9 @@ QtScriptResolver::stop() emit finished(); } -void QtScriptResolver::loadUi() + +void +QtScriptResolver::loadUi() { qDebug() << Q_FUNC_INFO; @@ -238,7 +243,8 @@ void QtScriptResolver::loadUi() } -QWidget* QtScriptResolver::configUI() const +QWidget* +QtScriptResolver::configUI() const { if( m_configWidget.isNull() ) return 0; @@ -246,7 +252,9 @@ QWidget* QtScriptResolver::configUI() const return m_configWidget.data(); } -void QtScriptResolver::saveConfig() + +void +QtScriptResolver::saveConfig() { QVariant saveData = loadDataFromWidgets(); qDebug() << Q_FUNC_INFO << saveData; @@ -255,6 +263,7 @@ void QtScriptResolver::saveConfig() m_engine->mainFrame()->evaluateJavaScript( "saveConfig();" ); } + QWidget* QtScriptResolver::findWidget(QWidget* widget, const QStringList& widgetPath) { @@ -282,7 +291,8 @@ QtScriptResolver::findWidget(QWidget* widget, const QStringList& widgetPath) } -QVariant QtScriptResolver::widgetData(QWidget* widget, const QString& property) +QVariant +QtScriptResolver::widgetData(QWidget* widget, const QString& property) { for( int i = 0; i < widget->metaObject()->propertyCount(); i++ ) { @@ -295,7 +305,9 @@ QVariant QtScriptResolver::widgetData(QWidget* widget, const QString& property) return QVariant(); } -void QtScriptResolver::setWidgetData(const QVariant& value, QWidget* widget, const QString& property) + +void +QtScriptResolver::setWidgetData(const QVariant& value, QWidget* widget, const QString& property) { for( int i = 0; i < widget->metaObject()->propertyCount(); i++ ) { @@ -308,7 +320,8 @@ void QtScriptResolver::setWidgetData(const QVariant& value, QWidget* widget, con } -QVariantMap QtScriptResolver::loadDataFromWidgets() +QVariantMap +QtScriptResolver::loadDataFromWidgets() { QVariantMap saveData; foreach(const QVariant& dataWidget, m_dataWidgets) @@ -333,7 +346,9 @@ QVariantMap QtScriptResolver::loadDataFromWidgets() return saveData; } -void QtScriptResolver::fillDataInWidgets( const QVariantMap& data ) + +void +QtScriptResolver::fillDataInWidgets( const QVariantMap& data ) { qDebug() << Q_FUNC_INFO << data; foreach(const QVariant& dataWidget, m_dataWidgets) From fe7c79ff31423168c0546bc372d0e17beea6d433 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sun, 26 Jun 2011 07:21:14 +0200 Subject: [PATCH 44/86] * Added HeaderLabel to replace our old ugly labels. --- src/libtomahawk/CMakeLists.txt | 5 ++ src/libtomahawk/widgets/HeaderLabel.cpp | 86 +++++++++++++++++++ src/libtomahawk/widgets/HeaderLabel.h | 47 ++++++++++ .../widgets/infowidgets/sourceinfowidget.cpp | 24 ++++++ .../widgets/infowidgets/sourceinfowidget.ui | 44 +++------- src/libtomahawk/widgets/welcomewidget.cpp | 21 +++++ src/libtomahawk/widgets/welcomewidget.ui | 34 +++----- 7 files changed, 209 insertions(+), 52 deletions(-) create mode 100644 src/libtomahawk/widgets/HeaderLabel.cpp create mode 100644 src/libtomahawk/widgets/HeaderLabel.h diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index da15df272..3e6fd33ac 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -171,7 +171,9 @@ set( libSources widgets/welcomewidget.cpp widgets/welcomeplaylistmodel.cpp widgets/overlaywidget.cpp + widgets/HeaderLabel.cpp widgets/infowidgets/sourceinfowidget.cpp +# widgets/infowidgets/ArtistInfoWidget.cpp kdsingleapplicationguard/kdsingleapplicationguard.cpp kdsingleapplicationguard/kdsharedmemorylocker.cpp @@ -338,7 +340,9 @@ set( libHeaders widgets/welcomewidget.h widgets/welcomeplaylistmodel.h widgets/overlaywidget.h + widgets/HeaderLabel.h widgets/infowidgets/sourceinfowidget.h +# widgets/infowidgets/ArtistInfoWidget.h kdsingleapplicationguard/kdsingleapplicationguard.h ) @@ -360,6 +364,7 @@ set( libUI ${libUI} widgets/searchwidget.ui widgets/welcomewidget.ui widgets/infowidgets/sourceinfowidget.ui + widgets/infowidgets/ArtistInfoWidget.ui playlist/topbar/topbar.ui playlist/infobar/infobar.ui ) diff --git a/src/libtomahawk/widgets/HeaderLabel.cpp b/src/libtomahawk/widgets/HeaderLabel.cpp new file mode 100644 index 000000000..f30fbc7b2 --- /dev/null +++ b/src/libtomahawk/widgets/HeaderLabel.cpp @@ -0,0 +1,86 @@ +/* === 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 "HeaderLabel.h" + +#include +#include + +#define FONT_SIZE 16 + + +HeaderLabel::HeaderLabel( QWidget* parent ) + : QLabel( parent ) + , m_parent( parent ) +{ + QFont f( font() ); + f.setBold( true ); + f.setPointSize( 11 ); + +#ifdef Q_WS_MAC + f.setPointSize( f.pointSize() - 2 ); +#endif + + setFont( f ); + setFixedHeight( sizeHint().height() + 6 ); + qDebug() << "FOOBAR:" << minimumSize(); +} + + +HeaderLabel::~HeaderLabel() +{ +} + + +QSize +HeaderLabel::sizeHint() const +{ + return QLabel::sizeHint(); +} + + +void +HeaderLabel::paintEvent( QPaintEvent* event ) +{ + QPainter p( this ); + QRect r = contentsRect(); + +// p.setRenderHint( QPainter::Antialiasing ); + + QRect upperHalf( 0, 0, r.width(), r.height() / 2 ); + QRect lowerHalf( 0, upperHalf.height(), r.width(), r.height() ); + p.fillRect( upperHalf, QColor( 80, 80, 80 ) ); + p.fillRect( lowerHalf, QColor( 72, 72, 72 ) ); + + { + QColor lineColor( 100, 100, 100 ); + QLine line( 0, 0, r.width(), 0 ); + p.setPen( lineColor ); + p.drawLine( line ); + } + { + QColor lineColor( 63, 63, 63 ); + QLine line( 0, r.height() - 1, r.width(), r.height() - 1 ); + p.setPen( lineColor ); + p.drawLine( line ); + } + + r.adjust( 8, 3, -8, -3 ); + p.setPen( Qt::white ); + p.drawText( r, text() ); +} diff --git a/src/libtomahawk/widgets/HeaderLabel.h b/src/libtomahawk/widgets/HeaderLabel.h new file mode 100644 index 000000000..3333dabf6 --- /dev/null +++ b/src/libtomahawk/widgets/HeaderLabel.h @@ -0,0 +1,47 @@ +/* === 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 HEADERLABEL_H +#define HEADERLABEL_H + +#include + +#include "dllmacro.h" + +class DLLEXPORT HeaderLabel : public QLabel +{ +Q_OBJECT + +public: + HeaderLabel( QWidget* parent ); + ~HeaderLabel(); + + QSize minimumSizeHint() const { return sizeHint(); } + QSize sizeHint() const; + +public slots: + +protected: +// void changeEvent( QEvent* e ); + void paintEvent( QPaintEvent* event ); + +private: + QWidget* m_parent; +}; + +#endif // HEADERLABEL_H diff --git a/src/libtomahawk/widgets/infowidgets/sourceinfowidget.cpp b/src/libtomahawk/widgets/infowidgets/sourceinfowidget.cpp index 77912e92a..0f8288589 100644 --- a/src/libtomahawk/widgets/infowidgets/sourceinfowidget.cpp +++ b/src/libtomahawk/widgets/infowidgets/sourceinfowidget.cpp @@ -38,6 +38,30 @@ SourceInfoWidget::SourceInfoWidget( const Tomahawk::source_ptr& source, QWidget* { ui->setupUi( this ); + ui->historyView->setFrameShape( QFrame::NoFrame ); + ui->historyView->setAttribute( Qt::WA_MacShowFocusRect, 0 ); + ui->recentAlbumView->setFrameShape( QFrame::NoFrame ); + ui->recentAlbumView->setAttribute( Qt::WA_MacShowFocusRect, 0 ); + ui->recentCollectionView->setFrameShape( QFrame::NoFrame ); + ui->recentCollectionView->setAttribute( Qt::WA_MacShowFocusRect, 0 ); + + ui->horizontalLayout->setContentsMargins( 0, 0, 0, 0 ); + ui->horizontalLayout->setMargin( 0 ); + ui->horizontalLayout->setSpacing( 0 ); + + ui->verticalLayout->setContentsMargins( 0, 0, 0, 0 ); + ui->verticalLayout->setMargin( 0 ); + ui->verticalLayout->setSpacing( 0 ); + ui->verticalLayout_2->setContentsMargins( 0, 0, 0, 0 ); + ui->verticalLayout_2->setMargin( 0 ); + ui->verticalLayout_2->setSpacing( 0 ); + ui->verticalLayout_3->setContentsMargins( 0, 0, 0, 0 ); + ui->verticalLayout_3->setMargin( 0 ); + ui->verticalLayout_3->setSpacing( 0 ); + ui->verticalLayout_4->setContentsMargins( 0, 0, 0, 0 ); + ui->verticalLayout_4->setMargin( 0 ); + ui->verticalLayout_4->setSpacing( 0 ); + ui->historyView->overlay()->setEnabled( false ); m_recentCollectionModel = new CollectionFlatModel( ui->recentCollectionView ); diff --git a/src/libtomahawk/widgets/infowidgets/sourceinfowidget.ui b/src/libtomahawk/widgets/infowidgets/sourceinfowidget.ui index cfb416fcb..bde48ccbc 100644 --- a/src/libtomahawk/widgets/infowidgets/sourceinfowidget.ui +++ b/src/libtomahawk/widgets/infowidgets/sourceinfowidget.ui @@ -6,7 +6,7 @@ 0 0 - 985 + 831 460 @@ -14,14 +14,7 @@ - - - - 13 - 75 - true - - + Recent Albums @@ -56,14 +49,7 @@ - - - - 13 - 75 - true - - + Latest Additions to their Collection @@ -77,14 +63,7 @@ - - - - 13 - 75 - true - - + Recently played Tracks @@ -100,21 +79,26 @@ + + HeaderLabel + QLabel +
widgets/HeaderLabel.h
+
PlaylistView QTreeView
playlist/playlistview.h
- - CollectionView - QTreeView -
playlist/collectionview.h
-
AlbumView QListView
playlist/albumview.h
+ + CollectionView + QTreeView +
playlist/collectionview.h
+
diff --git a/src/libtomahawk/widgets/welcomewidget.cpp b/src/libtomahawk/widgets/welcomewidget.cpp index f288f6714..2f0ae31e8 100644 --- a/src/libtomahawk/widgets/welcomewidget.cpp +++ b/src/libtomahawk/widgets/welcomewidget.cpp @@ -52,6 +52,27 @@ WelcomeWidget::WelcomeWidget( QWidget* parent ) WelcomePlaylistModel* model = new WelcomePlaylistModel( this ); model->setMaxPlaylists( HISTORY_PLAYLIST_ITEMS ); + ui->playlistWidget->setFrameShape( QFrame::NoFrame ); + ui->playlistWidget->setAttribute( Qt::WA_MacShowFocusRect, 0 ); + ui->tracksView->setFrameShape( QFrame::NoFrame ); + ui->tracksView->setAttribute( Qt::WA_MacShowFocusRect, 0 ); + ui->additionsView->setFrameShape( QFrame::NoFrame ); + ui->additionsView->setAttribute( Qt::WA_MacShowFocusRect, 0 ); + + ui->horizontalLayout->setContentsMargins( 0, 0, 0, 0 ); + ui->horizontalLayout->setMargin( 0 ); + ui->horizontalLayout->setSpacing( 0 ); + + ui->verticalLayout->setContentsMargins( 0, 0, 0, 0 ); + ui->verticalLayout->setMargin( 0 ); + ui->verticalLayout->setSpacing( 0 ); + ui->verticalLayout_2->setContentsMargins( 0, 0, 0, 0 ); + ui->verticalLayout_2->setMargin( 0 ); + ui->verticalLayout_2->setSpacing( 0 ); + ui->verticalLayout_3->setContentsMargins( 0, 0, 0, 0 ); + ui->verticalLayout_3->setMargin( 0 ); + ui->verticalLayout_3->setSpacing( 0 ); + ui->playlistWidget->setItemDelegate( new PlaylistDelegate() ); ui->playlistWidget->setModel( model ); ui->playlistWidget->overlay()->resize( 380, 86 ); diff --git a/src/libtomahawk/widgets/welcomewidget.ui b/src/libtomahawk/widgets/welcomewidget.ui index d55ca2ff7..5866dc325 100644 --- a/src/libtomahawk/widgets/welcomewidget.ui +++ b/src/libtomahawk/widgets/welcomewidget.ui @@ -6,8 +6,8 @@ 0 0 - 985 - 459 + 875 + 513 @@ -16,15 +16,10 @@ Qt::Vertical - + - - - - 14 - - + Recent Additions @@ -35,15 +30,10 @@ - + - - - - 14 - - + Newest Stations & Playlists @@ -59,18 +49,13 @@ - + 16777215 16777215 - - - 14 - - Recently Played Tracks @@ -91,6 +76,11 @@ + + HeaderLabel + QLabel +
widgets/HeaderLabel.h
+
PlaylistView QTreeView From 61f9fd5c99b1e78ccff495cf92acbfeff18c99b9 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sun, 26 Jun 2011 07:24:57 +0200 Subject: [PATCH 45/86] * Fixed CMakeLists.txt. --- src/libtomahawk/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index 3e6fd33ac..a02545d1e 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -364,7 +364,7 @@ set( libUI ${libUI} widgets/searchwidget.ui widgets/welcomewidget.ui widgets/infowidgets/sourceinfowidget.ui - widgets/infowidgets/ArtistInfoWidget.ui +# widgets/infowidgets/ArtistInfoWidget.ui playlist/topbar/topbar.ui playlist/infobar/infobar.ui ) From 1e62c117e4d55b864a318f575eb951eb9b3e5523 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sun, 26 Jun 2011 08:26:44 +0200 Subject: [PATCH 46/86] * A few more improvements for and around HeaderLabels. --- .../playlist/playlistitemdelegate.cpp | 6 +- src/libtomahawk/utils/tomahawkutils.cpp | 17 +++ src/libtomahawk/utils/tomahawkutils.h | 5 +- src/libtomahawk/widgets/HeaderLabel.cpp | 2 +- .../widgets/infowidgets/sourceinfowidget.cpp | 17 +-- src/libtomahawk/widgets/welcomewidget.cpp | 21 ++-- src/libtomahawk/widgets/welcomewidget.ui | 111 +++++++++--------- src/resolvers/qtscriptresolver.h | 1 + 8 files changed, 92 insertions(+), 88 deletions(-) diff --git a/src/libtomahawk/playlist/playlistitemdelegate.cpp b/src/libtomahawk/playlist/playlistitemdelegate.cpp index 9bfc69445..68fe42143 100644 --- a/src/libtomahawk/playlist/playlistitemdelegate.cpp +++ b/src/libtomahawk/playlist/playlistitemdelegate.cpp @@ -205,16 +205,16 @@ PlaylistItemDelegate::paintShort( QPainter* painter, const QStyleOptionViewItem& QFont boldFont = opt.font; boldFont.setBold( true ); - r.adjust( ir.width() + 12, 0, 0, 0 ); + r.adjust( ir.width() + 12, 0, -12, 0 ); QTextOption to( Qt::AlignTop ); to.setWrapMode( QTextOption::NoWrap ); painter->setFont( boldFont ); - QString text = painter->fontMetrics().elidedText( upperText, Qt::ElideRight, r.width() - 3 ); + QString text = painter->fontMetrics().elidedText( upperText, Qt::ElideRight, r.width() ); painter->drawText( r.adjusted( 0, 1, 0, 0 ), text, to ); to.setAlignment( Qt::AlignBottom ); painter->setFont( opt.font ); - text = painter->fontMetrics().elidedText( lowerText, Qt::ElideRight, r.width() - 3 ); + text = painter->fontMetrics().elidedText( lowerText, Qt::ElideRight, r.width() ); painter->drawText( r.adjusted( 0, 1, 0, 0 ), text, to ); } painter->restore(); diff --git a/src/libtomahawk/utils/tomahawkutils.cpp b/src/libtomahawk/utils/tomahawkutils.cpp index 8cb25944b..6cf01c787 100644 --- a/src/libtomahawk/utils/tomahawkutils.cpp +++ b/src/libtomahawk/utils/tomahawkutils.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -338,6 +339,22 @@ createDragPixmap( int itemCount ) } +void +unmarginLayout( QLayout* layout ) +{ + layout->setContentsMargins( 0, 0, 0, 0 ); + layout->setMargin( 0 ); + layout->setSpacing( 0 ); + + for ( int i = 0; i < layout->count(); i++ ) + { + QLayout* childLayout = layout->itemAt( i )->layout(); + if ( childLayout ) + unmarginLayout( childLayout ); + } +} + + QWeakPointer< QNetworkAccessManager > s_nam; NetworkProxyFactory* s_proxyFactory = 0; diff --git a/src/libtomahawk/utils/tomahawkutils.h b/src/libtomahawk/utils/tomahawkutils.h index e4d461e99..581252bf7 100644 --- a/src/libtomahawk/utils/tomahawkutils.h +++ b/src/libtomahawk/utils/tomahawkutils.h @@ -24,7 +24,6 @@ #include #include #include -#include #define RESPATH ":/data/" @@ -33,8 +32,8 @@ class QDir; class QDateTime; class QString; class QPixmap; +class QLayout; class QNetworkAccessManager; -class QNetworkProxy; namespace TomahawkUtils { @@ -72,6 +71,8 @@ namespace TomahawkUtils DLLEXPORT QColor alphaBlend( const QColor& colorFrom, const QColor& colorTo, float opacity ); DLLEXPORT QPixmap createDragPixmap( int itemCount = 1 ); + DLLEXPORT void unmarginLayout( QLayout* layout ); + DLLEXPORT NetworkProxyFactory* proxyFactory(); DLLEXPORT QNetworkAccessManager* nam(); diff --git a/src/libtomahawk/widgets/HeaderLabel.cpp b/src/libtomahawk/widgets/HeaderLabel.cpp index f30fbc7b2..5f95fd2ae 100644 --- a/src/libtomahawk/widgets/HeaderLabel.cpp +++ b/src/libtomahawk/widgets/HeaderLabel.cpp @@ -74,7 +74,7 @@ HeaderLabel::paintEvent( QPaintEvent* event ) p.drawLine( line ); } { - QColor lineColor( 63, 63, 63 ); + QColor lineColor( 30, 30, 30 ); QLine line( 0, r.height() - 1, r.width(), r.height() - 1 ); p.setPen( lineColor ); p.drawLine( line ); diff --git a/src/libtomahawk/widgets/infowidgets/sourceinfowidget.cpp b/src/libtomahawk/widgets/infowidgets/sourceinfowidget.cpp index 0f8288589..228284d19 100644 --- a/src/libtomahawk/widgets/infowidgets/sourceinfowidget.cpp +++ b/src/libtomahawk/widgets/infowidgets/sourceinfowidget.cpp @@ -45,22 +45,7 @@ SourceInfoWidget::SourceInfoWidget( const Tomahawk::source_ptr& source, QWidget* ui->recentCollectionView->setFrameShape( QFrame::NoFrame ); ui->recentCollectionView->setAttribute( Qt::WA_MacShowFocusRect, 0 ); - ui->horizontalLayout->setContentsMargins( 0, 0, 0, 0 ); - ui->horizontalLayout->setMargin( 0 ); - ui->horizontalLayout->setSpacing( 0 ); - - ui->verticalLayout->setContentsMargins( 0, 0, 0, 0 ); - ui->verticalLayout->setMargin( 0 ); - ui->verticalLayout->setSpacing( 0 ); - ui->verticalLayout_2->setContentsMargins( 0, 0, 0, 0 ); - ui->verticalLayout_2->setMargin( 0 ); - ui->verticalLayout_2->setSpacing( 0 ); - ui->verticalLayout_3->setContentsMargins( 0, 0, 0, 0 ); - ui->verticalLayout_3->setMargin( 0 ); - ui->verticalLayout_3->setSpacing( 0 ); - ui->verticalLayout_4->setContentsMargins( 0, 0, 0, 0 ); - ui->verticalLayout_4->setMargin( 0 ); - ui->verticalLayout_4->setSpacing( 0 ); + TomahawkUtils::unmarginLayout( layout() ); ui->historyView->overlay()->setEnabled( false ); diff --git a/src/libtomahawk/widgets/welcomewidget.cpp b/src/libtomahawk/widgets/welcomewidget.cpp index 2f0ae31e8..7dbbf50b3 100644 --- a/src/libtomahawk/widgets/welcomewidget.cpp +++ b/src/libtomahawk/widgets/welcomewidget.cpp @@ -48,6 +48,9 @@ WelcomeWidget::WelcomeWidget( QWidget* parent ) ui->setupUi( this ); ui->splitter->setHandleWidth( 1 ); + ui->splitter_2->setHandleWidth( 1 ); + ui->splitter_2->setStretchFactor( 0, 3 ); + ui->splitter_2->setStretchFactor( 0, 2 ); WelcomePlaylistModel* model = new WelcomePlaylistModel( this ); model->setMaxPlaylists( HISTORY_PLAYLIST_ITEMS ); @@ -59,19 +62,11 @@ WelcomeWidget::WelcomeWidget( QWidget* parent ) ui->additionsView->setFrameShape( QFrame::NoFrame ); ui->additionsView->setAttribute( Qt::WA_MacShowFocusRect, 0 ); - ui->horizontalLayout->setContentsMargins( 0, 0, 0, 0 ); - ui->horizontalLayout->setMargin( 0 ); - ui->horizontalLayout->setSpacing( 0 ); - - ui->verticalLayout->setContentsMargins( 0, 0, 0, 0 ); - ui->verticalLayout->setMargin( 0 ); - ui->verticalLayout->setSpacing( 0 ); - ui->verticalLayout_2->setContentsMargins( 0, 0, 0, 0 ); - ui->verticalLayout_2->setMargin( 0 ); - ui->verticalLayout_2->setSpacing( 0 ); - ui->verticalLayout_3->setContentsMargins( 0, 0, 0, 0 ); - ui->verticalLayout_3->setMargin( 0 ); - ui->verticalLayout_3->setSpacing( 0 ); + TomahawkUtils::unmarginLayout( layout() ); + TomahawkUtils::unmarginLayout( ui->verticalLayout->layout() ); + TomahawkUtils::unmarginLayout( ui->verticalLayout_2->layout() ); + TomahawkUtils::unmarginLayout( ui->verticalLayout_3->layout() ); + TomahawkUtils::unmarginLayout( ui->verticalLayout_4->layout() ); ui->playlistWidget->setItemDelegate( new PlaylistDelegate() ); ui->playlistWidget->setModel( model ); diff --git a/src/libtomahawk/widgets/welcomewidget.ui b/src/libtomahawk/widgets/welcomewidget.ui index 5866dc325..b28514dde 100644 --- a/src/libtomahawk/widgets/welcomewidget.ui +++ b/src/libtomahawk/widgets/welcomewidget.ui @@ -10,69 +10,74 @@ 513 - + - + - Qt::Vertical + Qt::Horizontal - - - - - - Recent Additions - - - - - - - + + + Qt::Vertical + + + + + + + Recent Additions + + + + + + + + + + + + + + Newest Stations & Playlists + + + + + + + + - - + + - + + + + 16777215 + 16777215 + + - Newest Stations & Playlists + Recently Played Tracks - + + + + 16777215 + 16777215 + + + - - - - - - - 16777215 - 16777215 - - - - Recently Played Tracks - - - - - - - - 16777215 - 16777215 - - - - - -
@@ -86,16 +91,16 @@ QTreeView
playlist/playlistview.h
- - PlaylistWidget - QListWidget -
widgets/welcomewidget.h
-
AlbumView QListView
playlist/albumview.h
+ + PlaylistWidget + QListWidget +
widgets/welcomewidget.h
+
diff --git a/src/resolvers/qtscriptresolver.h b/src/resolvers/qtscriptresolver.h index a9b439176..cf148990d 100644 --- a/src/resolvers/qtscriptresolver.h +++ b/src/resolvers/qtscriptresolver.h @@ -26,6 +26,7 @@ #include #include +#include #include #include #include From 39409ed861c9e2ddb41bea573576fc6d258bfb60 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sun, 26 Jun 2011 13:28:04 +0200 Subject: [PATCH 47/86] * Don't cut off fonts in HeaderLabel. --- src/libtomahawk/widgets/HeaderLabel.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libtomahawk/widgets/HeaderLabel.cpp b/src/libtomahawk/widgets/HeaderLabel.cpp index 5f95fd2ae..19d347d2a 100644 --- a/src/libtomahawk/widgets/HeaderLabel.cpp +++ b/src/libtomahawk/widgets/HeaderLabel.cpp @@ -38,7 +38,6 @@ HeaderLabel::HeaderLabel( QWidget* parent ) setFont( f ); setFixedHeight( sizeHint().height() + 6 ); - qDebug() << "FOOBAR:" << minimumSize(); } @@ -80,7 +79,7 @@ HeaderLabel::paintEvent( QPaintEvent* event ) p.drawLine( line ); } - r.adjust( 8, 3, -8, -3 ); + r.adjust( 8, 2, -8, -2 ); p.setPen( Qt::white ); p.drawText( r, text() ); } From 97986d8d3e38869a60adbc773cbe21dbc0720030 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sun, 26 Jun 2011 15:20:50 +0200 Subject: [PATCH 48/86] * Use QTextOption to v-center HeaderLabel properly. --- src/libtomahawk/widgets/HeaderLabel.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/libtomahawk/widgets/HeaderLabel.cpp b/src/libtomahawk/widgets/HeaderLabel.cpp index 19d347d2a..208abed60 100644 --- a/src/libtomahawk/widgets/HeaderLabel.cpp +++ b/src/libtomahawk/widgets/HeaderLabel.cpp @@ -37,7 +37,7 @@ HeaderLabel::HeaderLabel( QWidget* parent ) #endif setFont( f ); - setFixedHeight( sizeHint().height() + 6 ); + setFixedHeight( sizeHint().height() + 8 ); } @@ -79,7 +79,8 @@ HeaderLabel::paintEvent( QPaintEvent* event ) p.drawLine( line ); } - r.adjust( 8, 2, -8, -2 ); + QTextOption to( Qt::AlignVCenter ); + r.adjust( 8, 0, -8, 0 ); p.setPen( Qt::white ); - p.drawText( r, text() ); + p.drawText( r, text(), to ); } From ee70b9e3a7189b6422be6175db69e85b6413be5b Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sun, 26 Jun 2011 15:35:42 +0200 Subject: [PATCH 49/86] * Set minimum size for recently-played tracks in WelcomeWidget. --- src/libtomahawk/widgets/welcomewidget.cpp | 2 +- src/libtomahawk/widgets/welcomewidget.ui | 12 +++--------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/libtomahawk/widgets/welcomewidget.cpp b/src/libtomahawk/widgets/welcomewidget.cpp index 7dbbf50b3..8ec1d4d1a 100644 --- a/src/libtomahawk/widgets/welcomewidget.cpp +++ b/src/libtomahawk/widgets/welcomewidget.cpp @@ -49,8 +49,8 @@ WelcomeWidget::WelcomeWidget( QWidget* parent ) ui->splitter->setHandleWidth( 1 ); ui->splitter_2->setHandleWidth( 1 ); - ui->splitter_2->setStretchFactor( 0, 3 ); ui->splitter_2->setStretchFactor( 0, 2 ); + ui->splitter_2->setStretchFactor( 0, 1 ); WelcomePlaylistModel* model = new WelcomePlaylistModel( this ); model->setMaxPlaylists( HISTORY_PLAYLIST_ITEMS ); diff --git a/src/libtomahawk/widgets/welcomewidget.ui b/src/libtomahawk/widgets/welcomewidget.ui index b28514dde..489ff9fb2 100644 --- a/src/libtomahawk/widgets/welcomewidget.ui +++ b/src/libtomahawk/widgets/welcomewidget.ui @@ -53,12 +53,6 @@ - - - 16777215 - 16777215 - - Recently Played Tracks @@ -66,10 +60,10 @@ - + - 16777215 - 16777215 + 320 + 0 From c6d2a5df89d2d36ac9398476d83abba10b2078a2 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Sun, 26 Jun 2011 12:58:51 -0400 Subject: [PATCH 50/86] Remove extraneous code --- src/libtomahawk/sourceplaylistinterface.cpp | 10 ---------- src/libtomahawk/sourceplaylistinterface.h | 1 - 2 files changed, 11 deletions(-) diff --git a/src/libtomahawk/sourceplaylistinterface.cpp b/src/libtomahawk/sourceplaylistinterface.cpp index bf1836228..bf3fafb66 100644 --- a/src/libtomahawk/sourceplaylistinterface.cpp +++ b/src/libtomahawk/sourceplaylistinterface.cpp @@ -103,16 +103,6 @@ SourcePlaylistInterface::onSourcePlaybackStarted( const Tomahawk::query_ptr& que } -void -SourcePlaylistInterface::resolveResultsAdded( const QList& results ) const -{ - qDebug() << Q_FUNC_INFO; - foreach ( Tomahawk::result_ptr ptr, results ) - { -// qDebug() << "Found result:" << ptr->track(); - } -} - void SourcePlaylistInterface::resolvingFinished( bool hasResults ) { diff --git a/src/libtomahawk/sourceplaylistinterface.h b/src/libtomahawk/sourceplaylistinterface.h index 7eb8d179d..097d1a4be 100644 --- a/src/libtomahawk/sourceplaylistinterface.h +++ b/src/libtomahawk/sourceplaylistinterface.h @@ -74,7 +74,6 @@ signals: private slots: void onSourcePlaybackStarted( const Tomahawk::query_ptr& query ); - void resolveResultsAdded( const QList& results ) const; void resolvingFinished( bool hasResults ); private: From e983742c9b09f15a187abe91ac06cf38a4ad7b0e Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Sun, 26 Jun 2011 13:25:55 -0400 Subject: [PATCH 51/86] When notifying of a played track, show the source's image. Ideally we'd show the album cover but I can't find a good way to get at that (yet). --- src/libtomahawk/audio/audioengine.cpp | 13 +++++++------ .../infoplugins/unix/fdonotifyplugin.cpp | 15 +++++++++++---- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/libtomahawk/audio/audioengine.cpp b/src/libtomahawk/audio/audioengine.cpp index f3f6362b6..9491275d0 100644 --- a/src/libtomahawk/audio/audioengine.cpp +++ b/src/libtomahawk/audio/audioengine.cpp @@ -154,9 +154,9 @@ AudioEngine::stop() sendWaitingNotification(); else if ( TomahawkSettings::instance()->verboseNotifications() ) { - Tomahawk::InfoSystem::InfoCriteriaHash stopInfo; + Tomahawk::InfoSystem::InfoCustomData stopInfo; stopInfo["message"] = QString( "Tomahawk is stopped." ); - map[ Tomahawk::InfoSystem::InfoNotifyUser ] = QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( stopInfo ); + map[ Tomahawk::InfoSystem::InfoNotifyUser ] = QVariant::fromValue< Tomahawk::InfoSystem::InfoCustomData >( stopInfo ); } Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( s_aeInfoIdentifier, map ); @@ -240,11 +240,11 @@ AudioEngine::mute() void AudioEngine::sendWaitingNotification() const { - Tomahawk::InfoSystem::InfoCriteriaHash retryInfo; + Tomahawk::InfoSystem::InfoCustomData retryInfo; retryInfo["message"] = QString( "The current track could not be resolved. Tomahawk will pick back up with the next resolvable track from this source." ); Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNotifyUser, - QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( retryInfo ) ); + QVariant::fromValue< Tomahawk::InfoSystem::InfoCustomData >( retryInfo ) ); } @@ -329,12 +329,13 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result ) if ( TomahawkSettings::instance()->verboseNotifications() ) { - Tomahawk::InfoSystem::InfoCriteriaHash playInfo; + Tomahawk::InfoSystem::InfoCustomData playInfo; playInfo["message"] = QString( "Tomahawk is playing \"%1\" by %2 on album %3." ) .arg( m_currentTrack->track() ) .arg( m_currentTrack->artist()->name() ) .arg( m_currentTrack->album()->name() ); - map[ Tomahawk::InfoSystem::InfoNotifyUser ] = QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( playInfo ); + playInfo["image"] = QVariant( m_currentTrack->collection()->source()->avatar().toImage() ); + map[ Tomahawk::InfoSystem::InfoNotifyUser ] = QVariant::fromValue< Tomahawk::InfoSystem::InfoCustomData >( playInfo ); } Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( s_aeInfoIdentifier, map ); diff --git a/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.cpp b/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.cpp index c0b7f9d0d..7e38e615f 100644 --- a/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.cpp @@ -63,12 +63,12 @@ FdoNotifyPlugin::pushInfo( const QString caller, const Tomahawk::InfoSystem::Inf { Q_UNUSED( caller ); qDebug() << Q_FUNC_INFO; - if ( type != Tomahawk::InfoSystem::InfoNotifyUser || !pushData.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() ) + if ( type != Tomahawk::InfoSystem::InfoNotifyUser || !pushData.canConvert< Tomahawk::InfoSystem::InfoCustomData >() ) { qDebug() << Q_FUNC_INFO << " not the right type or could not convert the hash"; return; } - Tomahawk::InfoSystem::InfoCriteriaHash hash = pushData.value< Tomahawk::InfoSystem::InfoCriteriaHash >(); + Tomahawk::InfoSystem::InfoCustomData hash = pushData.value< Tomahawk::InfoSystem::InfoCustomData >(); if ( !hash.contains( "message" ) ) { qDebug() << Q_FUNC_INFO << " hash did not contain a message"; @@ -81,11 +81,18 @@ FdoNotifyPlugin::pushInfo( const QString caller, const Tomahawk::InfoSystem::Inf arguments << quint32( 0 ); //notification_id arguments << QString(); //app_icon arguments << QString( "Tomahawk" ); //summary - arguments << hash["message"]; //body + arguments << hash["message"].toString(); //body arguments << QStringList(); //actions QVariantMap dict; dict["desktop-entry"] = QString( "tomahawk" ); - dict["image_data"] = ImageConverter::variantForImage( QImage( RESPATH "icons/tomahawk-icon-128x128.png" ) ); + if ( hash.contains( "image" ) ) + { + QVariant tempVariant = hash["image"]; + QImage tempImage = tempVariant.value< QImage >(); + dict["image_data"] = ImageConverter::variantForImage( tempImage ); + } + else + dict["image_data"] = ImageConverter::variantForImage( QImage( RESPATH "icons/tomahawk-icon-128x128.png" ) ); arguments << dict; //hints arguments << qint32( -1 ); //expire_timeout message.setArguments( arguments ); From 5d21dded5c1eb68ffa349cff79828a28359cb084 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Sun, 26 Jun 2011 19:20:55 +0200 Subject: [PATCH 52/86] Implement new js-resolver api --- src/resolvers/qtscriptresolver.cpp | 38 ++++++++++++++++++++---------- src/resolvers/qtscriptresolver.h | 8 +++++-- 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/resolvers/qtscriptresolver.cpp b/src/resolvers/qtscriptresolver.cpp index 0f73d8f2b..5e9694d97 100644 --- a/src/resolvers/qtscriptresolver.cpp +++ b/src/resolvers/qtscriptresolver.cpp @@ -62,7 +62,7 @@ QtScriptResolverHelper::compress( const QString& data ) QVariantMap -QtScriptResolverHelper::resolver() +QtScriptResolverHelper::resolverData() { QVariantMap resolver; resolver["config"] = m_resolverConfig; @@ -96,18 +96,18 @@ QtScriptResolver::QtScriptResolver( const QString& scriptPath ) } m_engine->mainFrame()->setHtml( "" ); - m_engine->mainFrame()->evaluateJavaScript( scriptFile.readAll() ); m_engine->mainFrame()->addToJavaScriptWindowObject( "Tomahawk", m_resolverHelper ); + m_engine->mainFrame()->evaluateJavaScript( scriptFile.readAll() ); scriptFile.close(); - QVariantMap m = m_engine->mainFrame()->evaluateJavaScript( "getSettings();" ).toMap(); + QVariantMap m = resolverSettings(); m_name = m.value( "name" ).toString(); m_weight = m.value( "weight", 0 ).toUInt(); m_timeout = m.value( "timeout", 25 ).toUInt() * 1000; // load config widget and apply settings loadUi(); - QVariantMap config = m_engine->mainFrame()->evaluateJavaScript( "getConfig();" ).toMap(); + QVariantMap config = resolverUserConfig(); fillDataInWidgets( config ); qDebug() << Q_FUNC_INFO << m_name << m_weight << m_timeout; @@ -139,7 +139,7 @@ QtScriptResolver::resolve( const Tomahawk::query_ptr& query ) if ( !query->isFullTextQuery() ) { - eval = QString( "resolve( '%1', '%2', '%3', '%4' );" ) + eval = QString( "Tomahawk.resolver.instance.resolve( '%1', '%2', '%3', '%4' );" ) .arg( query->id().replace( "'", "\\'" ) ) .arg( query->artist().replace( "'", "\\'" ) ) .arg( query->album().replace( "'", "\\'" ) ) @@ -147,7 +147,7 @@ QtScriptResolver::resolve( const Tomahawk::query_ptr& query ) } else { - eval = QString( "resolve( '%1', '%2', '%3', '%4' );" ) + eval = QString( "Tomahawk.resolver.instance.resolve( '%1', '%2', '%3', '%4' );" ) .arg( query->id().replace( "'", "\\'" ) ) .arg( query->fullTextQuery().replace( "'", "\\'" ) ) .arg( QString() ) @@ -219,7 +219,9 @@ QtScriptResolver::loadUi() { qDebug() << Q_FUNC_INFO; - QVariantMap m = m_engine->mainFrame()->evaluateJavaScript( "getConfigUi();" ).toMap(); + QVariantMap m = m_engine->mainFrame()->evaluateJavaScript( "Tomahawk.resolver.instance.getConfigUi();" ).toMap(); + m_dataWidgets = m["fields"].toList(); + bool compressed = m.value( "compressed", "false" ).toBool(); bool base64 = m.value( "base64", "false" ).toBool(); @@ -237,8 +239,6 @@ QtScriptResolver::loadUi() m_configWidget = QWeakPointer< QWidget >( widgetFromData( uiData, 0 ) ); - m_dataWidgets = m_engine->mainFrame()->evaluateJavaScript( "getDataWidgets();" ).toList(); - emit changed(); } @@ -260,18 +260,18 @@ QtScriptResolver::saveConfig() qDebug() << Q_FUNC_INFO << saveData; m_resolverHelper->setResolverConfig( saveData.toMap() ); - m_engine->mainFrame()->evaluateJavaScript( "saveConfig();" ); + m_engine->mainFrame()->evaluateJavaScript( "Tomahawk.resolver.instance.saveUserConfig();" ); } QWidget* QtScriptResolver::findWidget(QWidget* widget, const QStringList& widgetPath) { - qDebug() << Q_FUNC_INFO << widget->objectName() << widgetPath; - if( !widget || !widget->isWidgetType() ) return 0; + qDebug() << Q_FUNC_INFO << widget->objectName() << widgetPath; + if( widgetPath.isEmpty() ) return widget; @@ -373,3 +373,17 @@ QtScriptResolver::fillDataInWidgets( const QVariantMap& data ) setWidgetData( data[ name ], widget, propertyName ); } } + + +QVariantMap +QtScriptResolver::resolverSettings() +{ + return m_engine->mainFrame()->evaluateJavaScript( "Tomahawk.resolver.instance.getSettings();" ).toMap(); +} + + +QVariantMap +QtScriptResolver::resolverUserConfig() +{ + return m_engine->mainFrame()->evaluateJavaScript( "Tomahawk.resolver.instance.getUserConfig();" ).toMap(); +} diff --git a/src/resolvers/qtscriptresolver.h b/src/resolvers/qtscriptresolver.h index 7e7966f36..94994a954 100644 --- a/src/resolvers/qtscriptresolver.h +++ b/src/resolvers/qtscriptresolver.h @@ -44,7 +44,7 @@ public: public slots: QString readFile( const QString& fileName ); QString compress( const QString& data ); - QVariantMap resolver(); + QVariantMap resolverData(); private: QString m_scriptPath; @@ -75,7 +75,7 @@ public slots: protected: virtual void javaScriptConsoleMessage( const QString & message, int lineNumber, const QString & sourceID ) - { qDebug() << "JAVASCRIPT ERROR:" << message << lineNumber << sourceID; } + { qDebug() << "JAVASCRIPT:" << message << lineNumber << sourceID; } private: QtScriptResolver* m_parent; @@ -112,6 +112,10 @@ private: QVariantMap loadDataFromWidgets(); void fillDataInWidgets( const QVariantMap& data ); + // encapsulate javascript calls + QVariantMap resolverSettings(); + QVariantMap resolverUserConfig(); + ScriptEngine* m_engine; QString m_name; From 931ed5b91876dc1fe1fa4d19be15ffe5a5360a34 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Mon, 27 Jun 2011 00:12:29 +0200 Subject: [PATCH 53/86] Fix loading images from qtscriptresolvers --- src/resolvers/qtscriptresolver.cpp | 40 ++++++++++++++++++++++++------ src/resolvers/qtscriptresolver.h | 5 +++- 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/src/resolvers/qtscriptresolver.cpp b/src/resolvers/qtscriptresolver.cpp index 5e9694d97..296d4ea10 100644 --- a/src/resolvers/qtscriptresolver.cpp +++ b/src/resolvers/qtscriptresolver.cpp @@ -34,8 +34,8 @@ QtScriptResolverHelper::QtScriptResolverHelper( const QString& scriptPath, QObje } -QString -QtScriptResolverHelper::readFile( const QString& fileName ) +QByteArray +QtScriptResolverHelper::readRaw( const QString& fileName ) { QString path = QFileInfo( m_scriptPath ).absolutePath(); // remove directories @@ -45,7 +45,8 @@ QtScriptResolverHelper::readFile( const QString& fileName ) QFile file( absoluteFilePath ); if ( !file.exists() ) { - return QString(); + Q_ASSERT(false); + return QByteArray(); } file.open( QIODevice::ReadOnly ); @@ -61,6 +62,20 @@ QtScriptResolverHelper::compress( const QString& data ) } +QString +QtScriptResolverHelper::readCompressed(const QString& fileName) +{ + return compress( readRaw( fileName ) ); +} + + +QString +QtScriptResolverHelper::readBase64(const QString& fileName) +{ + return readRaw( fileName ).toBase64(); +} + + QVariantMap QtScriptResolverHelper::resolverData() { @@ -224,18 +239,27 @@ QtScriptResolver::loadUi() bool compressed = m.value( "compressed", "false" ).toBool(); - bool base64 = m.value( "base64", "false" ).toBool(); - qDebug() << "Resolver has a preferences widget! compressed?" << compressed << m; QByteArray uiData = m[ "widget" ].toByteArray(); - if( base64 && compressed ) + + if( compressed ) uiData = qUncompress( QByteArray::fromBase64( uiData ) ); - else if( base64 ) + else uiData = QByteArray::fromBase64( uiData ); + QVariantMap images; + foreach(const QVariant& item, m[ "images" ].toList()) + { + QString key = item.toMap().keys().first(); + QVariant value = item.toMap().value(key); + images[key] = value; + } + if( m.contains( "images" ) ) - uiData = fixDataImagePaths( uiData, compressed, m[ "images" ].toMap() ); + uiData = fixDataImagePaths( uiData, compressed, images ); + + m_configWidget = QWeakPointer< QWidget >( widgetFromData( uiData, 0 ) ); diff --git a/src/resolvers/qtscriptresolver.h b/src/resolvers/qtscriptresolver.h index 94994a954..f55f50433 100644 --- a/src/resolvers/qtscriptresolver.h +++ b/src/resolvers/qtscriptresolver.h @@ -42,7 +42,10 @@ public: void setResolverConfig( QVariantMap config ); public slots: - QString readFile( const QString& fileName ); + QByteArray readRaw( const QString& fileName ); + QString readBase64( const QString& fileName ); + QString readCompressed( const QString& fileName ); + QString compress( const QString& data ); QVariantMap resolverData(); From bf46ca7b71ad715a06bc0a492c8c070ece5ea36f Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Mon, 27 Jun 2011 04:22:40 +0200 Subject: [PATCH 54/86] Add more api for qtscriptresolvers --- resources.qrc | 1 + src/resolvers/qtscriptresolver.cpp | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/resources.qrc b/resources.qrc index 4afb8151f..763a4d08e 100644 --- a/resources.qrc +++ b/resources.qrc @@ -97,5 +97,6 @@ ./data/sql/dbmigrate-22_to_23.sql ./data/sql/dbmigrate-23_to_24.sql ./data/sql/dbmigrate-24_to_25.sql + ./data/js/tomahawk.js diff --git a/src/resolvers/qtscriptresolver.cpp b/src/resolvers/qtscriptresolver.cpp index 296d4ea10..664ec321f 100644 --- a/src/resolvers/qtscriptresolver.cpp +++ b/src/resolvers/qtscriptresolver.cpp @@ -111,10 +111,21 @@ QtScriptResolver::QtScriptResolver( const QString& scriptPath ) } m_engine->mainFrame()->setHtml( "" ); + + // add c++ part of tomahawk javascript library m_engine->mainFrame()->addToJavaScriptWindowObject( "Tomahawk", m_resolverHelper ); + + // add rest of it + QFile jslib( RESPATH "js/tomahawk.js" ); + jslib.open( QIODevice::ReadOnly ); + m_engine->mainFrame()->evaluateJavaScript( jslib.readAll() ); + jslib.close(); + + // execute resolver m_engine->mainFrame()->evaluateJavaScript( scriptFile.readAll() ); scriptFile.close(); + QVariantMap m = resolverSettings(); m_name = m.value( "name" ).toString(); m_weight = m.value( "weight", 0 ).toUInt(); From bb6da0daa91063160528cda84cc2a35762d9f373 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Mon, 27 Jun 2011 15:00:25 -0400 Subject: [PATCH 55/86] Fix broken proxying. Not sure when it broke but this is a more robust solution considering that both lastfm and echonest manager their own nams. See notes; liblastfm may be problematic on Windows and Mac. --- .../infoplugins/generic/echonestplugin.cpp | 22 +++++++++- .../infoplugins/generic/lastfmplugin.cpp | 43 +++++++++++++++++-- .../infosystem/infosystemcache.cpp | 4 +- src/libtomahawk/playlist/albummodel.cpp | 2 +- src/libtomahawk/playlist/treemodel.cpp | 2 +- src/tomahawkapp.cpp | 23 +++++----- 6 files changed, 77 insertions(+), 19 deletions(-) diff --git a/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.cpp b/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.cpp index 979b84a9c..bca856a2b 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.cpp @@ -20,6 +20,10 @@ #include #include +#include "utils/tomahawkutils.h" + +#include + using namespace Tomahawk::InfoSystem; using namespace Echonest; @@ -43,9 +47,23 @@ EchoNestPlugin::namChangedSlot( QNetworkAccessManager *nam ) qDebug() << Q_FUNC_INFO; if( !nam ) return; + + QNetworkAccessManager* currNam = Echonest::Config::instance()->nam(); + TomahawkUtils::NetworkProxyFactory* oldProxyFactory = dynamic_cast< TomahawkUtils::NetworkProxyFactory* >( nam->proxyFactory() ); + + if ( !oldProxyFactory ) + { + qDebug() << "Could not get old proxyFactory!"; + return; + } - m_nam = QWeakPointer< QNetworkAccessManager >( nam ); - Echonest::Config::instance()->setNetworkAccessManager( nam ); + currNam->setConfiguration( nam->configuration() ); + currNam->setNetworkAccessible( nam->networkAccessible() ); + TomahawkUtils::NetworkProxyFactory* newProxyFactory = new TomahawkUtils::NetworkProxyFactory(); + newProxyFactory->setNoProxyHosts( oldProxyFactory->noProxyHosts() ); + newProxyFactory->setProxy( oldProxyFactory->proxy() ); + currNam->setProxyFactory( newProxyFactory ); + m_nam = QWeakPointer< QNetworkAccessManager >( currNam ); } void diff --git a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp index ded62fd51..387becd3b 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include "album.h" #include "typedefs.h" @@ -93,10 +94,30 @@ void LastFmPlugin::namChangedSlot( QNetworkAccessManager *nam ) { qDebug() << Q_FUNC_INFO; - if( !nam ) + + if ( !nam ) return; + + QNetworkAccessManager* currNam = lastfm::nam(); + TomahawkUtils::NetworkProxyFactory* oldProxyFactory = dynamic_cast< TomahawkUtils::NetworkProxyFactory* >( nam->proxyFactory() ); + + if ( !oldProxyFactory ) + { + qDebug() << "Could not get old proxyFactory!"; + return; + } + + currNam->setConfiguration( nam->configuration() ); + currNam->setNetworkAccessible( nam->networkAccessible() ); + TomahawkUtils::NetworkProxyFactory* newProxyFactory = new TomahawkUtils::NetworkProxyFactory(); + newProxyFactory->setNoProxyHosts( oldProxyFactory->noProxyHosts() ); + newProxyFactory->setProxy( oldProxyFactory->proxy() ); + currNam->setProxyFactory( newProxyFactory ); + //FIXME: on Mac/Win as liblastfm's network access manager also sets its overriding application proxy + //may have to do a QNetworkProxy::setApplicationProxy and clobber our own factory to override it + + m_nam = QWeakPointer< QNetworkAccessManager >( currNam ); - m_nam = QWeakPointer< QNetworkAccessManager >( nam ); settingsChanged(); // to get the scrobbler set up } @@ -172,7 +193,6 @@ LastFmPlugin::nowPlaying( const QVariant &input ) if ( !hash.contains( "title" ) || !hash.contains( "artist" ) || !hash.contains( "album" ) || !hash.contains( "duration" ) ) return; - qDebug() << "LastFmPlugin::nowPlaying valid criteria hash"; m_track = lastfm::MutableTrack(); m_track.stamp(); @@ -350,6 +370,14 @@ LastFmPlugin::coverArtReturned() if ( redir.isEmpty() ) { QByteArray ba = reply->readAll(); + if ( ba.isNull() || !ba.length() ) + { + qDebug() << "Uh oh, null byte array"; + InfoType type = (Tomahawk::InfoSystem::InfoType)(reply->property( "type" ).toUInt()); + InfoCustomData customData = reply->property( "customData" ).value< Tomahawk::InfoSystem::InfoCustomData >(); + emit info( reply->property( "caller" ).toString(), type, reply->property( "origData" ), QVariant(), customData ); + return; + } foreach ( const QUrl& url, m_badUrls ) { if ( reply->url().toString().startsWith( url.toString() ) ) @@ -409,12 +437,19 @@ LastFmPlugin::artistImagesReturned() if ( redir.isEmpty() ) { QByteArray ba = reply->readAll(); + if ( ba.isNull() || !ba.length() ) + { + qDebug() << "Uh oh, null byte array"; + InfoType type = (Tomahawk::InfoSystem::InfoType)(reply->property( "type" ).toUInt()); + InfoCustomData customData = reply->property( "customData" ).value< Tomahawk::InfoSystem::InfoCustomData >(); + emit info( reply->property( "caller" ).toString(), type, reply->property( "origData" ), QVariant(), customData ); + return; + } foreach ( const QUrl& url, m_badUrls ) { if ( reply->url().toString().startsWith( url.toString() ) ) ba = QByteArray(); } - InfoCustomData returnedData; returnedData["imgbytes"] = ba; returnedData["url"] = reply->url().toString(); diff --git a/src/libtomahawk/infosystem/infosystemcache.cpp b/src/libtomahawk/infosystem/infosystemcache.cpp index 64ef7bd77..0623b32db 100644 --- a/src/libtomahawk/infosystem/infosystemcache.cpp +++ b/src/libtomahawk/infosystem/infosystemcache.cpp @@ -159,13 +159,15 @@ InfoSystemCache::getCachedInfoSlot( const Tomahawk::InfoSystem::InfoCriteriaHash if ( !m_dataCache.contains( criteriaHashVal ) ) { QSettings cachedSettings( fileLocationHash[criteriaHashVal], QSettings::IniFormat ); - QVariant output = cachedSettings.value( "data" ); + QVariant output = cachedSettings.value( "data" ); m_dataCache.insert( criteriaHashVal, new QVariant( output ) ); emit info( caller, type, input, output, customData ); } else + { emit info( caller, type, input, QVariant( *(m_dataCache[criteriaHashVal]) ), customData ); + } } diff --git a/src/libtomahawk/playlist/albummodel.cpp b/src/libtomahawk/playlist/albummodel.cpp index 3db313e8d..bf82bd864 100644 --- a/src/libtomahawk/playlist/albummodel.cpp +++ b/src/libtomahawk/playlist/albummodel.cpp @@ -314,7 +314,7 @@ void AlbumModel::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ) { Q_UNUSED( customData ); - qDebug() << Q_FUNC_INFO; + qDebug() << Q_FUNC_INFO << " with caller " << caller; if ( caller != s_tmInfoIdentifier || ( type != Tomahawk::InfoSystem::InfoAlbumCoverArt && type != Tomahawk::InfoSystem::InfoArtistImages ) ) diff --git a/src/libtomahawk/playlist/treemodel.cpp b/src/libtomahawk/playlist/treemodel.cpp index c57d17b94..aa9995f52 100644 --- a/src/libtomahawk/playlist/treemodel.cpp +++ b/src/libtomahawk/playlist/treemodel.cpp @@ -602,11 +602,11 @@ TreeModel::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, Tomahawk::InfoSystem::InfoCriteriaHash pptr = input.value< Tomahawk::InfoSystem::InfoCriteriaHash >(); Tomahawk::InfoSystem::InfoCustomData returnedData = output.value< Tomahawk::InfoSystem::InfoCustomData >(); const QByteArray ba = returnedData["imgbytes"].toByteArray(); + qDebug() << "ba.length = " << ba.length(); if ( ba.length() ) { QPixmap pm; pm.loadFromData( ba ); - bool ok; qlonglong p = pptr["pptr"].toLongLong( &ok ); TreeModelItem* ai = reinterpret_cast(p); diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index 10543e925..20a13f3f6 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -204,6 +204,14 @@ TomahawkApp::init() new TomahawkSettings( this ); TomahawkSettings* s = TomahawkSettings::instance(); + #ifdef LIBLASTFM_FOUND + qDebug() << "Setting NAM."; + TomahawkUtils::setNam( lastfm::nam() ); + #else + qDebug() << "Setting NAM."; + TomahawkUtils::setNam( new QNetworkAccessManager() ); + #endif + TomahawkUtils::NetworkProxyFactory* proxyFactory = new TomahawkUtils::NetworkProxyFactory(); if( s->proxyType() != QNetworkProxy::NoProxy && @@ -212,20 +220,15 @@ TomahawkApp::init() qDebug() << "Setting proxy to saved values"; QNetworkProxy proxy( static_cast( s->proxyType() ), s->proxyHost(), s->proxyPort(), s->proxyUsername(), s->proxyPassword() ); proxyFactory->setProxy( proxy ); + //TODO: On Windows and Mac because liblastfm sets an application level proxy it may override our factory, so may need to explicitly do + //a QNetworkProxy::setApplicationProxy with our own proxy (but then also overriding our own factory :-( ) } if ( !s->proxyNoProxyHosts().isEmpty() ) proxyFactory->setNoProxyHosts( s->proxyNoProxyHosts().split( ',', QString::SkipEmptyParts ) ); - TomahawkUtils::NetworkProxyFactory::setApplicationProxyFactory( proxyFactory ); - -#ifdef LIBLASTFM_FOUND - qDebug() << "Setting NAM."; - TomahawkUtils::setNam( lastfm::nam() ); -#else - qDebug() << "Setting NAM."; - TomahawkUtils::setNam( new QNetworkAccessManager() ); -#endif - + + TomahawkUtils::setProxyFactory( proxyFactory ); + Echonest::Config::instance()->setAPIKey( "JRIHWEP6GPOER2QQ6" ); m_audioEngine = QWeakPointer( new AudioEngine ); From 75ec478caed605973db3f3d7720948e63a881ef6 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Mon, 27 Jun 2011 21:06:36 +0200 Subject: [PATCH 56/86] Fix streaming from https-links --- src/libtomahawk/audio/audioengine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libtomahawk/audio/audioengine.cpp b/src/libtomahawk/audio/audioengine.cpp index f3f6362b6..0ee4a37da 100644 --- a/src/libtomahawk/audio/audioengine.cpp +++ b/src/libtomahawk/audio/audioengine.cpp @@ -520,7 +520,7 @@ AudioEngine::setCurrentTrack( const Tomahawk::result_ptr& result ) bool AudioEngine::isHttpResult( const QString& url ) const { - return url.startsWith( "http://" ); + return url.startsWith( "http://" ) || url.startsWith( "https://" ); } From d35fbd50484e0cd7a2f0b425e8453fc6e36056bb Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Mon, 27 Jun 2011 21:07:22 +0200 Subject: [PATCH 57/86] Make debug output more readable and assert on javascript failures --- src/resolvers/qtscriptresolver.cpp | 2 ++ src/resolvers/qtscriptresolver.h | 8 +++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/resolvers/qtscriptresolver.cpp b/src/resolvers/qtscriptresolver.cpp index 664ec321f..642bac917 100644 --- a/src/resolvers/qtscriptresolver.cpp +++ b/src/resolvers/qtscriptresolver.cpp @@ -116,12 +116,14 @@ QtScriptResolver::QtScriptResolver( const QString& scriptPath ) m_engine->mainFrame()->addToJavaScriptWindowObject( "Tomahawk", m_resolverHelper ); // add rest of it + m_engine->setScriptPath( "tomahawk.js" ); QFile jslib( RESPATH "js/tomahawk.js" ); jslib.open( QIODevice::ReadOnly ); m_engine->mainFrame()->evaluateJavaScript( jslib.readAll() ); jslib.close(); // execute resolver + m_engine->setScriptPath( scriptPath ); m_engine->mainFrame()->evaluateJavaScript( scriptFile.readAll() ); scriptFile.close(); diff --git a/src/resolvers/qtscriptresolver.h b/src/resolvers/qtscriptresolver.h index f55f50433..20ac3fc47 100644 --- a/src/resolvers/qtscriptresolver.h +++ b/src/resolvers/qtscriptresolver.h @@ -70,6 +70,11 @@ public: settings()->setAttribute( QWebSettings::LocalStorageDatabaseEnabled, true ); } + void setScriptPath( const QString& scriptPath ) + { + m_scriptPath = scriptPath; + } + public slots: bool shouldInterruptJavaScript() { @@ -78,10 +83,11 @@ public slots: protected: virtual void javaScriptConsoleMessage( const QString & message, int lineNumber, const QString & sourceID ) - { qDebug() << "JAVASCRIPT:" << message << lineNumber << sourceID; } + { qDebug() << "JAVASCRIPT:" << m_scriptPath << message << lineNumber << sourceID; Q_ASSERT(false);} private: QtScriptResolver* m_parent; + QString m_scriptPath; }; From 6f0321f5851ec6e3736c60f1b52eec5228c7bab5 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Mon, 27 Jun 2011 21:33:44 +0200 Subject: [PATCH 58/86] Add tomahawk.js --- data/js/tomahawk.js | 259 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 259 insertions(+) create mode 100644 data/js/tomahawk.js diff --git a/data/js/tomahawk.js b/data/js/tomahawk.js new file mode 100644 index 000000000..0206a8b59 --- /dev/null +++ b/data/js/tomahawk.js @@ -0,0 +1,259 @@ + +// if run in phantomjs add fake Tomahawk environment +if(window.Tomahawk === undefined) +{ + alert("PHANTOMJS ENVIRONMENT"); + var Tomahawk = { + resolverData: function() + { + return { + scriptPath: function() + { + return "/home/tomahawk/resolver.js"; + } + }; + } + }; +} + +Tomahawk.resolver = { + scriptPath: Tomahawk.resolverData().scriptPath +}; + + +// javascript part of Tomahawk-Object API +Tomahawk.extend = function(object, members) { + var F = function() {}; + F.prototype = object; + var newObject = new F; + + for(var key in members) + { + newObject[key] = members[key]; + } + + return newObject; +} + + +// Resolver BaseObject, inherit it to implement your own resolver +var TomahawkResolver = { + scriptPath: function() + { + return Tomahawk.resolverData().scriptPath; + }, + getConfigUi: function() + { + return {}; + }, + getUserConfig: function() + { + var configJson = window.localStorage[this.scriptPath()]; + if(configJson === undefined) + configJson = "{}"; + + var config = JSON.parse(configJson); + + return config; + }, + saveUserConfig: function() + { + var config = Tomahawk.resolverData().config; + var configJson = JSON.stringify(config); + + window.localStorage[this.scriptPath()] = configJson; + } +}; + +/**** begin example implementation of a resolver ****/ + + +// implement the resolver +/* + * var DemoResolver = Tomahawk.extend(TomahawkResolver, + * { + * getSettings: function() + * { + * return { + * name: "Demo Resolver", + * weigth: 95, + * timeout: 5, + * limit: 10 + }; + }, + resolve: function( qid, artist, album, track ) + { + return { + qid: qid, + results: [ + { + artist: "Mokele", + album: "You Yourself are Me Myself and I am in Love", + track: "Hiding In Your Insides (php)", + source: "Mokele.co.uk", + url: "http://play.mokele.co.uk/music/Hiding%20In%20Your%20Insides.mp3", + bitrate: 160, + duration: 248, + size: 4971780, + score: 1.0, + extension: "mp3", + mimetype: "audio/mpeg" + } + ] + }; + } + } + ); + + // register the resolver + Tomahawk.resolver.instance = DemoResolver;*/ + +/**** end example implementation of a resolver ****/ + + +// help functions + +Tomahawk.valueForSubNode = function(node, tag) +{ + if(node === undefined) + throw new Error("Tomahawk.valueForSubnode: node is undefined!"); + + return node.getElementsByTagName(tag)[0].textContent; +}; + + +Tomahawk.syncRequest = function(url) +{ + var xmlHttpRequest = new XMLHttpRequest(); + xmlHttpRequest.open('GET', url, false); + xmlHttpRequest.send(null); + return xmlHttpRequest.responseText; +} + +/** +* +* Secure Hash Algorithm (SHA256) +* http://www.webtoolkit.info/ +* +* Original code by Angel Marin, Paul Johnston. +* +**/ + +Tomahawk.sha256=function(s){ + + var chrsz = 8; + var hexcase = 0; + + function safe_add (x, y) { + var lsw = (x & 0xFFFF) + (y & 0xFFFF); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); + } + + function S (X, n) { return ( X >>> n ) | (X << (32 - n)); } + function R (X, n) { return ( X >>> n ); } + function Ch(x, y, z) { return ((x & y) ^ ((~x) & z)); } + function Maj(x, y, z) { return ((x & y) ^ (x & z) ^ (y & z)); } + function Sigma0256(x) { return (S(x, 2) ^ S(x, 13) ^ S(x, 22)); } + function Sigma1256(x) { return (S(x, 6) ^ S(x, 11) ^ S(x, 25)); } + function Gamma0256(x) { return (S(x, 7) ^ S(x, 18) ^ R(x, 3)); } + function Gamma1256(x) { return (S(x, 17) ^ S(x, 19) ^ R(x, 10)); } + + function core_sha256 (m, l) { + var K = new Array(0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, 0xE49B69C1, 0xEFBE4786, 0xFC19DC6, 0x240CA1CC, 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147, 0x6CA6351, 0x14292967, 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2); + var HASH = new Array(0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19); + var W = new Array(64); + var a, b, c, d, e, f, g, h, i, j; + var T1, T2; + + m[l >> 5] |= 0x80 << (24 - l % 32); + m[((l + 64 >> 9) << 4) + 15] = l; + + for ( var i = 0; i>5] |= (str.charCodeAt(i / chrsz) & mask) << (24 - i%32); + } + return bin; + } + + function Utf8Encode(string) { + string = string.replace(/\r\n/g,"\n"); + var utftext = ""; + + for (var n = 0; n < string.length; n++) { + + var c = string.charCodeAt(n); + + if (c < 128) { + utftext += String.fromCharCode(c); + } + else if((c > 127) && (c < 2048)) { + utftext += String.fromCharCode((c >> 6) | 192); + utftext += String.fromCharCode((c & 63) | 128); + } + else { + utftext += String.fromCharCode((c >> 12) | 224); + utftext += String.fromCharCode(((c >> 6) & 63) | 128); + utftext += String.fromCharCode((c & 63) | 128); + } + + } + + return utftext; + } + + function binb2hex (binarray) { + var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; + var str = ""; + for(var i = 0; i < binarray.length * 4; i++) { + str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) + + hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8 )) & 0xF); + } + return str; + } + + s = Utf8Encode(s); + return binb2hex(core_sha256(str2binb(s), s.length * chrsz)); + +} From c276e58c55bf42b9585006120ca5b7296b0bf3d3 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Tue, 28 Jun 2011 13:47:35 +0200 Subject: [PATCH 59/86] Add default implementations of search and resolve to the QtScriptResolver API --- data/js/tomahawk.js | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/data/js/tomahawk.js b/data/js/tomahawk.js index 0206a8b59..3b7bc2525 100644 --- a/data/js/tomahawk.js +++ b/data/js/tomahawk.js @@ -48,20 +48,31 @@ var TomahawkResolver = { }, getUserConfig: function() { - var configJson = window.localStorage[this.scriptPath()]; - if(configJson === undefined) + var configJson = window.localStorage[ this.scriptPath() ]; + if( configJson === undefined ) configJson = "{}"; - var config = JSON.parse(configJson); + var config = JSON.parse( configJson ); return config; }, saveUserConfig: function() { var config = Tomahawk.resolverData().config; - var configJson = JSON.stringify(config); + var configJson = JSON.stringify( config ); - window.localStorage[this.scriptPath()] = configJson; + window.localStorage[ this.scriptPath() ] = configJson; + }, + resolve: function( qid, artist, album, title ) + { + return { + qid: qid, + results: [] + }; + }, + search: function( qid, searchString ) + { + return this.resolve( qid, "", "", searchString ); } }; From 07d9360a654072b04734de10406396303b5b4494 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Tue, 28 Jun 2011 09:00:16 -0400 Subject: [PATCH 60/86] Massive cleanup of echonest plugin, also some cleanup for lastfmplugin. Hope I didn't break anything. :-) --- src/libtomahawk/audio/audioengine.cpp | 4 +- .../infoplugins/generic/echonestplugin.cpp | 67 +++++++++++-------- .../infoplugins/generic/echonestplugin.h | 5 -- .../infoplugins/generic/lastfmplugin.cpp | 17 ++--- .../infoplugins/generic/lastfmplugin.h | 2 - src/libtomahawk/infosystem/infosystem.cpp | 4 +- src/libtomahawk/infosystem/infosystem.h | 6 +- src/xmppbot/xmppbot.cpp | 2 +- src/xmppbot/xmppbot.h | 2 +- 9 files changed, 54 insertions(+), 55 deletions(-) diff --git a/src/libtomahawk/audio/audioengine.cpp b/src/libtomahawk/audio/audioengine.cpp index 9491275d0..dd5a910b4 100644 --- a/src/libtomahawk/audio/audioengine.cpp +++ b/src/libtomahawk/audio/audioengine.cpp @@ -147,7 +147,7 @@ AudioEngine::stop() setCurrentTrack( Tomahawk::result_ptr() ); emit stopped(); - Tomahawk::InfoSystem::InfoMap map; + Tomahawk::InfoSystem::InfoTypeMap map; map[ Tomahawk::InfoSystem::InfoNowStopped ] = QVariant(); if ( m_waitingOnNewTrack ) @@ -319,7 +319,7 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result ) DatabaseCommand_LogPlayback* cmd = new DatabaseCommand_LogPlayback( m_currentTrack, DatabaseCommand_LogPlayback::Started ); Database::instance()->enqueue( QSharedPointer(cmd) ); - Tomahawk::InfoSystem::InfoMap map; + Tomahawk::InfoSystem::InfoTypeMap map; Tomahawk::InfoSystem::InfoCriteriaHash trackInfo; trackInfo["title"] = m_currentTrack->track(); diff --git a/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.cpp b/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.cpp index bca856a2b..7034b565e 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.cpp @@ -63,7 +63,6 @@ EchoNestPlugin::namChangedSlot( QNetworkAccessManager *nam ) newProxyFactory->setNoProxyHosts( oldProxyFactory->noProxyHosts() ); newProxyFactory->setProxy( oldProxyFactory->proxy() ); currNam->setProxyFactory( newProxyFactory ); - m_nam = QWeakPointer< QNetworkAccessManager >( currNam ); } void @@ -116,10 +115,10 @@ EchoNestPlugin::getArtistBiography(const QString &caller, const QVariant &input, Echonest::Artist artist( input.toString() ); QNetworkReply *reply = artist.fetchBiographies(); - reply->setProperty("artist", QVariant::fromValue(artist)); + reply->setProperty( "artist", QVariant::fromValue< Echonest::Artist >( artist ) ); reply->setProperty( "input", input ); - m_replyMap[reply] = customData; - m_callerMap[reply] = caller; + reply->setProperty( "customData", customData ); + reply->setProperty( "caller", caller ); connect(reply, SIGNAL(finished()), SLOT(getArtistBiographySlot())); } @@ -134,8 +133,8 @@ EchoNestPlugin::getArtistFamiliarity(const QString &caller, const QVariant &inpu QNetworkReply* reply = artist.fetchFamiliarity(); reply->setProperty( "artist", QVariant::fromValue(artist)); reply->setProperty( "input", input ); - m_replyMap[reply] = customData; - m_callerMap[reply] = caller; + reply->setProperty( "customData", customData ); + reply->setProperty( "caller", caller ); connect(reply, SIGNAL(finished()), SLOT(getArtistFamiliaritySlot())); } @@ -149,8 +148,8 @@ EchoNestPlugin::getArtistHotttnesss(const QString &caller, const QVariant &input QNetworkReply* reply = artist.fetchHotttnesss(); reply->setProperty( "artist", QVariant::fromValue(artist)); reply->setProperty( "input", input ); - m_replyMap[reply] = customData; - m_callerMap[reply] = caller; + reply->setProperty( "customData", customData ); + reply->setProperty( "caller", caller ); connect(reply, SIGNAL(finished()), SLOT(getArtistHotttnesssSlot())); } @@ -164,9 +163,9 @@ EchoNestPlugin::getArtistTerms(const QString &caller, const QVariant &input, con QNetworkReply* reply = artist.fetchTerms( Echonest::Artist::Weight ); reply->setProperty( "artist", QVariant::fromValue(artist)); reply->setProperty( "input", input ); - m_replyMap[reply] = customData; - m_callerMap[reply] = caller; - connect(reply, SIGNAL(finished()), SLOT(getArtistTermsSlot())); + reply->setProperty( "customData", customData ); + reply->setProperty( "caller", caller ); + connect(reply, SIGNAL( finished() ), SLOT( getArtistTermsSlot() ) ); } void @@ -174,9 +173,9 @@ EchoNestPlugin::getMiscTopTerms(const QString &caller, const QVariant &input, co { Q_UNUSED( input ); QNetworkReply* reply = Echonest::Artist::topTerms( 20 ); - m_replyMap[reply] = customData; - m_callerMap[reply] = caller; - connect( reply,SIGNAL(finished()), SLOT( getMiscTopSlot())); + reply->setProperty( "customData", customData ); + reply->setProperty( "caller", caller ); + connect( reply, SIGNAL( finished() ), SLOT( getMiscTopSlot() ) ); } @@ -197,9 +196,11 @@ EchoNestPlugin::getArtistBiographySlot() biographyMap[biography.site()]["attribution"] = biography.license().url.toString(); } - emit info( m_callerMap[reply], Tomahawk::InfoSystem::InfoArtistBiography, reply->property( "input" ), QVariant::fromValue(biographyMap), m_replyMap[reply] ); - m_replyMap.remove(reply); - m_callerMap.remove(reply); + emit info( reply->property( "caller" ).toString(), + Tomahawk::InfoSystem::InfoArtistBiography, + reply->property( "input" ), + QVariant::fromValue< Tomahawk::InfoSystem::InfoGenericMap >( biographyMap ), + reply->property( "customData" ).value< Tomahawk::InfoSystem::InfoCustomData >() ); reply->deleteLater(); } @@ -209,9 +210,11 @@ EchoNestPlugin::getArtistFamiliaritySlot() QNetworkReply* reply = qobject_cast( sender() ); Echonest::Artist artist = artistFromReply( reply ); qreal familiarity = artist.familiarity(); - emit info( m_callerMap[reply], Tomahawk::InfoSystem::InfoArtistFamiliarity, reply->property( "input" ), familiarity, m_replyMap[reply] ); - m_replyMap.remove(reply); - m_callerMap.remove(reply); + emit info( reply->property( "caller" ).toString(), + Tomahawk::InfoSystem::InfoArtistFamiliarity, + reply->property( "input" ), + familiarity, + reply->property( "customData" ).value< Tomahawk::InfoSystem::InfoCustomData >() ); reply->deleteLater(); } @@ -221,9 +224,11 @@ EchoNestPlugin::getArtistHotttnesssSlot() QNetworkReply* reply = qobject_cast( sender() ); Echonest::Artist artist = artistFromReply( reply ); qreal hotttnesss = artist.hotttnesss(); - emit info( m_callerMap[reply], Tomahawk::InfoSystem::InfoArtistHotttness, reply->property( "input" ), hotttnesss, m_replyMap[reply] ); - m_replyMap.remove(reply); - m_callerMap.remove(reply); + emit info( reply->property( "caller" ).toString(), + Tomahawk::InfoSystem::InfoArtistHotttness, + reply->property( "input" ), + hotttnesss, + reply->property( "customData" ).value< Tomahawk::InfoSystem::InfoCustomData >() ); reply->deleteLater(); } @@ -240,9 +245,11 @@ EchoNestPlugin::getArtistTermsSlot() termMap[ "frequency" ] = QString::number(term.frequency()); termsMap[ term.name() ] = termMap; } - emit info( m_callerMap[reply], Tomahawk::InfoSystem::InfoArtistTerms, reply->property( "input" ), QVariant::fromValue(termsMap), m_replyMap[reply] ); - m_replyMap.remove(reply); - m_callerMap.remove(reply); + emit info( reply->property( "caller" ).toString(), + Tomahawk::InfoSystem::InfoArtistTerms, + reply->property( "input" ), + QVariant::fromValue< Tomahawk::InfoSystem::InfoGenericMap >( termsMap ), + reply->property( "customData" ).value< Tomahawk::InfoSystem::InfoCustomData >() ); reply->deleteLater(); } @@ -258,9 +265,11 @@ EchoNestPlugin::getMiscTopSlot() termMap[ "frequency" ] = QString::number( term.frequency() ); termsMap[ term.name().toLower() ] = termMap; } - emit info( m_callerMap[reply], Tomahawk::InfoSystem::InfoMiscTopTerms, QVariant(), QVariant::fromValue(termsMap), m_replyMap[reply] ); - m_replyMap.remove(reply); - m_callerMap.remove(reply); + emit info( reply->property( "caller" ).toString(), + Tomahawk::InfoSystem::InfoMiscTopTerms, + QVariant(), + QVariant::fromValue< Tomahawk::InfoSystem::InfoGenericMap >( termsMap ), + reply->property( "customData" ).value< Tomahawk::InfoSystem::InfoCustomData >() ); reply->deleteLater(); } diff --git a/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.h b/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.h index bd21cbca2..e27a306f7 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.h +++ b/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.h @@ -83,11 +83,6 @@ private slots: void getArtistHotttnesssSlot(); void getArtistTermsSlot(); void getMiscTopSlot(); - -private: - QHash< QNetworkReply*, InfoCustomData > m_replyMap; - QHash< QNetworkReply*, QString > m_callerMap; - QWeakPointer< QNetworkAccessManager > m_nam; }; } diff --git a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp index 387becd3b..d26efe385 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp @@ -115,9 +115,6 @@ LastFmPlugin::namChangedSlot( QNetworkAccessManager *nam ) currNam->setProxyFactory( newProxyFactory ); //FIXME: on Mac/Win as liblastfm's network access manager also sets its overriding application proxy //may have to do a QNetworkProxy::setApplicationProxy and clobber our own factory to override it - - m_nam = QWeakPointer< QNetworkAccessManager >( currNam ); - settingsChanged(); // to get the scrobbler set up } @@ -309,7 +306,7 @@ LastFmPlugin::notInCacheSlot( const QHash criteria, const QStr { qDebug() << Q_FUNC_INFO; - if ( m_nam.isNull() ) + if ( !lastfm::nam() ) { qDebug() << "Have a null QNAM, uh oh"; emit info( caller, type, input, QVariant(), customData ); @@ -325,7 +322,7 @@ LastFmPlugin::notInCacheSlot( const QHash criteria, const QStr QString imgurl = "http://ws.audioscrobbler.com/2.0/?method=album.imageredirect&artist=%1&album=%2&autocorrect=1&size=large&api_key=7a90f6672a04b809ee309af169f34b8b"; QNetworkRequest req( imgurl.arg( artistName ).arg( albumName ) ); - QNetworkReply* reply = m_nam.data()->get( req ); + QNetworkReply* reply = lastfm::nam()->get( req ); reply->setProperty( "customData", QVariant::fromValue( customData ) ); reply->setProperty( "origData", input ); reply->setProperty( "caller", caller ); @@ -341,7 +338,7 @@ LastFmPlugin::notInCacheSlot( const QHash criteria, const QStr 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 = m_nam.data()->get( req ); + QNetworkReply* reply = lastfm::nam()->get( req ); reply->setProperty( "customData", QVariant::fromValue( customData ) ); reply->setProperty( "origData", input ); reply->setProperty( "caller", caller ); @@ -406,7 +403,7 @@ LastFmPlugin::coverArtReturned() } else { - if ( m_nam.isNull() ) + if ( !lastfm::nam() ) { qDebug() << "Uh oh, nam is null"; InfoType type = (Tomahawk::InfoSystem::InfoType)(reply->property( "type" ).toUInt()); @@ -416,7 +413,7 @@ LastFmPlugin::coverArtReturned() } // Follow HTTP redirect QNetworkRequest req( redir ); - QNetworkReply* newReply = m_nam.data()->get( req ); + QNetworkReply* newReply = lastfm::nam()->get( req ); newReply->setProperty( "origData", reply->property( "origData" ) ); newReply->setProperty( "customData", reply->property( "customData" ) ); newReply->setProperty( "caller", reply->property( "caller" ) ); @@ -465,7 +462,7 @@ LastFmPlugin::artistImagesReturned() } else { - if ( m_nam.isNull() ) + if ( !lastfm::nam() ) { qDebug() << "Uh oh, nam is null"; InfoType type = (Tomahawk::InfoSystem::InfoType)(reply->property( "type" ).toUInt()); @@ -475,7 +472,7 @@ LastFmPlugin::artistImagesReturned() } // Follow HTTP redirect QNetworkRequest req( redir ); - QNetworkReply* newReply = m_nam.data()->get( req ); + QNetworkReply* newReply = lastfm::nam()->get( req ); newReply->setProperty( "origData", reply->property( "origData" ) ); newReply->setProperty( "customData", reply->property( "customData" ) ); newReply->setProperty( "caller", reply->property( "caller" ) ); diff --git a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.h b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.h index 597082638..e2b470770 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.h +++ b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.h @@ -74,8 +74,6 @@ private: QString m_pw; QList< QUrl > m_badUrls; - - QWeakPointer< QNetworkAccessManager > m_nam; }; } diff --git a/src/libtomahawk/infosystem/infosystem.cpp b/src/libtomahawk/infosystem/infosystem.cpp index 611533ade..4fe9af12f 100644 --- a/src/libtomahawk/infosystem/infosystem.cpp +++ b/src/libtomahawk/infosystem/infosystem.cpp @@ -127,7 +127,7 @@ InfoSystem::getInfo( const QString &caller, const InfoType type, const QVariant& void -InfoSystem::getInfo( const QString &caller, const InfoMap &input, InfoCustomData customData ) +InfoSystem::getInfo( const QString &caller, const InfoTypeMap &input, InfoCustomData customData ) { Q_FOREACH( InfoType type, input.keys() ) getInfo( caller, type, input[type], customData ); @@ -144,7 +144,7 @@ InfoSystem::pushInfo( const QString &caller, const InfoType type, const QVariant void -InfoSystem::pushInfo( const QString &caller, const InfoMap &input ) +InfoSystem::pushInfo( const QString &caller, const InfoTypeMap &input ) { Q_FOREACH( InfoType type, input.keys() ) pushInfo( caller, type, input[type] ); diff --git a/src/libtomahawk/infosystem/infosystem.h b/src/libtomahawk/infosystem/infosystem.h index 0dea90be1..2a3c873d8 100644 --- a/src/libtomahawk/infosystem/infosystem.h +++ b/src/libtomahawk/infosystem/infosystem.h @@ -107,7 +107,7 @@ enum InfoType { // as items are saved in cache, mark them here to not change the InfoNotifyUser = 55 }; -typedef QMap< InfoType, QVariant > InfoMap; +typedef QMap< InfoType, QVariant > InfoTypeMap; typedef QMap< QString, QMap< QString, QString > > InfoGenericMap; typedef QHash< QString, QVariant > InfoCustomData; typedef QHash< QString, QString > InfoCriteriaHash; @@ -159,9 +159,9 @@ public: ~InfoSystem(); void getInfo( const QString &caller, const InfoType type, const QVariant &input, InfoCustomData customData ); - void getInfo( const QString &caller, const InfoMap &input, InfoCustomData customData ); + void getInfo( const QString &caller, const InfoTypeMap &input, InfoCustomData customData ); void pushInfo( const QString &caller, const InfoType type, const QVariant &input ); - void pushInfo( const QString &caller, const InfoMap &input ); + void pushInfo( const QString &caller, const InfoTypeMap &input ); signals: void info( QString caller, Tomahawk::InfoSystem::InfoType, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ); diff --git a/src/xmppbot/xmppbot.cpp b/src/xmppbot/xmppbot.cpp index 404d64fd2..01ebe5509 100644 --- a/src/xmppbot/xmppbot.cpp +++ b/src/xmppbot/xmppbot.cpp @@ -201,7 +201,7 @@ void XMPPBot::handleMessage(const Message& msg, MessageSession* session) return; } - InfoMap infoMap; + InfoTypeMap infoMap; Q_FOREACH(QString token, tokens) { if (token == "biography") diff --git a/src/xmppbot/xmppbot.h b/src/xmppbot/xmppbot.h index e22a564ae..20b504118 100644 --- a/src/xmppbot/xmppbot.h +++ b/src/xmppbot/xmppbot.h @@ -87,7 +87,7 @@ private slots: private: QWeakPointer m_client; Tomahawk::result_ptr m_currTrack; - Tomahawk::InfoSystem::InfoMap m_currInfoMap; + Tomahawk::InfoSystem::InfoTypeMap m_currInfoMap; QString m_currReturnMessage; QString m_currReturnJid; }; From 3f48e93a89a01eac79ecca993f1b7e583275521e Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Tue, 28 Jun 2011 13:59:11 -0400 Subject: [PATCH 61/86] Show album covers in notifications when playing a track instead of the source image. Need to implement some sort of timeout for getInfo. --- src/libtomahawk/audio/audioengine.cpp | 95 ++++++++++++++++++++++----- src/libtomahawk/audio/audioengine.h | 8 ++- 2 files changed, 87 insertions(+), 16 deletions(-) diff --git a/src/libtomahawk/audio/audioengine.cpp b/src/libtomahawk/audio/audioengine.cpp index dd5a910b4..a9dad2dcf 100644 --- a/src/libtomahawk/audio/audioengine.cpp +++ b/src/libtomahawk/audio/audioengine.cpp @@ -26,7 +26,6 @@ #include "database/database.h" #include "database/databasecommand_logplayback.h" -#include "infosystem/infosystem.h" #include "network/servent.h" #include "album.h" @@ -53,6 +52,7 @@ AudioEngine::AudioEngine() , m_timeElapsed( 0 ) , m_expectStop( false ) , m_waitingOnNewTrack( false ) + , m_infoSystemConnected( false ) { s_instance = this; qDebug() << "Init AudioEngine"; @@ -248,6 +248,79 @@ AudioEngine::sendWaitingNotification() const } +void +AudioEngine::sendNowPlayingNotification() +{ + qDebug() << Q_FUNC_INFO; + + if ( ! m_infoSystemConnected ) + { + 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( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( finished( QString ) ), SLOT( infoSystemFinished( QString ) ) ); + + m_infoSystemConnected = true; + } + + Tomahawk::InfoSystem::InfoCriteriaHash trackInfo; + trackInfo["artist"] = m_currentTrack->album()->artist()->name(); + trackInfo["album"] = m_currentTrack->album()->name(); + + Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( + s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoAlbumCoverArt, + QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ), Tomahawk::InfoSystem::InfoCustomData() ); +} + + +void +AudioEngine::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ) +{ + qDebug() << Q_FUNC_INFO; + Q_UNUSED( input ); + Q_UNUSED( customData ); + + if ( caller != s_aeInfoIdentifier || + ( type != Tomahawk::InfoSystem::InfoAlbumCoverArt ) ) + { + qDebug() << Q_FUNC_INFO << " not desgined for us, caller is " << caller; + return; + } + + Tomahawk::InfoSystem::InfoCustomData playInfo; + playInfo["message"] = QString( "Tomahawk is playing \"%1\" by %2 on album %3." ) + .arg( m_currentTrack->track() ) + .arg( m_currentTrack->artist()->name() ) + .arg( m_currentTrack->album()->name() ); + if ( !output.isNull() && output.isValid() ) + { + qDebug() << Q_FUNC_INFO << " output is valid"; + Tomahawk::InfoSystem::InfoCustomData returnedData = output.value< Tomahawk::InfoSystem::InfoCustomData >(); + const QByteArray ba = returnedData["imgbytes"].toByteArray(); + qDebug() << "ba.length = " << ba.length(); + if ( ba.length() ) + { + QPixmap pm; + pm.loadFromData( ba ); + playInfo["image"] = QVariant( pm.toImage() ); + } + } + + Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( + s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNotifyUser, + QVariant::fromValue< Tomahawk::InfoSystem::InfoCustomData >( playInfo ) ); +} + + +void +AudioEngine::infoSystemFinished( QString caller ) +{ + Q_UNUSED( caller ); + qDebug() << Q_FUNC_INFO; +} + + void AudioEngine::onTrackAboutToFinish() { @@ -319,26 +392,18 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result ) DatabaseCommand_LogPlayback* cmd = new DatabaseCommand_LogPlayback( m_currentTrack, DatabaseCommand_LogPlayback::Started ); Database::instance()->enqueue( QSharedPointer(cmd) ); - Tomahawk::InfoSystem::InfoTypeMap map; - Tomahawk::InfoSystem::InfoCriteriaHash trackInfo; trackInfo["title"] = m_currentTrack->track(); trackInfo["artist"] = m_currentTrack->artist()->name(); trackInfo["album"] = m_currentTrack->album()->name(); - map[ Tomahawk::InfoSystem::InfoNowPlaying ] = QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ); - + if ( TomahawkSettings::instance()->verboseNotifications() ) - { - Tomahawk::InfoSystem::InfoCustomData playInfo; - playInfo["message"] = QString( "Tomahawk is playing \"%1\" by %2 on album %3." ) - .arg( m_currentTrack->track() ) - .arg( m_currentTrack->artist()->name() ) - .arg( m_currentTrack->album()->name() ); - playInfo["image"] = QVariant( m_currentTrack->collection()->source()->avatar().toImage() ); - map[ Tomahawk::InfoSystem::InfoNotifyUser ] = QVariant::fromValue< Tomahawk::InfoSystem::InfoCustomData >( playInfo ); - } + sendNowPlayingNotification(); - Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( s_aeInfoIdentifier, map ); + Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( + s_aeInfoIdentifier, + Tomahawk::InfoSystem::InfoNowPlaying, + QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ) ); } } diff --git a/src/libtomahawk/audio/audioengine.h b/src/libtomahawk/audio/audioengine.h index dea60d648..bdc8ee705 100644 --- a/src/libtomahawk/audio/audioengine.h +++ b/src/libtomahawk/audio/audioengine.h @@ -25,6 +25,8 @@ #include #include +#include "infosystem/infosystem.h" + #include "result.h" #include "typedefs.h" @@ -85,6 +87,9 @@ public slots: void playlistNextTrackReady(); + void infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ); + void infoSystemFinished( QString caller ); + signals: void loading( const Tomahawk::result_ptr& track ); void started( const Tomahawk::result_ptr& track ); @@ -118,6 +123,7 @@ private: bool isHttpResult( const QString& ) const; bool isLocalResult( const QString& ) const; void sendWaitingNotification() const; + void sendNowPlayingNotification(); bool m_isPlayingHttp; QSharedPointer m_input; @@ -133,8 +139,8 @@ private: unsigned int m_timeElapsed; bool m_expectStop; - bool m_waitingOnNewTrack; + bool m_infoSystemConnected; static AudioEngine* s_instance; }; From c9fb10362708d3b48f2cc6bb098bd0634f2f9817 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Tue, 28 Jun 2011 21:29:44 +0200 Subject: [PATCH 62/86] More API cleanup for QtScriptResolver --- data/js/tomahawk.js | 35 ++++++++++++++++++++++++++++-- src/resolvers/qtscriptresolver.cpp | 29 +++++++++++++++++++------ src/resolvers/qtscriptresolver.h | 4 ++++ 3 files changed, 59 insertions(+), 9 deletions(-) diff --git a/data/js/tomahawk.js b/data/js/tomahawk.js index 3b7bc2525..88e0a7bf7 100644 --- a/data/js/tomahawk.js +++ b/data/js/tomahawk.js @@ -4,6 +4,10 @@ if(window.Tomahawk === undefined) { alert("PHANTOMJS ENVIRONMENT"); var Tomahawk = { + fakeEnv: function() + { + return true; + }, resolverData: function() { return { @@ -12,14 +16,34 @@ if(window.Tomahawk === undefined) return "/home/tomahawk/resolver.js"; } }; + }, + log: function( message ) + { + console.log( message ); } }; } + Tomahawk.resolver = { scriptPath: Tomahawk.resolverData().scriptPath }; +Tomahawk.timestamp = function() { + return Math.round( new Date()/1000 ); +} + +Tomahawk.dumpResult = function( result ) { + var results = result.results; + Tomahawk.log("Dumping " + results.length + " results for query " + result.qid + "..."); + for(var i=0; imainFrame()->evaluateJavaScript( jslib.readAll() ); jslib.close(); - // execute resolver + // add resolver m_engine->setScriptPath( scriptPath ); m_engine->mainFrame()->evaluateJavaScript( scriptFile.readAll() ); scriptFile.close(); + // init resolver + resolverInit(); + QVariantMap m = resolverSettings(); m_name = m.value( "name" ).toString(); @@ -167,7 +176,7 @@ QtScriptResolver::resolve( const Tomahawk::query_ptr& query ) if ( !query->isFullTextQuery() ) { - eval = QString( "Tomahawk.resolver.instance.resolve( '%1', '%2', '%3', '%4' );" ) + eval = QString( "Tomahawk.resolver.instance.resolve( '%1', '%4', '%3', '%4' );" ) .arg( query->id().replace( "'", "\\'" ) ) .arg( query->artist().replace( "'", "\\'" ) ) .arg( query->album().replace( "'", "\\'" ) ) @@ -175,11 +184,9 @@ QtScriptResolver::resolve( const Tomahawk::query_ptr& query ) } else { - eval = QString( "Tomahawk.resolver.instance.resolve( '%1', '%2', '%3', '%4' );" ) + eval = QString( "Tomahawk.resolver.instance.search( '%1', '%2' );" ) .arg( query->id().replace( "'", "\\'" ) ) - .arg( query->fullTextQuery().replace( "'", "\\'" ) ) - .arg( QString() ) - .arg( QString() ); + .arg( query->fullTextQuery().replace( "'", "\\'" ) ); } QList< Tomahawk::result_ptr > results; @@ -415,7 +422,7 @@ QtScriptResolver::fillDataInWidgets( const QVariantMap& data ) QVariantMap QtScriptResolver::resolverSettings() { - return m_engine->mainFrame()->evaluateJavaScript( "Tomahawk.resolver.instance.getSettings();" ).toMap(); + return m_engine->mainFrame()->evaluateJavaScript( "Tomahawk.resolver.instance.settings;" ).toMap(); } @@ -424,3 +431,11 @@ QtScriptResolver::resolverUserConfig() { return m_engine->mainFrame()->evaluateJavaScript( "Tomahawk.resolver.instance.getUserConfig();" ).toMap(); } + + +QVariantMap +QtScriptResolver::resolverInit() +{ + return m_engine->mainFrame()->evaluateJavaScript( "Tomahawk.resolver.instance.init();" ).toMap(); +} + diff --git a/src/resolvers/qtscriptresolver.h b/src/resolvers/qtscriptresolver.h index 20ac3fc47..86475df4f 100644 --- a/src/resolvers/qtscriptresolver.h +++ b/src/resolvers/qtscriptresolver.h @@ -49,6 +49,9 @@ public slots: QString compress( const QString& data ); QVariantMap resolverData(); + void log( const QString& message); + bool fakeEnv() { return false; } + private: QString m_scriptPath; QVariantMap m_resolverConfig; @@ -124,6 +127,7 @@ private: // encapsulate javascript calls QVariantMap resolverSettings(); QVariantMap resolverUserConfig(); + QVariantMap resolverInit(); ScriptEngine* m_engine; From 1416c401726dd58f4f0f7632d18b26b3d5a24baf Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Tue, 28 Jun 2011 22:30:29 +0200 Subject: [PATCH 63/86] Be compatible with the old resolvers *shrug* --- src/resolvers/qtscriptresolver.cpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/resolvers/qtscriptresolver.cpp b/src/resolvers/qtscriptresolver.cpp index acf83631e..abe4e17de 100644 --- a/src/resolvers/qtscriptresolver.cpp +++ b/src/resolvers/qtscriptresolver.cpp @@ -26,6 +26,7 @@ #include +#define RESOLVER_LEGACY_CODE "var resolver = Tomahawk.resolver.instance ? Tomahawk.resolver.instance : TomahawkResolver;" QtScriptResolverHelper::QtScriptResolverHelper( const QString& scriptPath, QObject* parent ) : QObject( parent ) @@ -176,7 +177,7 @@ QtScriptResolver::resolve( const Tomahawk::query_ptr& query ) if ( !query->isFullTextQuery() ) { - eval = QString( "Tomahawk.resolver.instance.resolve( '%1', '%4', '%3', '%4' );" ) + eval = QString( RESOLVER_LEGACY_CODE "resolver.resolve( '%1', '%2', '%3', '%4' );" ) .arg( query->id().replace( "'", "\\'" ) ) .arg( query->artist().replace( "'", "\\'" ) ) .arg( query->album().replace( "'", "\\'" ) ) @@ -184,7 +185,12 @@ QtScriptResolver::resolve( const Tomahawk::query_ptr& query ) } else { - eval = QString( "Tomahawk.resolver.instance.search( '%1', '%2' );" ) + eval = QString( "if(Tomahawk.resolver.instance !== undefined) {" + " resolver.search( '%1', '%2' );" + "} else {" + " resolve( '%1', '', '', '%2' );" + "}" + ) .arg( query->id().replace( "'", "\\'" ) ) .arg( query->fullTextQuery().replace( "'", "\\'" ) ); } @@ -254,7 +260,7 @@ QtScriptResolver::loadUi() { qDebug() << Q_FUNC_INFO; - QVariantMap m = m_engine->mainFrame()->evaluateJavaScript( "Tomahawk.resolver.instance.getConfigUi();" ).toMap(); + QVariantMap m = m_engine->mainFrame()->evaluateJavaScript( RESOLVER_LEGACY_CODE "resolver.getConfigUi();" ).toMap(); m_dataWidgets = m["fields"].toList(); @@ -304,7 +310,7 @@ QtScriptResolver::saveConfig() qDebug() << Q_FUNC_INFO << saveData; m_resolverHelper->setResolverConfig( saveData.toMap() ); - m_engine->mainFrame()->evaluateJavaScript( "Tomahawk.resolver.instance.saveUserConfig();" ); + m_engine->mainFrame()->evaluateJavaScript( RESOLVER_LEGACY_CODE "resolver.saveUserConfig();" ); } @@ -422,20 +428,20 @@ QtScriptResolver::fillDataInWidgets( const QVariantMap& data ) QVariantMap QtScriptResolver::resolverSettings() { - return m_engine->mainFrame()->evaluateJavaScript( "Tomahawk.resolver.instance.settings;" ).toMap(); + return m_engine->mainFrame()->evaluateJavaScript( RESOLVER_LEGACY_CODE "if(resolver.settings) resolver.settings; else getSettings(); " ).toMap(); } QVariantMap QtScriptResolver::resolverUserConfig() { - return m_engine->mainFrame()->evaluateJavaScript( "Tomahawk.resolver.instance.getUserConfig();" ).toMap(); + return m_engine->mainFrame()->evaluateJavaScript( RESOLVER_LEGACY_CODE "resolver.getUserConfig();" ).toMap(); } QVariantMap QtScriptResolver::resolverInit() { - return m_engine->mainFrame()->evaluateJavaScript( "Tomahawk.resolver.instance.init();" ).toMap(); + return m_engine->mainFrame()->evaluateJavaScript( RESOLVER_LEGACY_CODE "resolver.init();" ).toMap(); } From 3d297795c2d8054a245cff90d9507cfcc4d1328d Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Thu, 30 Jun 2011 01:03:15 +0200 Subject: [PATCH 64/86] Be simplistic :D --- data/js/tomahawk.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/data/js/tomahawk.js b/data/js/tomahawk.js index 88e0a7bf7..278ced0c6 100644 --- a/data/js/tomahawk.js +++ b/data/js/tomahawk.js @@ -93,8 +93,7 @@ var TomahawkResolver = { resolve: function( qid, artist, album, title ) { return { - qid: qid, - results: [] + qid: qid }; }, search: function( qid, searchString ) From 25775b505137ecac7809aaac716413043754cf38 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Thu, 30 Jun 2011 01:27:49 +0200 Subject: [PATCH 65/86] Make the Resolver API expect a widgetName instead of a widgetPath We dont have gazillions of widgets in one dialog, so make the API a bit easier to use :) --- src/resolvers/qtscriptresolver.cpp | 37 +++++++++--------------------- src/resolvers/qtscriptresolver.h | 2 +- 2 files changed, 12 insertions(+), 27 deletions(-) diff --git a/src/resolvers/qtscriptresolver.cpp b/src/resolvers/qtscriptresolver.cpp index abe4e17de..4ff0e0151 100644 --- a/src/resolvers/qtscriptresolver.cpp +++ b/src/resolvers/qtscriptresolver.cpp @@ -315,26 +315,21 @@ QtScriptResolver::saveConfig() QWidget* -QtScriptResolver::findWidget(QWidget* widget, const QStringList& widgetPath) +QtScriptResolver::findWidget(QWidget* widget, const QString& objectName) { if( !widget || !widget->isWidgetType() ) return 0; - qDebug() << Q_FUNC_INFO << widget->objectName() << widgetPath; - - if( widgetPath.isEmpty() ) + if( widget->objectName() == objectName ) return widget; - QString searchName = widgetPath.first(); foreach( QObject* child, widget->children() ) { - if( child->isWidgetType() && child->objectName() == searchName ) - { - QStringList newWidgetPath = widgetPath; - newWidgetPath.removeFirst(); - return findWidget(qobject_cast< QWidget* >( child ), newWidgetPath); - } + QWidget* found = findWidget(qobject_cast< QWidget* >( child ), objectName); + + if( found ) + return found; } return 0; @@ -378,13 +373,8 @@ QtScriptResolver::loadDataFromWidgets() { QVariantMap data = dataWidget.toMap(); - QStringList widgetPath; - foreach(const QVariant& pathItem, data["widget"].toList()) - { - widgetPath << pathItem.toString(); - } - - QWidget* widget= findWidget( m_configWidget.data(), widgetPath ); + QString widgetName = data["widget"].toString(); + QWidget* widget= findWidget( m_configWidget.data(), widgetName ); QString value = widgetData( widget, data["property"].toString() ).toString(); @@ -403,16 +393,11 @@ QtScriptResolver::fillDataInWidgets( const QVariantMap& data ) qDebug() << Q_FUNC_INFO << data; foreach(const QVariant& dataWidget, m_dataWidgets) { - QStringList widgetPath; - foreach(const QVariant& pathItem, dataWidget.toMap()["widget"].toList()) - { - widgetPath << pathItem.toString(); - } - - QWidget* widget= findWidget( m_configWidget.data(), widgetPath ); + QString widgetName = dataWidget.toMap()["widget"].toString(); + QWidget* widget= findWidget( m_configWidget.data(), widgetName ); if( !widget ) { - qDebug() << Q_FUNC_INFO << "widget specified in resolver was not found:" << widgetPath; + qDebug() << Q_FUNC_INFO << "widget specified in resolver was not found:" << widgetName; Q_ASSERT(false); return; } diff --git a/src/resolvers/qtscriptresolver.h b/src/resolvers/qtscriptresolver.h index 6ea58c5e0..a988b1e9e 100644 --- a/src/resolvers/qtscriptresolver.h +++ b/src/resolvers/qtscriptresolver.h @@ -119,7 +119,7 @@ signals: private: virtual void loadUi(); - QWidget* findWidget( QWidget* widget, const QStringList& widgetPath ); + QWidget* findWidget( QWidget* widget, const QString& objectName ); void setWidgetData( const QVariant& value, QWidget* widget, const QString& property ); QVariant widgetData( QWidget* widget, const QString& property ); QVariantMap loadDataFromWidgets(); From 11c051916524684f16bed017b03ab1de3b49e51d Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Fri, 1 Jul 2011 16:52:35 -0400 Subject: [PATCH 66/86] Remove extra > --- src/headlesscheck.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/headlesscheck.h b/src/headlesscheck.h index f82fcea33..05f55f4ce 100644 --- a/src/headlesscheck.h +++ b/src/headlesscheck.h @@ -22,8 +22,7 @@ #ifdef ENABLE_HEADLESS #define TOMAHAWK_APPLICATION QCoreApplication -#define TOMAHAWK_HEADLESS -#include > +#include #else From 40fb61b9a920cb23912085f9745dd6e3f7e12b61 Mon Sep 17 00:00:00 2001 From: Christopher Reichert Date: Fri, 1 Jul 2011 21:03:27 -0500 Subject: [PATCH 67/86] Do not allow same jabber credentials more than once. --- src/delegateconfigwrapper.h | 8 ++++++++ src/libtomahawk/sip/SipPlugin.h | 2 ++ src/settingsdialog.cpp | 2 ++ src/sip/jabber/configwidget.ui | 17 ++++++++++++----- src/sip/jabber/jabber.cpp | 29 +++++++++++++++++++++++++++++ src/sip/jabber/jabber.h | 2 ++ 6 files changed, 55 insertions(+), 5 deletions(-) diff --git a/src/delegateconfigwrapper.h b/src/delegateconfigwrapper.h index 9155c2cd4..e0a354e2d 100644 --- a/src/delegateconfigwrapper.h +++ b/src/delegateconfigwrapper.h @@ -21,6 +21,7 @@ #include #include #include +#include class DelegateConfigWrapper : public QDialog { @@ -39,6 +40,7 @@ public: v->addWidget( m_widget ); QDialogButtonBox* buttons = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this ); + m_okButton = buttons->button( QDialogButtonBox::Ok ); connect( buttons, SIGNAL( clicked( QAbstractButton*) ), this, SLOT( closed( QAbstractButton* ) ) ); connect( this, SIGNAL( rejected() ), this, SLOT( rejected() ) ); v->addWidget( buttons ); @@ -57,6 +59,11 @@ public: } public slots: + void toggleOkButton( bool dataError ) + { + // if dataError is True we want to set the button enabled to false + m_okButton->setEnabled( !dataError ); + } void closed( QAbstractButton* b ) { // let the config widget live to see another day @@ -90,6 +97,7 @@ public slots: private: QWidget* m_widget; + QPushButton* m_okButton; }; #endif diff --git a/src/libtomahawk/sip/SipPlugin.h b/src/libtomahawk/sip/SipPlugin.h index 6e803c154..ae8ce58b7 100644 --- a/src/libtomahawk/sip/SipPlugin.h +++ b/src/libtomahawk/sip/SipPlugin.h @@ -113,6 +113,8 @@ signals: void addMenu( QMenu* menu ); void removeMenu( QMenu* menu ); + + void dataError( bool ); private slots: void onError( int, const QString& ); diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index 4ce763879..1639a1a24 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -598,11 +598,13 @@ SettingsDialog::sipFactoryClicked( SipPluginFactory* factory ) DelegateConfigWrapper* dialog = new DelegateConfigWrapper( p->configWidget(), QString("%1 Config" ).arg( p->friendlyName() ), this, Qt::Sheet ); dialog->setProperty( "sipplugin", QVariant::fromValue< QObject* >( p ) ); connect( dialog, SIGNAL( finished( int ) ), this, SLOT( sipCreateConfigClosed( int ) ) ); + connect( p, SIGNAL( datatError( bool ) ), &dialog, SLOT( toggleOkButton( bool ) ) ); dialog->show(); #else DelegateConfigWrapper dialog( p->configWidget(), QString("%1 Config" ).arg( p->friendlyName() ), this ); QWeakPointer< DelegateConfigWrapper > watcher( &dialog ); + connect( p, SIGNAL( dataError( bool ) ), &dialog, SLOT( toggleOkButton( bool ) ) ); int ret = dialog.exec(); if( !watcher.isNull() && ret == QDialog::Accepted ) { // send changed config to resolver diff --git a/src/sip/jabber/configwidget.ui b/src/sip/jabber/configwidget.ui index 456f19255..cd5fd72b1 100644 --- a/src/sip/jabber/configwidget.ui +++ b/src/sip/jabber/configwidget.ui @@ -6,17 +6,14 @@ 0 0 - 433 - 260 + 451 + 335 Jabber Configuration - - 0 - @@ -185,6 +182,16 @@ + + + + An account with this name already exists! + + + Qt::AlignCenter + + +
diff --git a/src/sip/jabber/jabber.cpp b/src/sip/jabber/jabber.cpp index e1b239536..0575651ea 100644 --- a/src/sip/jabber/jabber.cpp +++ b/src/sip/jabber/jabber.cpp @@ -80,11 +80,13 @@ JabberPlugin::JabberPlugin( const QString& pluginId ) m_ui->jabberPassword->setText( readPassword() ); m_ui->jabberServer->setText( readServer() ); m_ui->jabberPort->setValue( readPort() ); + m_ui->jidExistsLabel->hide(); m_currentUsername = accountName(); m_currentServer = readServer(); m_currentPassword = readPassword(); m_currentPort = readPort(); + connect( m_ui->jabberUsername, SIGNAL( textChanged( QString ) ), SLOT( onCheckJidExists( QString ) ) ); // setup JID object Jreen::JID jid = Jreen::JID( accountName() ); @@ -999,6 +1001,33 @@ JabberPlugin::readServer() return TomahawkSettings::instance()->value( pluginId() + "/server" ).toString(); } + +void +JabberPlugin::onCheckJidExists( QString jid ) +{ + for ( int i=0; isipPlugins().count(); i++ ) + { + QString savedUsername = TomahawkSettings::instance()->value( + TomahawkSettings::instance()->sipPlugins().at( i ) + "/username" ).toString(); + QStringList splitUserName = TomahawkSettings::instance()->value( + TomahawkSettings::instance()->sipPlugins().at( i ) + "/username" ).toString().split("@"); + QString server = TomahawkSettings::instance()->value( + TomahawkSettings::instance()->sipPlugins().at( i ) + "/server" ).toString(); + + if ( ( savedUsername == jid || splitUserName.contains( jid ) ) && + server == m_ui->jabberServer->text() && !jid.trimmed().isEmpty() ) + { + m_ui->jidExistsLabel->show(); + // the already jid exists + emit dataError( true ); + return; + } + } + m_ui->jidExistsLabel->hide(); + emit dataError( false ); +} + + void JabberPlugin::saveConfig() { diff --git a/src/sip/jabber/jabber.h b/src/sip/jabber/jabber.h index 8462b1092..d71bcdd5f 100644 --- a/src/sip/jabber/jabber.h +++ b/src/sip/jabber/jabber.h @@ -85,6 +85,7 @@ public: virtual void deletePlugin(); signals: + void dataError( bool exists ); void jidChanged( const QString& ); public slots: @@ -118,6 +119,7 @@ private slots: } void onNewIq( const Jreen::IQ &iq ); void onNewAvatar( const QString &jid ); + void onCheckJidExists( QString jid ); private: bool readXmlConsoleEnabled(); From eaf8cad990a2380bf6c71a5301352a10c54258d4 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sat, 2 Jul 2011 21:03:04 +0200 Subject: [PATCH 68/86] * Fixed compiling and error. --- src/settingsdialog.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index 1639a1a24..68af571ba 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -598,13 +598,13 @@ SettingsDialog::sipFactoryClicked( SipPluginFactory* factory ) DelegateConfigWrapper* dialog = new DelegateConfigWrapper( p->configWidget(), QString("%1 Config" ).arg( p->friendlyName() ), this, Qt::Sheet ); dialog->setProperty( "sipplugin", QVariant::fromValue< QObject* >( p ) ); connect( dialog, SIGNAL( finished( int ) ), this, SLOT( sipCreateConfigClosed( int ) ) ); - connect( p, SIGNAL( datatError( bool ) ), &dialog, SLOT( toggleOkButton( bool ) ) ); + connect( p, SIGNAL( datatError( bool ) ), dialog, SLOT( toggleOkButton( bool ) ) ); dialog->show(); #else DelegateConfigWrapper dialog( p->configWidget(), QString("%1 Config" ).arg( p->friendlyName() ), this ); QWeakPointer< DelegateConfigWrapper > watcher( &dialog ); - connect( p, SIGNAL( dataError( bool ) ), &dialog, SLOT( toggleOkButton( bool ) ) ); + connect( p, SIGNAL( dataError( bool ) ), dialog, SLOT( toggleOkButton( bool ) ) ); int ret = dialog.exec(); if( !watcher.isNull() && ret == QDialog::Accepted ) { // send changed config to resolver From 8017bcacc7cd6a6679d7025f2d22d29d3069a241 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sat, 2 Jul 2011 21:10:59 +0200 Subject: [PATCH 69/86] * Fixed compiling on non-OS X. --- src/settingsdialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index 68af571ba..22e418e9a 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -604,7 +604,7 @@ SettingsDialog::sipFactoryClicked( SipPluginFactory* factory ) #else DelegateConfigWrapper dialog( p->configWidget(), QString("%1 Config" ).arg( p->friendlyName() ), this ); QWeakPointer< DelegateConfigWrapper > watcher( &dialog ); - connect( p, SIGNAL( dataError( bool ) ), dialog, SLOT( toggleOkButton( bool ) ) ); + connect( p, SIGNAL( dataError( bool ) ), &dialog, SLOT( toggleOkButton( bool ) ) ); int ret = dialog.exec(); if( !watcher.isNull() && ret == QDialog::Accepted ) { // send changed config to resolver From dc095ec963743db4e0bde8a060b03b04d3ee9e88 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sun, 3 Jul 2011 02:18:28 +0200 Subject: [PATCH 70/86] * Added ArtistInfoWidget, our new Artist page and ViewManager's default show(artist) action. --- src/libtomahawk/CMakeLists.txt | 6 +- src/libtomahawk/artist.cpp | 22 +- src/libtomahawk/artist.h | 7 +- src/libtomahawk/database/database.h | 4 + .../database/databasecommand_addfiles.cpp | 10 +- .../databasecommand_loadsocialactions.cpp | 23 +- .../database/databasecommand_logplayback.cpp | 7 +- .../database/databasecommand_socialaction.cpp | 13 +- src/libtomahawk/database/databaseimpl.cpp | 39 +-- src/libtomahawk/database/databaseimpl.h | 2 +- .../infoplugins/generic/lastfmplugin.cpp | 161 ++++++++++++- .../infoplugins/generic/lastfmplugin.h | 8 +- src/libtomahawk/playlist/artistview.cpp | 2 + src/libtomahawk/playlist/infobar/infobar.cpp | 22 +- src/libtomahawk/playlist/infobar/infobar.h | 5 +- src/libtomahawk/playlist/infobar/infobar.ui | 80 ++++++- src/libtomahawk/playlist/treemodel.cpp | 33 ++- src/libtomahawk/playlist/treemodel.h | 1 + src/libtomahawk/utils/elidedlabel.cpp | 21 +- src/libtomahawk/utils/elidedlabel.h | 8 +- src/libtomahawk/viewmanager.cpp | 33 ++- src/libtomahawk/viewmanager.h | 3 +- src/libtomahawk/viewpage.h | 3 + .../widgets/infowidgets/ArtistInfoWidget.cpp | 222 ++++++++++++++++++ .../widgets/infowidgets/ArtistInfoWidget.h | 89 +++++++ .../widgets/infowidgets/ArtistInfoWidget.ui | 84 +++++++ thirdparty/liblastfm2/src/types/Artist.cpp | 26 ++ thirdparty/liblastfm2/src/types/Artist.h | 3 + 28 files changed, 832 insertions(+), 105 deletions(-) create mode 100644 src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.cpp create mode 100644 src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.h create mode 100644 src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.ui diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index a02545d1e..98efdf554 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -173,7 +173,7 @@ set( libSources widgets/overlaywidget.cpp widgets/HeaderLabel.cpp widgets/infowidgets/sourceinfowidget.cpp -# widgets/infowidgets/ArtistInfoWidget.cpp + widgets/infowidgets/ArtistInfoWidget.cpp kdsingleapplicationguard/kdsingleapplicationguard.cpp kdsingleapplicationguard/kdsharedmemorylocker.cpp @@ -342,7 +342,7 @@ set( libHeaders widgets/overlaywidget.h widgets/HeaderLabel.h widgets/infowidgets/sourceinfowidget.h -# widgets/infowidgets/ArtistInfoWidget.h + widgets/infowidgets/ArtistInfoWidget.h kdsingleapplicationguard/kdsingleapplicationguard.h ) @@ -364,7 +364,7 @@ set( libUI ${libUI} widgets/searchwidget.ui widgets/welcomewidget.ui widgets/infowidgets/sourceinfowidget.ui -# widgets/infowidgets/ArtistInfoWidget.ui + widgets/infowidgets/ArtistInfoWidget.ui playlist/topbar/topbar.ui playlist/infobar/infobar.ui ) diff --git a/src/libtomahawk/artist.cpp b/src/libtomahawk/artist.cpp index b801c38a6..ec96f206b 100644 --- a/src/libtomahawk/artist.cpp +++ b/src/libtomahawk/artist.cpp @@ -26,9 +26,27 @@ using namespace Tomahawk; -Artist::Artist() {} -Artist::~Artist() {} +Artist::Artist() +{ +} + + +Artist::~Artist() +{ +} + + +artist_ptr +Artist::get( const QString& name, bool autoCreate ) +{ + int artid = Database::instance()->impl()->artistId( name, autoCreate ); + if ( artid < 1 ) + return artist_ptr(); + + return Artist::get( artid, name ); +} + artist_ptr Artist::get( unsigned int id, const QString& name ) diff --git a/src/libtomahawk/artist.h b/src/libtomahawk/artist.h index d30cc57a9..26d655b2a 100644 --- a/src/libtomahawk/artist.h +++ b/src/libtomahawk/artist.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 @@ -36,6 +36,7 @@ class DLLEXPORT Artist : public QObject, public PlaylistInterface Q_OBJECT public: + static artist_ptr get( const QString& name, bool autoCreate = false ); static artist_ptr get( unsigned int id, const QString& name ); Artist( unsigned int id, const QString& name ); @@ -54,7 +55,7 @@ public: virtual bool hasNextItem(); virtual Tomahawk::result_ptr currentItem() const { return m_currentItem; } - + virtual PlaylistInterface::RepeatMode repeatMode() const { return PlaylistInterface::NoRepeat; } virtual bool shuffled() const { return false; } @@ -72,7 +73,7 @@ signals: void sourceTrackCountChanged( unsigned int tracks ); void nextTrackReady(); - + private slots: void onTracksAdded( const QList& tracks ); diff --git a/src/libtomahawk/database/database.h b/src/libtomahawk/database/database.h index 239e59def..d04cb74d9 100644 --- a/src/libtomahawk/database/database.h +++ b/src/libtomahawk/database/database.h @@ -69,6 +69,8 @@ private slots: void setIsReadyTrue() { m_ready = true; } private: + DatabaseImpl* impl() const { return m_impl; } + bool m_ready; DatabaseImpl* m_impl; DatabaseWorker* m_workerRW; @@ -77,6 +79,8 @@ private: int m_maxConcurrentThreads; static Database* s_instance; + + friend class Tomahawk::Artist; }; #endif // DATABASE_H diff --git a/src/libtomahawk/database/databasecommand_addfiles.cpp b/src/libtomahawk/database/databasecommand_addfiles.cpp index b8a09c90a..b02e23378 100644 --- a/src/libtomahawk/database/databasecommand_addfiles.cpp +++ b/src/libtomahawk/database/databasecommand_addfiles.cpp @@ -148,14 +148,16 @@ DatabaseCommand_AddFiles::exec( DatabaseImpl* dbi ) if( !source()->isLocal() ) url = QString( "servent://%1\t%2" ).arg( source()->userName() ).arg( url ); - bool isnew; - artistid = dbi->artistId( artist, isnew ); + bool autoCreate = true; + artistid = dbi->artistId( artist, autoCreate ); if ( artistid < 1 ) continue; - trackid = dbi->trackId( artistid, track, isnew ); + autoCreate = true; // artistId overwrites autoCreate (reference) + trackid = dbi->trackId( artistid, track, autoCreate ); if ( trackid < 1 ) continue; - albumid = dbi->albumId( artistid, album, isnew ); + autoCreate = true; // trackId overwrites autoCreate (reference) + albumid = dbi->albumId( artistid, album, autoCreate ); // Now add the association query_filejoin.bindValue( 0, fileid ); diff --git a/src/libtomahawk/database/databasecommand_loadsocialactions.cpp b/src/libtomahawk/database/databasecommand_loadsocialactions.cpp index 61b949bea..4a29e9359 100644 --- a/src/libtomahawk/database/databasecommand_loadsocialactions.cpp +++ b/src/libtomahawk/database/databasecommand_loadsocialactions.cpp @@ -33,31 +33,32 @@ DatabaseCommand_LoadSocialActions::exec( DatabaseImpl* dbi ) { qDebug() << Q_FUNC_INFO; Q_ASSERT( !source().isNull() ); - + TomahawkSqlQuery query = dbi->newquery(); - + QVariant srcid = source()->isLocal() ? QVariant( QVariant::Int ) : source()->id(); - bool isnew; - int artid = dbi->artistId( m_artist, isnew ); + bool autoCreate = true; + int artid = dbi->artistId( m_artist, autoCreate ); if( artid < 1 ) return; - int trkid = dbi->trackId( artid, m_track, isnew ); + autoCreate = true; // artistId overwrites autoCreate (reference) + int trkid = dbi->trackId( artid, m_track, autoCreate ); if( trkid < 1 ) return; - + QString whereToken; whereToken = QString( "WHERE id IS %1" ).arg( trkid ); - + QString sql = QString( "SELECT k, v, timestamp, source " "FROM social_attributes %1 " "ORDER BY timestamp ASC" ).arg( whereToken ); - + query.prepare( sql ); query.exec(); - + QList< Tomahawk::SocialAction > allSocialActions; while ( query.next() ) { Tomahawk::SocialAction action; @@ -65,10 +66,10 @@ DatabaseCommand_LoadSocialActions::exec( DatabaseImpl* dbi ) action.value = query.value( 1 ); // comment action.timestamp = query.value( 2 ); // timestamp action.source = query.value( 3 ); // source - + allSocialActions.append( action ); } - + m_result->setAllSocialActions( allSocialActions ); } diff --git a/src/libtomahawk/database/databasecommand_logplayback.cpp b/src/libtomahawk/database/databasecommand_logplayback.cpp index e34ea7809..b6aeff307 100644 --- a/src/libtomahawk/database/databasecommand_logplayback.cpp +++ b/src/libtomahawk/database/databasecommand_logplayback.cpp @@ -80,12 +80,13 @@ DatabaseCommand_LogPlayback::exec( DatabaseImpl* dbi ) query.bindValue( 0, srcid ); - bool isnew; - int artid = dbi->artistId( m_artist, isnew ); + bool autoCreate = true; + int artid = dbi->artistId( m_artist, autoCreate ); if( artid < 1 ) return; - int trkid = dbi->trackId( artid, m_track, isnew ); + autoCreate = true; // artistId overwrites autoCreate (reference) + int trkid = dbi->trackId( artid, m_track, autoCreate ); if( trkid < 1 ) return; diff --git a/src/libtomahawk/database/databasecommand_socialaction.cpp b/src/libtomahawk/database/databasecommand_socialaction.cpp index 850cfbc5f..d284d432c 100644 --- a/src/libtomahawk/database/databasecommand_socialaction.cpp +++ b/src/libtomahawk/database/databasecommand_socialaction.cpp @@ -45,21 +45,22 @@ DatabaseCommand_SocialAction::exec( DatabaseImpl* dbi ) Q_ASSERT( !source().isNull() ); TomahawkSqlQuery query = dbi->newquery(); - + query.prepare( "INSERT INTO social_attributes(id, source, k, v, timestamp) " "VALUES (?, ?, ?, ?, ?)" ); - + QVariant srcid = source()->isLocal() ? QVariant( QVariant::Int ) : source()->id(); - bool isnew; - int artid = dbi->artistId( m_artist, isnew ); + bool autoCreate = true; + int artid = dbi->artistId( m_artist, autoCreate ); if( artid < 1 ) return; - int trkid = dbi->trackId( artid, m_track, isnew ); + autoCreate = true; // artistId overwrites autoCreate (reference) + int trkid = dbi->trackId( artid, m_track, autoCreate ); if( trkid < 1 ) return; - + query.bindValue( 0, trkid ); query.bindValue( 1, srcid ); query.bindValue( 2, m_action ); diff --git a/src/libtomahawk/database/databaseimpl.cpp b/src/libtomahawk/database/databaseimpl.cpp index f80578475..b7bb8d159 100644 --- a/src/libtomahawk/database/databaseimpl.cpp +++ b/src/libtomahawk/database/databaseimpl.cpp @@ -224,7 +224,7 @@ DatabaseImpl::file( int fid ) "WHERE file.id = file_join.file AND file.id = %1" ) .arg( fid ) ); - if( query.next() ) + if ( query.next() ) { Tomahawk::source_ptr s; @@ -266,10 +266,10 @@ DatabaseImpl::file( int fid ) int -DatabaseImpl::artistId( const QString& name_orig, bool& isnew ) +DatabaseImpl::artistId( const QString& name_orig, bool& autoCreate ) { - isnew = false; - if( m_lastart == name_orig ) + bool isnew = false; + if ( m_lastart == name_orig ) return m_lastartid; int id = 0; @@ -279,31 +279,36 @@ DatabaseImpl::artistId( const QString& name_orig, bool& isnew ) query.prepare( "SELECT id FROM artist WHERE sortname = ?" ); query.addBindValue( sortname ); query.exec(); - if( query.next() ) + if ( query.next() ) { id = query.value( 0 ).toInt(); } - if( id ) + if ( id ) { m_lastart = name_orig; m_lastartid = id; return id; } - // not found, insert it. - query.prepare( "INSERT INTO artist(id,name,sortname) VALUES(NULL,?,?)" ); - query.addBindValue( name_orig ); - query.addBindValue( sortname ); - if( !query.exec() ) + if ( autoCreate ) { - qDebug() << "Failed to insert artist:" << name_orig; - return 0; + // not found, insert it. + query.prepare( "INSERT INTO artist(id,name,sortname) VALUES(NULL,?,?)" ); + query.addBindValue( name_orig ); + query.addBindValue( sortname ); + if ( !query.exec() ) + { + qDebug() << "Failed to insert artist:" << name_orig; + return 0; + } + + id = query.lastInsertId().toInt(); + isnew = true; + m_lastart = name_orig; + m_lastartid = id; } - id = query.lastInsertId().toInt(); - isnew = true; - m_lastart = name_orig; - m_lastartid = id; + autoCreate = isnew; return id; } diff --git a/src/libtomahawk/database/databaseimpl.h b/src/libtomahawk/database/databaseimpl.h index 151c5ee27..cb0eda4c9 100644 --- a/src/libtomahawk/database/databaseimpl.h +++ b/src/libtomahawk/database/databaseimpl.h @@ -53,7 +53,7 @@ public: TomahawkSqlQuery newquery() { return TomahawkSqlQuery( db ); } QSqlDatabase& database() { return db; } - int artistId( const QString& name_orig, bool& isnew ); + int artistId( const QString& name_orig, bool& autoCreate ); int trackId( int artistid, const QString& name_orig, bool& isnew ); int albumId( int artistid, const QString& name_orig, bool& isnew ); diff --git a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp index d26efe385..a7ef22e8f 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp @@ -46,7 +46,7 @@ LastFmPlugin::LastFmPlugin() : InfoPlugin() , m_scrobbler( 0 ) { - m_supportedGetTypes << InfoAlbumCoverArt << InfoArtistImages; + m_supportedGetTypes << InfoAlbumCoverArt << InfoArtistImages << InfoArtistSimilars << InfoArtistSongs; m_supportedPushTypes << InfoSubmitScrobble << InfoSubmitNowPlaying << InfoLove << InfoUnLove; /* @@ -94,10 +94,10 @@ void LastFmPlugin::namChangedSlot( QNetworkAccessManager *nam ) { qDebug() << Q_FUNC_INFO; - + if ( !nam ) return; - + QNetworkAccessManager* currNam = lastfm::nam(); TomahawkUtils::NetworkProxyFactory* oldProxyFactory = dynamic_cast< TomahawkUtils::NetworkProxyFactory* >( nam->proxyFactory() ); @@ -106,7 +106,7 @@ LastFmPlugin::namChangedSlot( QNetworkAccessManager *nam ) qDebug() << "Could not get old proxyFactory!"; return; } - + currNam->setConfiguration( nam->configuration() ); currNam->setNetworkAccessible( nam->networkAccessible() ); TomahawkUtils::NetworkProxyFactory* newProxyFactory = new TomahawkUtils::NetworkProxyFactory(); @@ -142,6 +142,14 @@ LastFmPlugin::getInfo( const QString caller, const Tomahawk::InfoSystem::InfoTyp fetchCoverArt( caller, type, input, customData ); break; + case InfoArtistSimilars: + fetchSimilarArtists( caller, type, input, customData ); + break; + + case InfoArtistSongs: + fetchTopTracks( caller, type, input, customData ); + break; + default: dataError( caller, type, input, customData ); } @@ -242,7 +250,7 @@ LastFmPlugin::sendLoveSong( const InfoType type, QVariant input ) bool ok; track.setDuration( hash["duration"].toUInt( &ok ) ); track.setSource( lastfm::Track::Player ); - + if ( type == Tomahawk::InfoSystem::InfoLove ) { track.love(); @@ -254,6 +262,52 @@ LastFmPlugin::sendLoveSong( const InfoType type, QVariant input ) } +void +LastFmPlugin::fetchSimilarArtists( const QString &caller, const InfoType type, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData ) +{ + qDebug() << Q_FUNC_INFO; + if ( !input.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() ) + { + dataError( caller, type, input, customData ); + return; + } + InfoCriteriaHash hash = input.value< Tomahawk::InfoSystem::InfoCriteriaHash >(); + if ( !hash.contains( "artist" ) ) + { + dataError( caller, type, input, customData ); + return; + } + + Tomahawk::InfoSystem::InfoCriteriaHash criteria; + criteria["artist"] = hash["artist"]; + + emit getCachedInfo( criteria, 2419200000, caller, type, input, customData ); +} + + +void +LastFmPlugin::fetchTopTracks( const QString &caller, const InfoType type, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData ) +{ + qDebug() << Q_FUNC_INFO; + if ( !input.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() ) + { + dataError( caller, type, input, customData ); + return; + } + InfoCriteriaHash hash = input.value< Tomahawk::InfoSystem::InfoCriteriaHash >(); + if ( !hash.contains( "artist" ) ) + { + dataError( caller, type, input, customData ); + return; + } + + Tomahawk::InfoSystem::InfoCriteriaHash criteria; + criteria["artist"] = hash["artist"]; + + emit getCachedInfo( criteria, 2419200000, caller, type, input, customData ); +} + + void LastFmPlugin::fetchCoverArt( const QString &caller, const InfoType type, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData ) { @@ -315,6 +369,32 @@ LastFmPlugin::notInCacheSlot( const QHash criteria, const QStr switch ( type ) { + case InfoArtistSimilars: + { + lastfm::Artist a( criteria["artist"] ); + QNetworkReply* reply = a.getSimilar(); + reply->setProperty( "customData", QVariant::fromValue( customData ) ); + reply->setProperty( "origData", input ); + reply->setProperty( "caller", caller ); + reply->setProperty( "type", (uint)(type) ); + + connect( reply, SIGNAL( finished() ), SLOT( similarArtistsReturned() ) ); + return; + } + + case InfoArtistSongs: + { + lastfm::Artist a( criteria["artist"] ); + QNetworkReply* reply = a.getTopTracks(); + reply->setProperty( "customData", QVariant::fromValue( customData ) ); + reply->setProperty( "origData", input ); + reply->setProperty( "caller", caller ); + reply->setProperty( "type", (uint)(type) ); + + connect( reply, SIGNAL( finished() ), SLOT( topTracksReturned() ) ); + return; + } + case InfoAlbumCoverArt: { QString artistName = criteria["artist"]; @@ -336,7 +416,7 @@ LastFmPlugin::notInCacheSlot( const QHash criteria, const QStr { QString artistName = criteria["artist"]; - QString imgurl = "http://ws.audioscrobbler.com/2.0/?method=artist.imageredirect&artist=%1&autocorrect=1&size=medium&api_key=7a90f6672a04b809ee309af169f34b8b"; + QString imgurl = "http://ws.audioscrobbler.com/2.0/?method=artist.imageredirect&artist=%1&autocorrect=1&size=large&api_key=7a90f6672a04b809ee309af169f34b8b"; QNetworkRequest req( imgurl.arg( artistName ) ); QNetworkReply* reply = lastfm::nam()->get( req ); reply->setProperty( "customData", QVariant::fromValue( customData ) ); @@ -358,6 +438,75 @@ LastFmPlugin::notInCacheSlot( const QHash criteria, const QStr } +void +LastFmPlugin::similarArtistsReturned() +{ + qDebug() << Q_FUNC_INFO; + QNetworkReply* reply = qobject_cast( sender() ); + + QMap< int, QString > similarArtists = lastfm::Artist::getSimilar( reply ); + QStringList al; + QStringList sl; + + foreach ( const QString& a, similarArtists.values() ) + { + qDebug() << "Got sim-artist:" << a; + al << a; + } + + InfoCustomData returnedData; + returnedData["artists"] = al; + returnedData["score"] = sl; + + 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 + ); + + InfoCriteriaHash origData = reply->property( "origData" ).value< Tomahawk::InfoSystem::InfoCriteriaHash >(); + Tomahawk::InfoSystem::InfoCriteriaHash criteria; + criteria["artist"] = origData["artist"]; +// emit updateCache( criteria, 2419200000, type, returnedData ); +} + + +void +LastFmPlugin::topTracksReturned() +{ + qDebug() << Q_FUNC_INFO; + QNetworkReply* reply = qobject_cast( sender() ); + + QStringList topTracks = lastfm::Artist::getTopTracks( reply ); + foreach ( const QString& t, topTracks ) + { + qDebug() << "Got top-track:" << t; + } + + InfoCustomData returnedData; + returnedData["tracks"] = topTracks; + + 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 + ); + + InfoCriteriaHash origData = reply->property( "origData" ).value< Tomahawk::InfoSystem::InfoCriteriaHash >(); + Tomahawk::InfoSystem::InfoCriteriaHash criteria; + criteria["artist"] = origData["artist"]; + //emit updateCache( criteria, 2419200000, type, returnedData ); +} + + void LastFmPlugin::coverArtReturned() { diff --git a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.h b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.h index e2b470770..25c576a85 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.h +++ b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.h @@ -49,6 +49,8 @@ public slots: void onAuthenticated(); void coverArtReturned(); void artistImagesReturned(); + void similarArtistsReturned(); + void topTracksReturned(); void namChangedSlot( QNetworkAccessManager *nam ); @@ -57,17 +59,19 @@ protected slots: virtual void notInCacheSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData ); virtual void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant data ); - + private: void fetchCoverArt( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData ); void fetchArtistImages( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData ); + void fetchSimilarArtists( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData ); + void fetchTopTracks( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData ); void createScrobbler(); void nowPlaying( const QVariant &input ); void scrobble(); + void sendLoveSong( const InfoType type, QVariant input ); void dataError( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData ); - void sendLoveSong( const InfoType type, QVariant input ); lastfm::MutableTrack m_track; lastfm::Audioscrobbler* m_scrobbler; diff --git a/src/libtomahawk/playlist/artistview.cpp b/src/libtomahawk/playlist/artistview.cpp index d2502fd95..75d6a8d6f 100644 --- a/src/libtomahawk/playlist/artistview.cpp +++ b/src/libtomahawk/playlist/artistview.cpp @@ -242,6 +242,8 @@ ArtistView::onScrollTimeout() for ( int i = left.row(); i < max; i++ ) { TreeModelItem* item = m_model->itemFromIndex( m_proxyModel->mapToSource( m_proxyModel->index( i, 0 ) ) ); + if ( item->artist().isNull() ) + continue; Tomahawk::InfoSystem::InfoCriteriaHash trackInfo; trackInfo["artist"] = item->artist()->name(); diff --git a/src/libtomahawk/playlist/infobar/infobar.cpp b/src/libtomahawk/playlist/infobar/infobar.cpp index 569c8a247..f90953df1 100644 --- a/src/libtomahawk/playlist/infobar/infobar.cpp +++ b/src/libtomahawk/playlist/infobar/infobar.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,18 +43,25 @@ InfoBar::InfoBar( QWidget* parent ) boldFont.setPixelSize( 12 ); ui->descriptionLabel->setFont( boldFont ); - ui->descriptionLabel->setMargin( 10 ); + + QFont regFont = ui->longDescriptionLabel->font(); + regFont.setPixelSize( 11 ); + ui->longDescriptionLabel->setFont( regFont ); QPalette whitePal = ui->captionLabel->palette(); whitePal.setColor( QPalette::Foreground, Qt::white ); ui->captionLabel->setPalette( whitePal ); ui->descriptionLabel->setPalette( whitePal ); + ui->longDescriptionLabel->setPalette( whitePal ); + + ui->captionLabel->setMargin( 6 ); + ui->descriptionLabel->setMargin( 6 ); + ui->longDescriptionLabel->setMargin( 6 ); ui->captionLabel->setText( QString() ); - ui->captionLabel->setMargin( 6 ); - ui->descriptionLabel->setText( QString() ); + ui->longDescriptionLabel->setText( QString() ); ui->imageLabel->setText( QString() ); setAutoFillBackground( true ); @@ -81,6 +88,13 @@ InfoBar::setDescription( const QString& s ) } +void +InfoBar::setLongDescription( const QString& s ) +{ + ui->longDescriptionLabel->setText( s ); +} + + void InfoBar::setPixmap( const QPixmap& p ) { diff --git a/src/libtomahawk/playlist/infobar/infobar.h b/src/libtomahawk/playlist/infobar/infobar.h index 4bd677c78..5f8939a34 100644 --- a/src/libtomahawk/playlist/infobar/infobar.h +++ b/src/libtomahawk/playlist/infobar/infobar.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,8 +39,9 @@ public: public slots: void setCaption( const QString& s ); void setDescription( const QString& s ); + void setLongDescription( const QString& s ); void setPixmap( const QPixmap& p ); - + protected: void changeEvent( QEvent* e ); void resizeEvent( QResizeEvent* e ); diff --git a/src/libtomahawk/playlist/infobar/infobar.ui b/src/libtomahawk/playlist/infobar/infobar.ui index 764fd040a..379101249 100644 --- a/src/libtomahawk/playlist/infobar/infobar.ui +++ b/src/libtomahawk/playlist/infobar/infobar.ui @@ -36,7 +36,7 @@ - 32 + 16 20 @@ -65,7 +65,7 @@ - 32 + 16 20 @@ -73,10 +73,13 @@
+ + QLayout::SetMinimumSize + - + 0 0 @@ -89,7 +92,7 @@ - + 0 0 @@ -101,6 +104,73 @@ + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 16 + 20 + + + + + + + + QLayout::SetMaximumSize + + + + + + 0 + 0 + + + + + 0 + 62 + + + + + 16777215 + 62 + + + + TextLabel + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + + + + + Qt::Horizontal + + + + 40 + 1 + + + + + + @@ -111,7 +181,7 @@ - 32 + 16 20 diff --git a/src/libtomahawk/playlist/treemodel.cpp b/src/libtomahawk/playlist/treemodel.cpp index aa9995f52..e542d4062 100644 --- a/src/libtomahawk/playlist/treemodel.cpp +++ b/src/libtomahawk/playlist/treemodel.cpp @@ -378,6 +378,22 @@ TreeModel::addAllCollections() } +void +TreeModel::addArtists( const artist_ptr& artist ) +{ + qDebug() << Q_FUNC_INFO; + + if ( artist.isNull() ) + return; + + emit loadingStarted(); + + QList artists; + artists << artist; + onArtistsAdded( artists ); +} + + void TreeModel::addAlbums( const artist_ptr& artist, const QModelIndex& parent ) { @@ -494,21 +510,24 @@ TreeModel::onArtistsAdded( const QList& artists ) void TreeModel::onAlbumsAdded( const QList& albums, const QVariant& data ) { - qDebug() << Q_FUNC_INFO << albums.count(); + qDebug() << Q_FUNC_INFO << albums.count() << data.toInt(); if ( !albums.count() ) return; - QModelIndex parent = index( data.toUInt(), 0, QModelIndex() ); + QModelIndex parent = index( data.toInt(), 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; + int c = rowCount( parent ); crows.first = c; crows.second = c + albums.count() - 1; - if ( crows.second > 0 ) - emit beginInsertRows( parent, crows.first + 1, crows.second ); + if ( parent.isValid() ) + crows.second -= 1; + + qDebug() << crows.first << crows.second; + if ( !parent.isValid() || crows.second > 0 ) + emit beginInsertRows( parent, crows.first, crows.second ); TreeModelItem* albumitem = 0; foreach( const album_ptr& album, albums ) @@ -528,7 +547,7 @@ TreeModel::onAlbumsAdded( const QList& albums, const QVaria QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ), Tomahawk::InfoSystem::InfoCustomData() ); } - if ( crows.second > 0 ) + if ( !parent.isValid() || crows.second > 0 ) emit endInsertRows(); else emit dataChanged( albumitem->index, albumitem->index.sibling( albumitem->index.row(), columnCount( QModelIndex() ) - 1 ) ); diff --git a/src/libtomahawk/playlist/treemodel.h b/src/libtomahawk/playlist/treemodel.h index b1dae2de8..ddd2bf253 100644 --- a/src/libtomahawk/playlist/treemodel.h +++ b/src/libtomahawk/playlist/treemodel.h @@ -80,6 +80,7 @@ public: void addCollection( const Tomahawk::collection_ptr& collection ); void addFilteredCollection( const Tomahawk::collection_ptr& collection, unsigned int amount, DatabaseCommand_AllArtists::SortOrder order ); + void addArtists( const Tomahawk::artist_ptr& artist ); void addAlbums( const Tomahawk::artist_ptr& artist, const QModelIndex& parent ); void addTracks( const Tomahawk::album_ptr& album, const QModelIndex& parent ); diff --git a/src/libtomahawk/utils/elidedlabel.cpp b/src/libtomahawk/utils/elidedlabel.cpp index 9b4343383..f43502175 100644 --- a/src/libtomahawk/utils/elidedlabel.cpp +++ b/src/libtomahawk/utils/elidedlabel.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 @@ -98,19 +98,29 @@ ElidedLabel::setElideMode( Qt::TextElideMode mode ) } } -void + +void ElidedLabel::setMargin( int margin ) { m_margin = margin; } -int + +int ElidedLabel::margin() const { return m_margin; } +void +ElidedLabel::setFont( const QFont& font ) +{ + QWidget::setFont( font ); + updateLabel(); +} + + void ElidedLabel::init( const QString& txt ) { @@ -134,8 +144,7 @@ QSize ElidedLabel::sizeHint() const { const QFontMetrics& fm = fontMetrics(); - QSize size( fm.width( m_text ), fm.height() ); - return size; + return QSize( fm.width( m_text ) + m_margin * 2, fm.height() + m_margin * 2 ); } @@ -164,7 +173,7 @@ ElidedLabel::paintEvent( QPaintEvent* event ) QPainter p( this ); QRect r = contentsRect(); r.adjust( m_margin, m_margin, -m_margin, -m_margin ); - + const QString elidedText = fontMetrics().elidedText( m_text, m_mode, r.width() ); p.drawText( r, m_align, elidedText ); } diff --git a/src/libtomahawk/utils/elidedlabel.h b/src/libtomahawk/utils/elidedlabel.h index 2f45e1c97..00198d888 100644 --- a/src/libtomahawk/utils/elidedlabel.h +++ b/src/libtomahawk/utils/elidedlabel.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 @@ -44,9 +44,11 @@ public: Qt::TextElideMode elideMode() const; void setElideMode( Qt::TextElideMode mode ); + void setFont( const QFont& font ); + void setMargin( int margin ); int margin() const; - + virtual QSize sizeHint() const; virtual QSize minimumSizeHint() const; @@ -65,7 +67,7 @@ protected: virtual void mousePressEvent( QMouseEvent* event ); virtual void mouseReleaseEvent( QMouseEvent* event ); virtual void paintEvent( QPaintEvent* event ); - + private: QTime m_time; QString m_text; diff --git a/src/libtomahawk/viewmanager.cpp b/src/libtomahawk/viewmanager.cpp index 1e14db964..d558167c0 100644 --- a/src/libtomahawk/viewmanager.cpp +++ b/src/libtomahawk/viewmanager.cpp @@ -25,8 +25,6 @@ #include "utils/animatedsplitter.h" #include "infobar/infobar.h" #include "topbar/topbar.h" -#include "widgets/infowidgets/sourceinfowidget.h" -#include "widgets/welcomewidget.h" #include "treemodel.h" #include "collectionflatmodel.h" @@ -47,6 +45,7 @@ #include "widgets/welcomewidget.h" #include "widgets/infowidgets/sourceinfowidget.h" +#include "widgets/infowidgets/ArtistInfoWidget.h" #include "widgets/newplaylistwidget.h" #define FILTER_TIMEOUT 280 @@ -217,28 +216,19 @@ ViewManager::show( const Tomahawk::dynplaylist_ptr& playlist ) Tomahawk::ViewPage* ViewManager::show( const Tomahawk::artist_ptr& artist ) { - PlaylistView* view; - + ArtistInfoWidget* swidget; if ( !m_artistViews.contains( artist ) ) { - view = new PlaylistView(); - PlaylistModel* model = new PlaylistModel(); - view->setPlaylistModel( model ); - view->setFrameShape( QFrame::NoFrame ); - view->setAttribute( Qt::WA_MacShowFocusRect, 0 ); - model->append( artist ); - - m_artistViews.insert( artist, view ); + swidget = new ArtistInfoWidget( artist ); + m_artistViews.insert( artist, swidget ); } else { - view = m_artistViews.value( artist ); + swidget = m_artistViews.value( artist ); } - setPage( view ); - emit numSourcesChanged( 1 ); - - return view; + setPage( swidget ); + return swidget; } @@ -367,8 +357,6 @@ ViewManager::show( const Tomahawk::source_ptr& source ) } setPage( swidget ); - emit numSourcesChanged( 1 ); - return swidget; } @@ -617,9 +605,15 @@ ViewManager::setPage( ViewPage* page, bool trackHistory ) if( obj->metaObject()->indexOfSignal( "descriptionChanged(QString)" ) > -1 ) connect( obj, SIGNAL( descriptionChanged( QString ) ), m_infobar, SLOT( setDescription( QString ) ), Qt::UniqueConnection ); + if( obj->metaObject()->indexOfSignal( "longDescriptionChanged(QString)" ) > -1 ) + connect( obj, SIGNAL( longDescriptionChanged( QString ) ), m_infobar, SLOT( setLongDescription( QString ) ), Qt::UniqueConnection ); + if( obj->metaObject()->indexOfSignal( "nameChanged(QString)" ) > -1 ) connect( obj, SIGNAL( nameChanged( QString ) ), m_infobar, SLOT( setCaption( QString ) ), Qt::UniqueConnection ); + if( obj->metaObject()->indexOfSignal( "pixmapChanged(QPixmap)" ) > -1 ) + connect( obj, SIGNAL( pixmapChanged( QPixmap ) ), m_infobar, SLOT( setPixmap( QPixmap ) ), Qt::UniqueConnection ); + if( obj->metaObject()->indexOfSignal( "destroyed(QWidget*)" ) > -1 ) connect( obj, SIGNAL( destroyed( QWidget* ) ), SLOT( onWidgetDestroyed( QWidget* ) ), Qt::UniqueConnection ); } @@ -724,6 +718,7 @@ ViewManager::updateView() m_infobar->setCaption( currentPage()->title() ); m_infobar->setDescription( currentPage()->description() ); + m_infobar->setLongDescription( currentPage()->longDescription() ); m_infobar->setPixmap( currentPage()->pixmap() ); // turn on shuffle/repeat mode for the new playlist view if specified in config diff --git a/src/libtomahawk/viewmanager.h b/src/libtomahawk/viewmanager.h index 20919534b..9982f671b 100644 --- a/src/libtomahawk/viewmanager.h +++ b/src/libtomahawk/viewmanager.h @@ -33,6 +33,7 @@ class AnimatedSplitter; class AlbumModel; class AlbumView; +class ArtistInfoWidget; class ArtistView; class CollectionModel; class CollectionFlatModel; @@ -190,7 +191,7 @@ private: 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::artist_ptr, ArtistInfoWidget* > m_artistViews; QHash< Tomahawk::album_ptr, PlaylistView* > m_albumViews; QHash< Tomahawk::playlist_ptr, PlaylistView* > m_playlistViews; QHash< Tomahawk::source_ptr, SourceInfoWidget* > m_sourceViews; diff --git a/src/libtomahawk/viewpage.h b/src/libtomahawk/viewpage.h index e17acf2b3..c36a12f8e 100644 --- a/src/libtomahawk/viewpage.h +++ b/src/libtomahawk/viewpage.h @@ -42,6 +42,7 @@ public: virtual QString title() const = 0; virtual QString description() const = 0; + virtual QString longDescription() const { return QString(); } virtual QPixmap pixmap() const { return QPixmap( RESPATH "icons/tomahawk-icon-128x128.png" ); } virtual bool showStatsBar() const { return true; } @@ -56,6 +57,8 @@ public: /** subclasses implementing ViewPage can emit the following signals: * nameChanged( const QString& ) * descriptionChanged( const QString& ) + * longDescriptionChanged( const QString& ) + * pixmapChanged( const QPixmap& ) * destroyed( QWidget* widget ); * * See DynamicWidget for an example diff --git a/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.cpp b/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.cpp new file mode 100644 index 000000000..4f9ac834e --- /dev/null +++ b/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.cpp @@ -0,0 +1,222 @@ +/* === 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 "ArtistInfoWidget.h" +#include "ui_ArtistInfoWidget.h" + +#include "utils/tomahawkutils.h" + +#include "viewmanager.h" +#include "playlist/treemodel.h" +#include "playlist/playlistmodel.h" + +#include "database/databasecommand_alltracks.h" +#include "database/databasecommand_allalbums.h" + +#include "widgets/overlaywidget.h" + +static QString s_aiInfoIdentifier = QString( "ArtistInfoWidget" ); + +using namespace Tomahawk; + + +ArtistInfoWidget::ArtistInfoWidget( const Tomahawk::artist_ptr& artist, QWidget* parent ) + : QWidget( parent ) + , ui( new Ui::ArtistInfoWidget ) + , m_artist( artist ) +{ + ui->setupUi( this ); + + ui->albums->setFrameShape( QFrame::NoFrame ); + ui->albums->setAttribute( Qt::WA_MacShowFocusRect, 0 ); + ui->relatedArtists->setFrameShape( QFrame::NoFrame ); + ui->relatedArtists->setAttribute( Qt::WA_MacShowFocusRect, 0 ); + ui->topHits->setFrameShape( QFrame::NoFrame ); + ui->topHits->setAttribute( Qt::WA_MacShowFocusRect, 0 ); + + TomahawkUtils::unmarginLayout( layout() ); + + m_albumsModel = new TreeModel( ui->albums ); + ui->albums->setTreeModel( m_albumsModel ); + + m_relatedModel = new TreeModel( ui->relatedArtists ); + ui->relatedArtists->setTreeModel( m_relatedModel ); + + m_topHitsModel = new PlaylistModel( ui->topHits ); + m_topHitsModel->setStyle( TrackModel::Short ); + ui->topHits->setTrackModel( m_topHitsModel ); + + m_pixmap = QPixmap( RESPATH "images/no-album-art-placeholder.png" ).scaledToWidth( 48, Qt::SmoothTransformation ); + + 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( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( finished( QString ) ), SLOT( infoSystemFinished( QString ) ) ); + + load( artist ); +} + + +ArtistInfoWidget::~ArtistInfoWidget() +{ + delete ui; +} + + +void +ArtistInfoWidget::load( const artist_ptr& artist ) +{ + m_title = artist->name(); + m_albumsModel->addAlbums( artist, QModelIndex() ); + + Tomahawk::InfoSystem::InfoCriteriaHash artistInfo; + artistInfo["artist"] = artist->name(); + + InfoSystem::InfoTypeMap infoMap; + InfoSystem::InfoCustomData hash; + infoMap[InfoSystem::InfoArtistBiography] = artist->name(); + + Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( + s_aiInfoIdentifier, infoMap, hash ); + + Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( + s_aiInfoIdentifier, Tomahawk::InfoSystem::InfoArtistImages, + QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( artistInfo ), Tomahawk::InfoSystem::InfoCustomData() ); + + Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( + s_aiInfoIdentifier, Tomahawk::InfoSystem::InfoArtistSimilars, + QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( artistInfo ), Tomahawk::InfoSystem::InfoCustomData() ); + + Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( + s_aiInfoIdentifier, Tomahawk::InfoSystem::InfoArtistSongs, + QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( artistInfo ), Tomahawk::InfoSystem::InfoCustomData() ); +} + + +void +ArtistInfoWidget::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ) +{ + Q_UNUSED( input ); + Q_UNUSED( customData ); + + if ( caller != s_aiInfoIdentifier ) + { +// qDebug() << "Info of wrong type or not with our identifier"; + return; + } + qDebug() << Q_FUNC_INFO << caller << type << s_aiInfoIdentifier; + + InfoSystem::InfoCriteriaHash trackInfo; + trackInfo = input.value< InfoSystem::InfoCriteriaHash >(); + + if ( output.canConvert< Tomahawk::InfoSystem::InfoCustomData >() ) + { + if ( trackInfo["artist"] != m_artist->name() ) + { + qDebug() << "Returned info was for:" << trackInfo["artist"] << "- was looking for:" << m_artist->name(); + return; + } + } + + InfoSystem::InfoCustomData returnedData = output.value< Tomahawk::InfoSystem::InfoCustomData >(); + switch ( type ) + { + case InfoSystem::InfoArtistBiography: + { + InfoSystem::InfoGenericMap bmap = output.value< Tomahawk::InfoSystem::InfoGenericMap >(); + + foreach ( const QString& source, bmap.keys() ) + { + if ( m_longDescription.isEmpty() || source == "last.fm" ) + m_longDescription = bmap[source]["text"]; + } + emit longDescriptionChanged( m_longDescription ); + break; + } + + case InfoSystem::InfoArtistSongs: + { + const QStringList tracks = returnedData["tracks"].toStringList(); + + int i = 0; + foreach ( const QString& track, tracks ) + { + query_ptr query = Query::get( m_artist->name(), track, QString(), uuid() ); + m_topHitsModel->append( query ); + + if ( ++i == 15 ) + break; + } + break; + } + + case InfoSystem::InfoArtistImages: + { + const QByteArray ba = returnedData["imgbytes"].toByteArray(); + if ( ba.length() ) + { + QPixmap pm; + pm.loadFromData( ba ); + + if ( !pm.isNull() ) + m_pixmap = pm.scaledToHeight( 48, Qt::SmoothTransformation ); + + emit pixmapChanged( m_pixmap ); + } + break; + } + + case InfoSystem::InfoArtistSimilars: + { + const QStringList artists = returnedData["artists"].toStringList(); + foreach ( const QString& artist, artists ) + { + m_relatedModel->addArtists( Artist::get( artist ) ); + } + break; + } + + default: + return; + } +} + + +void +ArtistInfoWidget::infoSystemFinished( QString target ) +{ + Q_UNUSED( target ); + qDebug() << Q_FUNC_INFO; +} + + +void +ArtistInfoWidget::changeEvent( QEvent* e ) +{ + QWidget::changeEvent( e ); + switch ( e->type() ) + { + case QEvent::LanguageChange: + ui->retranslateUi( this ); + break; + + default: + break; + } +} diff --git a/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.h b/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.h new file mode 100644 index 000000000..31dc8dc03 --- /dev/null +++ b/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.h @@ -0,0 +1,89 @@ +/* === 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 ARTISTINFOWIDGET_H +#define ARTISTINFOWIDGET_H + +#include + +#include "artist.h" +#include "result.h" +#include "playlistinterface.h" +#include "viewpage.h" +#include "infosystem/infosystem.h" + +#include "dllmacro.h" + +class PlaylistModel; +class TreeModel; + +namespace Ui +{ + class ArtistInfoWidget; +} + +class DLLEXPORT ArtistInfoWidget : public QWidget, public Tomahawk::ViewPage +{ +Q_OBJECT + +public: + ArtistInfoWidget( const Tomahawk::artist_ptr& artist, QWidget* parent = 0 ); + ~ArtistInfoWidget(); + + void load( const Tomahawk::artist_ptr& artist ); + + virtual QWidget* widget() { return this; } + virtual Tomahawk::PlaylistInterface* playlistInterface() const { return 0; } + + virtual QString title() const { return m_title; } + virtual QString description() const { return m_description; } + virtual QString longDescription() const { return m_longDescription; } + virtual QPixmap pixmap() const { if ( m_pixmap.isNull() ) return Tomahawk::ViewPage::pixmap(); else return m_pixmap; } + + virtual bool showStatsBar() const { return false; } + + virtual bool jumpToCurrentTrack() { return false; } + +signals: + void longDescriptionChanged( const QString& description ); + void descriptionChanged( const QString& description ); + void pixmapChanged( const QPixmap& pixmap ); + +protected: + void changeEvent( QEvent* e ); + +private slots: + void infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ); + void infoSystemFinished( QString target ); + +private: + Ui::ArtistInfoWidget *ui; + + Tomahawk::artist_ptr m_artist; + + TreeModel* m_relatedModel; + TreeModel* m_albumsModel; + PlaylistModel* m_topHitsModel; + + QString m_title; + QString m_description; + QString m_longDescription; + QPixmap m_pixmap; +}; + +#endif // SOURCEINFOWIDGET_H diff --git a/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.ui b/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.ui new file mode 100644 index 000000000..738ebffca --- /dev/null +++ b/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.ui @@ -0,0 +1,84 @@ + + + ArtistInfoWidget + + + + 0 + 0 + 902 + 696 + + + + Form + + + + + + + + + + Top Hits + + + + + + + + + + + + + + Related Artists + + + + + + + + + + + + + + + + Albums + + + + + + + + + + + + + HeaderLabel + QLabel +
widgets/HeaderLabel.h
+
+ + ArtistView + QTreeView +
artistview.h
+
+ + PlaylistView + QTreeView +
playlistview.h
+
+
+ + +
diff --git a/thirdparty/liblastfm2/src/types/Artist.cpp b/thirdparty/liblastfm2/src/types/Artist.cpp index 242834e83..9af4303e1 100644 --- a/thirdparty/liblastfm2/src/types/Artist.cpp +++ b/thirdparty/liblastfm2/src/types/Artist.cpp @@ -116,6 +116,13 @@ Artist::getTopTags() const } +QNetworkReply* +Artist::getTopTracks() const +{ + return ws::get( params("getTopTracks") ); +} + + QNetworkReply* Artist::getSimilar() const { @@ -154,6 +161,25 @@ Artist::getSimilar( QNetworkReply* r ) } +QStringList /* static */ +Artist::getTopTracks( QNetworkReply* r ) +{ + QStringList tracks; + try + { + XmlQuery lfm = ws::parse(r); + foreach (XmlQuery e, lfm.children( "track" )) + { + tracks << e["name"].text(); + } + } + catch (ws::ParseError& e) + { + qWarning() << e.what(); + } + return tracks; +} + QList /* static */ Artist::list( QNetworkReply* r ) diff --git a/thirdparty/liblastfm2/src/types/Artist.h b/thirdparty/liblastfm2/src/types/Artist.h index 2bfd6d007..9eae719f5 100644 --- a/thirdparty/liblastfm2/src/types/Artist.h +++ b/thirdparty/liblastfm2/src/types/Artist.h @@ -86,6 +86,9 @@ namespace lastfm /** use Tag::list to get the tag list out of the finished reply */ QNetworkReply* getTags() const; QNetworkReply* getTopTags() const; + + QNetworkReply* getTopTracks() const; + static QStringList getTopTracks( QNetworkReply* ); /** Last.fm dictates that you may submit at most 10 of these */ QNetworkReply* addTags( const QStringList& ) const; From 15cdc8f910d0e2ad0ecb7b5646f459b38979430d Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sun, 3 Jul 2011 17:04:49 +0200 Subject: [PATCH 71/86] * Let's start doxygen-ing new classes. --- src/libtomahawk/playlist/infobar/infobar.cpp | 2 +- .../widgets/infowidgets/ArtistInfoWidget.h | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/libtomahawk/playlist/infobar/infobar.cpp b/src/libtomahawk/playlist/infobar/infobar.cpp index f90953df1..8edc51b20 100644 --- a/src/libtomahawk/playlist/infobar/infobar.cpp +++ b/src/libtomahawk/playlist/infobar/infobar.cpp @@ -57,7 +57,7 @@ InfoBar::InfoBar( QWidget* parent ) ui->captionLabel->setMargin( 6 ); ui->descriptionLabel->setMargin( 6 ); - ui->longDescriptionLabel->setMargin( 6 ); + ui->longDescriptionLabel->setMargin( 4 ); ui->captionLabel->setText( QString() ); ui->descriptionLabel->setText( QString() ); diff --git a/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.h b/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.h index 31dc8dc03..824c69f8b 100644 --- a/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.h +++ b/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.h @@ -16,6 +16,16 @@ * along with Tomahawk. If not, see . */ +/** + * \class ArtistInfoWidget + * \brief A ViewPage class, which displays top-hits, related artists and albums. + * + * This Tomahawk ViewPage displays top-hits, related artists and known albums + * for any given artist. It is our default ViewPage when showing an artist + * via ViewManager. + * + */ + #ifndef ARTISTINFOWIDGET_H #define ARTISTINFOWIDGET_H @@ -45,6 +55,14 @@ public: ArtistInfoWidget( const Tomahawk::artist_ptr& artist, QWidget* parent = 0 ); ~ArtistInfoWidget(); + /** \brief Load information for a given artist. + * \param artist The artist that you want to load information for. + * + * Calling this method will make ArtistInfoWidget load information about + * an artist's top hits, related artists and all available albums. It is + * automatically called by the constructor, but you can use it to load + * another artist's information at any point. + */ void load( const Tomahawk::artist_ptr& artist ); virtual QWidget* widget() { return this; } From 5e9fa240087ece6cd5f20b75a6dbfd6ca7ab9a6e Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Mon, 4 Jul 2011 02:42:42 +0200 Subject: [PATCH 72/86] * Fixed crashing after a right-click on the Super Collection. --- src/sourcetree/sourcetreeview.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sourcetree/sourcetreeview.cpp b/src/sourcetree/sourcetreeview.cpp index 695633a29..8043624cd 100644 --- a/src/sourcetree/sourcetreeview.cpp +++ b/src/sourcetree/sourcetreeview.cpp @@ -127,7 +127,7 @@ SourceTreeView::setupMenus() m_playlistMenu.clear(); m_roPlaylistMenu.clear(); m_latchMenu.clear(); - + bool readonly = true; SourcesModel::RowType type = ( SourcesModel::RowType )model()->data( m_contextMenuIndex, SourcesModel::SourceTreeItemTypeRole ).toInt(); if ( type == SourcesModel::StaticPlaylist || type == SourcesModel::AutomaticPlaylist || type == SourcesModel::Station ) @@ -345,7 +345,7 @@ SourceTreeView::latchOn() CollectionItem* item = itemFromIndex< CollectionItem >( m_contextMenuIndex ); source_ptr source = item->source(); PlaylistInterface* pi = AudioEngine::instance()->playlist(); - + if ( pi && dynamic_cast< SourcePlaylistInterface* >( pi ) ) { SourcePlaylistInterface* sourcepi = dynamic_cast< SourcePlaylistInterface* >( pi ); @@ -414,7 +414,7 @@ SourceTreeView::onCustomContextMenu( const QPoint& pos ) else if ( model()->data( m_contextMenuIndex, SourcesModel::SourceTreeItemTypeRole ) == SourcesModel::Collection ) { CollectionItem* item = itemFromIndex< CollectionItem >( m_contextMenuIndex ); - if ( !item->source()->isLocal() ) + if ( !item->source().isNull() && !item->source()->isLocal() ) m_latchMenu.exec( mapToGlobal( pos ) ); } } From 8f0984c5ac25b70a25439d0da4d7e89d770a26db Mon Sep 17 00:00:00 2001 From: Christopher Reichert Date: Sun, 3 Jul 2011 21:25:56 -0500 Subject: [PATCH 73/86] Added doxygen comments for DatabaseCommand_SocialAction. --- .../database/databasecommand_socialaction.h | 104 +++++++++++++++++- 1 file changed, 98 insertions(+), 6 deletions(-) diff --git a/src/libtomahawk/database/databasecommand_socialaction.h b/src/libtomahawk/database/databasecommand_socialaction.h index 070cb38bb..20188a95c 100644 --- a/src/libtomahawk/database/databasecommand_socialaction.h +++ b/src/libtomahawk/database/databasecommand_socialaction.h @@ -6,7 +6,7 @@ * 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 @@ -28,7 +28,17 @@ #include "dllmacro.h" - +/** + * \class DatabaseCommand_SocialAction + * \brief Database command used to write social actions to database. + * + * This Database command allows Tomahawk to write social actions to + * the local database. These social actions can be interfaced with social + * networking API's such as LastFm, Facebook, or Twitter to allow the user + * to sync these actions with their accounts on these sites. + * + * \see DatabaseCommand_LoadSocialAction + */ class DLLEXPORT DatabaseCommand_SocialAction : public DatabaseCommand { Q_OBJECT @@ -38,10 +48,24 @@ Q_PROPERTY( int timestamp READ timestamp WRITE setTimestamp ) public: + /** + * \brief Default constructor for DatabaseCommand_SocialAction. + * + * Constructs an empty database command for a social action. + */ explicit DatabaseCommand_SocialAction( QObject* parent = 0 ) : DatabaseCommand( parent ) {} + /** + * \brief Overloaded constructor for DatabaseCommand_SocialAction. + * \param result Pointer to a Tomahawk::Result. + * \param action Name of the social action to be written to the database. + * \param comment Comment associated with this social action. + * \param parent Parent class. + * + * Constructor which creates a new database command for the specified social action. + */ explicit DatabaseCommand_SocialAction( const Tomahawk::result_ptr& result, QString action, QString comment="", QObject* parent = 0 ) : DatabaseCommand( parent ), m_result( result ), m_action( action ) { @@ -53,26 +77,94 @@ public: setTimestamp( QDateTime::currentDateTime().toTime_t() ); } + /** + * \brief Returns the name of this database command. + * \return QString containing the database command name 'socialaction'. + */ virtual QString commandname() const { return "socialaction"; } - virtual void exec( DatabaseImpl* ); + /** + * \brief Executes the database command. + * \param dbi Database instance. + * + * This method prepares an sql query to write this social action + * into the local database. + */ + virtual void exec( DatabaseImpl* dbi ); + + /** + * \brief Triggers a Database Sync. + */ virtual void postCommitHook(); + /** + * \brief Returns the artist associated with this database command. + * \return Name of the artist. + * \see setArtist() + */ QString artist() const { return m_artist; } + + /** + * \brief Sets the artist name for this database command. + * \param s QString containing the artist name. + * \see artist() + */ void setArtist( const QString& s ) { m_artist = s; } + /** + * \brief Returns the track name associated with this social action. + * \return QString containing the track name. + * \see setTrack() + */ QString track() const { return m_track; } - void setTrack( const QString& s ) { m_track = s; } - // key + /** + * \brief Sets the track name associated with this database command. + * \param track QString containing the track name. + * \see track() + */ + void setTrack( const QString& track ) { m_track = track; } + + /** + * \brief Returns the social action for this database command instance. + * \return QString containing the action name. + * \see setAction() + */ QString action() const { return m_action; } + + /** + * \brief Sets the social actions + * \param a QString containing action to be set in this class. + * \see action() + */ void setAction( QString a ) { m_action = a; } - // value + /** + * \brief Returns comment associated with this social action. + * \return QString containing comment associated with this social action. + * \see setComment() + */ QString comment() const { return m_comment; } + + /** + * \brief Sets the comment associated with this social action. + * \param com Comment associated with this social action. + * \see comment() + */ void setComment( const QString& com ) { m_comment = com; } + /** + * \brief Returns the timestamp associated with this social action. + * \return unsigned integer containing timestamp + * \see setTimesetamp() + */ int timestamp() const { return m_timestamp; } + + /** + * \brief Sets the timestamp associated with this social action. + * \param ts unsigned integer associated with this social action. + * \see timestamp() + */ void setTimestamp( const int ts ) { m_timestamp = ts; } private: From ce7040d1fd2ce41dde0169790994ac8ffa031528 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Wed, 6 Jul 2011 11:22:20 -0400 Subject: [PATCH 74/86] Replace InfoCustomData with QVariantMap --- src/audiocontrols.cpp | 12 ++--- src/audiocontrols.h | 2 +- src/libtomahawk/audio/audioengine.cpp | 22 ++++----- src/libtomahawk/audio/audioengine.h | 2 +- .../infoplugins/generic/echonestplugin.cpp | 28 +++++------ .../infoplugins/generic/echonestplugin.h | 20 ++++---- .../infoplugins/generic/lastfmplugin.cpp | 46 +++++++++---------- .../infoplugins/generic/lastfmplugin.h | 14 +++--- .../infoplugins/generic/musixmatchplugin.cpp | 24 +++++----- .../infoplugins/generic/musixmatchplugin.h | 6 +-- .../infoplugins/mac/adiumplugin.cpp | 2 +- .../infosystem/infoplugins/mac/adiumplugin.h | 4 +- .../infoplugins/unix/fdonotifyplugin.cpp | 4 +- .../infoplugins/unix/fdonotifyplugin.h | 4 +- src/libtomahawk/infosystem/infosystem.cpp | 16 +++---- src/libtomahawk/infosystem/infosystem.h | 18 ++++---- .../infosystem/infosystemcache.cpp | 2 +- src/libtomahawk/infosystem/infosystemcache.h | 6 +-- .../infosystem/infosystemworker.cpp | 16 +++---- src/libtomahawk/infosystem/infosystemworker.h | 4 +- src/libtomahawk/playlist/albummodel.cpp | 10 ++-- src/libtomahawk/playlist/albummodel.h | 2 +- src/libtomahawk/playlist/albumview.cpp | 2 +- src/libtomahawk/playlist/artistview.cpp | 2 +- src/libtomahawk/playlist/treemodel.cpp | 12 ++--- src/libtomahawk/playlist/treemodel.h | 2 +- .../widgets/infowidgets/ArtistInfoWidget.cpp | 18 ++++---- .../widgets/infowidgets/ArtistInfoWidget.h | 2 +- src/scrobbler.cpp | 6 +-- src/scrobbler.h | 2 +- src/tomahawkapp.cpp | 1 - src/xmppbot/xmppbot.cpp | 16 +++---- src/xmppbot/xmppbot.h | 2 +- 33 files changed, 163 insertions(+), 166 deletions(-) diff --git a/src/audiocontrols.cpp b/src/audiocontrols.cpp index 7961669f9..2a7a26355 100644 --- a/src/audiocontrols.cpp +++ b/src/audiocontrols.cpp @@ -167,8 +167,8 @@ AudioControls::AudioControls( QWidget* parent ) .scaled( ui->coverImage->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation ); 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 ) ) ); + SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), + SLOT( infoSystemInfo( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ) ); connect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( finished( QString ) ), SLOT( infoSystemFinished( QString ) ) ); @@ -220,12 +220,12 @@ AudioControls::onPlaybackStarted( const Tomahawk::result_ptr& result ) Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( s_acInfoIdentifier, Tomahawk::InfoSystem::InfoAlbumCoverArt, - QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ), Tomahawk::InfoSystem::InfoCustomData() ); + QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ), QVariantMap() ); } void -AudioControls::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ) +AudioControls::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, QVariantMap customData ) { Q_UNUSED( input ); Q_UNUSED( customData ); @@ -243,13 +243,13 @@ AudioControls::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType ty return; } - if ( !output.canConvert< Tomahawk::InfoSystem::InfoCustomData >() ) + if ( !output.canConvert< QVariantMap >() ) { qDebug() << "Cannot convert fetched art from a QByteArray"; return; } - Tomahawk::InfoSystem::InfoCustomData returnedData = output.value< Tomahawk::InfoSystem::InfoCustomData >(); + QVariantMap returnedData = output.value< QVariantMap >(); const QByteArray ba = returnedData["imgbytes"].toByteArray(); if ( ba.length() ) { diff --git a/src/audiocontrols.h b/src/audiocontrols.h index 74e611e2e..d4753dede 100644 --- a/src/audiocontrols.h +++ b/src/audiocontrols.h @@ -67,7 +67,7 @@ private slots: void onTrackClicked(); void onLoveButtonClicked( bool ); - void infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ); + void infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, QVariantMap customData ); void infoSystemFinished( QString target ); private: diff --git a/src/libtomahawk/audio/audioengine.cpp b/src/libtomahawk/audio/audioengine.cpp index 7c7fbe68e..4d17fa930 100644 --- a/src/libtomahawk/audio/audioengine.cpp +++ b/src/libtomahawk/audio/audioengine.cpp @@ -154,9 +154,9 @@ AudioEngine::stop() sendWaitingNotification(); else if ( TomahawkSettings::instance()->verboseNotifications() ) { - Tomahawk::InfoSystem::InfoCustomData stopInfo; + QVariantMap stopInfo; stopInfo["message"] = QString( "Tomahawk is stopped." ); - map[ Tomahawk::InfoSystem::InfoNotifyUser ] = QVariant::fromValue< Tomahawk::InfoSystem::InfoCustomData >( stopInfo ); + map[ Tomahawk::InfoSystem::InfoNotifyUser ] = QVariant::fromValue< QVariantMap >( stopInfo ); } Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( s_aeInfoIdentifier, map ); @@ -240,11 +240,11 @@ AudioEngine::mute() void AudioEngine::sendWaitingNotification() const { - Tomahawk::InfoSystem::InfoCustomData retryInfo; + QVariantMap retryInfo; retryInfo["message"] = QString( "The current track could not be resolved. Tomahawk will pick back up with the next resolvable track from this source." ); Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNotifyUser, - QVariant::fromValue< Tomahawk::InfoSystem::InfoCustomData >( retryInfo ) ); + QVariant::fromValue< QVariantMap >( retryInfo ) ); } @@ -256,8 +256,8 @@ AudioEngine::sendNowPlayingNotification() if ( ! m_infoSystemConnected ) { 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 ) ) ); + SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), + SLOT( infoSystemInfo( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ) ); connect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( finished( QString ) ), SLOT( infoSystemFinished( QString ) ) ); @@ -270,12 +270,12 @@ AudioEngine::sendNowPlayingNotification() Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoAlbumCoverArt, - QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ), Tomahawk::InfoSystem::InfoCustomData() ); + QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ), QVariantMap() ); } void -AudioEngine::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ) +AudioEngine::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, QVariantMap customData ) { qDebug() << Q_FUNC_INFO; Q_UNUSED( input ); @@ -288,7 +288,7 @@ AudioEngine::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type return; } - Tomahawk::InfoSystem::InfoCustomData playInfo; + QVariantMap playInfo; playInfo["message"] = QString( "Tomahawk is playing \"%1\" by %2 on album %3." ) .arg( m_currentTrack->track() ) .arg( m_currentTrack->artist()->name() ) @@ -296,7 +296,7 @@ AudioEngine::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type if ( !output.isNull() && output.isValid() ) { qDebug() << Q_FUNC_INFO << " output is valid"; - Tomahawk::InfoSystem::InfoCustomData returnedData = output.value< Tomahawk::InfoSystem::InfoCustomData >(); + QVariantMap returnedData = output.value< QVariantMap >(); const QByteArray ba = returnedData["imgbytes"].toByteArray(); qDebug() << "ba.length = " << ba.length(); if ( ba.length() ) @@ -309,7 +309,7 @@ AudioEngine::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNotifyUser, - QVariant::fromValue< Tomahawk::InfoSystem::InfoCustomData >( playInfo ) ); + QVariant::fromValue< QVariantMap >( playInfo ) ); } diff --git a/src/libtomahawk/audio/audioengine.h b/src/libtomahawk/audio/audioengine.h index bdc8ee705..41816efdf 100644 --- a/src/libtomahawk/audio/audioengine.h +++ b/src/libtomahawk/audio/audioengine.h @@ -87,7 +87,7 @@ public slots: void playlistNextTrackReady(); - void infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ); + void infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, QVariantMap customData ); void infoSystemFinished( QString caller ); signals: diff --git a/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.cpp b/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.cpp index 7034b565e..d39226d12 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.cpp @@ -66,7 +66,7 @@ EchoNestPlugin::namChangedSlot( QNetworkAccessManager *nam ) } void -EchoNestPlugin::getInfo(const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData) +EchoNestPlugin::getInfo(const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData) { switch (type) { @@ -91,7 +91,7 @@ EchoNestPlugin::getInfo(const QString caller, const Tomahawk::InfoSystem::InfoTy } void -EchoNestPlugin::getSongProfile(const QString &caller, const QVariant &input, const InfoCustomData &customData, const QString &item) +EchoNestPlugin::getSongProfile(const QString &caller, const QVariant &input, const QVariantMap &customData, const QString &item) { //WARNING: Totally not implemented yet Q_UNUSED( item ); @@ -108,7 +108,7 @@ EchoNestPlugin::getSongProfile(const QString &caller, const QVariant &input, con } void -EchoNestPlugin::getArtistBiography(const QString &caller, const QVariant &input, const InfoCustomData &customData) +EchoNestPlugin::getArtistBiography(const QString &caller, const QVariant &input, const QVariantMap &customData) { if( !isValidArtistData( caller, input, customData ) ) return; @@ -123,7 +123,7 @@ EchoNestPlugin::getArtistBiography(const QString &caller, const QVariant &input, } void -EchoNestPlugin::getArtistFamiliarity(const QString &caller, const QVariant &input, const InfoCustomData &customData) +EchoNestPlugin::getArtistFamiliarity(const QString &caller, const QVariant &input, const QVariantMap &customData) { if( !isValidArtistData( caller, input, customData ) ) return; @@ -139,7 +139,7 @@ EchoNestPlugin::getArtistFamiliarity(const QString &caller, const QVariant &inpu } void -EchoNestPlugin::getArtistHotttnesss(const QString &caller, const QVariant &input, const InfoCustomData &customData) +EchoNestPlugin::getArtistHotttnesss(const QString &caller, const QVariant &input, const QVariantMap &customData) { if( !isValidArtistData( caller, input, customData ) ) return; @@ -154,7 +154,7 @@ EchoNestPlugin::getArtistHotttnesss(const QString &caller, const QVariant &input } void -EchoNestPlugin::getArtistTerms(const QString &caller, const QVariant &input, const InfoCustomData &customData) +EchoNestPlugin::getArtistTerms(const QString &caller, const QVariant &input, const QVariantMap &customData) { if( !isValidArtistData( caller, input, customData ) ) return; @@ -169,7 +169,7 @@ EchoNestPlugin::getArtistTerms(const QString &caller, const QVariant &input, con } void -EchoNestPlugin::getMiscTopTerms(const QString &caller, const QVariant &input, const InfoCustomData& customData) +EchoNestPlugin::getMiscTopTerms(const QString &caller, const QVariant &input, const QVariantMap& customData) { Q_UNUSED( input ); QNetworkReply* reply = Echonest::Artist::topTerms( 20 ); @@ -200,7 +200,7 @@ EchoNestPlugin::getArtistBiographySlot() Tomahawk::InfoSystem::InfoArtistBiography, reply->property( "input" ), QVariant::fromValue< Tomahawk::InfoSystem::InfoGenericMap >( biographyMap ), - reply->property( "customData" ).value< Tomahawk::InfoSystem::InfoCustomData >() ); + reply->property( "customData" ).value< QVariantMap >() ); reply->deleteLater(); } @@ -214,7 +214,7 @@ EchoNestPlugin::getArtistFamiliaritySlot() Tomahawk::InfoSystem::InfoArtistFamiliarity, reply->property( "input" ), familiarity, - reply->property( "customData" ).value< Tomahawk::InfoSystem::InfoCustomData >() ); + reply->property( "customData" ).value< QVariantMap >() ); reply->deleteLater(); } @@ -228,7 +228,7 @@ EchoNestPlugin::getArtistHotttnesssSlot() Tomahawk::InfoSystem::InfoArtistHotttness, reply->property( "input" ), hotttnesss, - reply->property( "customData" ).value< Tomahawk::InfoSystem::InfoCustomData >() ); + reply->property( "customData" ).value< QVariantMap >() ); reply->deleteLater(); } @@ -249,7 +249,7 @@ EchoNestPlugin::getArtistTermsSlot() Tomahawk::InfoSystem::InfoArtistTerms, reply->property( "input" ), QVariant::fromValue< Tomahawk::InfoSystem::InfoGenericMap >( termsMap ), - reply->property( "customData" ).value< Tomahawk::InfoSystem::InfoCustomData >() ); + reply->property( "customData" ).value< QVariantMap >() ); reply->deleteLater(); } @@ -269,12 +269,12 @@ EchoNestPlugin::getMiscTopSlot() Tomahawk::InfoSystem::InfoMiscTopTerms, QVariant(), QVariant::fromValue< Tomahawk::InfoSystem::InfoGenericMap >( termsMap ), - reply->property( "customData" ).value< Tomahawk::InfoSystem::InfoCustomData >() ); + reply->property( "customData" ).value< QVariantMap >() ); reply->deleteLater(); } bool -EchoNestPlugin::isValidArtistData(const QString &caller, const QVariant &input, const InfoCustomData &customData) +EchoNestPlugin::isValidArtistData(const QString &caller, const QVariant &input, const QVariantMap &customData) { if (input.isNull() || !input.isValid() || !input.canConvert()) { @@ -291,7 +291,7 @@ EchoNestPlugin::isValidArtistData(const QString &caller, const QVariant &input, } bool -EchoNestPlugin::isValidTrackData(const QString &caller, const QVariant &input, const InfoCustomData &customData) +EchoNestPlugin::isValidTrackData(const QString &caller, const QVariant &input, const QVariantMap &customData) { if (input.isNull() || !input.isValid() || !input.canConvert()) { diff --git a/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.h b/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.h index e27a306f7..85bad01b5 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.h +++ b/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.h @@ -44,7 +44,7 @@ public: virtual ~EchoNestPlugin(); protected slots: - virtual void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData ); + virtual void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ); virtual void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant data ) { @@ -53,7 +53,7 @@ protected slots: Q_UNUSED( data ); } - virtual void notInCacheSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData ) + virtual void notInCacheSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) { Q_UNUSED( criteria ); Q_UNUSED( caller ); @@ -66,15 +66,15 @@ public slots: void namChangedSlot( QNetworkAccessManager *nam ); private: - void getSongProfile( const QString &caller, const QVariant &input, const InfoCustomData &customData, const QString &item = QString() ); - void getArtistBiography ( const QString &caller, const QVariant &input, const InfoCustomData &customData ); - void getArtistFamiliarity( const QString &caller, const QVariant &input, const InfoCustomData &customData ); - void getArtistHotttnesss( const QString &caller, const QVariant &input, const InfoCustomData &customData ); - void getArtistTerms( const QString &caller, const QVariant &input, const InfoCustomData &customData ); - void getMiscTopTerms( const QString &caller, const QVariant &input, const InfoCustomData &customData ); + void getSongProfile( const QString &caller, const QVariant &input, const QVariantMap &customData, const QString &item = QString() ); + void getArtistBiography ( const QString &caller, const QVariant &input, const QVariantMap &customData ); + void getArtistFamiliarity( const QString &caller, const QVariant &input, const QVariantMap &customData ); + void getArtistHotttnesss( const QString &caller, const QVariant &input, const QVariantMap &customData ); + void getArtistTerms( const QString &caller, const QVariant &input, const QVariantMap &customData ); + void getMiscTopTerms( const QString &caller, const QVariant &input, const QVariantMap &customData ); - bool isValidArtistData( const QString &caller, const QVariant &input, const InfoCustomData& customData ); - bool isValidTrackData( const QString &caller, const QVariant &input, const InfoCustomData& customData ); + bool isValidArtistData( const QString &caller, const QVariant &input, const QVariantMap& customData ); + bool isValidTrackData( const QString &caller, const QVariant &input, const QVariantMap& customData ); Echonest::Artist artistFromReply( QNetworkReply* ); private slots: diff --git a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp index a7ef22e8f..a3ce55d94 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp @@ -120,7 +120,7 @@ LastFmPlugin::namChangedSlot( QNetworkAccessManager *nam ) void -LastFmPlugin::dataError( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData ) +LastFmPlugin::dataError( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const QVariantMap &customData ) { emit info( caller, type, input, QVariant(), customData ); return; @@ -128,7 +128,7 @@ LastFmPlugin::dataError( const QString &caller, const Tomahawk::InfoSystem::Info void -LastFmPlugin::getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData ) +LastFmPlugin::getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) { qDebug() << Q_FUNC_INFO; @@ -263,7 +263,7 @@ LastFmPlugin::sendLoveSong( const InfoType type, QVariant input ) void -LastFmPlugin::fetchSimilarArtists( const QString &caller, const InfoType type, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData ) +LastFmPlugin::fetchSimilarArtists( const QString &caller, const InfoType type, const QVariant &input, const QVariantMap &customData ) { qDebug() << Q_FUNC_INFO; if ( !input.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() ) @@ -286,7 +286,7 @@ LastFmPlugin::fetchSimilarArtists( const QString &caller, const InfoType type, c void -LastFmPlugin::fetchTopTracks( const QString &caller, const InfoType type, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData ) +LastFmPlugin::fetchTopTracks( const QString &caller, const InfoType type, const QVariant &input, const QVariantMap &customData ) { qDebug() << Q_FUNC_INFO; if ( !input.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() ) @@ -309,7 +309,7 @@ LastFmPlugin::fetchTopTracks( const QString &caller, const InfoType type, const void -LastFmPlugin::fetchCoverArt( const QString &caller, const InfoType type, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData ) +LastFmPlugin::fetchCoverArt( const QString &caller, const InfoType type, const QVariant &input, const QVariantMap &customData ) { qDebug() << Q_FUNC_INFO; if ( !input.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() ) @@ -333,7 +333,7 @@ LastFmPlugin::fetchCoverArt( const QString &caller, const InfoType type, const Q void -LastFmPlugin::fetchArtistImages( const QString &caller, const InfoType type, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData ) +LastFmPlugin::fetchArtistImages( const QString &caller, const InfoType type, const QVariant &input, const QVariantMap &customData ) { qDebug() << Q_FUNC_INFO; if ( !input.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() ) @@ -356,7 +356,7 @@ LastFmPlugin::fetchArtistImages( const QString &caller, const InfoType type, con void -LastFmPlugin::notInCacheSlot( const QHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData ) +LastFmPlugin::notInCacheSlot( const QHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) { qDebug() << Q_FUNC_INFO; @@ -373,7 +373,7 @@ LastFmPlugin::notInCacheSlot( const QHash criteria, const QStr { lastfm::Artist a( criteria["artist"] ); QNetworkReply* reply = a.getSimilar(); - reply->setProperty( "customData", QVariant::fromValue( customData ) ); + reply->setProperty( "customData", QVariant::fromValue( customData ) ); reply->setProperty( "origData", input ); reply->setProperty( "caller", caller ); reply->setProperty( "type", (uint)(type) ); @@ -386,7 +386,7 @@ LastFmPlugin::notInCacheSlot( const QHash criteria, const QStr { lastfm::Artist a( criteria["artist"] ); QNetworkReply* reply = a.getTopTracks(); - reply->setProperty( "customData", QVariant::fromValue( customData ) ); + reply->setProperty( "customData", QVariant::fromValue( customData ) ); reply->setProperty( "origData", input ); reply->setProperty( "caller", caller ); reply->setProperty( "type", (uint)(type) ); @@ -403,7 +403,7 @@ LastFmPlugin::notInCacheSlot( const QHash criteria, const QStr QString imgurl = "http://ws.audioscrobbler.com/2.0/?method=album.imageredirect&artist=%1&album=%2&autocorrect=1&size=large&api_key=7a90f6672a04b809ee309af169f34b8b"; QNetworkRequest req( imgurl.arg( artistName ).arg( albumName ) ); QNetworkReply* reply = lastfm::nam()->get( req ); - reply->setProperty( "customData", QVariant::fromValue( customData ) ); + reply->setProperty( "customData", QVariant::fromValue( customData ) ); reply->setProperty( "origData", input ); reply->setProperty( "caller", caller ); reply->setProperty( "type", (uint)(type) ); @@ -419,7 +419,7 @@ LastFmPlugin::notInCacheSlot( const QHash criteria, const QStr QString imgurl = "http://ws.audioscrobbler.com/2.0/?method=artist.imageredirect&artist=%1&autocorrect=1&size=large&api_key=7a90f6672a04b809ee309af169f34b8b"; QNetworkRequest req( imgurl.arg( artistName ) ); QNetworkReply* reply = lastfm::nam()->get( req ); - reply->setProperty( "customData", QVariant::fromValue( customData ) ); + reply->setProperty( "customData", QVariant::fromValue( customData ) ); reply->setProperty( "origData", input ); reply->setProperty( "caller", caller ); reply->setProperty( "type", (uint)(type) ); @@ -454,11 +454,11 @@ LastFmPlugin::similarArtistsReturned() al << a; } - InfoCustomData returnedData; + QVariantMap returnedData; returnedData["artists"] = al; returnedData["score"] = sl; - InfoCustomData customData = reply->property( "customData" ).value< Tomahawk::InfoSystem::InfoCustomData >(); + QVariantMap customData = reply->property( "customData" ).value< QVariantMap >(); InfoType type = (Tomahawk::InfoSystem::InfoType)(reply->property( "type" ).toUInt()); emit info( reply->property( "caller" ).toString(), @@ -487,10 +487,10 @@ LastFmPlugin::topTracksReturned() qDebug() << "Got top-track:" << t; } - InfoCustomData returnedData; + QVariantMap returnedData; returnedData["tracks"] = topTracks; - InfoCustomData customData = reply->property( "customData" ).value< Tomahawk::InfoSystem::InfoCustomData >(); + QVariantMap customData = reply->property( "customData" ).value< QVariantMap >(); InfoType type = (Tomahawk::InfoSystem::InfoType)(reply->property( "type" ).toUInt()); emit info( reply->property( "caller" ).toString(), @@ -520,7 +520,7 @@ LastFmPlugin::coverArtReturned() { qDebug() << "Uh oh, null byte array"; InfoType type = (Tomahawk::InfoSystem::InfoType)(reply->property( "type" ).toUInt()); - InfoCustomData customData = reply->property( "customData" ).value< Tomahawk::InfoSystem::InfoCustomData >(); + QVariantMap customData = reply->property( "customData" ).value< QVariantMap >(); emit info( reply->property( "caller" ).toString(), type, reply->property( "origData" ), QVariant(), customData ); return; } @@ -530,11 +530,11 @@ LastFmPlugin::coverArtReturned() ba = QByteArray(); } - InfoCustomData returnedData; + QVariantMap returnedData; returnedData["imgbytes"] = ba; returnedData["url"] = reply->url().toString(); - InfoCustomData customData = reply->property( "customData" ).value< Tomahawk::InfoSystem::InfoCustomData >(); + QVariantMap customData = reply->property( "customData" ).value< QVariantMap >(); InfoType type = (Tomahawk::InfoSystem::InfoType)(reply->property( "type" ).toUInt()); emit info( reply->property( "caller" ).toString(), @@ -556,7 +556,7 @@ LastFmPlugin::coverArtReturned() { qDebug() << "Uh oh, nam is null"; InfoType type = (Tomahawk::InfoSystem::InfoType)(reply->property( "type" ).toUInt()); - InfoCustomData customData = reply->property( "customData" ).value< Tomahawk::InfoSystem::InfoCustomData >(); + QVariantMap customData = reply->property( "customData" ).value< QVariantMap >(); emit info( reply->property( "caller" ).toString(), type, reply->property( "origData" ), QVariant(), customData ); return; } @@ -587,7 +587,7 @@ LastFmPlugin::artistImagesReturned() { qDebug() << "Uh oh, null byte array"; InfoType type = (Tomahawk::InfoSystem::InfoType)(reply->property( "type" ).toUInt()); - InfoCustomData customData = reply->property( "customData" ).value< Tomahawk::InfoSystem::InfoCustomData >(); + QVariantMap customData = reply->property( "customData" ).value< QVariantMap >(); emit info( reply->property( "caller" ).toString(), type, reply->property( "origData" ), QVariant(), customData ); return; } @@ -596,12 +596,12 @@ LastFmPlugin::artistImagesReturned() if ( reply->url().toString().startsWith( url.toString() ) ) ba = QByteArray(); } - InfoCustomData returnedData; + QVariantMap returnedData; returnedData["imgbytes"] = ba; returnedData["url"] = reply->url().toString(); InfoType type = (Tomahawk::InfoSystem::InfoType)(reply->property( "type" ).toUInt()); - InfoCustomData customData = reply->property( "customData" ).value< Tomahawk::InfoSystem::InfoCustomData >(); + QVariantMap customData = reply->property( "customData" ).value< QVariantMap >(); emit info( reply->property( "caller" ).toString(), type, reply->property( "origData" ), returnedData, customData ); InfoCriteriaHash origData = reply->property( "origData" ).value< Tomahawk::InfoSystem::InfoCriteriaHash >(); @@ -615,7 +615,7 @@ LastFmPlugin::artistImagesReturned() { qDebug() << "Uh oh, nam is null"; InfoType type = (Tomahawk::InfoSystem::InfoType)(reply->property( "type" ).toUInt()); - InfoCustomData customData = reply->property( "customData" ).value< Tomahawk::InfoSystem::InfoCustomData >(); + QVariantMap customData = reply->property( "customData" ).value< QVariantMap >(); emit info( reply->property( "caller" ).toString(), type, reply->property( "origData" ), QVariant(), customData ); return; } diff --git a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.h b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.h index 25c576a85..253c93fcd 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.h +++ b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.h @@ -55,23 +55,23 @@ public slots: void namChangedSlot( QNetworkAccessManager *nam ); protected slots: - virtual void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData ); - virtual void notInCacheSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData ); + virtual void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ); + virtual void notInCacheSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ); virtual void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant data ); private: - void fetchCoverArt( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData ); - void fetchArtistImages( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData ); - void fetchSimilarArtists( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData ); - void fetchTopTracks( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData ); + void fetchCoverArt( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const QVariantMap &customData ); + void fetchArtistImages( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const QVariantMap &customData ); + void fetchSimilarArtists( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const QVariantMap &customData ); + void fetchTopTracks( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const QVariantMap &customData ); void createScrobbler(); void nowPlaying( const QVariant &input ); void scrobble(); void sendLoveSong( const InfoType type, QVariant input ); - void dataError( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData ); + void dataError( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const QVariantMap &customData ); lastfm::MutableTrack m_track; lastfm::Audioscrobbler* m_scrobbler; diff --git a/src/libtomahawk/infosystem/infoplugins/generic/musixmatchplugin.cpp b/src/libtomahawk/infosystem/infoplugins/generic/musixmatchplugin.cpp index eb60882a4..0714cb977 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/musixmatchplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/generic/musixmatchplugin.cpp @@ -51,12 +51,12 @@ MusixMatchPlugin::namChangedSlot( QNetworkAccessManager *nam ) } void -MusixMatchPlugin::getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData ) +MusixMatchPlugin::getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) { qDebug() << Q_FUNC_INFO; - if( !isValidTrackData(caller, input, customData) || !input.canConvert() || m_nam.isNull() || type != Tomahawk::InfoSystem::InfoTrackLyrics ) + if( !isValidTrackData(caller, input, customData) || !input.canConvert() || m_nam.isNull() || type != Tomahawk::InfoSystem::InfoTrackLyrics ) return; - Tomahawk::InfoSystem::InfoCustomData hash = input.value(); + QVariantMap hash = input.value(); QString artist = hash["artistName"].toString(); QString track = hash["trackName"].toString(); if( artist.isEmpty() || track.isEmpty() ) @@ -71,7 +71,7 @@ MusixMatchPlugin::getInfo( const QString caller, const Tomahawk::InfoSystem::Inf url.addQueryItem("q_artist", artist); url.addQueryItem("q_track", track); QNetworkReply* reply = m_nam.data()->get(QNetworkRequest(url)); - reply->setProperty("customData", QVariant::fromValue(customData)); + reply->setProperty("customData", QVariant::fromValue(customData)); reply->setProperty("origData", input); reply->setProperty("caller", caller); @@ -79,16 +79,16 @@ MusixMatchPlugin::getInfo( const QString caller, const Tomahawk::InfoSystem::Inf } bool -MusixMatchPlugin::isValidTrackData( const QString &caller, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData ) +MusixMatchPlugin::isValidTrackData( const QString &caller, const QVariant &input, const QVariantMap &customData ) { qDebug() << Q_FUNC_INFO; - if (input.isNull() || !input.isValid() || !input.canConvert()) + if (input.isNull() || !input.isValid() || !input.canConvert()) { emit info(caller, Tomahawk::InfoSystem::InfoTrackLyrics, input, QVariant(), customData); qDebug() << "MusixMatchPlugin::isValidTrackData: Data null, invalid, or can't convert"; return false; } - InfoCustomData hash = input.value(); + QVariantMap hash = input.value(); if (hash["trackName"].toString().isEmpty() ) { emit info(caller, Tomahawk::InfoSystem::InfoTrackLyrics, input, QVariant(), customData); @@ -111,7 +111,7 @@ MusixMatchPlugin::trackSearchSlot() QNetworkReply* oldReply = qobject_cast( sender() ); if ( !oldReply || m_nam.isNull() ) { - emit info(QString(), Tomahawk::InfoSystem::InfoTrackLyrics, QVariant(), QVariant(), Tomahawk::InfoSystem::InfoCustomData()); + emit info(QString(), Tomahawk::InfoSystem::InfoTrackLyrics, QVariant(), QVariant(), QVariantMap()); return; } QDomDocument doc; @@ -120,7 +120,7 @@ MusixMatchPlugin::trackSearchSlot() QDomNodeList domNodeList = doc.elementsByTagName("track_id"); if (domNodeList.isEmpty()) { - emit info(oldReply->property("caller").toString(), Tomahawk::InfoSystem::InfoTrackLyrics, oldReply->property("origData"), QVariant(), oldReply->property("customData").value()); + emit info(oldReply->property("caller").toString(), Tomahawk::InfoSystem::InfoTrackLyrics, oldReply->property("origData"), QVariant(), oldReply->property("customData").value()); return; } QString track_id = domNodeList.at(0).toElement().text(); @@ -142,7 +142,7 @@ MusixMatchPlugin::trackLyricsSlot() QNetworkReply* reply = qobject_cast( sender() ); if (!reply) { - emit info(QString(), Tomahawk::InfoSystem::InfoTrackLyrics, QVariant(), QVariant(), Tomahawk::InfoSystem::InfoCustomData()); + emit info(QString(), Tomahawk::InfoSystem::InfoTrackLyrics, QVariant(), QVariant(), QVariantMap()); return; } QDomDocument doc; @@ -150,10 +150,10 @@ MusixMatchPlugin::trackLyricsSlot() QDomNodeList domNodeList = doc.elementsByTagName("lyrics_body"); if (domNodeList.isEmpty()) { - emit info(reply->property("caller").toString(), Tomahawk::InfoSystem::InfoTrackLyrics, reply->property("origData"), QVariant(), reply->property("customData").value()); + emit info(reply->property("caller").toString(), Tomahawk::InfoSystem::InfoTrackLyrics, reply->property("origData"), QVariant(), reply->property("customData").value()); return; } QString lyrics = domNodeList.at(0).toElement().text(); qDebug() << "Emitting lyrics: " << lyrics; - emit info(reply->property("caller").toString(), Tomahawk::InfoSystem::InfoTrackLyrics, reply->property("origData"), QVariant(lyrics), reply->property("customData").value()); + emit info(reply->property("caller").toString(), Tomahawk::InfoSystem::InfoTrackLyrics, reply->property("origData"), QVariant(lyrics), reply->property("customData").value()); } diff --git a/src/libtomahawk/infosystem/infoplugins/generic/musixmatchplugin.h b/src/libtomahawk/infosystem/infoplugins/generic/musixmatchplugin.h index 8174e2824..3451e3088 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/musixmatchplugin.h +++ b/src/libtomahawk/infosystem/infoplugins/generic/musixmatchplugin.h @@ -45,7 +45,7 @@ public slots: void namChangedSlot( QNetworkAccessManager *nam ); protected slots: - virtual void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData ); + virtual void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ); virtual void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant data ) { @@ -54,7 +54,7 @@ protected slots: Q_UNUSED( data ); } - virtual void notInCacheSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData ) + virtual void notInCacheSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) { Q_UNUSED( criteria ); Q_UNUSED( caller ); @@ -64,7 +64,7 @@ protected slots: } private: - bool isValidTrackData( const QString &caller, const QVariant &input, const InfoCustomData &customData ); + bool isValidTrackData( const QString &caller, const QVariant &input, const QVariantMap &customData ); QString m_apiKey; diff --git a/src/libtomahawk/infosystem/infoplugins/mac/adiumplugin.cpp b/src/libtomahawk/infosystem/infoplugins/mac/adiumplugin.cpp index 7a76a632e..c2da08fb5 100644 --- a/src/libtomahawk/infosystem/infoplugins/mac/adiumplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/mac/adiumplugin.cpp @@ -97,7 +97,7 @@ AdiumPlugin::settingsChanged() } void -AdiumPlugin::getInfo( const QString caller, const InfoType type, const QVariant data, InfoCustomData customData ) +AdiumPlugin::getInfo( const QString caller, const InfoType type, const QVariant data, QVariantMap customData ) { switch (type) { diff --git a/src/libtomahawk/infosystem/infoplugins/mac/adiumplugin.h b/src/libtomahawk/infosystem/infoplugins/mac/adiumplugin.h index 76417fb74..681b9e2e1 100644 --- a/src/libtomahawk/infosystem/infoplugins/mac/adiumplugin.h +++ b/src/libtomahawk/infosystem/infoplugins/mac/adiumplugin.h @@ -39,12 +39,12 @@ public: virtual ~AdiumPlugin(); protected slots: - void getInfo( const QString caller, const InfoType type, const QVariant data, InfoCustomData customData ); + void getInfo( const QString caller, const InfoType type, const QVariant data, QVariantMap customData ); void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input ); public slots: void namChangedSlot( QNetworkAccessManager* /*nam*/ ) {} // unused - void notInCacheSlot( const Tomahawk::InfoSystem::InfoCriteriaHash /*criteria*/, const QString /*caller*/, const Tomahawk::InfoSystem::InfoType /*type*/, const QVariant /*input*/, const Tomahawk::InfoSystem::InfoCustomData /*customData*/ ) {} // unused + void notInCacheSlot( const Tomahawk::InfoSystem::InfoCriteriaHash /*criteria*/, const QString /*caller*/, const Tomahawk::InfoSystem::InfoType /*type*/, const QVariant /*input*/, const QVariantMap /*customData*/ ) {} // unused private slots: void clearStatus(); diff --git a/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.cpp b/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.cpp index 7e38e615f..56551fc19 100644 --- a/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.cpp @@ -63,12 +63,12 @@ FdoNotifyPlugin::pushInfo( const QString caller, const Tomahawk::InfoSystem::Inf { Q_UNUSED( caller ); qDebug() << Q_FUNC_INFO; - if ( type != Tomahawk::InfoSystem::InfoNotifyUser || !pushData.canConvert< Tomahawk::InfoSystem::InfoCustomData >() ) + if ( type != Tomahawk::InfoSystem::InfoNotifyUser || !pushData.canConvert< QVariantMap >() ) { qDebug() << Q_FUNC_INFO << " not the right type or could not convert the hash"; return; } - Tomahawk::InfoSystem::InfoCustomData hash = pushData.value< Tomahawk::InfoSystem::InfoCustomData >(); + QVariantMap hash = pushData.value< QVariantMap >(); if ( !hash.contains( "message" ) ) { qDebug() << Q_FUNC_INFO << " hash did not contain a message"; diff --git a/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.h b/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.h index 87cc2ba61..f0a0afc91 100644 --- a/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.h +++ b/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.h @@ -38,7 +38,7 @@ public: virtual void namChangedSlot( QNetworkAccessManager* ) {} protected slots: - virtual void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData ) + virtual void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) { Q_UNUSED( caller ); Q_UNUSED( type ); @@ -48,7 +48,7 @@ protected slots: virtual void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant pushData ); - virtual void notInCacheSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData ) + virtual void notInCacheSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) { Q_UNUSED( criteria ); Q_UNUSED( caller ); diff --git a/src/libtomahawk/infosystem/infosystem.cpp b/src/libtomahawk/infosystem/infosystem.cpp index 4fe9af12f..cfcce976f 100644 --- a/src/libtomahawk/infosystem/infosystem.cpp +++ b/src/libtomahawk/infosystem/infosystem.cpp @@ -71,11 +71,11 @@ InfoSystem::InfoSystem(QObject *parent) connect( TomahawkSettings::instance(), SIGNAL( changed() ), SLOT( newNam() ) ); - connect( m_cache.data(), SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ), - this, SLOT( infoSlot( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ), Qt::UniqueConnection ); + connect( m_cache.data(), SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), + this, SLOT( infoSlot( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), Qt::UniqueConnection ); - connect( m_worker.data(), SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ), - this, SLOT( infoSlot( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ), Qt::UniqueConnection ); + connect( m_worker.data(), SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), + this, SLOT( infoSlot( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), Qt::UniqueConnection ); } InfoSystem::~InfoSystem() @@ -116,18 +116,18 @@ InfoSystem::newNam() const void -InfoSystem::getInfo( const QString &caller, const InfoType type, const QVariant& input, InfoCustomData customData ) +InfoSystem::getInfo( const QString &caller, const InfoType type, const QVariant& input, QVariantMap customData ) { qDebug() << Q_FUNC_INFO; m_dataTracker[caller][type] = m_dataTracker[caller][type] + 1; qDebug() << "current count in dataTracker for type" << type << "is" << m_dataTracker[caller][type]; - QMetaObject::invokeMethod( m_worker.data(), "getInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input ), Q_ARG( Tomahawk::InfoSystem::InfoCustomData, customData ) ); + QMetaObject::invokeMethod( m_worker.data(), "getInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input ), Q_ARG( QVariantMap, customData ) ); } void -InfoSystem::getInfo( const QString &caller, const InfoTypeMap &input, InfoCustomData customData ) +InfoSystem::getInfo( const QString &caller, const InfoTypeMap &input, QVariantMap customData ) { Q_FOREACH( InfoType type, input.keys() ) getInfo( caller, type, input[type], customData ); @@ -152,7 +152,7 @@ InfoSystem::pushInfo( const QString &caller, const InfoTypeMap &input ) void -InfoSystem::infoSlot( QString target, InfoType type, QVariant input, QVariant output, InfoCustomData customData ) +InfoSystem::infoSlot( QString target, InfoType type, QVariant input, QVariant output, QVariantMap customData ) { qDebug() << Q_FUNC_INFO; qDebug() << "current count in dataTracker is " << m_dataTracker[target][type]; diff --git a/src/libtomahawk/infosystem/infosystem.h b/src/libtomahawk/infosystem/infosystem.h index 2a3c873d8..1681473c0 100644 --- a/src/libtomahawk/infosystem/infosystem.h +++ b/src/libtomahawk/infosystem/infosystem.h @@ -109,7 +109,6 @@ enum InfoType { // as items are saved in cache, mark them here to not change the typedef QMap< InfoType, QVariant > InfoTypeMap; typedef QMap< QString, QMap< QString, QString > > InfoGenericMap; -typedef QHash< QString, QVariant > InfoCustomData; typedef QHash< QString, QString > InfoCriteriaHash; class DLLEXPORT InfoPlugin : public QObject @@ -125,15 +124,15 @@ public: QSet< InfoType > supportedPushTypes() const { return m_supportedPushTypes; } signals: - void getCachedInfo( Tomahawk::InfoSystem::InfoCriteriaHash criteria, qint64 newMaxAge, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, Tomahawk::InfoSystem::InfoCustomData customData ); + void getCachedInfo( Tomahawk::InfoSystem::InfoCriteriaHash criteria, qint64 newMaxAge, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariantMap customData ); void updateCache( Tomahawk::InfoSystem::InfoCriteriaHash 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 info( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, QVariantMap customData ); void finished( QString, Tomahawk::InfoSystem::InfoType ); protected slots: - virtual void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant data, const Tomahawk::InfoSystem::InfoCustomData customData ) = 0; + virtual void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant data, const QVariantMap customData ) = 0; virtual void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant data ) = 0; - virtual void notInCacheSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData ) = 0; + virtual void notInCacheSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) = 0; virtual void namChangedSlot( QNetworkAccessManager *nam ) = 0; @@ -158,17 +157,17 @@ public: InfoSystem( QObject *parent ); ~InfoSystem(); - void getInfo( const QString &caller, const InfoType type, const QVariant &input, InfoCustomData customData ); - void getInfo( const QString &caller, const InfoTypeMap &input, InfoCustomData customData ); + void getInfo( const QString &caller, const InfoType type, const QVariant &input, QVariantMap customData ); + void getInfo( const QString &caller, const InfoTypeMap &input, QVariantMap customData ); void pushInfo( const QString &caller, const InfoType type, const QVariant &input ); void pushInfo( const QString &caller, const InfoTypeMap &input ); signals: - void info( QString caller, Tomahawk::InfoSystem::InfoType, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ); + void info( QString caller, Tomahawk::InfoSystem::InfoType, QVariant input, QVariant output, QVariantMap customData ); void finished( QString target ); public slots: - void infoSlot( const QString target, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariant output, const Tomahawk::InfoSystem::InfoCustomData customData ); + void infoSlot( const QString target, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariant output, const QVariantMap customData ); void newNam() const; @@ -206,7 +205,6 @@ inline uint qHash( Tomahawk::InfoSystem::InfoCriteriaHash hash ) } Q_DECLARE_METATYPE( Tomahawk::InfoSystem::InfoGenericMap ); -Q_DECLARE_METATYPE( Tomahawk::InfoSystem::InfoCustomData ); Q_DECLARE_METATYPE( Tomahawk::InfoSystem::InfoCriteriaHash ); Q_DECLARE_METATYPE( QWeakPointer< Tomahawk::InfoSystem::InfoSystemCache > ); diff --git a/src/libtomahawk/infosystem/infosystemcache.cpp b/src/libtomahawk/infosystem/infosystemcache.cpp index 0623b32db..0966333af 100644 --- a/src/libtomahawk/infosystem/infosystemcache.cpp +++ b/src/libtomahawk/infosystem/infosystemcache.cpp @@ -84,7 +84,7 @@ InfoSystemCache::pruneTimerFired() void -InfoSystemCache::getCachedInfoSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const qint64 newMaxAge, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData ) +InfoSystemCache::getCachedInfoSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const qint64 newMaxAge, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) { qDebug() << Q_FUNC_INFO; const QString criteriaHashVal = criteriaMd5( criteria ); diff --git a/src/libtomahawk/infosystem/infosystemcache.h b/src/libtomahawk/infosystem/infosystemcache.h index 90fa31818..115724f60 100644 --- a/src/libtomahawk/infosystem/infosystemcache.h +++ b/src/libtomahawk/infosystem/infosystemcache.h @@ -43,11 +43,11 @@ public: virtual ~InfoSystemCache(); signals: - void notInCache( Tomahawk::InfoSystem::InfoCriteriaHash criteria, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, Tomahawk::InfoSystem::InfoCustomData customData ); - void info( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ); + void notInCache( Tomahawk::InfoSystem::InfoCriteriaHash criteria, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariantMap customData ); + void info( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, QVariantMap customData ); public slots: - void getCachedInfoSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const qint64 newMaxAge, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData ); + void getCachedInfoSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const qint64 newMaxAge, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ); void updateCacheSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const qint64 maxAge, const Tomahawk::InfoSystem::InfoType type, const QVariant output ); private slots: diff --git a/src/libtomahawk/infosystem/infosystemworker.cpp b/src/libtomahawk/infosystem/infosystemworker.cpp index 3dfd4414b..bc9636ec5 100644 --- a/src/libtomahawk/infosystem/infosystemworker.cpp +++ b/src/libtomahawk/infosystem/infosystemworker.cpp @@ -87,23 +87,23 @@ InfoSystemWorker::init( QWeakPointer< Tomahawk::InfoSystem::InfoSystemCache> cac { connect( plugin.data(), - SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ), + SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), InfoSystem::instance(), - SLOT( infoSlot( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ), + SLOT( infoSlot( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), Qt::UniqueConnection ); connect( plugin.data(), - SIGNAL( getCachedInfo( Tomahawk::InfoSystem::InfoCriteriaHash, qint64, QString, Tomahawk::InfoSystem::InfoType, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ), + SIGNAL( getCachedInfo( Tomahawk::InfoSystem::InfoCriteriaHash, qint64, QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariantMap ) ), cache.data(), - SLOT( getCachedInfoSlot( Tomahawk::InfoSystem::InfoCriteriaHash, qint64, QString, Tomahawk::InfoSystem::InfoType, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ) + SLOT( getCachedInfoSlot( Tomahawk::InfoSystem::InfoCriteriaHash, qint64, QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariantMap ) ) ); connect( cache.data(), - SIGNAL( notInCache( Tomahawk::InfoSystem::InfoCriteriaHash, QString, Tomahawk::InfoSystem::InfoType, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ), + SIGNAL( notInCache( Tomahawk::InfoSystem::InfoCriteriaHash, QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariantMap ) ), plugin.data(), - SLOT( notInCacheSlot( Tomahawk::InfoSystem::InfoCriteriaHash, QString, Tomahawk::InfoSystem::InfoType, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ) + SLOT( notInCacheSlot( Tomahawk::InfoSystem::InfoCriteriaHash, QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariantMap ) ) ); connect( plugin.data(), @@ -147,7 +147,7 @@ InfoSystemWorker::determineOrderedMatches( const InfoType type ) const void -InfoSystemWorker::getInfo( QString caller, InfoType type, QVariant input, InfoCustomData customData ) +InfoSystemWorker::getInfo( QString caller, InfoType type, QVariant input, QVariantMap customData ) { qDebug() << Q_FUNC_INFO; QLinkedList< InfoPluginPtr > providers = determineOrderedMatches(type); @@ -164,7 +164,7 @@ InfoSystemWorker::getInfo( QString caller, InfoType type, QVariant input, InfoCu return; } - QMetaObject::invokeMethod( ptr.data(), "getInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input ), Q_ARG( Tomahawk::InfoSystem::InfoCustomData, customData ) ); + QMetaObject::invokeMethod( ptr.data(), "getInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input ), Q_ARG( QVariantMap, customData ) ); } diff --git a/src/libtomahawk/infosystem/infosystemworker.h b/src/libtomahawk/infosystem/infosystemworker.h index c7f4ada6d..3d87839e0 100644 --- a/src/libtomahawk/infosystem/infosystemworker.h +++ b/src/libtomahawk/infosystem/infosystemworker.h @@ -48,12 +48,12 @@ public: QNetworkAccessManager* nam() const; signals: - void info( QString target, Tomahawk::InfoSystem::InfoType, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ); + void info( QString target, Tomahawk::InfoSystem::InfoType, QVariant input, QVariant output, QVariantMap customData ); void namChanged( QNetworkAccessManager* ); public slots: void init( QWeakPointer< Tomahawk::InfoSystem::InfoSystemCache > cache ); - void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData ); + void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ); void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input ); void newNam(); diff --git a/src/libtomahawk/playlist/albummodel.cpp b/src/libtomahawk/playlist/albummodel.cpp index bf82bd864..6eb3a3b38 100644 --- a/src/libtomahawk/playlist/albummodel.cpp +++ b/src/libtomahawk/playlist/albummodel.cpp @@ -44,8 +44,8 @@ AlbumModel::AlbumModel( QObject* parent ) .scaled( QSize( 120, 120 ), Qt::IgnoreAspectRatio, Qt::SmoothTransformation ); 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 ) ) ); + SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), + SLOT( infoSystemInfo( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ) ); connect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( finished( QString ) ), SLOT( infoSystemFinished( QString ) ) ); } @@ -311,7 +311,7 @@ AlbumModel::onAlbumsAdded( const QList& albums ) void -AlbumModel::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ) +AlbumModel::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, QVariantMap customData ) { Q_UNUSED( customData ); qDebug() << Q_FUNC_INFO << " with caller " << caller; @@ -323,14 +323,14 @@ AlbumModel::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, return; } - if ( !output.canConvert< Tomahawk::InfoSystem::InfoCustomData >() ) + if ( !output.canConvert< QVariantMap >() ) { qDebug() << "Cannot convert fetched art from a QByteArray"; return; } Tomahawk::InfoSystem::InfoCriteriaHash pptr = input.value< Tomahawk::InfoSystem::InfoCriteriaHash >(); - Tomahawk::InfoSystem::InfoCustomData returnedData = output.value< Tomahawk::InfoSystem::InfoCustomData >(); + QVariantMap returnedData = output.value< QVariantMap >(); const QByteArray ba = returnedData["imgbytes"].toByteArray(); if ( ba.length() ) { diff --git a/src/libtomahawk/playlist/albummodel.h b/src/libtomahawk/playlist/albummodel.h index ff58fee0e..95e3c8c1d 100644 --- a/src/libtomahawk/playlist/albummodel.h +++ b/src/libtomahawk/playlist/albummodel.h @@ -97,7 +97,7 @@ private slots: void onAlbumsAdded( const QList& albums ); void onDataChanged(); - void infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ); + void infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, QVariantMap customData ); void infoSystemFinished( QString target ); private: diff --git a/src/libtomahawk/playlist/albumview.cpp b/src/libtomahawk/playlist/albumview.cpp index 41b2abe0e..48879a42a 100644 --- a/src/libtomahawk/playlist/albumview.cpp +++ b/src/libtomahawk/playlist/albumview.cpp @@ -164,7 +164,7 @@ AlbumView::onScrollTimeout() Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( s_tmInfoIdentifier, Tomahawk::InfoSystem::InfoAlbumCoverArt, - QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ), Tomahawk::InfoSystem::InfoCustomData() ); + QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ), QVariantMap() ); } } } diff --git a/src/libtomahawk/playlist/artistview.cpp b/src/libtomahawk/playlist/artistview.cpp index 75d6a8d6f..9e30adec0 100644 --- a/src/libtomahawk/playlist/artistview.cpp +++ b/src/libtomahawk/playlist/artistview.cpp @@ -251,7 +251,7 @@ ArtistView::onScrollTimeout() Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( s_tmInfoIdentifier, Tomahawk::InfoSystem::InfoArtistImages, - QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ), Tomahawk::InfoSystem::InfoCustomData() ); + QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ), QVariantMap() ); } } diff --git a/src/libtomahawk/playlist/treemodel.cpp b/src/libtomahawk/playlist/treemodel.cpp index e542d4062..ce7f86918 100644 --- a/src/libtomahawk/playlist/treemodel.cpp +++ b/src/libtomahawk/playlist/treemodel.cpp @@ -47,8 +47,8 @@ TreeModel::TreeModel( QObject* parent ) connect( AudioEngine::instance(), SIGNAL( stopped() ), SLOT( onPlaybackStopped() ), Qt::DirectConnection ); 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 ) ) ); + SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), + SLOT( infoSystemInfo( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ) ); connect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( finished( QString ) ), SLOT( infoSystemFinished( QString ) ) ); } @@ -544,7 +544,7 @@ TreeModel::onAlbumsAdded( const QList& albums, const QVaria Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( s_tmInfoIdentifier, Tomahawk::InfoSystem::InfoAlbumCoverArt, - QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ), Tomahawk::InfoSystem::InfoCustomData() ); + QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ), QVariantMap() ); } if ( !parent.isValid() || crows.second > 0 ) @@ -600,7 +600,7 @@ TreeModel::onTracksAdded( const QList& tracks, const QVaria void -TreeModel::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ) +TreeModel::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, QVariantMap customData ) { Q_UNUSED( customData ); qDebug() << Q_FUNC_INFO; @@ -612,14 +612,14 @@ TreeModel::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, return; } - if ( !output.canConvert< Tomahawk::InfoSystem::InfoCustomData >() ) + if ( !output.canConvert< QVariantMap >() ) { qDebug() << "Cannot convert fetched art from a QByteArray"; return; } Tomahawk::InfoSystem::InfoCriteriaHash pptr = input.value< Tomahawk::InfoSystem::InfoCriteriaHash >(); - Tomahawk::InfoSystem::InfoCustomData returnedData = output.value< Tomahawk::InfoSystem::InfoCustomData >(); + QVariantMap returnedData = output.value< QVariantMap >(); const QByteArray ba = returnedData["imgbytes"].toByteArray(); qDebug() << "ba.length = " << ba.length(); if ( ba.length() ) diff --git a/src/libtomahawk/playlist/treemodel.h b/src/libtomahawk/playlist/treemodel.h index ddd2bf253..be8a10a09 100644 --- a/src/libtomahawk/playlist/treemodel.h +++ b/src/libtomahawk/playlist/treemodel.h @@ -125,7 +125,7 @@ private slots: 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 infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, QVariantMap customData ); void infoSystemFinished( QString target ); void onPlaybackFinished( const Tomahawk::result_ptr& result ); diff --git a/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.cpp b/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.cpp index 4f9ac834e..c9664115f 100644 --- a/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.cpp +++ b/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.cpp @@ -64,8 +64,8 @@ ArtistInfoWidget::ArtistInfoWidget( const Tomahawk::artist_ptr& artist, QWidget* m_pixmap = QPixmap( RESPATH "images/no-album-art-placeholder.png" ).scaledToWidth( 48, Qt::SmoothTransformation ); 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 ) ) ); + SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), + SLOT( infoSystemInfo( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ) ); connect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( finished( QString ) ), SLOT( infoSystemFinished( QString ) ) ); @@ -89,7 +89,7 @@ ArtistInfoWidget::load( const artist_ptr& artist ) artistInfo["artist"] = artist->name(); InfoSystem::InfoTypeMap infoMap; - InfoSystem::InfoCustomData hash; + QVariantMap hash; infoMap[InfoSystem::InfoArtistBiography] = artist->name(); Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( @@ -97,20 +97,20 @@ ArtistInfoWidget::load( const artist_ptr& artist ) Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( s_aiInfoIdentifier, Tomahawk::InfoSystem::InfoArtistImages, - QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( artistInfo ), Tomahawk::InfoSystem::InfoCustomData() ); + QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( artistInfo ), QVariantMap() ); Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( s_aiInfoIdentifier, Tomahawk::InfoSystem::InfoArtistSimilars, - QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( artistInfo ), Tomahawk::InfoSystem::InfoCustomData() ); + QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( artistInfo ), QVariantMap() ); Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( s_aiInfoIdentifier, Tomahawk::InfoSystem::InfoArtistSongs, - QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( artistInfo ), Tomahawk::InfoSystem::InfoCustomData() ); + QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( artistInfo ), QVariantMap() ); } void -ArtistInfoWidget::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ) +ArtistInfoWidget::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, QVariantMap customData ) { Q_UNUSED( input ); Q_UNUSED( customData ); @@ -125,7 +125,7 @@ ArtistInfoWidget::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType InfoSystem::InfoCriteriaHash trackInfo; trackInfo = input.value< InfoSystem::InfoCriteriaHash >(); - if ( output.canConvert< Tomahawk::InfoSystem::InfoCustomData >() ) + if ( output.canConvert< QVariantMap >() ) { if ( trackInfo["artist"] != m_artist->name() ) { @@ -134,7 +134,7 @@ ArtistInfoWidget::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType } } - InfoSystem::InfoCustomData returnedData = output.value< Tomahawk::InfoSystem::InfoCustomData >(); + QVariantMap returnedData = output.value< QVariantMap >(); switch ( type ) { case InfoSystem::InfoArtistBiography: diff --git a/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.h b/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.h index 824c69f8b..df3ed01e2 100644 --- a/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.h +++ b/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.h @@ -86,7 +86,7 @@ protected: void changeEvent( QEvent* e ); private slots: - void infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ); + void infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, QVariantMap customData ); void infoSystemFinished( QString target ); private: diff --git a/src/scrobbler.cpp b/src/scrobbler.cpp index 82bf2855b..f3e6f268d 100644 --- a/src/scrobbler.cpp +++ b/src/scrobbler.cpp @@ -38,8 +38,8 @@ Scrobbler::Scrobbler( QObject* parent ) SLOT( engineTick( unsigned int ) ), Qt::QueuedConnection ); 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 ) ) ); + SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), + SLOT( infoSystemInfo( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ) ); connect( AudioEngine::instance(), SIGNAL( started( const Tomahawk::result_ptr& ) ), SLOT( trackStarted( const Tomahawk::result_ptr& ) ), Qt::QueuedConnection ); @@ -135,7 +135,7 @@ Scrobbler::scrobble() void -Scrobbler::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ) +Scrobbler::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, QVariantMap customData ) { Q_UNUSED( type ); Q_UNUSED( input ); diff --git a/src/scrobbler.h b/src/scrobbler.h index f2c484aa9..380b94267 100644 --- a/src/scrobbler.h +++ b/src/scrobbler.h @@ -45,7 +45,7 @@ public slots: void trackStopped(); void engineTick( unsigned int secondsElapsed ); - void infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData ); + void infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, QVariantMap customData ); void infoSystemFinished( QString target ); private: diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index 20a13f3f6..157229548 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -418,7 +418,6 @@ TomahawkApp::registerMetaTypes() qRegisterMetaType< AudioErrorCode >("AudioErrorCode"); qRegisterMetaType< QMap< QString, QMap< QString, QString > > >( "Tomahawk::InfoSystem::InfoGenericMap" ); - qRegisterMetaType< QHash< QString, QVariant > >( "Tomahawk::InfoSystem::InfoCustomData" ); qRegisterMetaType< QHash< QString, QString > >( "Tomahawk::InfoSystem::InfoCriteriaHash" ); qRegisterMetaType< Tomahawk::InfoSystem::InfoType >( "Tomahawk::InfoSystem::InfoType" ); qRegisterMetaType< QWeakPointer< Tomahawk::InfoSystem::InfoSystemCache > >( "QWeakPointer< Tomahawk::InfoSystem::InfoSystemCache >" ); diff --git a/src/xmppbot/xmppbot.cpp b/src/xmppbot/xmppbot.cpp index 01ebe5509..258384619 100644 --- a/src/xmppbot/xmppbot.cpp +++ b/src/xmppbot/xmppbot.cpp @@ -66,8 +66,8 @@ XMPPBot::XMPPBot(QObject *parent) SLOT(newTrackSlot(const Tomahawk::result_ptr &))); 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))); + SIGNAL(info(QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap)), + SLOT(infoReturnedSlot(QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap))); connect(InfoSystem::instance(), SIGNAL(finished(QString)), SLOT(infoFinishedSlot(QString))); @@ -214,10 +214,10 @@ void XMPPBot::handleMessage(const Message& msg, MessageSession* session) infoMap[InfoArtistFamiliarity] = m_currTrack.data()->artist()->name(); if (token == "lyrics") { - InfoCustomData myhash; + QVariantMap myhash; myhash["trackName"] = QVariant::fromValue(m_currTrack.data()->track()); myhash["artistName"] = QVariant::fromValue(m_currTrack.data()->artist()->name()); - infoMap[InfoTrackLyrics] = QVariant::fromValue(myhash); + infoMap[InfoTrackLyrics] = QVariant::fromValue(myhash); } } @@ -234,12 +234,12 @@ void XMPPBot::handleMessage(const Message& msg, MessageSession* session) QString waitMsg("Please wait..."); Message retMsg(Message::Chat, JID(originatingJid.toStdString()), waitMsg.toStdString()); m_client.data()->send(retMsg); - Tomahawk::InfoSystem::InfoCustomData hash; + QVariantMap hash; hash["XMPPBotSendToJID"] = originatingJid; InfoSystem::instance()->getInfo(s_botInfoIdentifier, infoMap, hash); } -void XMPPBot::infoReturnedSlot(QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData) +void XMPPBot::infoReturnedSlot(QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, QVariantMap customData) { qDebug() << Q_FUNC_INFO; @@ -363,13 +363,13 @@ void XMPPBot::infoReturnedSlot(QString caller, Tomahawk::InfoSystem::InfoType ty { qDebug() << "Lyrics requested"; if (!output.canConvert() || - !input.canConvert() + !input.canConvert() ) { qDebug() << "Variants failed to be valid"; break; } - InfoCustomData inHash = input.value(); + QVariantMap inHash = input.value(); QString artist = inHash["artistName"].toString(); QString track = inHash["trackName"].toString(); QString lyrics = output.toString(); diff --git a/src/xmppbot/xmppbot.h b/src/xmppbot/xmppbot.h index 20b504118..9b39ae29f 100644 --- a/src/xmppbot/xmppbot.h +++ b/src/xmppbot/xmppbot.h @@ -66,7 +66,7 @@ public: 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 infoReturnedSlot(QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, QVariantMap customData); virtual void infoFinishedSlot(QString caller); protected: From 5d0c734187c9df95a516759db7dbf40f1a704bd0 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Wed, 6 Jul 2011 12:16:44 -0400 Subject: [PATCH 75/86] Add requestId tracking to InfoSystem in preparation for timeouts --- .../infoplugins/generic/echonestplugin.cpp | 105 ++++++++++-------- .../infoplugins/generic/echonestplugin.h | 21 ++-- .../infoplugins/generic/lastfmplugin.cpp | 81 ++++++++------ .../infoplugins/generic/lastfmplugin.h | 14 +-- .../infoplugins/generic/musixmatchplugin.cpp | 86 +++++++------- .../infoplugins/generic/musixmatchplugin.h | 7 +- .../infosystem/infoplugins/mac/adiumplugin.h | 21 +++- .../infoplugins/unix/fdonotifyplugin.h | 6 +- src/libtomahawk/infosystem/infosystem.cpp | 37 +++--- src/libtomahawk/infosystem/infosystem.h | 14 ++- .../infosystem/infosystemcache.cpp | 16 +-- src/libtomahawk/infosystem/infosystemcache.h | 6 +- .../infosystem/infosystemworker.cpp | 20 ++-- src/libtomahawk/infosystem/infosystemworker.h | 4 +- 14 files changed, 245 insertions(+), 193 deletions(-) diff --git a/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.cpp b/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.cpp index d39226d12..99ca934d2 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.cpp @@ -66,37 +66,37 @@ EchoNestPlugin::namChangedSlot( QNetworkAccessManager *nam ) } void -EchoNestPlugin::getInfo(const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData) +EchoNestPlugin::getInfo( uint requestId, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) { - switch (type) + switch ( type ) { case Tomahawk::InfoSystem::InfoArtistBiography: - return getArtistBiography(caller, input, customData); + return getArtistBiography( requestId, caller, input, customData ); case Tomahawk::InfoSystem::InfoArtistFamiliarity: - return getArtistFamiliarity(caller, input, customData); + return getArtistFamiliarity( requestId, caller, input, customData ); case Tomahawk::InfoSystem::InfoArtistHotttness: - return getArtistHotttnesss(caller, input, customData); + return getArtistHotttnesss( requestId, caller, input, customData ); case Tomahawk::InfoSystem::InfoArtistTerms: - return getArtistTerms(caller, input, customData); + return getArtistTerms( requestId, caller, input, customData ); case Tomahawk::InfoSystem::InfoTrackEnergy: - return getSongProfile(caller, input, customData, "energy"); + return getSongProfile( requestId, caller, input, customData, "energy" ); case Tomahawk::InfoSystem::InfoMiscTopTerms: - return getMiscTopTerms(caller, input, customData); + return getMiscTopTerms( requestId, caller, input, customData ); default: { - emit info(caller, Tomahawk::InfoSystem::InfoNoInfo, QVariant(), QVariant(), customData); + emit info( requestId, caller, Tomahawk::InfoSystem::InfoNoInfo, QVariant(), QVariant(), customData ); return; } } } void -EchoNestPlugin::getSongProfile(const QString &caller, const QVariant &input, const QVariantMap &customData, const QString &item) +EchoNestPlugin::getSongProfile( uint requestId, const QString &caller, const QVariant &input, const QVariantMap &customData, const QString &item ) { //WARNING: Totally not implemented yet Q_UNUSED( item ); - if( !isValidTrackData( caller, input, customData ) ) + if( !isValidTrackData( requestId, caller, input, customData ) ) return; // Track track( input.toString() ); @@ -108,9 +108,9 @@ EchoNestPlugin::getSongProfile(const QString &caller, const QVariant &input, con } void -EchoNestPlugin::getArtistBiography(const QString &caller, const QVariant &input, const QVariantMap &customData) +EchoNestPlugin::getArtistBiography( uint requestId, const QString &caller, const QVariant &input, const QVariantMap &customData ) { - if( !isValidArtistData( caller, input, customData ) ) + if( !isValidArtistData( requestId, caller, input, customData ) ) return; Echonest::Artist artist( input.toString() ); @@ -119,62 +119,67 @@ EchoNestPlugin::getArtistBiography(const QString &caller, const QVariant &input, reply->setProperty( "input", input ); reply->setProperty( "customData", customData ); reply->setProperty( "caller", caller ); - connect(reply, SIGNAL(finished()), SLOT(getArtistBiographySlot())); + reply->setProperty( "requestId", requestId ); + connect( reply, SIGNAL( finished() ), SLOT( getArtistBiographySlot() ) ); } void -EchoNestPlugin::getArtistFamiliarity(const QString &caller, const QVariant &input, const QVariantMap &customData) +EchoNestPlugin::getArtistFamiliarity( uint requestId, const QString &caller, const QVariant &input, const QVariantMap &customData ) { - if( !isValidArtistData( caller, input, customData ) ) + if( !isValidArtistData( requestId, caller, input, customData ) ) return; qDebug() << "Fetching artist familiarity!" << input; Echonest::Artist artist( input.toString() ); QNetworkReply* reply = artist.fetchFamiliarity(); - reply->setProperty( "artist", QVariant::fromValue(artist)); + reply->setProperty( "artist", QVariant::fromValue< Echonest::Artist >( artist ) ); reply->setProperty( "input", input ); reply->setProperty( "customData", customData ); reply->setProperty( "caller", caller ); - connect(reply, SIGNAL(finished()), SLOT(getArtistFamiliaritySlot())); + reply->setProperty( "requestId", requestId ); + connect( reply, SIGNAL( finished() ), SLOT( getArtistFamiliaritySlot() ) ); } void -EchoNestPlugin::getArtistHotttnesss(const QString &caller, const QVariant &input, const QVariantMap &customData) +EchoNestPlugin::getArtistHotttnesss( uint requestId, const QString &caller, const QVariant &input, const QVariantMap &customData ) { - if( !isValidArtistData( caller, input, customData ) ) + if( !isValidArtistData( requestId, caller, input, customData ) ) return; Echonest::Artist artist( input.toString() ); QNetworkReply* reply = artist.fetchHotttnesss(); - reply->setProperty( "artist", QVariant::fromValue(artist)); + reply->setProperty( "artist", QVariant::fromValue< Echonest::Artist >( artist ) ); reply->setProperty( "input", input ); reply->setProperty( "customData", customData ); reply->setProperty( "caller", caller ); - connect(reply, SIGNAL(finished()), SLOT(getArtistHotttnesssSlot())); + reply->setProperty( "requestId", requestId ); + connect( reply, SIGNAL( finished() ), SLOT( getArtistHotttnesssSlot() ) ); } void -EchoNestPlugin::getArtistTerms(const QString &caller, const QVariant &input, const QVariantMap &customData) +EchoNestPlugin::getArtistTerms( uint requestId, const QString &caller, const QVariant &input, const QVariantMap &customData ) { - if( !isValidArtistData( caller, input, customData ) ) + if( !isValidArtistData( requestId, caller, input, customData ) ) return; Echonest::Artist artist( input.toString() ); QNetworkReply* reply = artist.fetchTerms( Echonest::Artist::Weight ); - reply->setProperty( "artist", QVariant::fromValue(artist)); + reply->setProperty( "artist", QVariant::fromValue< Echonest::Artist >( artist ) ); reply->setProperty( "input", input ); reply->setProperty( "customData", customData ); reply->setProperty( "caller", caller ); - connect(reply, SIGNAL( finished() ), SLOT( getArtistTermsSlot() ) ); + reply->setProperty( "requestId", requestId ); + connect( reply, SIGNAL( finished() ), SLOT( getArtistTermsSlot() ) ); } void -EchoNestPlugin::getMiscTopTerms(const QString &caller, const QVariant &input, const QVariantMap& customData) +EchoNestPlugin::getMiscTopTerms( uint requestId, const QString &caller, const QVariant &input, const QVariantMap& customData ) { Q_UNUSED( input ); QNetworkReply* reply = Echonest::Artist::topTerms( 20 ); reply->setProperty( "customData", customData ); reply->setProperty( "caller", caller ); + reply->setProperty( "requestId", requestId ); connect( reply, SIGNAL( finished() ), SLOT( getMiscTopSlot() ) ); } @@ -196,7 +201,8 @@ EchoNestPlugin::getArtistBiographySlot() biographyMap[biography.site()]["attribution"] = biography.license().url.toString(); } - emit info( reply->property( "caller" ).toString(), + emit info( reply->property( "requestId" ).toUInt(), + reply->property( "caller" ).toString(), Tomahawk::InfoSystem::InfoArtistBiography, reply->property( "input" ), QVariant::fromValue< Tomahawk::InfoSystem::InfoGenericMap >( biographyMap ), @@ -210,7 +216,8 @@ EchoNestPlugin::getArtistFamiliaritySlot() QNetworkReply* reply = qobject_cast( sender() ); Echonest::Artist artist = artistFromReply( reply ); qreal familiarity = artist.familiarity(); - emit info( reply->property( "caller" ).toString(), + emit info( reply->property( "requestId" ).toUInt(), + reply->property( "caller" ).toString(), Tomahawk::InfoSystem::InfoArtistFamiliarity, reply->property( "input" ), familiarity, @@ -224,7 +231,8 @@ EchoNestPlugin::getArtistHotttnesssSlot() QNetworkReply* reply = qobject_cast( sender() ); Echonest::Artist artist = artistFromReply( reply ); qreal hotttnesss = artist.hotttnesss(); - emit info( reply->property( "caller" ).toString(), + emit info( reply->property( "requestId" ).toUInt(), + reply->property( "caller" ).toString(), Tomahawk::InfoSystem::InfoArtistHotttness, reply->property( "input" ), hotttnesss, @@ -245,7 +253,8 @@ EchoNestPlugin::getArtistTermsSlot() termMap[ "frequency" ] = QString::number(term.frequency()); termsMap[ term.name() ] = termMap; } - emit info( reply->property( "caller" ).toString(), + emit info( reply->property( "requestId" ).toUInt(), + reply->property( "caller" ).toString(), Tomahawk::InfoSystem::InfoArtistTerms, reply->property( "input" ), QVariant::fromValue< Tomahawk::InfoSystem::InfoGenericMap >( termsMap ), @@ -265,7 +274,8 @@ EchoNestPlugin::getMiscTopSlot() termMap[ "frequency" ] = QString::number( term.frequency() ); termsMap[ term.name().toLower() ] = termMap; } - emit info( reply->property( "caller" ).toString(), + emit info( reply->property( "requestId" ).toUInt(), + reply->property( "caller" ).toString(), Tomahawk::InfoSystem::InfoMiscTopTerms, QVariant(), QVariant::fromValue< Tomahawk::InfoSystem::InfoGenericMap >( termsMap ), @@ -274,50 +284,53 @@ EchoNestPlugin::getMiscTopSlot() } bool -EchoNestPlugin::isValidArtistData(const QString &caller, const QVariant &input, const QVariantMap &customData) +EchoNestPlugin::isValidArtistData( uint requestId, const QString &caller, const QVariant &input, const QVariantMap &customData ) { - if (input.isNull() || !input.isValid() || !input.canConvert()) + if ( input.isNull() || !input.isValid() || !input.canConvert< QString >() ) { - emit info(caller, Tomahawk::InfoSystem::InfoNoInfo, QVariant(), QVariant(), customData); + emit info( requestId, caller, Tomahawk::InfoSystem::InfoNoInfo, QVariant(), QVariant(), customData ); return false; } QString artistName = input.toString(); - if (artistName.isEmpty() ) + if ( artistName.isEmpty() ) { - emit info(caller, Tomahawk::InfoSystem::InfoNoInfo, QVariant(), QVariant(), customData); + emit info( requestId, caller, Tomahawk::InfoSystem::InfoNoInfo, QVariant(), QVariant(), customData ); return false; } return true; } bool -EchoNestPlugin::isValidTrackData(const QString &caller, const QVariant &input, const QVariantMap &customData) +EchoNestPlugin::isValidTrackData( uint requestId, const QString &caller, const QVariant &input, const QVariantMap &customData ) { - if (input.isNull() || !input.isValid() || !input.canConvert()) + if ( input.isNull() || !input.isValid() || !input.canConvert< QString >() ) { - emit info(caller, Tomahawk::InfoSystem::InfoNoInfo, QVariant(), QVariant(), customData); + emit info( requestId, caller, Tomahawk::InfoSystem::InfoNoInfo, QVariant(), QVariant(), customData ); return false; } QString trackName = input.toString(); - if (trackName.isEmpty() ) + if ( trackName.isEmpty() ) { - emit info(caller, Tomahawk::InfoSystem::InfoNoInfo, QVariant(), QVariant(), customData); + emit info( requestId, caller, Tomahawk::InfoSystem::InfoNoInfo, QVariant(), QVariant(), customData ); return false; } - if (!customData.contains("artistName") || - customData["artistName"].toString().isEmpty()) + if ( !customData.contains( "artistName" ) || customData[ "artistName" ].toString().isEmpty() ) + { + emit info( requestId, caller, Tomahawk::InfoSystem::InfoNoInfo, QVariant(), QVariant(), customData ); return false; + } return true; } Artist -EchoNestPlugin::artistFromReply(QNetworkReply* reply) +EchoNestPlugin::artistFromReply( QNetworkReply* reply ) { Echonest::Artist artist = reply->property("artist").value(); try { - artist.parseProfile(reply); + artist.parseProfile( reply ); } catch( const Echonest::ParseError& e ) { qWarning() << "Caught parser error from echonest!" << e.what(); } return artist; } +// \ No newline at end of file diff --git a/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.h b/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.h index 85bad01b5..f06500532 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.h +++ b/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.h @@ -44,7 +44,7 @@ public: virtual ~EchoNestPlugin(); protected slots: - virtual void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ); + virtual void getInfo( uint requestId, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ); virtual void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant data ) { @@ -53,8 +53,9 @@ protected slots: Q_UNUSED( data ); } - virtual void notInCacheSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) + virtual void notInCacheSlot( uint requestId, const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) { + Q_UNUSED( requestId ); Q_UNUSED( criteria ); Q_UNUSED( caller ); Q_UNUSED( type ); @@ -66,15 +67,15 @@ public slots: void namChangedSlot( QNetworkAccessManager *nam ); private: - void getSongProfile( const QString &caller, const QVariant &input, const QVariantMap &customData, const QString &item = QString() ); - void getArtistBiography ( const QString &caller, const QVariant &input, const QVariantMap &customData ); - void getArtistFamiliarity( const QString &caller, const QVariant &input, const QVariantMap &customData ); - void getArtistHotttnesss( const QString &caller, const QVariant &input, const QVariantMap &customData ); - void getArtistTerms( const QString &caller, const QVariant &input, const QVariantMap &customData ); - void getMiscTopTerms( const QString &caller, const QVariant &input, const QVariantMap &customData ); + void getSongProfile( uint requestId, const QString &caller, const QVariant &input, const QVariantMap &customData, const QString &item = QString() ); + void getArtistBiography ( uint requestId, const QString &caller, const QVariant &input, const QVariantMap &customData ); + void getArtistFamiliarity( uint requestId, const QString &caller, const QVariant &input, const QVariantMap &customData ); + void getArtistHotttnesss( uint requestId, const QString &caller, const QVariant &input, const QVariantMap &customData ); + void getArtistTerms( uint requestId, const QString &caller, const QVariant &input, const QVariantMap &customData ); + void getMiscTopTerms( uint requestId, const QString &caller, const QVariant &input, const QVariantMap &customData ); - bool isValidArtistData( const QString &caller, const QVariant &input, const QVariantMap& customData ); - bool isValidTrackData( const QString &caller, const QVariant &input, const QVariantMap& customData ); + bool isValidArtistData( uint requestId, const QString &caller, const QVariant &input, const QVariantMap& customData ); + bool isValidTrackData( uint requestId, const QString &caller, const QVariant &input, const QVariantMap& customData ); Echonest::Artist artistFromReply( QNetworkReply* ); private slots: diff --git a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp index a3ce55d94..6ed7914dd 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp @@ -120,38 +120,38 @@ LastFmPlugin::namChangedSlot( QNetworkAccessManager *nam ) void -LastFmPlugin::dataError( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const QVariantMap &customData ) +LastFmPlugin::dataError( uint requestId, const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const QVariantMap &customData ) { - emit info( caller, type, input, QVariant(), customData ); + emit info( requestId, caller, type, input, QVariant(), customData ); return; } void -LastFmPlugin::getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) +LastFmPlugin::getInfo( uint requestId, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) { qDebug() << Q_FUNC_INFO; switch ( type ) { case InfoArtistImages: - fetchArtistImages( caller, type, input, customData ); + fetchArtistImages( requestId, caller, type, input, customData ); break; case InfoAlbumCoverArt: - fetchCoverArt( caller, type, input, customData ); + fetchCoverArt( requestId, caller, type, input, customData ); break; case InfoArtistSimilars: - fetchSimilarArtists( caller, type, input, customData ); + fetchSimilarArtists( requestId, caller, type, input, customData ); break; case InfoArtistSongs: - fetchTopTracks( caller, type, input, customData ); + fetchTopTracks( requestId, caller, type, input, customData ); break; default: - dataError( caller, type, input, customData ); + dataError( requestId, caller, type, input, customData ); } } @@ -263,64 +263,64 @@ LastFmPlugin::sendLoveSong( const InfoType type, QVariant input ) void -LastFmPlugin::fetchSimilarArtists( const QString &caller, const InfoType type, const QVariant &input, const QVariantMap &customData ) +LastFmPlugin::fetchSimilarArtists( uint requestId, const QString &caller, const InfoType type, const QVariant &input, const QVariantMap &customData ) { qDebug() << Q_FUNC_INFO; if ( !input.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() ) { - dataError( caller, type, input, customData ); + dataError( requestId, caller, type, input, customData ); return; } InfoCriteriaHash hash = input.value< Tomahawk::InfoSystem::InfoCriteriaHash >(); if ( !hash.contains( "artist" ) ) { - dataError( caller, type, input, customData ); + dataError( requestId, caller, type, input, customData ); return; } Tomahawk::InfoSystem::InfoCriteriaHash criteria; criteria["artist"] = hash["artist"]; - emit getCachedInfo( criteria, 2419200000, caller, type, input, customData ); + emit getCachedInfo( requestId, criteria, 2419200000, caller, type, input, customData ); } void -LastFmPlugin::fetchTopTracks( const QString &caller, const InfoType type, const QVariant &input, const QVariantMap &customData ) +LastFmPlugin::fetchTopTracks( uint requestId, const QString &caller, const InfoType type, const QVariant &input, const QVariantMap &customData ) { qDebug() << Q_FUNC_INFO; if ( !input.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() ) { - dataError( caller, type, input, customData ); + dataError( requestId, caller, type, input, customData ); return; } InfoCriteriaHash hash = input.value< Tomahawk::InfoSystem::InfoCriteriaHash >(); if ( !hash.contains( "artist" ) ) { - dataError( caller, type, input, customData ); + dataError( requestId, caller, type, input, customData ); return; } Tomahawk::InfoSystem::InfoCriteriaHash criteria; criteria["artist"] = hash["artist"]; - emit getCachedInfo( criteria, 2419200000, caller, type, input, customData ); + emit getCachedInfo( requestId, criteria, 2419200000, caller, type, input, customData ); } void -LastFmPlugin::fetchCoverArt( const QString &caller, const InfoType type, const QVariant &input, const QVariantMap &customData ) +LastFmPlugin::fetchCoverArt( uint requestId, const QString &caller, const InfoType type, const QVariant &input, const QVariantMap &customData ) { qDebug() << Q_FUNC_INFO; if ( !input.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() ) { - dataError( caller, type, input, customData ); + dataError( requestId, caller, type, input, customData ); return; } InfoCriteriaHash hash = input.value< Tomahawk::InfoSystem::InfoCriteriaHash >(); if ( !hash.contains( "artist" ) || !hash.contains( "album" ) ) { - dataError( caller, type, input, customData ); + dataError( requestId, caller, type, input, customData ); return; } @@ -328,42 +328,42 @@ LastFmPlugin::fetchCoverArt( const QString &caller, const InfoType type, const Q criteria["artist"] = hash["artist"]; criteria["album"] = hash["album"]; - emit getCachedInfo( criteria, 2419200000, caller, type, input, customData ); + emit getCachedInfo( requestId, criteria, 2419200000, caller, type, input, customData ); } void -LastFmPlugin::fetchArtistImages( const QString &caller, const InfoType type, const QVariant &input, const QVariantMap &customData ) +LastFmPlugin::fetchArtistImages( uint requestId, const QString &caller, const InfoType type, const QVariant &input, const QVariantMap &customData ) { qDebug() << Q_FUNC_INFO; if ( !input.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() ) { - dataError( caller, type, input, customData ); + dataError( requestId, caller, type, input, customData ); return; } InfoCriteriaHash hash = input.value< Tomahawk::InfoSystem::InfoCriteriaHash >(); if ( !hash.contains( "artist" ) ) { - dataError( caller, type, input, customData ); + dataError( requestId, caller, type, input, customData ); return; } Tomahawk::InfoSystem::InfoCriteriaHash criteria; criteria["artist"] = hash["artist"]; - emit getCachedInfo( criteria, 2419200000, caller, type, input, customData ); + emit getCachedInfo( requestId, criteria, 2419200000, caller, type, input, customData ); } void -LastFmPlugin::notInCacheSlot( const QHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) +LastFmPlugin::notInCacheSlot( uint requestId, const QHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) { qDebug() << Q_FUNC_INFO; if ( !lastfm::nam() ) { qDebug() << "Have a null QNAM, uh oh"; - emit info( caller, type, input, QVariant(), customData ); + emit info( requestId, caller, type, input, QVariant(), customData ); return; } @@ -376,7 +376,8 @@ LastFmPlugin::notInCacheSlot( const QHash criteria, const QStr reply->setProperty( "customData", QVariant::fromValue( customData ) ); reply->setProperty( "origData", input ); reply->setProperty( "caller", caller ); - reply->setProperty( "type", (uint)(type) ); + reply->setProperty( "type", (uint)( type ) ); + reply->setProperty( "requestId", requestId ); connect( reply, SIGNAL( finished() ), SLOT( similarArtistsReturned() ) ); return; @@ -389,7 +390,8 @@ LastFmPlugin::notInCacheSlot( const QHash criteria, const QStr reply->setProperty( "customData", QVariant::fromValue( customData ) ); reply->setProperty( "origData", input ); reply->setProperty( "caller", caller ); - reply->setProperty( "type", (uint)(type) ); + reply->setProperty( "type", (uint)( type ) ); + reply->setProperty( "requestId", requestId ); connect( reply, SIGNAL( finished() ), SLOT( topTracksReturned() ) ); return; @@ -406,7 +408,8 @@ LastFmPlugin::notInCacheSlot( const QHash criteria, const QStr reply->setProperty( "customData", QVariant::fromValue( customData ) ); reply->setProperty( "origData", input ); reply->setProperty( "caller", caller ); - reply->setProperty( "type", (uint)(type) ); + reply->setProperty( "type", (uint)( type ) ); + reply->setProperty( "requestId", requestId ); connect( reply, SIGNAL( finished() ), SLOT( coverArtReturned() ) ); return; @@ -422,7 +425,8 @@ LastFmPlugin::notInCacheSlot( const QHash criteria, const QStr reply->setProperty( "customData", QVariant::fromValue( customData ) ); reply->setProperty( "origData", input ); reply->setProperty( "caller", caller ); - reply->setProperty( "type", (uint)(type) ); + reply->setProperty( "type", (uint)( type ) ); + reply->setProperty( "requestId", requestId ); connect( reply, SIGNAL( finished() ), SLOT( artistImagesReturned() ) ); return; @@ -431,7 +435,7 @@ LastFmPlugin::notInCacheSlot( const QHash criteria, const QStr default: { qDebug() << "Couldn't figure out what to do with this type of request after cache miss"; - emit info( caller, type, input, QVariant(), customData ); + emit info( requestId, caller, type, input, QVariant(), customData ); return; } } @@ -461,6 +465,7 @@ LastFmPlugin::similarArtistsReturned() QVariantMap customData = reply->property( "customData" ).value< QVariantMap >(); InfoType type = (Tomahawk::InfoSystem::InfoType)(reply->property( "type" ).toUInt()); emit info( + reply->property( "requestId" ).toUInt(), reply->property( "caller" ).toString(), type, reply->property( "origData" ), @@ -493,6 +498,7 @@ LastFmPlugin::topTracksReturned() QVariantMap customData = reply->property( "customData" ).value< QVariantMap >(); InfoType type = (Tomahawk::InfoSystem::InfoType)(reply->property( "type" ).toUInt()); emit info( + reply->property( "requestId" ).toUInt(), reply->property( "caller" ).toString(), type, reply->property( "origData" ), @@ -521,7 +527,7 @@ LastFmPlugin::coverArtReturned() qDebug() << "Uh oh, null byte array"; InfoType type = (Tomahawk::InfoSystem::InfoType)(reply->property( "type" ).toUInt()); QVariantMap customData = reply->property( "customData" ).value< QVariantMap >(); - emit info( reply->property( "caller" ).toString(), type, reply->property( "origData" ), QVariant(), customData ); + emit info( reply->property( "requestId" ).toUInt(), reply->property( "caller" ).toString(), type, reply->property( "origData" ), QVariant(), customData ); return; } foreach ( const QUrl& url, m_badUrls ) @@ -537,6 +543,7 @@ LastFmPlugin::coverArtReturned() QVariantMap customData = reply->property( "customData" ).value< QVariantMap >(); InfoType type = (Tomahawk::InfoSystem::InfoType)(reply->property( "type" ).toUInt()); emit info( + reply->property( "requestId" ).toUInt(), reply->property( "caller" ).toString(), type, reply->property( "origData" ), @@ -557,7 +564,7 @@ LastFmPlugin::coverArtReturned() qDebug() << "Uh oh, nam is null"; InfoType type = (Tomahawk::InfoSystem::InfoType)(reply->property( "type" ).toUInt()); QVariantMap customData = reply->property( "customData" ).value< QVariantMap >(); - emit info( reply->property( "caller" ).toString(), type, reply->property( "origData" ), QVariant(), customData ); + emit info( reply->property( "requestId" ).toUInt(), reply->property( "caller" ).toString(), type, reply->property( "origData" ), QVariant(), customData ); return; } // Follow HTTP redirect @@ -567,6 +574,7 @@ LastFmPlugin::coverArtReturned() newReply->setProperty( "customData", reply->property( "customData" ) ); newReply->setProperty( "caller", reply->property( "caller" ) ); newReply->setProperty( "type", reply->property( "type" ) ); + newReply->setProperty( "requestId", reply->property( "requestId" ) ); connect( newReply, SIGNAL( finished() ), SLOT( coverArtReturned() ) ); } @@ -588,7 +596,7 @@ LastFmPlugin::artistImagesReturned() qDebug() << "Uh oh, null byte array"; InfoType type = (Tomahawk::InfoSystem::InfoType)(reply->property( "type" ).toUInt()); QVariantMap customData = reply->property( "customData" ).value< QVariantMap >(); - emit info( reply->property( "caller" ).toString(), type, reply->property( "origData" ), QVariant(), customData ); + emit info( reply->property( "requestId" ).toUInt(), reply->property( "caller" ).toString(), type, reply->property( "origData" ), QVariant(), customData ); return; } foreach ( const QUrl& url, m_badUrls ) @@ -602,7 +610,7 @@ LastFmPlugin::artistImagesReturned() InfoType type = (Tomahawk::InfoSystem::InfoType)(reply->property( "type" ).toUInt()); QVariantMap customData = reply->property( "customData" ).value< QVariantMap >(); - emit info( reply->property( "caller" ).toString(), type, reply->property( "origData" ), returnedData, customData ); + emit info( reply->property( "requestId" ).toUInt(), reply->property( "caller" ).toString(), type, reply->property( "origData" ), returnedData, customData ); InfoCriteriaHash origData = reply->property( "origData" ).value< Tomahawk::InfoSystem::InfoCriteriaHash >(); Tomahawk::InfoSystem::InfoCriteriaHash criteria; @@ -616,7 +624,7 @@ LastFmPlugin::artistImagesReturned() qDebug() << "Uh oh, nam is null"; InfoType type = (Tomahawk::InfoSystem::InfoType)(reply->property( "type" ).toUInt()); QVariantMap customData = reply->property( "customData" ).value< QVariantMap >(); - emit info( reply->property( "caller" ).toString(), type, reply->property( "origData" ), QVariant(), customData ); + emit info( reply->property( "requestId" ).toUInt(), reply->property( "caller" ).toString(), type, reply->property( "origData" ), QVariant(), customData ); return; } // Follow HTTP redirect @@ -626,6 +634,7 @@ LastFmPlugin::artistImagesReturned() newReply->setProperty( "customData", reply->property( "customData" ) ); newReply->setProperty( "caller", reply->property( "caller" ) ); newReply->setProperty( "type", reply->property( "type" ) ); + newReply->setProperty( "requestId", reply->property( "requestId" ) ); connect( newReply, SIGNAL( finished() ), SLOT( artistImagesReturned() ) ); } diff --git a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.h b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.h index 253c93fcd..8780034cb 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.h +++ b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.h @@ -55,23 +55,23 @@ public slots: void namChangedSlot( QNetworkAccessManager *nam ); protected slots: - virtual void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ); - virtual void notInCacheSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ); + virtual void getInfo( uint requestId, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ); + virtual void notInCacheSlot( uint requestId, const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ); virtual void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant data ); private: - void fetchCoverArt( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const QVariantMap &customData ); - void fetchArtistImages( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const QVariantMap &customData ); - void fetchSimilarArtists( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const QVariantMap &customData ); - void fetchTopTracks( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const QVariantMap &customData ); + void fetchCoverArt( uint requestId, const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const QVariantMap &customData ); + void fetchArtistImages( uint requestId, const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const QVariantMap &customData ); + void fetchSimilarArtists( uint requestId, const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const QVariantMap &customData ); + void fetchTopTracks( uint requestId, const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const QVariantMap &customData ); void createScrobbler(); void nowPlaying( const QVariant &input ); void scrobble(); void sendLoveSong( const InfoType type, QVariant input ); - void dataError( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const QVariantMap &customData ); + void dataError( uint requestId, const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const QVariantMap &customData ); lastfm::MutableTrack m_track; lastfm::Audioscrobbler* m_scrobbler; diff --git a/src/libtomahawk/infosystem/infoplugins/generic/musixmatchplugin.cpp b/src/libtomahawk/infosystem/infoplugins/generic/musixmatchplugin.cpp index 0714cb977..372f2995d 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/musixmatchplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/generic/musixmatchplugin.cpp @@ -51,53 +51,54 @@ MusixMatchPlugin::namChangedSlot( QNetworkAccessManager *nam ) } void -MusixMatchPlugin::getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) +MusixMatchPlugin::getInfo( uint requestId, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) { qDebug() << Q_FUNC_INFO; - if( !isValidTrackData(caller, input, customData) || !input.canConvert() || m_nam.isNull() || type != Tomahawk::InfoSystem::InfoTrackLyrics ) + if( !isValidTrackData( requestId, caller, input, customData ) || !input.canConvert< QVariantMap >() || m_nam.isNull() || type != Tomahawk::InfoSystem::InfoTrackLyrics ) return; - QVariantMap hash = input.value(); + QVariantMap hash = input.value< QVariantMap >(); QString artist = hash["artistName"].toString(); QString track = hash["trackName"].toString(); if( artist.isEmpty() || track.isEmpty() ) { - emit info(caller, Tomahawk::InfoSystem::InfoTrackLyrics, input, QVariant(), customData); + emit info( requestId, caller, Tomahawk::InfoSystem::InfoTrackLyrics, input, QVariant(), customData ); return; } qDebug() << "artist is " << artist << ", track is " << track; - QString requestString("http://api.musixmatch.com/ws/1.1/track.search?format=xml&page_size=1&f_has_lyrics=1"); - QUrl url(requestString); - url.addQueryItem("apikey", m_apiKey); - url.addQueryItem("q_artist", artist); - url.addQueryItem("q_track", track); - QNetworkReply* reply = m_nam.data()->get(QNetworkRequest(url)); - reply->setProperty("customData", QVariant::fromValue(customData)); - reply->setProperty("origData", input); - reply->setProperty("caller", caller); + QString requestString( "http://api.musixmatch.com/ws/1.1/track.search?format=xml&page_size=1&f_has_lyrics=1" ); + QUrl url( requestString ); + url.addQueryItem( "apikey", m_apiKey ); + url.addQueryItem( "q_artist", artist ); + url.addQueryItem( "q_track", track ); + QNetworkReply* reply = m_nam.data()->get( QNetworkRequest( url ) ); + reply->setProperty( "customData", QVariant::fromValue< QVariantMap >( customData ) ); + reply->setProperty( "origData", input ); + reply->setProperty( "caller", caller ); + reply->setProperty( "requestId", requestId ); - connect(reply, SIGNAL(finished()), SLOT(trackSearchSlot())); + connect( reply, SIGNAL( finished() ), SLOT( trackSearchSlot() ) ); } bool -MusixMatchPlugin::isValidTrackData( const QString &caller, const QVariant &input, const QVariantMap &customData ) +MusixMatchPlugin::isValidTrackData( uint requestId, const QString &caller, const QVariant &input, const QVariantMap &customData ) { qDebug() << Q_FUNC_INFO; - if (input.isNull() || !input.isValid() || !input.canConvert()) + if ( input.isNull() || !input.isValid() || !input.canConvert< QVariantMap >() ) { - emit info(caller, Tomahawk::InfoSystem::InfoTrackLyrics, input, QVariant(), customData); + emit info( requestId, caller, Tomahawk::InfoSystem::InfoTrackLyrics, input, QVariant(), customData ); qDebug() << "MusixMatchPlugin::isValidTrackData: Data null, invalid, or can't convert"; return false; } - QVariantMap hash = input.value(); - if (hash["trackName"].toString().isEmpty() ) + QVariantMap hash = input.value< QVariantMap >(); + if ( hash["trackName"].toString().isEmpty() ) { - emit info(caller, Tomahawk::InfoSystem::InfoTrackLyrics, input, QVariant(), customData); + emit info( requestId, caller, Tomahawk::InfoSystem::InfoTrackLyrics, input, QVariant(), customData ); qDebug() << "MusixMatchPlugin::isValidTrackData: Track name is empty"; return false; } - if (hash["artistName"].toString().isEmpty() ) + if ( hash["artistName"].toString().isEmpty() ) { - emit info(caller, Tomahawk::InfoSystem::InfoTrackLyrics, input, QVariant(), customData); + emit info( requestId, caller, Tomahawk::InfoSystem::InfoTrackLyrics, input, QVariant(), customData ); qDebug() << "MusixMatchPlugin::isValidTrackData: No artist name found"; return false; } @@ -109,9 +110,9 @@ MusixMatchPlugin::trackSearchSlot() { qDebug() << Q_FUNC_INFO; QNetworkReply* oldReply = qobject_cast( sender() ); - if ( !oldReply || m_nam.isNull() ) + if ( !oldReply ) { - emit info(QString(), Tomahawk::InfoSystem::InfoTrackLyrics, QVariant(), QVariant(), QVariantMap()); + emit info( 0, QString(), Tomahawk::InfoSystem::InfoTrackLyrics, QVariant(), QVariant(), QVariantMap() ); return; } QDomDocument doc; @@ -120,40 +121,41 @@ MusixMatchPlugin::trackSearchSlot() QDomNodeList domNodeList = doc.elementsByTagName("track_id"); if (domNodeList.isEmpty()) { - emit info(oldReply->property("caller").toString(), Tomahawk::InfoSystem::InfoTrackLyrics, oldReply->property("origData"), QVariant(), oldReply->property("customData").value()); + emit info( oldReply->property( "requestId" ).toUInt(), oldReply->property( "caller" ).toString(), Tomahawk::InfoSystem::InfoTrackLyrics, oldReply->property( "origData" ), QVariant(), oldReply->property( "customData" ).value< QVariantMap >() ); return; } QString track_id = domNodeList.at(0).toElement().text(); - QString requestString("http://api.musixmatch.com/ws/1.1/track.lyrics.get?track_id=%1&format=xml&apikey=%2"); - QUrl url(requestString); - url.addQueryItem("apikey", m_apiKey); - url.addQueryItem("track_id", track_id); - QNetworkReply* newReply = m_nam.data()->get(QNetworkRequest(url)); - newReply->setProperty("origData", oldReply->property("origData")); - newReply->setProperty("customData", oldReply->property("customData")); - newReply->setProperty("caller", oldReply->property("caller")); - connect(newReply, SIGNAL(finished()), SLOT(trackLyricsSlot())); + QString requestString( "http://api.musixmatch.com/ws/1.1/track.lyrics.get?track_id=%1&format=xml&apikey=%2" ); + QUrl url( requestString ); + url.addQueryItem( "apikey", m_apiKey ); + url.addQueryItem( "track_id", track_id ); + QNetworkReply* newReply = m_nam.data()->get( QNetworkRequest( url ) ); + newReply->setProperty( "origData", oldReply->property( "origData" ) ); + newReply->setProperty( "customData", oldReply->property( "customData" ) ); + newReply->setProperty( "caller", oldReply->property( "caller" ) ); + newReply->setProperty( "requestId", oldReply->property( "requestId" ) ); + connect( newReply, SIGNAL( finished() ), SLOT( trackLyricsSlot() ) ); } void MusixMatchPlugin::trackLyricsSlot() { qDebug() << Q_FUNC_INFO; - QNetworkReply* reply = qobject_cast( sender() ); - if (!reply) + QNetworkReply* reply = qobject_cast< QNetworkReply* >( sender() ); + if ( !reply ) { - emit info(QString(), Tomahawk::InfoSystem::InfoTrackLyrics, QVariant(), QVariant(), QVariantMap()); + emit info( 0, QString(), Tomahawk::InfoSystem::InfoTrackLyrics, QVariant(), QVariant(), QVariantMap() ); return; } QDomDocument doc; - doc.setContent(reply->readAll()); - QDomNodeList domNodeList = doc.elementsByTagName("lyrics_body"); - if (domNodeList.isEmpty()) + doc.setContent( reply->readAll() ); + QDomNodeList domNodeList = doc.elementsByTagName( "lyrics_body" ); + if ( domNodeList.isEmpty() ) { - emit info(reply->property("caller").toString(), Tomahawk::InfoSystem::InfoTrackLyrics, reply->property("origData"), QVariant(), reply->property("customData").value()); + emit info( reply->property( "requestId" ).toUInt(), reply->property( "caller" ).toString(), Tomahawk::InfoSystem::InfoTrackLyrics, reply->property( "origData" ), QVariant(), reply->property( "customData" ).value< QVariantMap >() ); return; } QString lyrics = domNodeList.at(0).toElement().text(); qDebug() << "Emitting lyrics: " << lyrics; - emit info(reply->property("caller").toString(), Tomahawk::InfoSystem::InfoTrackLyrics, reply->property("origData"), QVariant(lyrics), reply->property("customData").value()); + emit info( reply->property( "requestId" ).toUInt(), reply->property( "caller" ).toString(), Tomahawk::InfoSystem::InfoTrackLyrics, reply->property( "origData" ), QVariant( lyrics ), reply->property( "customData" ).value() ); } diff --git a/src/libtomahawk/infosystem/infoplugins/generic/musixmatchplugin.h b/src/libtomahawk/infosystem/infoplugins/generic/musixmatchplugin.h index 3451e3088..8b033b054 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/musixmatchplugin.h +++ b/src/libtomahawk/infosystem/infoplugins/generic/musixmatchplugin.h @@ -45,7 +45,7 @@ public slots: void namChangedSlot( QNetworkAccessManager *nam ); protected slots: - virtual void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ); + virtual void getInfo( uint requestId, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ); virtual void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant data ) { @@ -54,8 +54,9 @@ protected slots: Q_UNUSED( data ); } - virtual void notInCacheSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) +virtual void notInCacheSlot( uint requestId, const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) { + Q_UNUSED( requestId ); Q_UNUSED( criteria ); Q_UNUSED( caller ); Q_UNUSED( type ); @@ -64,7 +65,7 @@ protected slots: } private: - bool isValidTrackData( const QString &caller, const QVariant &input, const QVariantMap &customData ); + bool isValidTrackData( uint requestId, const QString &caller, const QVariant &input, const QVariantMap &customData ); QString m_apiKey; diff --git a/src/libtomahawk/infosystem/infoplugins/mac/adiumplugin.h b/src/libtomahawk/infosystem/infoplugins/mac/adiumplugin.h index 681b9e2e1..426fb3506 100644 --- a/src/libtomahawk/infosystem/infoplugins/mac/adiumplugin.h +++ b/src/libtomahawk/infosystem/infoplugins/mac/adiumplugin.h @@ -39,12 +39,29 @@ public: virtual ~AdiumPlugin(); protected slots: - void getInfo( const QString caller, const InfoType type, const QVariant data, QVariantMap customData ); + virtual void getInfo( uint requestId, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) + { + Q_UNUSED( requestId ); + Q_UNUSED( caller ); + Q_UNUSED( type ); + Q_UNUSED( input ); + Q_UNUSED( customData ); + } + void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input ); public slots: void namChangedSlot( QNetworkAccessManager* /*nam*/ ) {} // unused - void notInCacheSlot( const Tomahawk::InfoSystem::InfoCriteriaHash /*criteria*/, const QString /*caller*/, const Tomahawk::InfoSystem::InfoType /*type*/, const QVariant /*input*/, const QVariantMap /*customData*/ ) {} // unused + + virtual void notInCacheSlot( uint requestId, const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) + { + Q_UNUSED( requestId ); + Q_UNUSED( criteria ); + Q_UNUSED( caller ); + Q_UNUSED( type ); + Q_UNUSED( input ); + Q_UNUSED( customData ); + } private slots: void clearStatus(); diff --git a/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.h b/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.h index f0a0afc91..16f57cfb2 100644 --- a/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.h +++ b/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.h @@ -38,8 +38,9 @@ public: virtual void namChangedSlot( QNetworkAccessManager* ) {} protected slots: - virtual void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) + virtual void getInfo( uint requestId, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) { + Q_UNUSED( requestId ); Q_UNUSED( caller ); Q_UNUSED( type ); Q_UNUSED( input ); @@ -48,8 +49,9 @@ protected slots: virtual void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant pushData ); - virtual void notInCacheSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) + virtual void notInCacheSlot( uint requestId, const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) { + Q_UNUSED( requestId ); Q_UNUSED( criteria ); Q_UNUSED( caller ); Q_UNUSED( type ); diff --git a/src/libtomahawk/infosystem/infosystem.cpp b/src/libtomahawk/infosystem/infosystem.cpp index cfcce976f..c66cf5fe1 100644 --- a/src/libtomahawk/infosystem/infosystem.cpp +++ b/src/libtomahawk/infosystem/infosystem.cpp @@ -52,6 +52,9 @@ InfoSystem::instance() InfoSystem::InfoSystem(QObject *parent) : QObject(parent) + , m_infoSystemCacheThreadController( 0 ) + , m_infoSystemWorkerThreadController( 0 ) + , m_nextRequest( 0 ) { s_instance = this; @@ -71,11 +74,11 @@ InfoSystem::InfoSystem(QObject *parent) connect( TomahawkSettings::instance(), SIGNAL( changed() ), SLOT( newNam() ) ); - connect( m_cache.data(), SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), - this, SLOT( infoSlot( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), Qt::UniqueConnection ); + connect( m_cache.data(), SIGNAL( info( uint, QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), + this, SLOT( infoSlot( uint, QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), Qt::UniqueConnection ); - connect( m_worker.data(), SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), - this, SLOT( infoSlot( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), Qt::UniqueConnection ); + connect( m_worker.data(), SIGNAL( info( uint, QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), + this, SLOT( infoSlot( uint, QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), Qt::UniqueConnection ); } InfoSystem::~InfoSystem() @@ -120,9 +123,11 @@ InfoSystem::getInfo( const QString &caller, const InfoType type, const QVariant& { qDebug() << Q_FUNC_INFO; + uint requestnum = ++m_nextRequest; + qDebug() << "assigning request with requestId " << requestnum; m_dataTracker[caller][type] = m_dataTracker[caller][type] + 1; qDebug() << "current count in dataTracker for type" << type << "is" << m_dataTracker[caller][type]; - QMetaObject::invokeMethod( m_worker.data(), "getInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input ), Q_ARG( QVariantMap, customData ) ); + QMetaObject::invokeMethod( m_worker.data(), "getInfo", Qt::QueuedConnection, Q_ARG( uint, requestnum ), Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input ), Q_ARG( QVariantMap, customData ) ); } @@ -147,34 +152,34 @@ void InfoSystem::pushInfo( const QString &caller, const InfoTypeMap &input ) { Q_FOREACH( InfoType type, input.keys() ) - pushInfo( caller, type, input[type] ); + pushInfo( caller, type, input[ type ] ); } void -InfoSystem::infoSlot( QString target, InfoType type, QVariant input, QVariant output, QVariantMap customData ) +InfoSystem::infoSlot( uint requestId, QString target, InfoType type, QVariant input, QVariant output, QVariantMap customData ) { - qDebug() << Q_FUNC_INFO; - qDebug() << "current count in dataTracker is " << m_dataTracker[target][type]; - if (m_dataTracker[target][type] == 0) + qDebug() << Q_FUNC_INFO << " with requestId " << requestId; + qDebug() << "current count in dataTracker for target " << target << " is " << m_dataTracker[ target ][ type ]; + if ( m_dataTracker[ target ][ type ] == 0 ) { qDebug() << "Caller was not waiting for that type of data!"; return; } - emit info(target, type, input, output, customData); + 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()) + m_dataTracker[ target ][ type ] = m_dataTracker[ target ][ type ] - 1; + qDebug() << "current count in dataTracker for target " << target << " is " << m_dataTracker[ target ][ type ]; + Q_FOREACH( InfoType testtype, m_dataTracker[ target ].keys() ) { - if (m_dataTracker[target][testtype] != 0) + if ( m_dataTracker[ target ][ testtype ] != 0) { qDebug() << "found outstanding request of type" << testtype; return; } } qDebug() << "emitting finished with target" << target; - emit finished(target); + emit finished( target ); } } //namespace InfoSystem diff --git a/src/libtomahawk/infosystem/infosystem.h b/src/libtomahawk/infosystem/infosystem.h index 1681473c0..fa8e5b6ae 100644 --- a/src/libtomahawk/infosystem/infosystem.h +++ b/src/libtomahawk/infosystem/infosystem.h @@ -124,15 +124,15 @@ public: QSet< InfoType > supportedPushTypes() const { return m_supportedPushTypes; } signals: - void getCachedInfo( Tomahawk::InfoSystem::InfoCriteriaHash criteria, qint64 newMaxAge, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariantMap customData ); + void getCachedInfo( uint requestId, Tomahawk::InfoSystem::InfoCriteriaHash criteria, qint64 newMaxAge, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariantMap customData ); + void info( uint requestId, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, QVariantMap customData ); + void updateCache( Tomahawk::InfoSystem::InfoCriteriaHash criteria, qint64, Tomahawk::InfoSystem::InfoType type, QVariant output ); - void info( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, QVariantMap customData ); - void finished( QString, Tomahawk::InfoSystem::InfoType ); protected slots: - virtual void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant data, const QVariantMap customData ) = 0; + virtual void getInfo( uint requestId, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant data, const QVariantMap customData ) = 0; virtual void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant data ) = 0; - virtual void notInCacheSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) = 0; + virtual void notInCacheSlot( uint requestId, const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) = 0; virtual void namChangedSlot( QNetworkAccessManager *nam ) = 0; @@ -167,7 +167,7 @@ signals: void finished( QString target ); public slots: - void infoSlot( const QString target, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariant output, const QVariantMap customData ); + void infoSlot( uint requestId, const QString target, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariant output, const QVariantMap customData ); void newNam() const; @@ -179,6 +179,8 @@ private: QThread* m_infoSystemCacheThreadController; QThread* m_infoSystemWorkerThreadController; + uint m_nextRequest; + static InfoSystem* s_instance; }; diff --git a/src/libtomahawk/infosystem/infosystemcache.cpp b/src/libtomahawk/infosystem/infosystemcache.cpp index 0966333af..86f4cd2fa 100644 --- a/src/libtomahawk/infosystem/infosystemcache.cpp +++ b/src/libtomahawk/infosystem/infosystemcache.cpp @@ -84,7 +84,7 @@ InfoSystemCache::pruneTimerFired() void -InfoSystemCache::getCachedInfoSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const qint64 newMaxAge, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) +InfoSystemCache::getCachedInfoSlot( uint requestId, const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const qint64 newMaxAge, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) { qDebug() << Q_FUNC_INFO; const QString criteriaHashVal = criteriaMd5( criteria ); @@ -94,7 +94,7 @@ InfoSystemCache::getCachedInfoSlot( const Tomahawk::InfoSystem::InfoCriteriaHash if ( !fileLocationHash.isEmpty() ) { //We already know of some values, so no need to re-read the directory again as it's already happened - emit notInCache( criteria, caller, type, input, customData ); + emit notInCache( requestId, criteria, caller, type, input, customData ); return; } @@ -103,7 +103,7 @@ InfoSystemCache::getCachedInfoSlot( const Tomahawk::InfoSystem::InfoCriteriaHash if ( !dir.exists() ) { //Dir doesn't exist so clearly not in cache - emit notInCache( criteria, caller, type, input, customData ); + emit notInCache( requestId, criteria, caller, type, input, customData ); return; } @@ -119,7 +119,7 @@ InfoSystemCache::getCachedInfoSlot( const Tomahawk::InfoSystem::InfoCriteriaHash if ( !fileLocationHash.contains( criteriaHashVal ) ) { //Still didn't fine it? It's really not in the cache then - emit notInCache( criteria, caller, type, input, customData ); + emit notInCache( requestId, criteria, caller, type, input, customData ); return; } } @@ -138,7 +138,7 @@ InfoSystemCache::getCachedInfoSlot( const Tomahawk::InfoSystem::InfoCriteriaHash m_fileLocationCache[type] = fileLocationHash; m_dataCache.remove( criteriaHashVal ); - emit notInCache( criteria, caller, type, input, customData ); + emit notInCache( requestId, criteria, caller, type, input, customData ); return; } else if ( newMaxAge > 0 ) @@ -148,7 +148,7 @@ InfoSystemCache::getCachedInfoSlot( const Tomahawk::InfoSystem::InfoCriteriaHash if ( !QFile::rename( file.canonicalFilePath(), newFilePath ) ) { qDebug() << "Failed to move old cache file to new location!"; - emit notInCache( criteria, caller, type, input, customData ); + emit notInCache( requestId, criteria, caller, type, input, customData ); return; } @@ -162,11 +162,11 @@ InfoSystemCache::getCachedInfoSlot( const Tomahawk::InfoSystem::InfoCriteriaHash QVariant output = cachedSettings.value( "data" ); m_dataCache.insert( criteriaHashVal, new QVariant( output ) ); - emit info( caller, type, input, output, customData ); + emit info( requestId, caller, type, input, output, customData ); } else { - emit info( caller, type, input, QVariant( *(m_dataCache[criteriaHashVal]) ), customData ); + emit info( requestId, caller, type, input, QVariant( *(m_dataCache[criteriaHashVal]) ), customData ); } } diff --git a/src/libtomahawk/infosystem/infosystemcache.h b/src/libtomahawk/infosystem/infosystemcache.h index 115724f60..dfb78e4b0 100644 --- a/src/libtomahawk/infosystem/infosystemcache.h +++ b/src/libtomahawk/infosystem/infosystemcache.h @@ -43,11 +43,11 @@ public: virtual ~InfoSystemCache(); signals: - void notInCache( Tomahawk::InfoSystem::InfoCriteriaHash criteria, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariantMap customData ); - void info( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, QVariantMap customData ); + void notInCache( uint requestId, Tomahawk::InfoSystem::InfoCriteriaHash criteria, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariantMap customData ); + void info( uint requestId, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, QVariantMap customData ); public slots: - void getCachedInfoSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const qint64 newMaxAge, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ); + void getCachedInfoSlot( uint requestId, const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const qint64 newMaxAge, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ); void updateCacheSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const qint64 maxAge, const Tomahawk::InfoSystem::InfoType type, const QVariant output ); private slots: diff --git a/src/libtomahawk/infosystem/infosystemworker.cpp b/src/libtomahawk/infosystem/infosystemworker.cpp index bc9636ec5..8aa6eb00e 100644 --- a/src/libtomahawk/infosystem/infosystemworker.cpp +++ b/src/libtomahawk/infosystem/infosystemworker.cpp @@ -87,23 +87,23 @@ InfoSystemWorker::init( QWeakPointer< Tomahawk::InfoSystem::InfoSystemCache> cac { connect( plugin.data(), - SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), + SIGNAL( info( uint, QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), InfoSystem::instance(), - SLOT( infoSlot( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), + SLOT( infoSlot( uint, QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), Qt::UniqueConnection ); connect( plugin.data(), - SIGNAL( getCachedInfo( Tomahawk::InfoSystem::InfoCriteriaHash, qint64, QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariantMap ) ), + SIGNAL( getCachedInfo( uint, Tomahawk::InfoSystem::InfoCriteriaHash, qint64, QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariantMap ) ), cache.data(), - SLOT( getCachedInfoSlot( Tomahawk::InfoSystem::InfoCriteriaHash, qint64, QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariantMap ) ) + SLOT( getCachedInfoSlot( uint, Tomahawk::InfoSystem::InfoCriteriaHash, qint64, QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariantMap ) ) ); connect( cache.data(), - SIGNAL( notInCache( Tomahawk::InfoSystem::InfoCriteriaHash, QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariantMap ) ), + SIGNAL( notInCache( uint, Tomahawk::InfoSystem::InfoCriteriaHash, QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariantMap ) ), plugin.data(), - SLOT( notInCacheSlot( Tomahawk::InfoSystem::InfoCriteriaHash, QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariantMap ) ) + SLOT( notInCacheSlot( uint, Tomahawk::InfoSystem::InfoCriteriaHash, QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariantMap ) ) ); connect( plugin.data(), @@ -147,24 +147,24 @@ InfoSystemWorker::determineOrderedMatches( const InfoType type ) const void -InfoSystemWorker::getInfo( QString caller, InfoType type, QVariant input, QVariantMap customData ) +InfoSystemWorker::getInfo( uint requestId, QString caller, InfoType type, QVariant input, QVariantMap customData ) { qDebug() << Q_FUNC_INFO; QLinkedList< InfoPluginPtr > providers = determineOrderedMatches(type); if ( providers.isEmpty() ) { - emit info( caller, type, QVariant(), QVariant(), customData ); + emit info( requestId, caller, type, QVariant(), QVariant(), customData ); return; } InfoPluginPtr ptr = providers.first(); if ( !ptr ) { - emit info( caller, type, QVariant(), QVariant(), customData ); + emit info( requestId, caller, type, QVariant(), QVariant(), customData ); return; } - QMetaObject::invokeMethod( ptr.data(), "getInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input ), Q_ARG( QVariantMap, customData ) ); + QMetaObject::invokeMethod( ptr.data(), "getInfo", Qt::QueuedConnection, Q_ARG( uint, requestId ), Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input ), Q_ARG( QVariantMap, customData ) ); } diff --git a/src/libtomahawk/infosystem/infosystemworker.h b/src/libtomahawk/infosystem/infosystemworker.h index 3d87839e0..877ad2526 100644 --- a/src/libtomahawk/infosystem/infosystemworker.h +++ b/src/libtomahawk/infosystem/infosystemworker.h @@ -48,12 +48,12 @@ public: QNetworkAccessManager* nam() const; signals: - void info( QString target, Tomahawk::InfoSystem::InfoType, QVariant input, QVariant output, QVariantMap customData ); + void info( uint requestId, QString target, Tomahawk::InfoSystem::InfoType, QVariant input, QVariant output, QVariantMap customData ); void namChanged( QNetworkAccessManager* ); public slots: void init( QWeakPointer< Tomahawk::InfoSystem::InfoSystemCache > cache ); - void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ); + void getInfo( uint requestId, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ); void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input ); void newNam(); From 6bb26ecde8ae38d6de9b780bbe83a2fb074d508c Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Wed, 6 Jul 2011 12:49:58 -0400 Subject: [PATCH 76/86] Move almost all of the rest of the logic of infosystem to the worker thread --- src/libtomahawk/infosystem/infosystem.cpp | 47 +++---------------- src/libtomahawk/infosystem/infosystem.h | 8 +--- .../infosystem/infosystemworker.cpp | 47 ++++++++++++++++--- src/libtomahawk/infosystem/infosystemworker.h | 13 ++++- 4 files changed, 59 insertions(+), 56 deletions(-) diff --git a/src/libtomahawk/infosystem/infosystem.cpp b/src/libtomahawk/infosystem/infosystem.cpp index c66cf5fe1..6fa8f3c35 100644 --- a/src/libtomahawk/infosystem/infosystem.cpp +++ b/src/libtomahawk/infosystem/infosystem.cpp @@ -54,7 +54,6 @@ InfoSystem::InfoSystem(QObject *parent) : QObject(parent) , m_infoSystemCacheThreadController( 0 ) , m_infoSystemWorkerThreadController( 0 ) - , m_nextRequest( 0 ) { s_instance = this; @@ -75,10 +74,11 @@ InfoSystem::InfoSystem(QObject *parent) connect( TomahawkSettings::instance(), SIGNAL( changed() ), SLOT( newNam() ) ); connect( m_cache.data(), SIGNAL( info( uint, QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), - this, SLOT( infoSlot( uint, QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), Qt::UniqueConnection ); + m_worker.data(), SLOT( infoSlot( uint, QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), Qt::UniqueConnection ); - connect( m_worker.data(), SIGNAL( info( uint, QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), - this, SLOT( infoSlot( uint, QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), Qt::UniqueConnection ); + connect( m_worker.data(), SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), + this, SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), Qt::UniqueConnection ); + connect( m_worker.data(), SIGNAL( finished( QString ) ), this, SIGNAL( finished( QString) ), Qt::UniqueConnection ); } InfoSystem::~InfoSystem() @@ -122,12 +122,7 @@ void InfoSystem::getInfo( const QString &caller, const InfoType type, const QVariant& input, QVariantMap customData ) { qDebug() << Q_FUNC_INFO; - - uint requestnum = ++m_nextRequest; - qDebug() << "assigning request with requestId " << requestnum; - m_dataTracker[caller][type] = m_dataTracker[caller][type] + 1; - qDebug() << "current count in dataTracker for type" << type << "is" << m_dataTracker[caller][type]; - QMetaObject::invokeMethod( m_worker.data(), "getInfo", Qt::QueuedConnection, Q_ARG( uint, requestnum ), Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input ), Q_ARG( QVariantMap, customData ) ); + QMetaObject::invokeMethod( m_worker.data(), "getInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input ), Q_ARG( QVariantMap, customData ) ); } @@ -135,7 +130,7 @@ void InfoSystem::getInfo( const QString &caller, const InfoTypeMap &input, QVariantMap customData ) { Q_FOREACH( InfoType type, input.keys() ) - getInfo( caller, type, input[type], customData ); + QMetaObject::invokeMethod( m_worker.data(), "getInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input[ type ] ), Q_ARG( QVariantMap, customData ) ); } @@ -143,7 +138,6 @@ void InfoSystem::pushInfo( const QString &caller, const InfoType type, const QVariant& input ) { qDebug() << Q_FUNC_INFO; - QMetaObject::invokeMethod( m_worker.data(), "pushInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input ) ); } @@ -152,34 +146,7 @@ void InfoSystem::pushInfo( const QString &caller, const InfoTypeMap &input ) { Q_FOREACH( InfoType type, input.keys() ) - pushInfo( caller, type, input[ type ] ); -} - - -void -InfoSystem::infoSlot( uint requestId, QString target, InfoType type, QVariant input, QVariant output, QVariantMap customData ) -{ - qDebug() << Q_FUNC_INFO << " with requestId " << requestId; - qDebug() << "current count in dataTracker for target " << target << " is " << m_dataTracker[ target ][ type ]; - if ( m_dataTracker[ target ][ type ] == 0 ) - { - qDebug() << "Caller was not waiting for that type of data!"; - return; - } - emit info( target, type, input, output, customData ); - - m_dataTracker[ target ][ type ] = m_dataTracker[ target ][ type ] - 1; - qDebug() << "current count in dataTracker for target " << target << " is " << m_dataTracker[ target ][ type ]; - Q_FOREACH( InfoType testtype, m_dataTracker[ target ].keys() ) - { - if ( m_dataTracker[ target ][ testtype ] != 0) - { - qDebug() << "found outstanding request of type" << testtype; - return; - } - } - qDebug() << "emitting finished with target" << target; - emit finished( target ); + QMetaObject::invokeMethod( m_worker.data(), "pushInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input[ type ] ) ); } } //namespace InfoSystem diff --git a/src/libtomahawk/infosystem/infosystem.h b/src/libtomahawk/infosystem/infosystem.h index fa8e5b6ae..17c49fc07 100644 --- a/src/libtomahawk/infosystem/infosystem.h +++ b/src/libtomahawk/infosystem/infosystem.h @@ -163,24 +163,18 @@ public: void pushInfo( const QString &caller, const InfoTypeMap &input ); signals: - void info( QString caller, Tomahawk::InfoSystem::InfoType, QVariant input, QVariant output, QVariantMap customData ); + void info( QString target, Tomahawk::InfoSystem::InfoType, QVariant input, QVariant output, QVariantMap customData ); void finished( QString target ); public slots: - void infoSlot( uint requestId, const QString target, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariant output, const QVariantMap customData ); - void newNam() const; private: - QHash< QString, QHash< InfoType, int > > m_dataTracker; - QWeakPointer< InfoSystemCache > m_cache; QWeakPointer< InfoSystemWorker > m_worker; QThread* m_infoSystemCacheThreadController; QThread* m_infoSystemWorkerThreadController; - uint m_nextRequest; - static InfoSystem* s_instance; }; diff --git a/src/libtomahawk/infosystem/infosystemworker.cpp b/src/libtomahawk/infosystem/infosystemworker.cpp index 8aa6eb00e..a2c18e140 100644 --- a/src/libtomahawk/infosystem/infosystemworker.cpp +++ b/src/libtomahawk/infosystem/infosystemworker.cpp @@ -42,6 +42,8 @@ namespace InfoSystem { InfoSystemWorker::InfoSystemWorker() + : QObject() + , m_nextRequest( 0 ) { qDebug() << Q_FUNC_INFO; } @@ -88,7 +90,7 @@ InfoSystemWorker::init( QWeakPointer< Tomahawk::InfoSystem::InfoSystemCache> cac connect( plugin.data(), SIGNAL( info( uint, QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), - InfoSystem::instance(), + this, SLOT( infoSlot( uint, QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), Qt::UniqueConnection ); @@ -147,24 +149,29 @@ InfoSystemWorker::determineOrderedMatches( const InfoType type ) const void -InfoSystemWorker::getInfo( uint requestId, QString caller, InfoType type, QVariant input, QVariantMap customData ) +InfoSystemWorker::getInfo( QString caller, InfoType type, QVariant input, QVariantMap customData ) { qDebug() << Q_FUNC_INFO; - QLinkedList< InfoPluginPtr > providers = determineOrderedMatches(type); + QLinkedList< InfoPluginPtr > providers = determineOrderedMatches( type ); if ( providers.isEmpty() ) { - emit info( requestId, caller, type, QVariant(), QVariant(), customData ); + emit info( caller, type, QVariant(), QVariant(), customData ); return; } InfoPluginPtr ptr = providers.first(); if ( !ptr ) { - emit info( requestId, caller, type, QVariant(), QVariant(), customData ); + emit info( caller, type, QVariant(), QVariant(), customData ); return; } - QMetaObject::invokeMethod( ptr.data(), "getInfo", Qt::QueuedConnection, Q_ARG( uint, requestId ), Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input ), Q_ARG( QVariantMap, customData ) ); + uint requestnum = ++m_nextRequest; + qDebug() << "assigning request with requestId " << requestnum; + m_dataTracker[ caller ][ type ] = m_dataTracker[ caller ][ type ] + 1; + qDebug() << "current count in dataTracker for type" << type << "is" << m_dataTracker[ caller ][ type ]; + + QMetaObject::invokeMethod( ptr.data(), "getInfo", Qt::QueuedConnection, Q_ARG( uint, requestnum ), Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input ), Q_ARG( QVariantMap, customData ) ); } @@ -181,6 +188,33 @@ InfoSystemWorker::pushInfo( const QString caller, const InfoType type, const QVa } +void +InfoSystemWorker::infoSlot( uint requestId, QString target, InfoType type, QVariant input, QVariant output, QVariantMap customData ) +{ + qDebug() << Q_FUNC_INFO << " with requestId " << requestId; + qDebug() << "current count in dataTracker for target " << target << " is " << m_dataTracker[ target ][ type ]; + if ( m_dataTracker[ target ][ type ] == 0 ) + { + qDebug() << "Caller was not waiting for that type of data!"; + return; + } + emit info( target, type, input, output, customData ); + + m_dataTracker[ target ][ type ] = m_dataTracker[ target ][ type ] - 1; + qDebug() << "current count in dataTracker for target " << target << " is " << m_dataTracker[ target ][ type ]; + Q_FOREACH( InfoType testtype, m_dataTracker[ target ].keys() ) + { + if ( m_dataTracker[ target ][ testtype ] != 0) + { + qDebug() << "found outstanding request of type" << testtype; + return; + } + } + qDebug() << "emitting finished with target" << target; + emit finished( target ); +} + + QNetworkAccessManager* InfoSystemWorker::nam() const { @@ -235,7 +269,6 @@ InfoSystemWorker::newNam() //FIXME: Currently leaking nam/proxyfactory above -- how to change in a thread-safe way? } - } //namespace InfoSystem } //namespace Tomahawk diff --git a/src/libtomahawk/infosystem/infosystemworker.h b/src/libtomahawk/infosystem/infosystemworker.h index 877ad2526..9eb927a6c 100644 --- a/src/libtomahawk/infosystem/infosystemworker.h +++ b/src/libtomahawk/infosystem/infosystemworker.h @@ -48,16 +48,23 @@ public: QNetworkAccessManager* nam() const; signals: - void info( uint requestId, QString target, Tomahawk::InfoSystem::InfoType, QVariant input, QVariant output, QVariantMap customData ); + void info( QString target, Tomahawk::InfoSystem::InfoType, QVariant input, QVariant output, QVariantMap customData ); + void finished( QString target ); + void namChanged( QNetworkAccessManager* ); public slots: void init( QWeakPointer< Tomahawk::InfoSystem::InfoSystemCache > cache ); - void getInfo( uint requestId, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ); + void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ); void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input ); + + void infoSlot( uint requestId, const QString target, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariant output, const QVariantMap customData ); + void newNam(); private: + QHash< QString, QHash< InfoType, int > > m_dataTracker; + QLinkedList< InfoPluginPtr > determineOrderedMatches( const InfoType type ) const; // For now, statically instantiate plugins; this is just somewhere to keep them @@ -67,6 +74,8 @@ private: QMap< InfoType, QLinkedList< InfoPluginPtr > > m_infoPushMap; QWeakPointer< QNetworkAccessManager> m_nam; + + uint m_nextRequest; }; } From 226f823354674698448d3942d5090ed9ec8bf9e4 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Wed, 6 Jul 2011 14:58:56 -0400 Subject: [PATCH 77/86] Add timeout functionality -- mostly. Still have to figure out the best way to store items in case too much time has elapsed. --- src/libtomahawk/infosystem/infosystem.cpp | 10 +-- src/libtomahawk/infosystem/infosystem.h | 5 +- .../infosystem/infosystemworker.cpp | 66 +++++++++++++++++-- src/libtomahawk/infosystem/infosystemworker.h | 13 +++- 4 files changed, 81 insertions(+), 13 deletions(-) diff --git a/src/libtomahawk/infosystem/infosystem.cpp b/src/libtomahawk/infosystem/infosystem.cpp index 6fa8f3c35..15b3502ec 100644 --- a/src/libtomahawk/infosystem/infosystem.cpp +++ b/src/libtomahawk/infosystem/infosystem.cpp @@ -119,18 +119,18 @@ InfoSystem::newNam() const void -InfoSystem::getInfo( const QString &caller, const InfoType type, const QVariant& input, QVariantMap customData ) +InfoSystem::getInfo( const QString &caller, const InfoType type, const QVariant& input, QVariantMap customData, uint timeoutMillis ) { qDebug() << Q_FUNC_INFO; - QMetaObject::invokeMethod( m_worker.data(), "getInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input ), Q_ARG( QVariantMap, customData ) ); + QMetaObject::invokeMethod( m_worker.data(), "getInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input ), Q_ARG( QVariantMap, customData ), Q_ARG( uint, timeoutMillis ) ); } void -InfoSystem::getInfo( const QString &caller, const InfoTypeMap &input, QVariantMap customData ) +InfoSystem::getInfo( const QString &caller, const InfoTypeMap &inputMap, QVariantMap customData, const InfoTimeoutMap &timeoutMap ) { - Q_FOREACH( InfoType type, input.keys() ) - QMetaObject::invokeMethod( m_worker.data(), "getInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input[ type ] ), Q_ARG( QVariantMap, customData ) ); + Q_FOREACH( InfoType type, inputMap.keys() ) + QMetaObject::invokeMethod( m_worker.data(), "getInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, inputMap[ type ] ), Q_ARG( QVariantMap, customData ), Q_ARG( uint, ( timeoutMap.contains( type ) ? timeoutMap[ type ] : 3000 ) ) ); } diff --git a/src/libtomahawk/infosystem/infosystem.h b/src/libtomahawk/infosystem/infosystem.h index 17c49fc07..e48bb932f 100644 --- a/src/libtomahawk/infosystem/infosystem.h +++ b/src/libtomahawk/infosystem/infosystem.h @@ -108,6 +108,7 @@ enum InfoType { // as items are saved in cache, mark them here to not change the }; typedef QMap< InfoType, QVariant > InfoTypeMap; +typedef QMap< InfoType, uint > InfoTimeoutMap; typedef QMap< QString, QMap< QString, QString > > InfoGenericMap; typedef QHash< QString, QString > InfoCriteriaHash; @@ -157,8 +158,8 @@ public: InfoSystem( QObject *parent ); ~InfoSystem(); - void getInfo( const QString &caller, const InfoType type, const QVariant &input, QVariantMap customData ); - void getInfo( const QString &caller, const InfoTypeMap &input, QVariantMap customData ); + void getInfo( const QString &caller, const InfoType type, const QVariant &input, QVariantMap customData, uint timeoutSeconds = 3000 ); + void getInfo( const QString &caller, const InfoTypeMap &inputMap, QVariantMap customData, const InfoTimeoutMap &timeoutMap = InfoTimeoutMap() ); void pushInfo( const QString &caller, const InfoType type, const QVariant &input ); void pushInfo( const QString &caller, const InfoTypeMap &input ); diff --git a/src/libtomahawk/infosystem/infosystemworker.cpp b/src/libtomahawk/infosystem/infosystemworker.cpp index a2c18e140..5a1a65d34 100644 --- a/src/libtomahawk/infosystem/infosystemworker.cpp +++ b/src/libtomahawk/infosystem/infosystemworker.cpp @@ -46,6 +46,11 @@ InfoSystemWorker::InfoSystemWorker() , m_nextRequest( 0 ) { qDebug() << Q_FUNC_INFO; + + m_checkTimeoutsTimer.setInterval( 1000 ); + m_checkTimeoutsTimer.setSingleShot( false ); + connect( &m_checkTimeoutsTimer, SIGNAL( timeout() ), SLOT( checkTimeoutsTimerFired() ) ); + m_checkTimeoutsTimer.start(); } @@ -149,13 +154,14 @@ InfoSystemWorker::determineOrderedMatches( const InfoType type ) const void -InfoSystemWorker::getInfo( QString caller, InfoType type, QVariant input, QVariantMap customData ) +InfoSystemWorker::getInfo( QString caller, InfoType type, QVariant input, QVariantMap customData, uint timeoutMillis ) { qDebug() << Q_FUNC_INFO; QLinkedList< InfoPluginPtr > providers = determineOrderedMatches( type ); if ( providers.isEmpty() ) { emit info( caller, type, QVariant(), QVariant(), customData ); + checkFinished( caller ); return; } @@ -163,15 +169,22 @@ InfoSystemWorker::getInfo( QString caller, InfoType type, QVariant input, QVaria if ( !ptr ) { emit info( caller, type, QVariant(), QVariant(), customData ); + checkFinished( caller ); return; } - uint requestnum = ++m_nextRequest; - qDebug() << "assigning request with requestId " << requestnum; + uint requestId = ++m_nextRequest; + m_requestSatisfiedMap[ requestId ] = false; + if ( timeoutMillis != 0 ) + { + qint64 currMs = QDateTime::currentMSecsSinceEpoch(); + m_timeRequestMapper.insert( currMs + timeoutMillis, requestId ); + } + qDebug() << "assigning request with requestId " << requestId; m_dataTracker[ caller ][ type ] = m_dataTracker[ caller ][ type ] + 1; qDebug() << "current count in dataTracker for type" << type << "is" << m_dataTracker[ caller ][ type ]; - QMetaObject::invokeMethod( ptr.data(), "getInfo", Qt::QueuedConnection, Q_ARG( uint, requestnum ), Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input ), Q_ARG( QVariantMap, customData ) ); + QMetaObject::invokeMethod( ptr.data(), "getInfo", Qt::QueuedConnection, Q_ARG( uint, requestId ), Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input ), Q_ARG( QVariantMap, customData ) ); } @@ -192,16 +205,23 @@ void InfoSystemWorker::infoSlot( uint requestId, QString target, InfoType type, QVariant input, QVariant output, QVariantMap customData ) { qDebug() << Q_FUNC_INFO << " with requestId " << requestId; - qDebug() << "current count in dataTracker for target " << target << " is " << m_dataTracker[ target ][ type ]; if ( m_dataTracker[ target ][ type ] == 0 ) { qDebug() << "Caller was not waiting for that type of data!"; return; } + m_requestSatisfiedMap[ requestId ] = true; emit info( target, type, input, output, customData ); m_dataTracker[ target ][ type ] = m_dataTracker[ target ][ type ] - 1; qDebug() << "current count in dataTracker for target " << target << " is " << m_dataTracker[ target ][ type ]; + checkFinished( target ); +} + + +void +InfoSystemWorker::checkFinished( const QString &target ) +{ Q_FOREACH( InfoType testtype, m_dataTracker[ target ].keys() ) { if ( m_dataTracker[ target ][ testtype ] != 0) @@ -215,6 +235,42 @@ InfoSystemWorker::infoSlot( uint requestId, QString target, InfoType type, QVari } +void +InfoSystemWorker::checkTimeoutsTimerFired() +{ + qint64 currTime = QDateTime::currentMSecsSinceEpoch(); + Q_FOREACH( qint64 time, m_timeRequestMapper.keys() ) + { + Q_FOREACH( uint requestId, m_timeRequestMapper.values( time ) ) + { + if ( time < currTime ) + { + if ( m_requestSatisfiedMap[ requestId ] ) + { + qDebug() << Q_FUNC_INFO << " removing mapping of " << requestId << " which expired at time " << time << " and was already satisfied"; + m_timeRequestMapper.remove( time, requestId ); + if ( !m_timeRequestMapper.count( time ) ) + m_timeRequestMapper.remove( time ); + continue; + } + + //doh, timed out + //FIXME: do something + //m_requestSatisfiedMap[ requestId ] = true; + //m_timeRequestMapper.remove( time, requestId ); + //if ( !m_timeRequestMapper.count( time ) ) + // m_timeRequestMapper.remove( time ); + } + else + { + //we've caught up, the remaining requets still have time to work + return; + } + } + } +} + + QNetworkAccessManager* InfoSystemWorker::nam() const { diff --git a/src/libtomahawk/infosystem/infosystemworker.h b/src/libtomahawk/infosystem/infosystemworker.h index 9eb927a6c..cef6fc159 100644 --- a/src/libtomahawk/infosystem/infosystemworker.h +++ b/src/libtomahawk/infosystem/infosystemworker.h @@ -29,6 +29,7 @@ #include #include #include +#include #include "dllmacro.h" @@ -55,15 +56,23 @@ signals: public slots: void init( QWeakPointer< Tomahawk::InfoSystem::InfoSystemCache > cache ); - void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ); + void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData, uint timeoutMillis ); void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input ); void infoSlot( uint requestId, const QString target, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariant output, const QVariantMap customData ); void newNam(); + +private slots: + void checkTimeoutsTimerFired(); private: + + void checkFinished( const QString &target ); + QHash< QString, QHash< InfoType, int > > m_dataTracker; + QMultiMap< qint64, uint > m_timeRequestMapper; + QHash< uint, bool > m_requestSatisfiedMap; QLinkedList< InfoPluginPtr > determineOrderedMatches( const InfoType type ) const; @@ -76,6 +85,8 @@ private: QWeakPointer< QNetworkAccessManager> m_nam; uint m_nextRequest; + + QTimer m_checkTimeoutsTimer; }; } From 0bfc873559b3fef5c8c2c2f835745ccf97ed9f71 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Wed, 6 Jul 2011 16:00:05 -0400 Subject: [PATCH 78/86] Handle timeouts of getInfo requests --- src/libtomahawk/infosystem/infosystem.h | 2 +- .../infosystem/infosystemworker.cpp | 42 +++++++++++++++---- src/libtomahawk/infosystem/infosystemworker.h | 8 ++++ 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/src/libtomahawk/infosystem/infosystem.h b/src/libtomahawk/infosystem/infosystem.h index e48bb932f..d6bddc76d 100644 --- a/src/libtomahawk/infosystem/infosystem.h +++ b/src/libtomahawk/infosystem/infosystem.h @@ -158,7 +158,7 @@ public: InfoSystem( QObject *parent ); ~InfoSystem(); - void getInfo( const QString &caller, const InfoType type, const QVariant &input, QVariantMap customData, uint timeoutSeconds = 3000 ); + void getInfo( const QString &caller, const InfoType type, const QVariant &input, QVariantMap customData, uint timeoutMillis = 3000 ); void getInfo( const QString &caller, const InfoTypeMap &inputMap, QVariantMap customData, const InfoTimeoutMap &timeoutMap = InfoTimeoutMap() ); void pushInfo( const QString &caller, const InfoType type, const QVariant &input ); void pushInfo( const QString &caller, const InfoTypeMap &input ); diff --git a/src/libtomahawk/infosystem/infosystemworker.cpp b/src/libtomahawk/infosystem/infosystemworker.cpp index 5a1a65d34..e80ed55e8 100644 --- a/src/libtomahawk/infosystem/infosystemworker.cpp +++ b/src/libtomahawk/infosystem/infosystemworker.cpp @@ -184,6 +184,13 @@ InfoSystemWorker::getInfo( QString caller, InfoType type, QVariant input, QVaria m_dataTracker[ caller ][ type ] = m_dataTracker[ caller ][ type ] + 1; qDebug() << "current count in dataTracker for type" << type << "is" << m_dataTracker[ caller ][ type ]; + SavedRequestData* data = new SavedRequestData; + data->caller = caller; + data->type = type; + data->input = input; + data->customData = customData; + m_savedRequestMap[ requestId ] = data; + QMetaObject::invokeMethod( ptr.data(), "getInfo", Qt::QueuedConnection, Q_ARG( uint, requestId ), Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input ), Q_ARG( QVariantMap, customData ) ); } @@ -207,14 +214,22 @@ InfoSystemWorker::infoSlot( uint requestId, QString target, InfoType type, QVari qDebug() << Q_FUNC_INFO << " with requestId " << requestId; if ( m_dataTracker[ target ][ type ] == 0 ) { - qDebug() << "Caller was not waiting for that type of data!"; + qDebug() << Q_FUNC_INFO << " caller was not waiting for that type of data!"; return; } + if ( !m_requestSatisfiedMap.contains( requestId ) || m_requestSatisfiedMap[ requestId ] ) + { + qDebug() << Q_FUNC_INFO << " request was already taken care of!"; + return; + } + m_requestSatisfiedMap[ requestId ] = true; emit info( target, type, input, output, customData ); - + m_dataTracker[ target ][ type ] = m_dataTracker[ target ][ type ] - 1; qDebug() << "current count in dataTracker for target " << target << " is " << m_dataTracker[ target ][ type ]; + delete m_savedRequestMap[ requestId ]; + m_savedRequestMap.remove( requestId ); checkFinished( target ); } @@ -255,11 +270,24 @@ InfoSystemWorker::checkTimeoutsTimerFired() } //doh, timed out - //FIXME: do something - //m_requestSatisfiedMap[ requestId ] = true; - //m_timeRequestMapper.remove( time, requestId ); - //if ( !m_timeRequestMapper.count( time ) ) - // m_timeRequestMapper.remove( time ); + qDebug() << Q_FUNC_INFO << " doh, timed out for requestId " << requestId; + SavedRequestData *savedData = m_savedRequestMap[ requestId ]; + QString target = savedData->caller; + InfoType type = savedData->type; + emit info( target, type, savedData->input, QVariant(), savedData->customData ); + + delete savedData; + m_savedRequestMap.remove( requestId ); + + m_dataTracker[ target ][ type ] = m_dataTracker[ target ][ type ] - 1; + qDebug() << "current count in dataTracker for target " << target << " is " << m_dataTracker[ target ][ type ]; + + m_requestSatisfiedMap[ requestId ] = true; + m_timeRequestMapper.remove( time, requestId ); + if ( !m_timeRequestMapper.count( time ) ) + m_timeRequestMapper.remove( time ); + + checkFinished( target ); } else { diff --git a/src/libtomahawk/infosystem/infosystemworker.h b/src/libtomahawk/infosystem/infosystemworker.h index cef6fc159..62cf2a84d 100644 --- a/src/libtomahawk/infosystem/infosystemworker.h +++ b/src/libtomahawk/infosystem/infosystemworker.h @@ -37,6 +37,13 @@ namespace Tomahawk { namespace InfoSystem { +struct SavedRequestData { + QString caller; + Tomahawk::InfoSystem::InfoType type; + QVariant input; + QVariantMap customData; +}; + class DLLEXPORT InfoSystemWorker : public QObject { Q_OBJECT @@ -73,6 +80,7 @@ private: QHash< QString, QHash< InfoType, int > > m_dataTracker; QMultiMap< qint64, uint > m_timeRequestMapper; QHash< uint, bool > m_requestSatisfiedMap; + QHash< uint, SavedRequestData* > m_savedRequestMap; QLinkedList< InfoPluginPtr > determineOrderedMatches( const InfoType type ) const; From eb7f3fdab4919c9f02053ebea54b63581c1ac741 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Wed, 6 Jul 2011 16:20:20 -0400 Subject: [PATCH 79/86] Enable caching of two more infotypes --- .../infosystem/infoplugins/generic/lastfmplugin.cpp | 6 +++--- src/libtomahawk/infosystem/infosystem.h | 4 ++-- src/libtomahawk/infosystem/infosystemworker.cpp | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp index 6ed7914dd..ace2259d4 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp @@ -358,7 +358,7 @@ LastFmPlugin::fetchArtistImages( uint requestId, const QString &caller, const In void LastFmPlugin::notInCacheSlot( uint requestId, const QHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) { - qDebug() << Q_FUNC_INFO; + qDebug() << Q_FUNC_INFO << " for requestId " << requestId; if ( !lastfm::nam() ) { @@ -476,7 +476,7 @@ LastFmPlugin::similarArtistsReturned() InfoCriteriaHash origData = reply->property( "origData" ).value< Tomahawk::InfoSystem::InfoCriteriaHash >(); Tomahawk::InfoSystem::InfoCriteriaHash criteria; criteria["artist"] = origData["artist"]; -// emit updateCache( criteria, 2419200000, type, returnedData ); + emit updateCache( criteria, 2419200000, type, returnedData ); } @@ -509,7 +509,7 @@ LastFmPlugin::topTracksReturned() InfoCriteriaHash origData = reply->property( "origData" ).value< Tomahawk::InfoSystem::InfoCriteriaHash >(); Tomahawk::InfoSystem::InfoCriteriaHash criteria; criteria["artist"] = origData["artist"]; - //emit updateCache( criteria, 2419200000, type, returnedData ); + emit updateCache( criteria, 2419200000, type, returnedData ); } diff --git a/src/libtomahawk/infosystem/infosystem.h b/src/libtomahawk/infosystem/infosystem.h index d6bddc76d..01ce3fc24 100644 --- a/src/libtomahawk/infosystem/infosystem.h +++ b/src/libtomahawk/infosystem/infosystem.h @@ -75,8 +75,8 @@ enum InfoType { // as items are saved in cache, mark them here to not change the InfoArtistNews = 29, InfoArtistProfile = 30, InfoArtistReviews = 31, - InfoArtistSongs = 32, - InfoArtistSimilars = 33, + InfoArtistSongs = 32, //cached -- do not change + InfoArtistSimilars = 33, //cached -- do not change InfoArtistTerms = 34, InfoArtistLinks = 35, InfoArtistVideos = 36, diff --git a/src/libtomahawk/infosystem/infosystemworker.cpp b/src/libtomahawk/infosystem/infosystemworker.cpp index e80ed55e8..17e916d81 100644 --- a/src/libtomahawk/infosystem/infosystemworker.cpp +++ b/src/libtomahawk/infosystem/infosystemworker.cpp @@ -180,7 +180,7 @@ InfoSystemWorker::getInfo( QString caller, InfoType type, QVariant input, QVaria qint64 currMs = QDateTime::currentMSecsSinceEpoch(); m_timeRequestMapper.insert( currMs + timeoutMillis, requestId ); } - qDebug() << "assigning request with requestId " << requestId; + qDebug() << "assigning request with requestId " << requestId << " and type " << type; m_dataTracker[ caller ][ type ] = m_dataTracker[ caller ][ type ] + 1; qDebug() << "current count in dataTracker for type" << type << "is" << m_dataTracker[ caller ][ type ]; From 51fba9ae621a601b110119082077e6af884bbd00 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Wed, 6 Jul 2011 17:32:02 -0400 Subject: [PATCH 80/86] Rename SavedRequestData and promote it --- src/libtomahawk/infosystem/infosystem.h | 7 +++++++ src/libtomahawk/infosystem/infosystemworker.cpp | 4 ++-- src/libtomahawk/infosystem/infosystemworker.h | 10 ++-------- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/libtomahawk/infosystem/infosystem.h b/src/libtomahawk/infosystem/infosystem.h index 01ce3fc24..2b5ca3ef9 100644 --- a/src/libtomahawk/infosystem/infosystem.h +++ b/src/libtomahawk/infosystem/infosystem.h @@ -107,6 +107,13 @@ enum InfoType { // as items are saved in cache, mark them here to not change the InfoNotifyUser = 55 }; +struct InfoRequestData { + QString caller; + Tomahawk::InfoSystem::InfoType type; + QVariant input; + QVariantMap customData; +}; + typedef QMap< InfoType, QVariant > InfoTypeMap; typedef QMap< InfoType, uint > InfoTimeoutMap; typedef QMap< QString, QMap< QString, QString > > InfoGenericMap; diff --git a/src/libtomahawk/infosystem/infosystemworker.cpp b/src/libtomahawk/infosystem/infosystemworker.cpp index 17e916d81..6f880a161 100644 --- a/src/libtomahawk/infosystem/infosystemworker.cpp +++ b/src/libtomahawk/infosystem/infosystemworker.cpp @@ -184,7 +184,7 @@ InfoSystemWorker::getInfo( QString caller, InfoType type, QVariant input, QVaria m_dataTracker[ caller ][ type ] = m_dataTracker[ caller ][ type ] + 1; qDebug() << "current count in dataTracker for type" << type << "is" << m_dataTracker[ caller ][ type ]; - SavedRequestData* data = new SavedRequestData; + InfoRequestData* data = new InfoRequestData; data->caller = caller; data->type = type; data->input = input; @@ -271,7 +271,7 @@ InfoSystemWorker::checkTimeoutsTimerFired() //doh, timed out qDebug() << Q_FUNC_INFO << " doh, timed out for requestId " << requestId; - SavedRequestData *savedData = m_savedRequestMap[ requestId ]; + InfoRequestData *savedData = m_savedRequestMap[ requestId ]; QString target = savedData->caller; InfoType type = savedData->type; emit info( target, type, savedData->input, QVariant(), savedData->customData ); diff --git a/src/libtomahawk/infosystem/infosystemworker.h b/src/libtomahawk/infosystem/infosystemworker.h index 62cf2a84d..33af36bad 100644 --- a/src/libtomahawk/infosystem/infosystemworker.h +++ b/src/libtomahawk/infosystem/infosystemworker.h @@ -37,13 +37,7 @@ namespace Tomahawk { namespace InfoSystem { -struct SavedRequestData { - QString caller; - Tomahawk::InfoSystem::InfoType type; - QVariant input; - QVariantMap customData; -}; - + class DLLEXPORT InfoSystemWorker : public QObject { Q_OBJECT @@ -80,7 +74,7 @@ private: QHash< QString, QHash< InfoType, int > > m_dataTracker; QMultiMap< qint64, uint > m_timeRequestMapper; QHash< uint, bool > m_requestSatisfiedMap; - QHash< uint, SavedRequestData* > m_savedRequestMap; + QHash< uint, InfoRequestData* > m_savedRequestMap; QLinkedList< InfoPluginPtr > determineOrderedMatches( const InfoType type ) const; From 18aba6856b5aec4d60627739b96897ba30e989f7 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Thu, 7 Jul 2011 02:52:31 +0200 Subject: [PATCH 81/86] Use CPack for building the windows installer --- CMakeLists.txt | 16 +- CMakeModules/NSIS.InstallOptions.ini.in | 24 + CMakeModules/NSIS.template.in | 665 ++++++++++++++++++++++++ CPack.cmake | 52 ++ CPackOptions.cmake.in | 73 +++ 5 files changed, 826 insertions(+), 4 deletions(-) create mode 100644 CMakeModules/NSIS.InstallOptions.ini.in create mode 100644 CMakeModules/NSIS.template.in create mode 100644 CPack.cmake create mode 100644 CPackOptions.cmake.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 22f979886..7ee0e1824 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,15 +11,23 @@ ENDIF( ${CMAKE_VERSION} VERSION_GREATER 2.8.3 ) SET( TOMAHAWK_ORGANIZATION_NAME "Tomahawk" ) SET( TOMAHAWK_ORGANIZATION_DOMAIN "tomahawk-player.org" ) SET( TOMAHAWK_APPLICATION_NAME "Tomahawk" ) -SET( TOMAHAWK_VERSION "0.1.0" ) +SET( TOMAHAWK_DESCRIPTION_SUMMARY "The social media player" ) + +SET( TOMAHAWK_VERSION_MAJOR 0 ) +SET( TOMAHAWK_VERSION_MINOR 1 ) +SET( TOMAHAWK_VERSION_PATCH 0 ) +SET( TOMAHAWK_VERSION ${TOMAHAWK_VERSION_MAJOR}.${TOMAHAWK_VERSION_MINOR}.${TOMAHAWK_VERSION_PATCH} ) # set paths SET( CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" "${CMAKE_SOURCE_DIR}/CMakeModules" ) SET( THIRDPARTY_DIR ${CMAKE_SOURCE_DIR}/thirdparty ) -SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}") -SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}") -SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}") +SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" ) +SET( CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" ) +SET( CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" ) + +# installer creation +INCLUDE( CPack.cmake ) # Check if we need qtgui: IF( "${gui}" STREQUAL "no" ) diff --git a/CMakeModules/NSIS.InstallOptions.ini.in b/CMakeModules/NSIS.InstallOptions.ini.in new file mode 100644 index 000000000..566c0b47d --- /dev/null +++ b/CMakeModules/NSIS.InstallOptions.ini.in @@ -0,0 +1,24 @@ +[Settings] +NumFields=3 + +[Field 1] +Type=Label +Left=0 +Right=-1 +Top=0 +Bottom=24 + +[Field 2] +Type=RadioButton +Left=30 +Right=-1 +Top=50 +Bottom=58 +State=1 + +[Field 3] +Type=RadioButton +Left=30 +Right=-1 +Top=70 +Bottom=78 diff --git a/CMakeModules/NSIS.template.in b/CMakeModules/NSIS.template.in new file mode 100644 index 000000000..1a0b0d6ec --- /dev/null +++ b/CMakeModules/NSIS.template.in @@ -0,0 +1,665 @@ +;Tomahawk installer script. + +;----------------------------------------------------------------------------- +; Some installer script options (comment-out options not required) +;----------------------------------------------------------------------------- +;!define OPTION_LICENSE_AGREEMENT +!define OPTION_UAC_PLUGIN_ENHANCED +!define OPTION_SECTION_SC_START_MENU +!define OPTION_SECTION_SC_DESKTOP +!define OPTION_SECTION_SC_QUICK_LAUNCH +!define OPTION_FINISHPAGE +!define OPTION_FINISHPAGE_LAUNCHER +!define OPTION_FINISHPAGE_RELEASE_NOTES + +;----------------------------------------------------------------------------- +; Some paths. +;----------------------------------------------------------------------------- +!ifndef MING_PATH + !define MING_PATH "/usr/i686-w64-mingw32/sys-root/mingw" +!endif +!define MING_BIN "${MING_PATH}/bin" +!define MING_LIB "${MING_PATH}/lib" +!define BUILD_PATH "@CMAKE_BINARY_DIR@" +!define QT_DLL_PATH "${MING_BIN}" +!define SQLITE_DLL_PATH "${MING_LIB}/qt4/plugins/sqldrivers" +!define IMAGEFORMATS_DLL_PATH "${MING_LIB}/qt4/plugins/imageformats" +!define VLC_PLUGIN_PATH "${MING_LIB}\vlc\plugins" +!define NSI_PATH "@CMAKE_SOURCE_DIR@/admin/win/nsi" + +;----------------------------------------------------------------------------- +; Increment installer revision number as part of this script. +;----------------------------------------------------------------------------- +!define /file REVISION_LAST ${NSI_PATH}/revision.txt +!define /math REVISION ${REVISION_LAST} + 1 +!delfile revision.txt +!appendfile revision.txt ${REVISION} + +!define VER_MAJOR "@CPACK_PACKAGE_VERSION_MAJOR@" +!define VER_MINOR "@CPACK_PACKAGE_VERSION_MINOR@" +!define VER_BUILD "@CPACK_PACKAGE_VERSION_PATCH@" +!define VERSION "@CPACK_PACKAGE_VERSION@" + +;----------------------------------------------------------------------------- +; Installer build timestamp. +;----------------------------------------------------------------------------- +!define /date BUILD_TIME "built on %Y/%m/%d at %I:%M %p (rev. ${REVISION})" + +;----------------------------------------------------------------------------- +; Initial installer setup and definitions. +;----------------------------------------------------------------------------- +Name "@CPACK_NSIS_PACKAGE_NAME@" +Caption "Tomahawk Installer" +BrandingText "Tomahawk ${VERSION} -- ${BUILD_TIME}" +OutFile "@CPACK_TOPLEVEL_DIRECTORY@/@CPACK_OUTPUT_FILE_NAME@" +InstallDir "$PROGRAMFILES\@CPACK_PACKAGE_INSTALL_DIRECTORY@" +InstallDirRegKey HKCU "Software\Tomahawk" "" +InstType Standard +InstType Full +InstType Minimal +CRCCheck On +SetCompressor @CPACK_NSIS_COMPRESSOR@ +RequestExecutionLevel user ;Now using the UAC plugin. +ReserveFile NSIS.InstallOptions.ini +ReserveFile "${NSISDIR}\Plugins\InstallOptions.dll" + +@CPACK_NSIS_SECTION_SELECTED_VARS@ + +;----------------------------------------------------------------------------- +; Include some required header files. +;----------------------------------------------------------------------------- +!include LogicLib.nsh ;Used by APPDATA uninstaller. +!include nsDialogs.nsh ;Used by APPDATA uninstaller. +!include MUI2.nsh ;Used by APPDATA uninstaller. +!include InstallOptions.nsh ;Required by MUI2 to support old MUI_INSTALLOPTIONS. +!include Memento.nsh ;Remember user selections. +!include WinVer.nsh ;Windows version detection. +!include WordFunc.nsh ;Used by VersionCompare macro function. +!include UAC.nsh ;Used by the UAC elevation to install as user or admin. + +;----------------------------------------------------------------------------- +; Memento selections stored in registry. +;----------------------------------------------------------------------------- +!define MEMENTO_REGISTRY_ROOT HKLM +!define MEMENTO_REGISTRY_KEY Software\Microsoft\Windows\CurrentVersion\Uninstall\Tomahawk + +;----------------------------------------------------------------------------- +; Modern User Interface (MUI) defintions and setup. +;----------------------------------------------------------------------------- +!define MUI_ABORTWARNING +!define MUI_ICON ${NSI_PATH}\installer.ico +!define MUI_UNICON ${NSI_PATH}\installer.ico +!define MUI_WELCOMEFINISHPAGE_BITMAP ${NSI_PATH}\welcome.bmp +!define MUI_WELCOMEPAGE_TITLE "@CPACK_PACKAGE_NAME@ ${VERSION} Setup$\r$\nInstaller Build Revision ${REVISION}" +!define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the installation.$\r$\n$\r$\n$_CLICK" +!define MUI_HEADERIMAGE +!define MUI_HEADERIMAGE_BITMAP ${NSI_PATH}\page_header.bmp +!define MUI_COMPONENTSPAGE_SMALLDESC +!define MUI_FINISHPAGE_TITLE "@CPACK_PACKAGE_NAME@ Install Completed" +!define MUI_FINISHPAGE_LINK "Click here to visit the @CPACK_PACKAGE_NAME@ website." +!define MUI_FINISHPAGE_LINK_LOCATION "http://@TOMAHAWK_ORGANIZATION_DOMAIN@" +!define MUI_FINISHPAGE_NOREBOOTSUPPORT +!ifdef OPTION_FINISHPAGE_RELEASE_NOTES + !define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED + !define MUI_FINISHPAGE_SHOWREADME "$INSTDIR\NOTES.txt" + !define MUI_FINISHPAGE_SHOWREADME_TEXT "Show release notes" +!endif +!ifdef OPTION_FINISHPAGE_LAUNCHER + !define MUI_FINISHPAGE_NOAUTOCLOSE + !define MUI_FINISHPAGE_RUN + !define MUI_FINISHPAGE_RUN_FUNCTION "LaunchTomahawk" +!endif + +;----------------------------------------------------------------------------- +; Page macros. +;----------------------------------------------------------------------------- +!insertmacro MUI_PAGE_WELCOME +!ifdef OPTION_LICENSE_AGREEMENT + !insertmacro MUI_PAGE_LICENSE "LICENSE.txt" +!endif +Page custom PageReinstall PageLeaveReinstall +!insertmacro MUI_PAGE_COMPONENTS +!insertmacro MUI_PAGE_DIRECTORY +!insertmacro MUI_PAGE_INSTFILES +!ifdef OPTION_FINISHPAGE + !insertmacro MUI_PAGE_FINISH +!endif +!insertmacro MUI_UNPAGE_CONFIRM +UninstPage custom un.UnPageUserAppData un.UnPageUserAppDataLeave +!insertmacro MUI_UNPAGE_INSTFILES + +;----------------------------------------------------------------------------- +; Other MUI macros. +;----------------------------------------------------------------------------- +!insertmacro MUI_LANGUAGE "English" + +############################################################################## +# # +# FINISH PAGE LAUNCHER FUNCTIONS # +# # +############################################################################## + +Function LaunchTomahawk + ${UAC.CallFunctionAsUser} LaunchTomahawkAsUser +FunctionEnd + +Function LaunchTomahawkAsUser + Exec "$INSTDIR\tomahawk.exe" +FunctionEnd + +############################################################################## +# # +# PROCESS HANDLING FUNCTIONS AND MACROS # +# # +############################################################################## + +!macro CheckForProcess processName gotoWhenFound gotoWhenNotFound + Processes::FindProcess ${processName} + StrCmp $R0 "0" ${gotoWhenNotFound} ${gotoWhenFound} +!macroend + +!macro ConfirmEndProcess processName + MessageBox MB_YESNO|MB_ICONEXCLAMATION \ + "Found ${processName} process(s) which need to be stopped.$\nDo you want the installer to stop these for you?" \ + IDYES process_${processName}_kill IDNO process_${processName}_ended + process_${processName}_kill: + DetailPrint "Killing ${processName} processes." + Processes::KillProcess ${processName} + Sleep 1500 + StrCmp $R0 "1" process_${processName}_ended + DetailPrint "Process to kill not found!" + process_${processName}_ended: +!macroend + +!macro CheckAndConfirmEndProcess processName + !insertmacro CheckForProcess ${processName} 0 no_process_${processName}_to_end + !insertmacro ConfirmEndProcess ${processName} + no_process_${processName}_to_end: +!macroend + +Function EnsureTomahawkShutdown + !insertmacro CheckAndConfirmEndProcess "tomahawk.exe" +FunctionEnd + +############################################################################## +# # +# RE-INSTALLER FUNCTIONS # +# # +############################################################################## + +Function PageReinstall + ReadRegStr $R0 HKLM "Software\Tomahawk" "" + StrCmp $R0 "" 0 +2 + Abort + + ;Detect version + ReadRegDWORD $R0 HKLM "Software\Tomahawk" "VersionMajor" + IntCmp $R0 ${VER_MAJOR} minor_check new_version older_version + minor_check: + ReadRegDWORD $R0 HKLM "Software\Tomahawk" "VersionMinor" + IntCmp $R0 ${VER_MINOR} build_check new_version older_version + build_check: + ReadRegDWORD $R0 HKLM "Software\Tomahawk" "VersionBuild" + IntCmp $R0 ${VER_BUILD} revision_check new_version older_version + revision_check: + ReadRegDWORD $R0 HKLM "Software\Tomahawk" "VersionRevision" + IntCmp $R0 ${REVISION} same_version new_version older_version + + new_version: + !insertmacro INSTALLOPTIONS_WRITE "NSIS.InstallOptions.ini" "Field 1" "Text" "An older version of Tomahawk is installed on your system. It is recommended that you uninstall the current version before installing. Select the operation you want to perform and click Next to continue." + !insertmacro INSTALLOPTIONS_WRITE "NSIS.InstallOptions.ini" "Field 2" "Text" "Uninstall before installing" + !insertmacro INSTALLOPTIONS_WRITE "NSIS.InstallOptions.ini" "Field 3" "Text" "Do not uninstall" + !insertmacro MUI_HEADER_TEXT "Already Installed" "Choose how you want to install Tomahawk." + StrCpy $R0 "1" + Goto reinst_start + + older_version: + !insertmacro INSTALLOPTIONS_WRITE "NSIS.InstallOptions.ini" "Field 1" "Text" "A newer version of Tomahawk is already installed! It is not recommended that you install an older version. If you really want to install this older version, it is better to uninstall the current version first. Select the operation you want to perform and click Next to continue." + !insertmacro INSTALLOPTIONS_WRITE "NSIS.InstallOptions.ini" "Field 2" "Text" "Uninstall before installing" + !insertmacro INSTALLOPTIONS_WRITE "NSIS.InstallOptions.ini" "Field 3" "Text" "Do not uninstall" + !insertmacro MUI_HEADER_TEXT "Already Installed" "Choose how you want to install Tomahawk." + StrCpy $R0 "1" + Goto reinst_start + + same_version: + !insertmacro INSTALLOPTIONS_WRITE "NSIS.InstallOptions.ini" "Field 1" "Text" "Tomahawk ${VERSION} is already installed.\r\nSelect the operation you want to perform and click Next to continue." + !insertmacro INSTALLOPTIONS_WRITE "NSIS.InstallOptions.ini" "Field 2" "Text" "Add/Reinstall components" + !insertmacro INSTALLOPTIONS_WRITE "NSIS.InstallOptions.ini" "Field 3" "Text" "Uninstall Tomahawk" + !insertmacro MUI_HEADER_TEXT "Already Installed" "Choose the maintenance option to perform." + StrCpy $R0 "2" + + reinst_start: + !insertmacro INSTALLOPTIONS_DISPLAY "NSIS.InstallOptions.ini" +FunctionEnd + +Function PageLeaveReinstall + !insertmacro INSTALLOPTIONS_READ $R1 "NSIS.InstallOptions.ini" "Field 2" "State" + StrCmp $R0 "1" 0 +2 + StrCmp $R1 "1" reinst_uninstall reinst_done + StrCmp $R0 "2" 0 +3 + StrCmp $R1 "1" reinst_done reinst_uninstall + reinst_uninstall: + ReadRegStr $R1 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tomahawk" "UninstallString" + HideWindow + ClearErrors + ExecWait '$R1 _?=$INSTDIR' + IfErrors no_remove_uninstaller + IfFileExists "$INSTDIR\tomahawk.exe" no_remove_uninstaller + Delete $R1 + RMDir $INSTDIR + no_remove_uninstaller: + StrCmp $R0 "2" 0 +3 + UAC::Unload + Quit + BringToFront + reinst_done: +FunctionEnd + +############################################################################## +# # +# INSTALLER SECTIONS # +# # +############################################################################## +Section "Tomahawk Player" SEC_TOMAHAWK_PLAYER + SectionIn 1 2 3 RO + SetDetailsPrint listonly + + SetDetailsPrint textonly + DetailPrint "Installing Tomahawk Player essentials." + SetDetailsPrint listonly + SetOutPath "$INSTDIR" + + !ifdef INSTALL_PATH + ;Main executable. + File "${INSTALL_PATH}\bin\tomahawk.exe" + + File "${INSTALL_PATH}\bin\libqxtweb-standalone.dll" + File "${INSTALL_PATH}\bin\libtomahawk_portfwd.dll" + File "${INSTALL_PATH}\bin\libtomahawk_lastfm2.dll" + File "${INSTALL_PATH}\bin\libtomahawklib.dll" + File "${INSTALL_PATH}\lib\libtomahawk_sip*.dll" + !endif + !ifndef INSTALL_PATH + ;Main executable. + File "${BUILD_PATH}\tomahawk.exe" + + File "${BUILD_PATH}\libtomahawklib.dll" + File "${BUILD_PATH}\libqxtweb-standalone.dll" + File "${BUILD_PATH}\libtomahawk_portfwd.dll" + File "${BUILD_PATH}\libtomahawk_lastfm2.dll" + File "${BUILD_PATH}\libtomahawk_sip*.dll" + !endif + + ;License & release notes. + File "@CPACK_RESOURCE_FILE_LICENSE@" + File /oname=NOTES.txt ${NSI_PATH}\RELEASE_NOTES.txt + + ;QT stuff: + File "${QT_DLL_PATH}\QtCore4.dll" + File "${QT_DLL_PATH}\QtGui4.dll" + File "${QT_DLL_PATH}\QtNetwork4.dll" + File "${QT_DLL_PATH}\QtSql4.dll" + File "${QT_DLL_PATH}\QtXml4.dll" + File "${QT_DLL_PATH}\QtWebKit4.dll" + + ;SQLite driver + SetOutPath "$INSTDIR\sqldrivers" + File "${SQLITE_DLL_PATH}\qsqlite4.dll" + SetOutPath "$INSTDIR" + + ;Image plugins + SetOutPath "$INSTDIR\imageformats" + File "${IMAGEFORMATS_DLL_PATH}\qgif4.dll" + File "${IMAGEFORMATS_DLL_PATH}\qjpeg4.dll" + SetOutPath "$INSTDIR" + + ;Cygwin/c++ stuff + ;File "${MING_BIN}\cygmad-0.dll" + ;File "${MING_BIN}\libgcc_s_dw2-1.dll" + ;File "${MING_BIN}\mingwm10.dll" + File "${MING_BIN}\libgcc_s_sjlj-1.dll" + File "${MING_BIN}\libstdc++-6.dll" + + ;Phonon stuff + + ;Fix the phonon build to not use Dbus + File "${QT_DLL_PATH}\QtDbus4.dll" + File "${MING_BIN}\libdbus-1-3.dll" + File "${MING_BIN}\dbus-daemon.exe" + + File "${MING_BIN}\libphonon.dll" + SetOutPath "$INSTDIR\phonon_backend" + File "${MING_BIN}\phonon_backend\phonon_vlc.dll" + SetOutPath "$INSTDIR" + + ;VLC + ;SetOutPath "$INSTDIR\phonon_backend" + File "${MING_BIN}\libvlc.dll" + File "${MING_BIN}\libvlccore.dll" + SetOutPath "$INSTDIR\plugins" + File /r "${VLC_PLUGIN_PATH}\*.dll" + SetOutPath "$INSTDIR" + File "${MING_BIN}\libmad-0.dll" ; MP3 + File "${MING_BIN}\libFLAC-8.dll" ; FLAC + File "${MING_BIN}\libogg-0.dll" ; OGG, FLAC + File "${MING_BIN}\libvorbis-0.dll" ; OGG + File "${MING_BIN}\libvorbisenc-2.dll" ; OGG + + + + ; Other + File "${MING_BIN}\libqjson.dll" + File "${MING_BIN}\libtag.dll" + File "${MING_BIN}\libpng15-15.dll" + File "${MING_BIN}\libjpeg-8.dll" + File "${MING_BIN}\zlib1.dll" + + File "${MING_BIN}\libechonest.dll" + File "${MING_BIN}\libQTweetLib.dll" + + ; Jabber + File "${MING_BIN}\libjreen.dll" + File "${MING_BIN}\libqca.dll" + SetOutPath "$INSTDIR\crypto" + File "${MING_LIB}\qt4\plugins\crypto\libqca-ossl.dll" + SetOutPath "$INSTDIR" + File "${MING_BIN}\libssl-8.dll" + File "${MING_BIN}\libcrypto-8.dll" + + File "${MING_LIB}\libclucene-core.dll" + File "${MING_LIB}\libclucene-shared.dll" + + File "${MING_BIN}\libqtsparkle.dll" +SectionEnd + +SectionGroup "Shortcuts" + +!ifdef OPTION_SECTION_SC_START_MENU + ${MementoSection} "Start Menu Program Group" SEC_START_MENU + SectionIn 1 2 + SetDetailsPrint textonly + DetailPrint "Adding shortcuts for the Tomahawk program group to the Start Menu." + SetDetailsPrint listonly + SetShellVarContext all + RMDir /r "$SMPROGRAMS\Tomahawk" + CreateDirectory "$SMPROGRAMS\Tomahawk" + CreateShortCut "$SMPROGRAMS\Tomahawk\LICENSE.lnk" "$INSTDIR\LICENSE.txt" + CreateShortCut "$SMPROGRAMS\Tomahawk\Tomahawk.lnk" "$INSTDIR\tomahawk.exe" + CreateShortCut "$SMPROGRAMS\Tomahawk\Release notes.lnk" "$INSTDIR\NOTES.txt" + CreateShortCut "$SMPROGRAMS\Tomahawk\Uninstall.lnk" "$INSTDIR\uninstall.exe" + SetShellVarContext current + ${MementoSectionEnd} +!endif + +!ifdef OPTION_SECTION_SC_DESKTOP + ${MementoSection} "Desktop Shortcut" SEC_DESKTOP + SectionIn 1 2 + SetDetailsPrint textonly + DetailPrint "Creating Desktop Shortcuts" + SetDetailsPrint listonly + CreateShortCut "$DESKTOP\Tomahawk.lnk" "$INSTDIR\tomahawk.exe" + ${MementoSectionEnd} +!endif + +!ifdef OPTION_SECTION_SC_QUICK_LAUNCH + ${MementoSection} "Quick Launch Shortcut" SEC_QUICK_LAUNCH + SectionIn 1 2 + SetDetailsPrint textonly + DetailPrint "Creating Quick Launch Shortcut" + SetDetailsPrint listonly + CreateShortCut "$QUICKLAUNCH\Tomahawk.lnk" "$INSTDIR\tomahawk.exe" + ${MementoSectionEnd} +!endif + +SectionGroupEnd + +${MementoSectionDone} + +; Installer section descriptions +;-------------------------------- +!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN +!insertmacro MUI_DESCRIPTION_TEXT ${SEC_TOMAHAWK_PLAYER} "Tomahawk player essentials." +!insertmacro MUI_DESCRIPTION_TEXT ${SEC_START_MENU} "Tomahawk program group." +!insertmacro MUI_DESCRIPTION_TEXT ${SEC_DESKTOP} "Desktop shortcut for Tomahawk." +!insertmacro MUI_DESCRIPTION_TEXT ${SEC_QUICK_LAUNCH} "Quick Launch shortcut for Tomahawk." +!insertmacro MUI_FUNCTION_DESCRIPTION_END + +Section -post + + ;Uninstaller file. + SetDetailsPrint textonly + DetailPrint "Writing Uninstaller" + SetDetailsPrint listonly + WriteUninstaller $INSTDIR\uninstall.exe + + ;Registry keys required for installer version handling and uninstaller. + SetDetailsPrint textonly + DetailPrint "Writing Installer Registry Keys" + SetDetailsPrint listonly + + ;Version numbers used to detect existing installation version for comparisson. + WriteRegStr HKLM "Software\Tomahawk" "" $INSTDIR + WriteRegDWORD HKLM "Software\Tomahawk" "VersionMajor" "${VER_MAJOR}" + WriteRegDWORD HKLM "Software\Tomahawk" "VersionMinor" "${VER_MINOR}" + WriteRegDWORD HKLM "Software\Tomahawk" "VersionRevision" "${REVISION}" + WriteRegDWORD HKLM "Software\Tomahawk" "VersionBuild" "${VER_BUILD}" + + ;Add or Remove Programs entry. + WriteRegExpandStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tomahawk" "UninstallString" '"$INSTDIR\Uninstall.exe"' + WriteRegExpandStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tomahawk" "InstallLocation" "$INSTDIR" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tomahawk" "DisplayName" "Tomahawk" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tomahawk" "Publisher" "Tomahawk-player.org" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tomahawk" "DisplayIcon" "$INSTDIR\Uninstall.exe,0" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tomahawk" "DisplayVersion" "${VERSION}" + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tomahawk" "VersionMajor" "${VER_MAJOR}" + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tomahawk" "VersionMinor" "${VER_MINOR}.${REVISION}" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tomahawk" "URLInfoAbout" "http://tomahawk-player.org/" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tomahawk" "HelpLink" "http://tomahawk-player.org/" + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tomahawk" "NoModify" "1" + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tomahawk" "NoRepair" "1" + + ; Register tomahawk:// protocol handler + WriteRegStr HKCR "tomahawk" "" "URL: Tomahawk Protocol" + WriteRegStr HKCR "tomahawk\DefaultIcon" "" $INSTDIR\tomahawk.exe,1 + WriteRegStr HKCR "tomahawk\shell" "" "open" + WriteRegStr HKCR "tomahawk\shell\open\command" "" '"$INSTDIR\tomahawk.exe" "%1"' + + SetDetailsPrint textonly + DetailPrint "Finsihed." +SectionEnd + +############################################################################## +# # +# UNINSTALLER SECTION # +# # +############################################################################## + +Var UnPageUserAppDataDialog +Var UnPageUserAppDataCheckbox +Var UnPageUserAppDataCheckbox_State +Var UnPageUserAppDataEditBox + +Function un.UnPageUserAppData + !insertmacro MUI_HEADER_TEXT "Uninstall Tomahawk" "Remove Tomahawk's data folder from your computer." + nsDialogs::Create /NOUNLOAD 1018 + Pop $UnPageUserAppDataDialog + + ${If} $UnPageUserAppDataDialog == error + Abort + ${EndIf} + + ${NSD_CreateLabel} 0 0 100% 12u "Do you want to delete Tomahawk's data folder?" + Pop $0 + + ${NSD_CreateText} 0 13u 100% 12u "$LOCALAPPDATA\Tomahawk" + Pop $UnPageUserAppDataEditBox + SendMessage $UnPageUserAppDataEditBox ${EM_SETREADONLY} 1 0 + + ${NSD_CreateLabel} 0 46u 100% 24u "Leave unchecked to keep the data folder for later use or check to delete the data folder." + Pop $0 + + ${NSD_CreateCheckbox} 0 71u 100% 8u "Yes, delete this data folder." + Pop $UnPageUserAppDataCheckbox + + nsDialogs::Show +FunctionEnd + +Function un.UnPageUserAppDataLeave + ${NSD_GetState} $UnPageUserAppDataCheckbox $UnPageUserAppDataCheckbox_State +FunctionEnd + +Section Uninstall + IfFileExists "$INSTDIR\tomahawk.exe" tomahawk_installed + MessageBox MB_YESNO "It does not appear that Tomahawk is installed in the directory '$INSTDIR'.$\r$\nContinue anyway (not recommended)?" IDYES tomahawk_installed + Abort "Uninstall aborted by user" + tomahawk_installed: + + ;Delete registry keys. + DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tomahawk" + DeleteRegValue HKLM "Software\Tomahawk" "VersionBuild" + DeleteRegValue HKLM "Software\Tomahawk" "VersionMajor" + DeleteRegValue HKLM "Software\Tomahawk" "VersionMinor" + DeleteRegValue HKLM "Software\Tomahawk" "VersionRevision" + DeleteRegValue HKLM "Software\Tomahawk" "" + DeleteRegKey HKLM "Software\Tomahawk" + + DeleteRegKey HKCR "tomahawk" + + ;Start menu shortcuts. + !ifdef OPTION_SECTION_SC_START_MENU + SetShellVarContext all + RMDir /r "$SMPROGRAMS\Tomahawk" + SetShellVarContext current + !endif + + ;Desktop shortcut. + !ifdef OPTION_SECTION_SC_DESKTOP + IfFileExists "$DESKTOP\Tomahawk.lnk" 0 +2 + Delete "$DESKTOP\Tomahawk.lnk" + !endif + + ;Quick Launch shortcut. + !ifdef OPTION_SECTION_SC_QUICK_LAUNCH + IfFileExists "$QUICKLAUNCH\Tomahawk.lnk" 0 +2 + Delete "$QUICKLAUNCH\Tomahawk.lnk" + !endif + + ;Remove all the Program Files. + RMDir /r $INSTDIR + + ;Uninstall User Data if option is checked, otherwise skip. + ${If} $UnPageUserAppDataCheckbox_State == ${BST_CHECKED} + RMDir /r "$LOCALAPPDATA\Tomahawk" + ${EndIf} + + SetDetailsPrint textonly + DetailPrint "Finsihed." +SectionEnd + +############################################################################## +# # +# NSIS Installer Event Handler Functions # +# # +############################################################################## + +Function .onInit + !insertmacro INSTALLOPTIONS_EXTRACT "NSIS.InstallOptions.ini" + + ;Remove Quick Launch option from Windows 7, as no longer applicable - usually. + ${IfNot} ${AtMostWinVista} + SectionSetText ${SEC_QUICK_LAUNCH} "Quick Launch Shortcut (N/A)" + SectionSetFlags ${SEC_QUICK_LAUNCH} ${SF_RO} + SectionSetInstTypes ${SEC_QUICK_LAUNCH} 0 + ${EndIf} + + ${MementoSectionRestore} + + UAC_Elevate: + UAC::RunElevated + StrCmp 1223 $0 UAC_ElevationAborted ; UAC dialog aborted by user? + StrCmp 0 $0 0 UAC_Err ; Error? + StrCmp 1 $1 0 UAC_Success ;Are we the real deal or just the wrapper? + Quit + + UAC_Err: + MessageBox MB_ICONSTOP "Unable to elevate, error $0" + Abort + + UAC_ElevationAborted: + Abort + + UAC_Success: + StrCmp 1 $3 +4 ;Admin? + StrCmp 3 $1 0 UAC_ElevationAborted ;Try again? + MessageBox MB_ICONSTOP "This installer requires admin access, try again" + goto UAC_Elevate + + ;Prevent multiple instances. + System::Call 'kernel32::CreateMutexA(i 0, i 0, t "tomahawkInstaller") i .r1 ?e' + Pop $R0 + StrCmp $R0 0 +3 + MessageBox MB_OK|MB_ICONEXCLAMATION "The installer is already running." + Abort + + ;Use available InstallLocation when possible. This is useful in the uninstaller + ;via re-install, which would otherwise use a default location - a bug. + ReadRegStr $R0 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tomahawk" "InstallLocation" + StrCmp $R0 "" SkipSetInstDir + StrCpy $INSTDIR $R0 + SkipSetInstDir: + + ;Shutdown Tomahawk in case Add/Remove re-installer option used. + Call EnsureTomahawkShutdown +FunctionEnd + +Function .onInstSuccess + ${MementoSectionSave} + UAC::Unload ;Must call unload! +FunctionEnd + +Function .onInstFailed + UAC::Unload ;Must call unload! +FunctionEnd + +############################################################################## +# # +# NSIS Uninstaller Event Handler Functions # +# # +############################################################################## + +Function un.onInit + UAC_Elevate: + UAC::RunElevated + StrCmp 1223 $0 UAC_ElevationAborted ; UAC dialog aborted by user? + StrCmp 0 $0 0 UAC_Err ; Error? + StrCmp 1 $1 0 UAC_Success ;Are we the real deal or just the wrapper? + Quit + + UAC_Err: + MessageBox MB_ICONSTOP "Unable to elevate, error $0" + Abort + + UAC_ElevationAborted: + Abort + + UAC_Success: + StrCmp 1 $3 +4 ;Admin? + StrCmp 3 $1 0 UAC_ElevationAborted ;Try again? + MessageBox MB_ICONSTOP "This uninstaller requires admin access, try again" + goto UAC_Elevate + + ;Prevent multiple instances. + System::Call 'kernel32::CreateMutexA(i 0, i 0, t "tomahawkUninstaller") i .r1 ?e' + Pop $R0 + StrCmp $R0 0 +3 + MessageBox MB_OK|MB_ICONEXCLAMATION "This uninstaller is already running." + Abort +FunctionEnd + +Function un.onUnInstSuccess + UAC::Unload ;Must call unload! +FunctionEnd + +Function un.onUnInstFailed + UAC::Unload ;Must call unload! +FunctionEnd diff --git a/CPack.cmake b/CPack.cmake new file mode 100644 index 000000000..0c480e279 --- /dev/null +++ b/CPack.cmake @@ -0,0 +1,52 @@ +INCLUDE( InstallRequiredSystemLibraries ) + +SET( CPACK_PACKAGE_CONTACT "Dominik Schmidt " ) + +SET( CPACK_PACKAGE_FILE_NAME tomahawk-${TOMAHAWK_VERSION} ) # Package file name without extension. Also a directory of installer cmake-2.5.0-Linux-i686 + +# CPACK_GENERATOR CPack generator to be used STGZ;TGZ;TZ +# CPACK_INCLUDE_TOPLEVEL_DIRECTORY Controls whether CPack adds a top-level directory, usually of the form ProjectName-Version-OS, to the top of package tree. 0 to disable, 1 to enable +# CPACK_INSTALL_CMAKE_PROJECTS List of four values: Build directory, Project Name, Project Component, Directory in the package /home/andy/vtk/CMake-bin;CMake;ALL;/ +SET( CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/README" ) # File used as a description of a project /path/to/project/ReadMe.txt +SET( CPACK_PACKAGE_DESCRIPTION_SUMMARY ${TOMAHAWK_DESCRIPTION_SUMMARY} ) # Description summary of a project +# CPACK_PACKAGE_EXECUTABLES List of pairs of executables and labels. Used by the NSIS generator to create Start Menu shortcuts. ccmake;CMake +SET( CPACK_PACKAGE_INSTALL_DIRECTORY ${TOMAHAWK_APPLICATION_NAME} ) # Installation directory on the target system -> C:\Program Files\fellody +SET( CPACK_PACKAGE_INSTALL_REGISTRY_KEY ${TOMAHAWK_APPLICATION_NAME} ) # Registry key used when installing this project CMake 2.5.0 +SET( CPACK_PACKAGE_NAME ${TOMAHAWK_APPLICATION_NAME} ) # Package name, defaults to the project name +SET( CPACK_PACKAGE_VENDOR ${TOMAHAWK_ORGANIZATION_NAME} ) # Package vendor name +SET( CPACK_PACKAGE_VERSION_MAJOR ${TOMAHAWK_VERSION_MAJOR} ) +SET( CPACK_PACKAGE_VERSION_MINOR ${TOMAHAWK_VERSION_MINOR} ) +SET( CPACK_PACKAGE_VERSION_PATCH ${TOMAHAWK_VERSION_PATCH} ) + +# CPACK_SOURCE_GENERATOR List of generators used for the source package TGZ;TZ +# CPACK_SOURCE_IGNORE_FILES Pattern of files in the source tree that won't be packaged /CVS/;/\\.svn/;\\.swp$;\\.#;/#;.*~;cscope.* +# CPACK_SOURCE_PACKAGE_FILE_NAME Name of the source package cmake-2.5.0 +# CPACK_SOURCE_STRIP_FILES List of files in the source tree that will be stripped. Starting with CMake 2.6.0 CPACK_SOURCE_STRIP_FILES will be a boolean variable which enables stripping of all files (a list of files evaluates to TRUE in CMake, so this change is compatible). +# CPACK_STRIP_FILES List of files to be stripped. Starting with CMake 2.6.0 CPACK_STRIP_FILES will be a boolean variable which enables stripping of all files (a list of files evaluates to TRUE in CMake, so this change is compatible). bin/ccmake;bin/cmake;bin/cpack;bin/ctest +# CPACK_SYSTEM_NAME System name, defaults to the value of ${CMAKE_SYSTEM_NAME}. Linux-i686 + +# Advanced settings +# CPACK_CMAKE_GENERATOR What CMake generator should be used if the project is CMake project. Defaults to the value of CMAKE_GENERATOR. Unix Makefiles +SET( CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE.txt" ) # License file for the project, used by the STGZ, NSIS, and PackageMaker generators. /home/andy/vtk/CMake/Copyright.txt +# CPACK_RESOURCE_FILE_README ReadMe file for the project, used by PackageMaker generator. /home/andy/vtk/CMake/Templates/CPack.GenericDescription.txt +# CPACK_RESOURCE_FILE_WELCOME Welcome file for the project, used by PackageMaker generator. /home/andy/vtk/CMake/Templates/CPack.GenericWelcome.txt +SET( CPACK_PACKAGE_VERSION ${TOMAHAWK_VERSION} ) + +# CPACK_TOPLEVEL_TAG Directory for the installed files. Linux-i686 +# CPACK_INSTALL_COMMANDS Extra commands to install components. +# CPACK_INSTALL_DIRECTORIES Extra directories to install. +# CPACK_MONOLITHIC_INSTALL When set disables the component-based installer. +# CPACK_PACKAGING_INSTALL_PREFIX Sets the default root that the generated package installs into, '/usr' is the default for the debian and redhat generators /usr/local + +## +# INSTALL DEPS +## + + + +# Set the options file that needs to be included inside CMakeCPackOptions.cmake +#SET(QT_DIALOG_CPACK_OPTIONS_FILE ${CMake_BINARY_DIR}/Source/QtDialog/QtDialogCPack.cmake) +configure_file("${CMAKE_SOURCE_DIR}/CPackOptions.cmake.in" + "${CMAKE_BINARY_DIR}/CPackOptions.cmake" @ONLY) +set(CPACK_PROJECT_CONFIG_FILE "${CMAKE_BINARY_DIR}/CPackOptions.cmake") # File included at cpack time, once per generator after setting CPACK_GENERATOR to the actual generator being used; allows per-generator setting of CPACK_* variables at cpack time. ${PROJECT_BINARY_DIR}/CPackOptions.cmake +include(CPack) diff --git a/CPackOptions.cmake.in b/CPackOptions.cmake.in new file mode 100644 index 000000000..8084cf9aa --- /dev/null +++ b/CPackOptions.cmake.in @@ -0,0 +1,73 @@ +# This file is configured at cmake time, and loaded at cpack time. +# To pass variables to cpack from cmake, they must be configured +# in this file. + +if(CPACK_GENERATOR MATCHES "NSIS") + #SET(CPACK_NSIS_INSTALL_ROOT "@CPACK_NSIS_INSTALL_ROOT@") + + # set the install/unistall icon used for the installer itself + # There is a bug in NSI that does not handle full unix paths properly. + #SET(CPACK_NSIS_MUI_ICON "@CMake_SOURCE_DIR@/Utilities/Release\\CMakeLogo.ico") + #SET(CPACK_NSIS_MUI_UNIICON "@CMake_SOURCE_DIR@/Utilities/Release\\CMakeLogo.ico") + # set the package header icon for MUI + #SET(CPACK_PACKAGE_ICON "@CMake_SOURCE_DIR@/Utilities/Release\\CMakeInstall.bmp") + # tell cpack to create links to the doc files + #SET(CPACK_NSIS_MENU_LINKS + # "doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/cmake-gui.html" "cmake-gui Help" + # "doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/cmake.html" "CMake Help" + # "doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/cmake-properties.html" + # "CMake Properties and Variables Help" + # "doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/ctest.html" "CTest Help" + # "doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/cmake-modules.html" "CMake Modules Help" + # "doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/cmake-commands.html" "CMake Commands Help" + # "doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/cpack.html" "CPack Help" + # "http://www.cmake.org" "CMake Web Site" + # ) + # Use the icon from cmake-gui for add-remove programs + #SET(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\cmake-gui.exe") + # + #SET(CPACK_NSIS_PACKAGE_NAME "@CPACK_NSIS_PACKAGE_NAME@") + #SET(CPACK_NSIS_DISPLAY_NAME "@CPACK_NSIS_PACKAGE_NAME@, a cross-platform, open-source build system") + #SET(CPACK_NSIS_HELP_LINK "http://www.cmake.org") + #SET(CPACK_NSIS_URL_INFO_ABOUT "http://www.kitware.com") + #SET(CPACK_NSIS_CONTACT @CPACK_PACKAGE_CONTACT@) + #SET(CPACK_NSIS_MODIFY_PATH ON) + + + +##### all options +#CPACK_NSIS_MUI_ICON The icon file (.ico) for the generated install program. Both this and CPACK_NSIS_MUI_UNIICON need to set for this to have any effect. installer.ico +#CPACK_NSIS_MUI_UNIICON The icon file (.ico) for the generated uninstall program. Both this and CPACK_NSIS_MUI_ICON need to set for this to have any effect. uninstaller.ico +SET( CPACK_PACKAGE_ICON @CMAKE_SOURCE_DIR@/admin/win/nsi/installer.ico ) # A branding image that will be displayed on the top bar inside the installer. installer.bmp +#CPACK_NSIS_EXTRA_INSTALL_COMMANDS Extra NSIS commands that will be added to the install Section. ExecWait '\\\"$INSTDIR\\\\vcredist_x86.exe\\\" /q:a' +#CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS Extra NSIS commands that will be added to the uninstall Section. +SET( CPACK_NSIS_COMPRESSOR "/SOLID lzma" ) # The arguments that will be passed to the NSIS SetCompressor command. /SOLID lzma +#CPACK_NSIS_MODIFY_PATH If this is set to "ON", then an extra page will appear in the installer that will allow the user to choose whether the program directory should be added to the system PATH variable. ON +#CPACK_NSIS_DISPLAY_NAME Undocumented. "${CPACK_PACKAGE_INSTALL_DIRECTORY} My Famous Project" +#CPACK_NSIS_INSTALLED_ICON_NAME Set the icon used for the Windows "Add or Remove Programs" tool. "bin\\\\MyExecutable.exe" +#CPACK_NSIS_HELP_LINK Adds link to registry. URI. "http:\\\\\\\\www.my-project-home-page.org" +#CPACK_NSIS_URL_INFO_ABOUT Adds link to registry and the vendor in add/remove programs' "Click here for support information" in program entry links here. "http:\\\\\\\\www.my-personal-home-page.com" +#CPACK_NSIS_CONTACT Adds link to add/remove programs' "Click here for support information" in program entry. "me@my-personal-home-page.com" +#CPACK_NSIS_CREATE_ICONS_EXTRA Additional NSIS commands for creating start menu shortcuts. set(CPACK_NSIS_CREATE_ICONS "CreateShortCut '\$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\${PROJECT_NAME}.lnk' '\$INSTDIR\\\\${PROJECT_NAME}.exe'") +#CPACK_NSIS_DELETE_ICONS_EXTRA Undocumented. Possibly: Additional NSIS commands to uninstall start menu shortcuts. +#CPACK_NSIS_MENU_LINKS Used to override the Start Menu links. "doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/CMakeSetup.html" "CMakeSetup Help" +#CPACK_NSIS_MUI_FINISHPAGE_RUN If used, will make it possible for user to choose (on an additional page, displayed at the end of the installation) to run intalled program. Should point to program name to run, seemingly without any sub-directories of the installation directory in case program installed in such sub-directories (but please check generated NSIS script if you can't make it work). "MyExecutable.exe" + +endif(CPACK_GENERATOR MATCHES "NSIS") + +## include the cpack options for qt dialog if they exisit +## they might not if qt was not enabled for the build +#INCLUDE("@QT_DIALOG_CPACK_OPTIONS_FILE@" OPTIONAL) + + +#if("${CPACK_GENERATOR}" STREQUAL "PackageMaker") +# if(CMAKE_PACKAGE_QTGUI) +# set(CPACK_PACKAGE_DEFAULT_LOCATION "/Applications") +# else(CMAKE_PACKAGE_QTGUI) +# set(CPACK_PACKAGE_DEFAULT_LOCATION "/usr") +# endif(CMAKE_PACKAGE_QTGUI) +#endif("${CPACK_GENERATOR}" STREQUAL "PackageMaker") + + +SET( CMAKE_SOURCE_DIR @CMAKE_SOURCE_DIR@ ) +SET( CMAKE_BINARY_DIR @CMAKE_BINARY_DIR@ ) \ No newline at end of file From 7c5d6033d42629416dab48672b99f291f82a226e Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Thu, 7 Jul 2011 03:18:12 +0200 Subject: [PATCH 82/86] Add date and git revision to non-release package names --- CMakeLists.txt | 23 ++++++++++++++++- CMakeModules/CMakeVersionSource.cmake | 37 +++++++++++++++++++++++++++ CMakeModules/kwsysDateStamp.cmake | 21 +++++++++++++++ 3 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 CMakeModules/CMakeVersionSource.cmake create mode 100644 CMakeModules/kwsysDateStamp.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 7ee0e1824..83c342cd7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,6 @@ PROJECT( tomahawk ) CMAKE_MINIMUM_REQUIRED( VERSION 2.8 ) +SET( CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" "${CMAKE_SOURCE_DIR}/CMakeModules" ) IF( ${CMAKE_VERSION} VERSION_GREATER 2.8.3 ) CMAKE_POLICY(SET CMP0017 NEW) @@ -16,11 +17,31 @@ SET( TOMAHAWK_DESCRIPTION_SUMMARY "The social media player" ) SET( TOMAHAWK_VERSION_MAJOR 0 ) SET( TOMAHAWK_VERSION_MINOR 1 ) SET( TOMAHAWK_VERSION_PATCH 0 ) + +# SET( TOMAHAWK_VERSION_RC 0 ) + +IF( NOT CMAKE_BUILD_TYPE STREQUAL "Release" ) + # Use the date as the tweak level. + INCLUDE( ${CMAKE_MODULE_PATH}/kwsysDateStamp.cmake ) + SET( TOMAHAWK_VERSION_TWEAK "${KWSYS_DATE_STAMP_YEAR}${KWSYS_DATE_STAMP_MONTH}${KWSYS_DATE_STAMP_DAY}" ) + INCLUDE( ${CMAKE_MODULE_PATH}/CMakeVersionSource.cmake ) +ENDIF() + SET( TOMAHAWK_VERSION ${TOMAHAWK_VERSION_MAJOR}.${TOMAHAWK_VERSION_MINOR}.${TOMAHAWK_VERSION_PATCH} ) +IF( ${TOMAHAWK_VERSION_TWEAK} GREATER 0) + SET( TOMAHAWK_VERSION ${TOMAHAWK_VERSION}.${TOMAHAWK_VERSION_TWEAK} ) +ENDIF() +IF( TOMAHAWK_VERSION_RC ) + SET( CMake_VERSION ${TOMAHAWK_VERSION}-rc${TOMAHAWK_VERSION_RC} ) +ENDIF() +IF( CMAKE_VERSION_SOURCE ) + SET( TOMAHAWK_VERSION ${TOMAHAWK_VERSION}-${CMAKE_VERSION_SOURCE} ) +ENDIF() + + # set paths -SET( CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" "${CMAKE_SOURCE_DIR}/CMakeModules" ) SET( THIRDPARTY_DIR ${CMAKE_SOURCE_DIR}/thirdparty ) SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" ) SET( CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" ) diff --git a/CMakeModules/CMakeVersionSource.cmake b/CMakeModules/CMakeVersionSource.cmake new file mode 100644 index 000000000..acc177a75 --- /dev/null +++ b/CMakeModules/CMakeVersionSource.cmake @@ -0,0 +1,37 @@ +# Try to identify the current development source version. +set(CMAKE_VERSION_SOURCE "") +if(EXISTS ${CMAKE_SOURCE_DIR}/.git/HEAD) + find_program(GIT_EXECUTABLE NAMES git git.cmd) + mark_as_advanced(GIT_EXECUTABLE) + if(GIT_EXECUTABLE) + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse --verify -q --short=4 HEAD + OUTPUT_VARIABLE head + OUTPUT_STRIP_TRAILING_WHITESPACE + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + ) + if(head) + set(CMAKE_VERSION_SOURCE "g${head}") + execute_process( + COMMAND ${GIT_EXECUTABLE} update-index -q --refresh + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + ) + execute_process( + COMMAND ${GIT_EXECUTABLE} diff-index --name-only HEAD -- + OUTPUT_VARIABLE dirty + OUTPUT_STRIP_TRAILING_WHITESPACE + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + ) + if(dirty) + set(CMAKE_VERSION_SOURCE "${CMAKE_VERSION_SOURCE}-dirty") + endif() + endif() + endif() +elseif(EXISTS ${CMAKE_SOURCE_DIR}/CVS/Repository) + file(READ ${CMAKE_SOURCE_DIR}/CVS/Repository repo) + set(branch "") + if("${repo}" MATCHES "\\.git/") + string(REGEX REPLACE ".*\\.git/([^\r\n]*).*" "-\\1" branch "${repo}") + endif() + set(CMAKE_VERSION_SOURCE "cvs${branch}") +endif() diff --git a/CMakeModules/kwsysDateStamp.cmake b/CMakeModules/kwsysDateStamp.cmake new file mode 100644 index 000000000..f17c56cec --- /dev/null +++ b/CMakeModules/kwsysDateStamp.cmake @@ -0,0 +1,21 @@ +# Do not edit! Generated by kwsysDateStamp.py +#============================================================================= +# KWSys - Kitware System Library +# Copyright 2000-2009 Kitware, Inc., Insight Software Consortium +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= + +# KWSys version date year component. Format is CCYY. +SET(KWSYS_DATE_STAMP_YEAR 2011) + +# KWSys version date month component. Format is MM. +SET(KWSYS_DATE_STAMP_MONTH 07) + +# KWSys version date day component. Format is DD. +SET(KWSYS_DATE_STAMP_DAY 06) From a634d091267d8b6f825c7648d2f5b1df944a49bd Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Thu, 7 Jul 2011 04:16:28 +0200 Subject: [PATCH 83/86] cpack: build proper source tarballs --- CPack.cmake | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/CPack.cmake b/CPack.cmake index 0c480e279..1573c1b2c 100644 --- a/CPack.cmake +++ b/CPack.cmake @@ -19,8 +19,10 @@ SET( CPACK_PACKAGE_VERSION_MINOR ${TOMAHAWK_VERSION_MINOR} ) SET( CPACK_PACKAGE_VERSION_PATCH ${TOMAHAWK_VERSION_PATCH} ) # CPACK_SOURCE_GENERATOR List of generators used for the source package TGZ;TZ -# CPACK_SOURCE_IGNORE_FILES Pattern of files in the source tree that won't be packaged /CVS/;/\\.svn/;\\.swp$;\\.#;/#;.*~;cscope.* -# CPACK_SOURCE_PACKAGE_FILE_NAME Name of the source package cmake-2.5.0 + +SET( CPACK_SOURCE_GENERATOR TGZ ) +SET( CPACK_SOURCE_IGNORE_FILES "/\\\\.git/" ".*~$" ".kate-swp$" "/build_dir/" "/clang/" "/gcc/" "/build/" "/win/" ) # Pattern of files in the source tree that won't be packaged +SET( CPACK_SOURCE_PACKAGE_FILE_NAME tomahawk-${TOMAHAWK_VERSION} ) # Name of the source package # CPACK_SOURCE_STRIP_FILES List of files in the source tree that will be stripped. Starting with CMake 2.6.0 CPACK_SOURCE_STRIP_FILES will be a boolean variable which enables stripping of all files (a list of files evaluates to TRUE in CMake, so this change is compatible). # CPACK_STRIP_FILES List of files to be stripped. Starting with CMake 2.6.0 CPACK_STRIP_FILES will be a boolean variable which enables stripping of all files (a list of files evaluates to TRUE in CMake, so this change is compatible). bin/ccmake;bin/cmake;bin/cpack;bin/ctest # CPACK_SYSTEM_NAME System name, defaults to the value of ${CMAKE_SYSTEM_NAME}. Linux-i686 @@ -32,8 +34,7 @@ SET( CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE.txt" ) # License f # CPACK_RESOURCE_FILE_WELCOME Welcome file for the project, used by PackageMaker generator. /home/andy/vtk/CMake/Templates/CPack.GenericWelcome.txt SET( CPACK_PACKAGE_VERSION ${TOMAHAWK_VERSION} ) -# CPACK_TOPLEVEL_TAG Directory for the installed files. Linux-i686 -# CPACK_INSTALL_COMMANDS Extra commands to install components. +SET( CPACK_TOPLEVEL_TAG "narf" ) # Directory for the installed files. - needed to provide anything to avoid an error# CPACK_INSTALL_COMMANDS Extra commands to install components. # CPACK_INSTALL_DIRECTORIES Extra directories to install. # CPACK_MONOLITHIC_INSTALL When set disables the component-based installer. # CPACK_PACKAGING_INSTALL_PREFIX Sets the default root that the generated package installs into, '/usr' is the default for the debian and redhat generators /usr/local From dd311d99c4f84e28275d2bf84e0b7fc207012ac5 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Thu, 7 Jul 2011 04:18:18 +0200 Subject: [PATCH 84/86] Add more build dirs to the .gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index e3f800ccc..8a9671a2c 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,6 @@ moc_* thirdparty/qtweetlib/WARNING-twitter-api-keys .kdev4 tomahawk.kdev4 +clang/ +win/ +gcc/ From d7950472bc55a0271d8d9f9977af126b877d059f Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Wed, 6 Jul 2011 22:50:11 -0400 Subject: [PATCH 85/86] Fix Mac compilation --- .../infosystem/infoplugins/mac/adiumplugin.cpp | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/libtomahawk/infosystem/infoplugins/mac/adiumplugin.cpp b/src/libtomahawk/infosystem/infoplugins/mac/adiumplugin.cpp index c2da08fb5..278dfd500 100644 --- a/src/libtomahawk/infosystem/infoplugins/mac/adiumplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/mac/adiumplugin.cpp @@ -74,6 +74,7 @@ AdiumPlugin::AdiumPlugin() this, SLOT( clearStatus() ) ); } + AdiumPlugin::~AdiumPlugin() { qDebug() << Q_FUNC_INFO; @@ -81,6 +82,7 @@ AdiumPlugin::~AdiumPlugin() setStatus( "" ); } + void AdiumPlugin::clearStatus() { @@ -88,6 +90,7 @@ AdiumPlugin::clearStatus() setStatus( "" ); } + void AdiumPlugin::settingsChanged() { @@ -96,18 +99,6 @@ AdiumPlugin::settingsChanged() setStatus( "" ); } -void -AdiumPlugin::getInfo( const QString caller, const InfoType type, const QVariant data, QVariantMap customData ) -{ - switch (type) - { - default: - { - emit info(caller, Tomahawk::InfoSystem::InfoNoInfo, QVariant(), QVariant(), customData); - return; - } - } -} void AdiumPlugin::pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input ) From e0b559714931978977201171e1ec4e6303ae0d3e Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Thu, 7 Jul 2011 09:33:43 -0400 Subject: [PATCH 86/86] Huge overhaul of InfoSystem, using InfoRequestData structs to pass things around, making it far more clean (and easier to extend in the future) --- src/audiocontrols.cpp | 23 +-- src/audiocontrols.h | 2 +- src/libtomahawk/audio/audioengine.cpp | 24 +-- src/libtomahawk/audio/audioengine.h | 2 +- .../infoplugins/generic/echonestplugin.cpp | 134 ++++++-------- .../infoplugins/generic/echonestplugin.h | 25 ++- .../infoplugins/generic/lastfmplugin.cpp | 175 +++++++----------- .../infoplugins/generic/lastfmplugin.h | 16 +- .../infoplugins/generic/musixmatchplugin.cpp | 52 +++--- .../infoplugins/generic/musixmatchplugin.h | 13 +- .../infoplugins/mac/adiumplugin.cpp | 2 +- .../infosystem/infoplugins/mac/adiumplugin.h | 16 +- .../infoplugins/unix/fdonotifyplugin.cpp | 2 +- .../infoplugins/unix/fdonotifyplugin.h | 16 +- src/libtomahawk/infosystem/infosystem.cpp | 29 +-- src/libtomahawk/infosystem/infosystem.h | 19 +- .../infosystem/infosystemcache.cpp | 36 ++-- src/libtomahawk/infosystem/infosystemcache.h | 8 +- .../infosystem/infosystemworker.cpp | 72 +++---- src/libtomahawk/infosystem/infosystemworker.h | 8 +- src/libtomahawk/playlist/albummodel.cpp | 15 +- src/libtomahawk/playlist/albummodel.h | 2 +- src/libtomahawk/playlist/albumview.cpp | 10 +- src/libtomahawk/playlist/artistview.cpp | 10 +- src/libtomahawk/playlist/treemodel.cpp | 23 ++- src/libtomahawk/playlist/treemodel.h | 2 +- src/libtomahawk/sourceplaylistinterface.cpp | 1 - .../widgets/infowidgets/ArtistInfoWidget.cpp | 47 +++-- .../widgets/infowidgets/ArtistInfoWidget.h | 2 +- src/scrobbler.cpp | 22 ++- src/scrobbler.h | 2 +- src/tomahawkapp.cpp | 1 + 32 files changed, 377 insertions(+), 434 deletions(-) diff --git a/src/audiocontrols.cpp b/src/audiocontrols.cpp index 2a7a26355..f2ed4c808 100644 --- a/src/audiocontrols.cpp +++ b/src/audiocontrols.cpp @@ -167,8 +167,8 @@ AudioControls::AudioControls( QWidget* parent ) .scaled( ui->coverImage->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation ); connect( Tomahawk::InfoSystem::InfoSystem::instance(), - SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), - SLOT( infoSystemInfo( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ) ); + SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), + SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) ); connect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( finished( QString ) ), SLOT( infoSystemFinished( QString ) ) ); @@ -218,20 +218,21 @@ AudioControls::onPlaybackStarted( const Tomahawk::result_ptr& result ) trackInfo["artist"] = result->artist()->name(); trackInfo["album"] = result->album()->name(); - Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( - s_acInfoIdentifier, Tomahawk::InfoSystem::InfoAlbumCoverArt, - QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ), QVariantMap() ); + Tomahawk::InfoSystem::InfoRequestData requestData; + requestData.caller = s_acInfoIdentifier; + requestData.type = Tomahawk::InfoSystem::InfoAlbumCoverArt; + requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ); + requestData.customData = QVariantMap(); + + Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData ); } void -AudioControls::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, QVariantMap customData ) +AudioControls::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ) { - Q_UNUSED( input ); - Q_UNUSED( customData ); - - qDebug() << Q_FUNC_INFO << caller << type << s_acInfoIdentifier << Tomahawk::InfoSystem::InfoAlbumCoverArt; - if ( caller != s_acInfoIdentifier || type != Tomahawk::InfoSystem::InfoAlbumCoverArt ) + qDebug() << Q_FUNC_INFO << requestData.caller << requestData.type << s_acInfoIdentifier << Tomahawk::InfoSystem::InfoAlbumCoverArt; + if ( requestData.caller != s_acInfoIdentifier || requestData.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 d4753dede..b887d51f1 100644 --- a/src/audiocontrols.h +++ b/src/audiocontrols.h @@ -67,7 +67,7 @@ private slots: void onTrackClicked(); void onLoveButtonClicked( bool ); - void infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, QVariantMap customData ); + void infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ); void infoSystemFinished( QString target ); private: diff --git a/src/libtomahawk/audio/audioengine.cpp b/src/libtomahawk/audio/audioengine.cpp index 4d17fa930..464bcd748 100644 --- a/src/libtomahawk/audio/audioengine.cpp +++ b/src/libtomahawk/audio/audioengine.cpp @@ -256,8 +256,8 @@ AudioEngine::sendNowPlayingNotification() if ( ! m_infoSystemConnected ) { connect( Tomahawk::InfoSystem::InfoSystem::instance(), - SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), - SLOT( infoSystemInfo( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ) ); + SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), + SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) ); connect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( finished( QString ) ), SLOT( infoSystemFinished( QString ) ) ); @@ -267,24 +267,26 @@ AudioEngine::sendNowPlayingNotification() Tomahawk::InfoSystem::InfoCriteriaHash trackInfo; trackInfo["artist"] = m_currentTrack->album()->artist()->name(); trackInfo["album"] = m_currentTrack->album()->name(); + + Tomahawk::InfoSystem::InfoRequestData requestData; + requestData.caller = s_aeInfoIdentifier; + requestData.type = Tomahawk::InfoSystem::InfoAlbumCoverArt; + requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ); + requestData.customData = QVariantMap(); - Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( - s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoAlbumCoverArt, - QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ), QVariantMap() ); + Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData ); } void -AudioEngine::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, QVariantMap customData ) +AudioEngine::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ) { qDebug() << Q_FUNC_INFO; - Q_UNUSED( input ); - Q_UNUSED( customData ); - if ( caller != s_aeInfoIdentifier || - ( type != Tomahawk::InfoSystem::InfoAlbumCoverArt ) ) + if ( requestData.caller != s_aeInfoIdentifier || + requestData.type != Tomahawk::InfoSystem::InfoAlbumCoverArt ) { - qDebug() << Q_FUNC_INFO << " not desgined for us, caller is " << caller; + qDebug() << Q_FUNC_INFO << " not destined for us or wrong type, caller is " << requestData.caller << " and type is " << requestData.type; return; } diff --git a/src/libtomahawk/audio/audioengine.h b/src/libtomahawk/audio/audioengine.h index 41816efdf..571215edb 100644 --- a/src/libtomahawk/audio/audioengine.h +++ b/src/libtomahawk/audio/audioengine.h @@ -87,7 +87,7 @@ public slots: void playlistNextTrackReady(); - void infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, QVariantMap customData ); + void infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ); void infoSystemFinished( QString caller ); signals: diff --git a/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.cpp b/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.cpp index 99ca934d2..6e0f4d879 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.cpp @@ -66,37 +66,37 @@ EchoNestPlugin::namChangedSlot( QNetworkAccessManager *nam ) } void -EchoNestPlugin::getInfo( uint requestId, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) +EchoNestPlugin::getInfo( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData ) { - switch ( type ) + switch ( requestData.type ) { case Tomahawk::InfoSystem::InfoArtistBiography: - return getArtistBiography( requestId, caller, input, customData ); + return getArtistBiography( requestId, requestData ); case Tomahawk::InfoSystem::InfoArtistFamiliarity: - return getArtistFamiliarity( requestId, caller, input, customData ); + return getArtistFamiliarity( requestId, requestData ); case Tomahawk::InfoSystem::InfoArtistHotttness: - return getArtistHotttnesss( requestId, caller, input, customData ); + return getArtistHotttnesss( requestId, requestData ); case Tomahawk::InfoSystem::InfoArtistTerms: - return getArtistTerms( requestId, caller, input, customData ); + return getArtistTerms( requestId, requestData ); case Tomahawk::InfoSystem::InfoTrackEnergy: - return getSongProfile( requestId, caller, input, customData, "energy" ); + return getSongProfile( requestId, requestData, "energy" ); case Tomahawk::InfoSystem::InfoMiscTopTerms: - return getMiscTopTerms( requestId, caller, input, customData ); + return getMiscTopTerms( requestId, requestData ); default: { - emit info( requestId, caller, Tomahawk::InfoSystem::InfoNoInfo, QVariant(), QVariant(), customData ); + emit info( requestId, requestData, QVariant() ); return; } } } void -EchoNestPlugin::getSongProfile( uint requestId, const QString &caller, const QVariant &input, const QVariantMap &customData, const QString &item ) +EchoNestPlugin::getSongProfile( uint requestId, const Tomahawk::InfoSystem::InfoRequestData &requestData, const QString &item ) { //WARNING: Totally not implemented yet Q_UNUSED( item ); - if( !isValidTrackData( requestId, caller, input, customData ) ) + if( !isValidTrackData( requestId, requestData ) ) return; // Track track( input.toString() ); @@ -108,78 +108,68 @@ EchoNestPlugin::getSongProfile( uint requestId, const QString &caller, const QVa } void -EchoNestPlugin::getArtistBiography( uint requestId, const QString &caller, const QVariant &input, const QVariantMap &customData ) +EchoNestPlugin::getArtistBiography( uint requestId, const Tomahawk::InfoSystem::InfoRequestData &requestData ) { - if( !isValidArtistData( requestId, caller, input, customData ) ) + if( !isValidArtistData( requestId, requestData ) ) return; - Echonest::Artist artist( input.toString() ); + Echonest::Artist artist( requestData.input.toString() ); QNetworkReply *reply = artist.fetchBiographies(); reply->setProperty( "artist", QVariant::fromValue< Echonest::Artist >( artist ) ); - reply->setProperty( "input", input ); - reply->setProperty( "customData", customData ); - reply->setProperty( "caller", caller ); reply->setProperty( "requestId", requestId ); + reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) ); connect( reply, SIGNAL( finished() ), SLOT( getArtistBiographySlot() ) ); } void -EchoNestPlugin::getArtistFamiliarity( uint requestId, const QString &caller, const QVariant &input, const QVariantMap &customData ) +EchoNestPlugin::getArtistFamiliarity( uint requestId, const Tomahawk::InfoSystem::InfoRequestData &requestData ) { - if( !isValidArtistData( requestId, caller, input, customData ) ) + if( !isValidArtistData( requestId, requestData ) ) return; - qDebug() << "Fetching artist familiarity!" << input; - Echonest::Artist artist( input.toString() ); + qDebug() << "Fetching artist familiarity!" << requestData.input; + Echonest::Artist artist( requestData.input.toString() ); QNetworkReply* reply = artist.fetchFamiliarity(); reply->setProperty( "artist", QVariant::fromValue< Echonest::Artist >( artist ) ); - reply->setProperty( "input", input ); - reply->setProperty( "customData", customData ); - reply->setProperty( "caller", caller ); reply->setProperty( "requestId", requestId ); + reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) ); connect( reply, SIGNAL( finished() ), SLOT( getArtistFamiliaritySlot() ) ); } void -EchoNestPlugin::getArtistHotttnesss( uint requestId, const QString &caller, const QVariant &input, const QVariantMap &customData ) +EchoNestPlugin::getArtistHotttnesss( uint requestId, const Tomahawk::InfoSystem::InfoRequestData &requestData ) { - if( !isValidArtistData( requestId, caller, input, customData ) ) + if( !isValidArtistData( requestId, requestData ) ) return; - Echonest::Artist artist( input.toString() ); + Echonest::Artist artist( requestData.input.toString() ); QNetworkReply* reply = artist.fetchHotttnesss(); reply->setProperty( "artist", QVariant::fromValue< Echonest::Artist >( artist ) ); - reply->setProperty( "input", input ); - reply->setProperty( "customData", customData ); - reply->setProperty( "caller", caller ); reply->setProperty( "requestId", requestId ); + reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) ); connect( reply, SIGNAL( finished() ), SLOT( getArtistHotttnesssSlot() ) ); } void -EchoNestPlugin::getArtistTerms( uint requestId, const QString &caller, const QVariant &input, const QVariantMap &customData ) +EchoNestPlugin::getArtistTerms( uint requestId, const Tomahawk::InfoSystem::InfoRequestData &requestData ) { - if( !isValidArtistData( requestId, caller, input, customData ) ) + if( !isValidArtistData( requestId, requestData ) ) return; - Echonest::Artist artist( input.toString() ); + Echonest::Artist artist( requestData.input.toString() ); QNetworkReply* reply = artist.fetchTerms( Echonest::Artist::Weight ); reply->setProperty( "artist", QVariant::fromValue< Echonest::Artist >( artist ) ); - reply->setProperty( "input", input ); - reply->setProperty( "customData", customData ); - reply->setProperty( "caller", caller ); reply->setProperty( "requestId", requestId ); + reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) ); connect( reply, SIGNAL( finished() ), SLOT( getArtistTermsSlot() ) ); } void -EchoNestPlugin::getMiscTopTerms( uint requestId, const QString &caller, const QVariant &input, const QVariantMap& customData ) +EchoNestPlugin::getMiscTopTerms( uint requestId, const Tomahawk::InfoSystem::InfoRequestData &requestData ) { - Q_UNUSED( input ); QNetworkReply* reply = Echonest::Artist::topTerms( 20 ); - reply->setProperty( "customData", customData ); - reply->setProperty( "caller", caller ); reply->setProperty( "requestId", requestId ); + reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) ); connect( reply, SIGNAL( finished() ), SLOT( getMiscTopSlot() ) ); } @@ -201,12 +191,10 @@ EchoNestPlugin::getArtistBiographySlot() biographyMap[biography.site()]["attribution"] = biography.license().url.toString(); } + Tomahawk::InfoSystem::InfoRequestData requestData = reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(); emit info( reply->property( "requestId" ).toUInt(), - reply->property( "caller" ).toString(), - Tomahawk::InfoSystem::InfoArtistBiography, - reply->property( "input" ), - QVariant::fromValue< Tomahawk::InfoSystem::InfoGenericMap >( biographyMap ), - reply->property( "customData" ).value< QVariantMap >() ); + requestData, + QVariant::fromValue< Tomahawk::InfoSystem::InfoGenericMap >( biographyMap ) ); reply->deleteLater(); } @@ -216,12 +204,10 @@ EchoNestPlugin::getArtistFamiliaritySlot() QNetworkReply* reply = qobject_cast( sender() ); Echonest::Artist artist = artistFromReply( reply ); qreal familiarity = artist.familiarity(); + Tomahawk::InfoSystem::InfoRequestData requestData = reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(); emit info( reply->property( "requestId" ).toUInt(), - reply->property( "caller" ).toString(), - Tomahawk::InfoSystem::InfoArtistFamiliarity, - reply->property( "input" ), - familiarity, - reply->property( "customData" ).value< QVariantMap >() ); + requestData, + familiarity ); reply->deleteLater(); } @@ -231,12 +217,10 @@ EchoNestPlugin::getArtistHotttnesssSlot() QNetworkReply* reply = qobject_cast( sender() ); Echonest::Artist artist = artistFromReply( reply ); qreal hotttnesss = artist.hotttnesss(); + Tomahawk::InfoSystem::InfoRequestData requestData = reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(); emit info( reply->property( "requestId" ).toUInt(), - reply->property( "caller" ).toString(), - Tomahawk::InfoSystem::InfoArtistHotttness, - reply->property( "input" ), - hotttnesss, - reply->property( "customData" ).value< QVariantMap >() ); + requestData, + hotttnesss ); reply->deleteLater(); } @@ -253,12 +237,10 @@ EchoNestPlugin::getArtistTermsSlot() termMap[ "frequency" ] = QString::number(term.frequency()); termsMap[ term.name() ] = termMap; } + Tomahawk::InfoSystem::InfoRequestData requestData = reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(); emit info( reply->property( "requestId" ).toUInt(), - reply->property( "caller" ).toString(), - Tomahawk::InfoSystem::InfoArtistTerms, - reply->property( "input" ), - QVariant::fromValue< Tomahawk::InfoSystem::InfoGenericMap >( termsMap ), - reply->property( "customData" ).value< QVariantMap >() ); + requestData, + QVariant::fromValue< Tomahawk::InfoSystem::InfoGenericMap >( termsMap ) ); reply->deleteLater(); } @@ -274,49 +256,47 @@ EchoNestPlugin::getMiscTopSlot() termMap[ "frequency" ] = QString::number( term.frequency() ); termsMap[ term.name().toLower() ] = termMap; } + Tomahawk::InfoSystem::InfoRequestData requestData = reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(); emit info( reply->property( "requestId" ).toUInt(), - reply->property( "caller" ).toString(), - Tomahawk::InfoSystem::InfoMiscTopTerms, - QVariant(), - QVariant::fromValue< Tomahawk::InfoSystem::InfoGenericMap >( termsMap ), - reply->property( "customData" ).value< QVariantMap >() ); + requestData, + QVariant::fromValue< Tomahawk::InfoSystem::InfoGenericMap >( termsMap ) ); reply->deleteLater(); } bool -EchoNestPlugin::isValidArtistData( uint requestId, const QString &caller, const QVariant &input, const QVariantMap &customData ) +EchoNestPlugin::isValidArtistData( uint requestId, const Tomahawk::InfoSystem::InfoRequestData &requestData ) { - if ( input.isNull() || !input.isValid() || !input.canConvert< QString >() ) + if ( requestData.input.isNull() || !requestData.input.isValid() || !requestData.input.canConvert< QString >() ) { - emit info( requestId, caller, Tomahawk::InfoSystem::InfoNoInfo, QVariant(), QVariant(), customData ); + emit info( requestId, requestData, QVariant() ); return false; } - QString artistName = input.toString(); + QString artistName = requestData.input.toString(); if ( artistName.isEmpty() ) { - emit info( requestId, caller, Tomahawk::InfoSystem::InfoNoInfo, QVariant(), QVariant(), customData ); + emit info( requestId, requestData, QVariant() ); return false; } return true; } bool -EchoNestPlugin::isValidTrackData( uint requestId, const QString &caller, const QVariant &input, const QVariantMap &customData ) +EchoNestPlugin::isValidTrackData( uint requestId, const Tomahawk::InfoSystem::InfoRequestData &requestData ) { - if ( input.isNull() || !input.isValid() || !input.canConvert< QString >() ) + if ( requestData.input.isNull() || !requestData.input.isValid() || !requestData.input.canConvert< QString >() ) { - emit info( requestId, caller, Tomahawk::InfoSystem::InfoNoInfo, QVariant(), QVariant(), customData ); + emit info( requestId, requestData, QVariant() ); return false; } - QString trackName = input.toString(); + QString trackName = requestData.input.toString(); if ( trackName.isEmpty() ) { - emit info( requestId, caller, Tomahawk::InfoSystem::InfoNoInfo, QVariant(), QVariant(), customData ); + emit info( requestId, requestData, QVariant() ); return false; } - if ( !customData.contains( "artistName" ) || customData[ "artistName" ].toString().isEmpty() ) + if ( !requestData.customData.contains( "artistName" ) || requestData.customData[ "artistName" ].toString().isEmpty() ) { - emit info( requestId, caller, Tomahawk::InfoSystem::InfoNoInfo, QVariant(), QVariant(), customData ); + emit info( requestId, requestData, QVariant() ); return false; } return true; diff --git a/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.h b/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.h index f06500532..e1461daec 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.h +++ b/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.h @@ -44,7 +44,7 @@ public: virtual ~EchoNestPlugin(); protected slots: - virtual void getInfo( uint requestId, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ); + virtual void getInfo( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData ); virtual void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant data ) { @@ -53,29 +53,26 @@ protected slots: Q_UNUSED( data ); } - virtual void notInCacheSlot( uint requestId, const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) + virtual void notInCacheSlot( uint requestId, Tomahawk::InfoSystem::InfoCriteriaHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData ) { Q_UNUSED( requestId ); Q_UNUSED( criteria ); - Q_UNUSED( caller ); - Q_UNUSED( type ); - Q_UNUSED( input ); - Q_UNUSED( customData ); + Q_UNUSED( requestData ); } public slots: void namChangedSlot( QNetworkAccessManager *nam ); private: - void getSongProfile( uint requestId, const QString &caller, const QVariant &input, const QVariantMap &customData, const QString &item = QString() ); - void getArtistBiography ( uint requestId, const QString &caller, const QVariant &input, const QVariantMap &customData ); - void getArtistFamiliarity( uint requestId, const QString &caller, const QVariant &input, const QVariantMap &customData ); - void getArtistHotttnesss( uint requestId, const QString &caller, const QVariant &input, const QVariantMap &customData ); - void getArtistTerms( uint requestId, const QString &caller, const QVariant &input, const QVariantMap &customData ); - void getMiscTopTerms( uint requestId, const QString &caller, const QVariant &input, const QVariantMap &customData ); + void getSongProfile( uint requestId, const Tomahawk::InfoSystem::InfoRequestData &requestData, const QString &item = QString() ); + void getArtistBiography( uint requestId, const Tomahawk::InfoSystem::InfoRequestData &requestData ); + void getArtistFamiliarity( uint requestId, const Tomahawk::InfoSystem::InfoRequestData &requestData ); + void getArtistHotttnesss( uint requestId, const Tomahawk::InfoSystem::InfoRequestData &requestData ); + void getArtistTerms( uint requestId, const Tomahawk::InfoSystem::InfoRequestData &requestData ); + void getMiscTopTerms( uint requestId, const Tomahawk::InfoSystem::InfoRequestData &requestData ); - bool isValidArtistData( uint requestId, const QString &caller, const QVariant &input, const QVariantMap& customData ); - bool isValidTrackData( uint requestId, const QString &caller, const QVariant &input, const QVariantMap& customData ); + bool isValidArtistData( uint requestId, const Tomahawk::InfoSystem::InfoRequestData &requestData ); + bool isValidTrackData( uint requestId, const Tomahawk::InfoSystem::InfoRequestData &requestData ); Echonest::Artist artistFromReply( QNetworkReply* ); private slots: diff --git a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp index ace2259d4..30f0732d5 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp @@ -120,38 +120,38 @@ LastFmPlugin::namChangedSlot( QNetworkAccessManager *nam ) void -LastFmPlugin::dataError( uint requestId, const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const QVariantMap &customData ) +LastFmPlugin::dataError( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData ) { - emit info( requestId, caller, type, input, QVariant(), customData ); + emit info( requestId, requestData, QVariant() ); return; } void -LastFmPlugin::getInfo( uint requestId, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) +LastFmPlugin::getInfo( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData ) { qDebug() << Q_FUNC_INFO; - switch ( type ) + switch ( requestData.type ) { case InfoArtistImages: - fetchArtistImages( requestId, caller, type, input, customData ); + fetchArtistImages( requestId, requestData ); break; case InfoAlbumCoverArt: - fetchCoverArt( requestId, caller, type, input, customData ); + fetchCoverArt( requestId, requestData ); break; case InfoArtistSimilars: - fetchSimilarArtists( requestId, caller, type, input, customData ); + fetchSimilarArtists( requestId, requestData ); break; case InfoArtistSongs: - fetchTopTracks( requestId, caller, type, input, customData ); + fetchTopTracks( requestId, requestData ); break; default: - dataError( requestId, caller, type, input, customData ); + dataError( requestId, requestData ); } } @@ -263,64 +263,64 @@ LastFmPlugin::sendLoveSong( const InfoType type, QVariant input ) void -LastFmPlugin::fetchSimilarArtists( uint requestId, const QString &caller, const InfoType type, const QVariant &input, const QVariantMap &customData ) +LastFmPlugin::fetchSimilarArtists( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData ) { qDebug() << Q_FUNC_INFO; - if ( !input.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() ) + if ( !requestData.input.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() ) { - dataError( requestId, caller, type, input, customData ); + dataError( requestId, requestData ); return; } - InfoCriteriaHash hash = input.value< Tomahawk::InfoSystem::InfoCriteriaHash >(); + InfoCriteriaHash hash = requestData.input.value< Tomahawk::InfoSystem::InfoCriteriaHash >(); if ( !hash.contains( "artist" ) ) { - dataError( requestId, caller, type, input, customData ); + dataError( requestId, requestData ); return; } Tomahawk::InfoSystem::InfoCriteriaHash criteria; criteria["artist"] = hash["artist"]; - emit getCachedInfo( requestId, criteria, 2419200000, caller, type, input, customData ); + emit getCachedInfo( requestId, criteria, 2419200000, requestData ); } void -LastFmPlugin::fetchTopTracks( uint requestId, const QString &caller, const InfoType type, const QVariant &input, const QVariantMap &customData ) +LastFmPlugin::fetchTopTracks( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData ) { qDebug() << Q_FUNC_INFO; - if ( !input.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() ) + if ( !requestData.input.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() ) { - dataError( requestId, caller, type, input, customData ); + dataError( requestId, requestData ); return; } - InfoCriteriaHash hash = input.value< Tomahawk::InfoSystem::InfoCriteriaHash >(); + InfoCriteriaHash hash = requestData.input.value< Tomahawk::InfoSystem::InfoCriteriaHash >(); if ( !hash.contains( "artist" ) ) { - dataError( requestId, caller, type, input, customData ); + dataError( requestId, requestData ); return; } Tomahawk::InfoSystem::InfoCriteriaHash criteria; criteria["artist"] = hash["artist"]; - emit getCachedInfo( requestId, criteria, 2419200000, caller, type, input, customData ); + emit getCachedInfo( requestId, criteria, 2419200000, requestData ); } void -LastFmPlugin::fetchCoverArt( uint requestId, const QString &caller, const InfoType type, const QVariant &input, const QVariantMap &customData ) +LastFmPlugin::fetchCoverArt( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData ) { qDebug() << Q_FUNC_INFO; - if ( !input.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() ) + if ( !requestData.input.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() ) { - dataError( requestId, caller, type, input, customData ); + dataError( requestId, requestData ); return; } - InfoCriteriaHash hash = input.value< Tomahawk::InfoSystem::InfoCriteriaHash >(); + InfoCriteriaHash hash = requestData.input.value< Tomahawk::InfoSystem::InfoCriteriaHash >(); if ( !hash.contains( "artist" ) || !hash.contains( "album" ) ) { - dataError( requestId, caller, type, input, customData ); + dataError( requestId, requestData ); return; } @@ -328,56 +328,53 @@ LastFmPlugin::fetchCoverArt( uint requestId, const QString &caller, const InfoTy criteria["artist"] = hash["artist"]; criteria["album"] = hash["album"]; - emit getCachedInfo( requestId, criteria, 2419200000, caller, type, input, customData ); + emit getCachedInfo( requestId, criteria, 2419200000, requestData ); } void -LastFmPlugin::fetchArtistImages( uint requestId, const QString &caller, const InfoType type, const QVariant &input, const QVariantMap &customData ) +LastFmPlugin::fetchArtistImages( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData ) { qDebug() << Q_FUNC_INFO; - if ( !input.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() ) + if ( !requestData.input.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() ) { - dataError( requestId, caller, type, input, customData ); + dataError( requestId, requestData ); return; } - InfoCriteriaHash hash = input.value< Tomahawk::InfoSystem::InfoCriteriaHash >(); + InfoCriteriaHash hash = requestData.input.value< Tomahawk::InfoSystem::InfoCriteriaHash >(); if ( !hash.contains( "artist" ) ) { - dataError( requestId, caller, type, input, customData ); + dataError( requestId, requestData ); return; } Tomahawk::InfoSystem::InfoCriteriaHash criteria; criteria["artist"] = hash["artist"]; - emit getCachedInfo( requestId, criteria, 2419200000, caller, type, input, customData ); + emit getCachedInfo( requestId, criteria, 2419200000, requestData ); } void -LastFmPlugin::notInCacheSlot( uint requestId, const QHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) +LastFmPlugin::notInCacheSlot( uint requestId, QHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData ) { qDebug() << Q_FUNC_INFO << " for requestId " << requestId; if ( !lastfm::nam() ) { qDebug() << "Have a null QNAM, uh oh"; - emit info( requestId, caller, type, input, QVariant(), customData ); + emit info( requestId, requestData, QVariant() ); return; } - switch ( type ) + switch ( requestData.type ) { case InfoArtistSimilars: { lastfm::Artist a( criteria["artist"] ); QNetworkReply* reply = a.getSimilar(); - reply->setProperty( "customData", QVariant::fromValue( customData ) ); - reply->setProperty( "origData", input ); - reply->setProperty( "caller", caller ); - reply->setProperty( "type", (uint)( type ) ); reply->setProperty( "requestId", requestId ); + reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) ); connect( reply, SIGNAL( finished() ), SLOT( similarArtistsReturned() ) ); return; @@ -387,11 +384,8 @@ LastFmPlugin::notInCacheSlot( uint requestId, const QHash crit { lastfm::Artist a( criteria["artist"] ); QNetworkReply* reply = a.getTopTracks(); - reply->setProperty( "customData", QVariant::fromValue( customData ) ); - reply->setProperty( "origData", input ); - reply->setProperty( "caller", caller ); - reply->setProperty( "type", (uint)( type ) ); reply->setProperty( "requestId", requestId ); + reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) ); connect( reply, SIGNAL( finished() ), SLOT( topTracksReturned() ) ); return; @@ -405,11 +399,8 @@ LastFmPlugin::notInCacheSlot( uint requestId, const QHash crit QString imgurl = "http://ws.audioscrobbler.com/2.0/?method=album.imageredirect&artist=%1&album=%2&autocorrect=1&size=large&api_key=7a90f6672a04b809ee309af169f34b8b"; QNetworkRequest req( imgurl.arg( artistName ).arg( albumName ) ); QNetworkReply* reply = lastfm::nam()->get( req ); - reply->setProperty( "customData", QVariant::fromValue( customData ) ); - reply->setProperty( "origData", input ); - reply->setProperty( "caller", caller ); - reply->setProperty( "type", (uint)( type ) ); reply->setProperty( "requestId", requestId ); + reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) ); connect( reply, SIGNAL( finished() ), SLOT( coverArtReturned() ) ); return; @@ -422,11 +413,8 @@ LastFmPlugin::notInCacheSlot( uint requestId, const QHash crit QString imgurl = "http://ws.audioscrobbler.com/2.0/?method=artist.imageredirect&artist=%1&autocorrect=1&size=large&api_key=7a90f6672a04b809ee309af169f34b8b"; QNetworkRequest req( imgurl.arg( artistName ) ); QNetworkReply* reply = lastfm::nam()->get( req ); - reply->setProperty( "customData", QVariant::fromValue( customData ) ); - reply->setProperty( "origData", input ); - reply->setProperty( "caller", caller ); - reply->setProperty( "type", (uint)( type ) ); reply->setProperty( "requestId", requestId ); + reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) ); connect( reply, SIGNAL( finished() ), SLOT( artistImagesReturned() ) ); return; @@ -435,7 +423,7 @@ LastFmPlugin::notInCacheSlot( uint requestId, const QHash crit default: { qDebug() << "Couldn't figure out what to do with this type of request after cache miss"; - emit info( requestId, caller, type, input, QVariant(), customData ); + emit info( requestId, requestData, QVariant() ); return; } } @@ -462,21 +450,18 @@ LastFmPlugin::similarArtistsReturned() returnedData["artists"] = al; returnedData["score"] = sl; - QVariantMap customData = reply->property( "customData" ).value< QVariantMap >(); - InfoType type = (Tomahawk::InfoSystem::InfoType)(reply->property( "type" ).toUInt()); + Tomahawk::InfoSystem::InfoRequestData requestData = reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(); + emit info( reply->property( "requestId" ).toUInt(), - reply->property( "caller" ).toString(), - type, - reply->property( "origData" ), - returnedData, - customData + requestData, + returnedData ); - InfoCriteriaHash origData = reply->property( "origData" ).value< Tomahawk::InfoSystem::InfoCriteriaHash >(); + Tomahawk::InfoSystem::InfoCriteriaHash origData = requestData.input.value< Tomahawk::InfoSystem::InfoCriteriaHash>(); Tomahawk::InfoSystem::InfoCriteriaHash criteria; criteria["artist"] = origData["artist"]; - emit updateCache( criteria, 2419200000, type, returnedData ); + emit updateCache( criteria, 2419200000, requestData.type, returnedData ); } @@ -495,21 +480,18 @@ LastFmPlugin::topTracksReturned() QVariantMap returnedData; returnedData["tracks"] = topTracks; - QVariantMap customData = reply->property( "customData" ).value< QVariantMap >(); - InfoType type = (Tomahawk::InfoSystem::InfoType)(reply->property( "type" ).toUInt()); + Tomahawk::InfoSystem::InfoRequestData requestData = reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(); + emit info( reply->property( "requestId" ).toUInt(), - reply->property( "caller" ).toString(), - type, - reply->property( "origData" ), - returnedData, - customData + requestData, + returnedData ); - InfoCriteriaHash origData = reply->property( "origData" ).value< Tomahawk::InfoSystem::InfoCriteriaHash >(); + Tomahawk::InfoSystem::InfoCriteriaHash origData = requestData.input.value< Tomahawk::InfoSystem::InfoCriteriaHash>(); Tomahawk::InfoSystem::InfoCriteriaHash criteria; criteria["artist"] = origData["artist"]; - emit updateCache( criteria, 2419200000, type, returnedData ); + emit updateCache( criteria, 2419200000, requestData.type, returnedData ); } @@ -525,9 +507,7 @@ LastFmPlugin::coverArtReturned() if ( ba.isNull() || !ba.length() ) { qDebug() << "Uh oh, null byte array"; - InfoType type = (Tomahawk::InfoSystem::InfoType)(reply->property( "type" ).toUInt()); - QVariantMap customData = reply->property( "customData" ).value< QVariantMap >(); - emit info( reply->property( "requestId" ).toUInt(), reply->property( "caller" ).toString(), type, reply->property( "origData" ), QVariant(), customData ); + emit info( reply->property( "requestId" ).toUInt(), reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(), QVariant() ); return; } foreach ( const QUrl& url, m_badUrls ) @@ -540,41 +520,33 @@ LastFmPlugin::coverArtReturned() returnedData["imgbytes"] = ba; returnedData["url"] = reply->url().toString(); - QVariantMap customData = reply->property( "customData" ).value< QVariantMap >(); - InfoType type = (Tomahawk::InfoSystem::InfoType)(reply->property( "type" ).toUInt()); + Tomahawk::InfoSystem::InfoRequestData requestData = reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(); + emit info( reply->property( "requestId" ).toUInt(), - reply->property( "caller" ).toString(), - type, - reply->property( "origData" ), - returnedData, - customData + requestData, + returnedData ); - InfoCriteriaHash origData = reply->property( "origData" ).value< Tomahawk::InfoSystem::InfoCriteriaHash >(); + Tomahawk::InfoSystem::InfoCriteriaHash origData = requestData.input.value< Tomahawk::InfoSystem::InfoCriteriaHash>(); Tomahawk::InfoSystem::InfoCriteriaHash criteria; criteria["artist"] = origData["artist"]; criteria["album"] = origData["album"]; - emit updateCache( criteria, 2419200000, type, returnedData ); + emit updateCache( criteria, 2419200000, requestData.type, returnedData ); } else { if ( !lastfm::nam() ) { qDebug() << "Uh oh, nam is null"; - InfoType type = (Tomahawk::InfoSystem::InfoType)(reply->property( "type" ).toUInt()); - QVariantMap customData = reply->property( "customData" ).value< QVariantMap >(); - emit info( reply->property( "requestId" ).toUInt(), reply->property( "caller" ).toString(), type, reply->property( "origData" ), QVariant(), customData ); + emit info( reply->property( "requestId" ).toUInt(), reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(), QVariant() ); return; } // Follow HTTP redirect QNetworkRequest req( redir ); QNetworkReply* newReply = lastfm::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" ) ); newReply->setProperty( "requestId", reply->property( "requestId" ) ); + newReply->setProperty( "requestData", reply->property( "requestData" ) ); connect( newReply, SIGNAL( finished() ), SLOT( coverArtReturned() ) ); } @@ -594,9 +566,7 @@ LastFmPlugin::artistImagesReturned() if ( ba.isNull() || !ba.length() ) { qDebug() << "Uh oh, null byte array"; - InfoType type = (Tomahawk::InfoSystem::InfoType)(reply->property( "type" ).toUInt()); - QVariantMap customData = reply->property( "customData" ).value< QVariantMap >(); - emit info( reply->property( "requestId" ).toUInt(), reply->property( "caller" ).toString(), type, reply->property( "origData" ), QVariant(), customData ); + emit info( reply->property( "requestId" ).toUInt(), reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(), QVariant() ); return; } foreach ( const QUrl& url, m_badUrls ) @@ -608,33 +578,28 @@ LastFmPlugin::artistImagesReturned() returnedData["imgbytes"] = ba; returnedData["url"] = reply->url().toString(); - InfoType type = (Tomahawk::InfoSystem::InfoType)(reply->property( "type" ).toUInt()); - QVariantMap customData = reply->property( "customData" ).value< QVariantMap >(); - emit info( reply->property( "requestId" ).toUInt(), reply->property( "caller" ).toString(), type, reply->property( "origData" ), returnedData, customData ); + Tomahawk::InfoSystem::InfoRequestData requestData = reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(); + + emit info( reply->property( "requestId" ).toUInt(), requestData, returnedData ); - InfoCriteriaHash origData = reply->property( "origData" ).value< Tomahawk::InfoSystem::InfoCriteriaHash >(); + Tomahawk::InfoSystem::InfoCriteriaHash origData = requestData.input.value< Tomahawk::InfoSystem::InfoCriteriaHash>(); Tomahawk::InfoSystem::InfoCriteriaHash criteria; criteria["artist"] = origData["artist"]; - emit updateCache( criteria, 2419200000, type, returnedData ); + emit updateCache( criteria, 2419200000, requestData.type, returnedData ); } else { if ( !lastfm::nam() ) { qDebug() << "Uh oh, nam is null"; - InfoType type = (Tomahawk::InfoSystem::InfoType)(reply->property( "type" ).toUInt()); - QVariantMap customData = reply->property( "customData" ).value< QVariantMap >(); - emit info( reply->property( "requestId" ).toUInt(), reply->property( "caller" ).toString(), type, reply->property( "origData" ), QVariant(), customData ); + emit info( reply->property( "requestId" ).toUInt(), reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(), QVariant() ); return; } // Follow HTTP redirect QNetworkRequest req( redir ); QNetworkReply* newReply = lastfm::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" ) ); newReply->setProperty( "requestId", reply->property( "requestId" ) ); + newReply->setProperty( "requestData", reply->property( "requestData" ) ); connect( newReply, SIGNAL( finished() ), SLOT( artistImagesReturned() ) ); } diff --git a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.h b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.h index 8780034cb..dc1c2add6 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.h +++ b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.h @@ -55,23 +55,23 @@ public slots: void namChangedSlot( QNetworkAccessManager *nam ); protected slots: - virtual void getInfo( uint requestId, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ); - virtual void notInCacheSlot( uint requestId, const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ); + virtual void getInfo( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData ); + virtual void notInCacheSlot( uint requestId, Tomahawk::InfoSystem::InfoCriteriaHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData ); - virtual void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant data ); + virtual void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant data ); private: - void fetchCoverArt( uint requestId, const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const QVariantMap &customData ); - void fetchArtistImages( uint requestId, const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const QVariantMap &customData ); - void fetchSimilarArtists( uint requestId, const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const QVariantMap &customData ); - void fetchTopTracks( uint requestId, const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const QVariantMap &customData ); + void fetchCoverArt( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData ); + void fetchArtistImages( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData ); + void fetchSimilarArtists( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData ); + void fetchTopTracks( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData ); void createScrobbler(); void nowPlaying( const QVariant &input ); void scrobble(); void sendLoveSong( const InfoType type, QVariant input ); - void dataError( uint requestId, const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const QVariantMap &customData ); + void dataError( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData ); lastfm::MutableTrack m_track; lastfm::Audioscrobbler* m_scrobbler; diff --git a/src/libtomahawk/infosystem/infoplugins/generic/musixmatchplugin.cpp b/src/libtomahawk/infosystem/infoplugins/generic/musixmatchplugin.cpp index 372f2995d..70cef35d9 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/musixmatchplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/generic/musixmatchplugin.cpp @@ -51,17 +51,17 @@ MusixMatchPlugin::namChangedSlot( QNetworkAccessManager *nam ) } void -MusixMatchPlugin::getInfo( uint requestId, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) +MusixMatchPlugin::getInfo( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData ) { qDebug() << Q_FUNC_INFO; - if( !isValidTrackData( requestId, caller, input, customData ) || !input.canConvert< QVariantMap >() || m_nam.isNull() || type != Tomahawk::InfoSystem::InfoTrackLyrics ) + if( !isValidTrackData( requestId, requestData ) || !requestData.input.canConvert< QVariantMap >() || m_nam.isNull() || requestData.type != Tomahawk::InfoSystem::InfoTrackLyrics ) return; - QVariantMap hash = input.value< QVariantMap >(); + QVariantMap hash = requestData.input.value< QVariantMap >(); QString artist = hash["artistName"].toString(); QString track = hash["trackName"].toString(); if( artist.isEmpty() || track.isEmpty() ) { - emit info( requestId, caller, Tomahawk::InfoSystem::InfoTrackLyrics, input, QVariant(), customData ); + emit info( requestId, requestData, QVariant() ); return; } qDebug() << "artist is " << artist << ", track is " << track; @@ -71,34 +71,32 @@ MusixMatchPlugin::getInfo( uint requestId, const QString caller, const Tomahawk: url.addQueryItem( "q_artist", artist ); url.addQueryItem( "q_track", track ); QNetworkReply* reply = m_nam.data()->get( QNetworkRequest( url ) ); - reply->setProperty( "customData", QVariant::fromValue< QVariantMap >( customData ) ); - reply->setProperty( "origData", input ); - reply->setProperty( "caller", caller ); reply->setProperty( "requestId", requestId ); + reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) ); connect( reply, SIGNAL( finished() ), SLOT( trackSearchSlot() ) ); } bool -MusixMatchPlugin::isValidTrackData( uint requestId, const QString &caller, const QVariant &input, const QVariantMap &customData ) +MusixMatchPlugin::isValidTrackData( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData ) { qDebug() << Q_FUNC_INFO; - if ( input.isNull() || !input.isValid() || !input.canConvert< QVariantMap >() ) + if ( requestData.input.isNull() || !requestData.input.isValid() || !requestData.input.canConvert< QVariantMap >() ) { - emit info( requestId, caller, Tomahawk::InfoSystem::InfoTrackLyrics, input, QVariant(), customData ); + emit info( requestId, requestData, QVariant() ); qDebug() << "MusixMatchPlugin::isValidTrackData: Data null, invalid, or can't convert"; return false; } - QVariantMap hash = input.value< QVariantMap >(); - if ( hash["trackName"].toString().isEmpty() ) + QVariantMap hash = requestData.input.value< QVariantMap >(); + if ( hash[ "trackName" ].toString().isEmpty() ) { - emit info( requestId, caller, Tomahawk::InfoSystem::InfoTrackLyrics, input, QVariant(), customData ); + emit info( requestId, requestData, QVariant() ); qDebug() << "MusixMatchPlugin::isValidTrackData: Track name is empty"; return false; } - if ( hash["artistName"].toString().isEmpty() ) + if ( hash[ "artistName" ].toString().isEmpty() ) { - emit info( requestId, caller, Tomahawk::InfoSystem::InfoTrackLyrics, input, QVariant(), customData ); + emit info( requestId, requestData, QVariant() ); qDebug() << "MusixMatchPlugin::isValidTrackData: No artist name found"; return false; } @@ -111,17 +109,15 @@ MusixMatchPlugin::trackSearchSlot() qDebug() << Q_FUNC_INFO; QNetworkReply* oldReply = qobject_cast( sender() ); if ( !oldReply ) - { - emit info( 0, QString(), Tomahawk::InfoSystem::InfoTrackLyrics, QVariant(), QVariant(), QVariantMap() ); - return; - } + return; //timeout will handle it + QDomDocument doc; doc.setContent(oldReply->readAll()); qDebug() << doc.toString(); QDomNodeList domNodeList = doc.elementsByTagName("track_id"); - if (domNodeList.isEmpty()) + if ( domNodeList.isEmpty() ) { - emit info( oldReply->property( "requestId" ).toUInt(), oldReply->property( "caller" ).toString(), Tomahawk::InfoSystem::InfoTrackLyrics, oldReply->property( "origData" ), QVariant(), oldReply->property( "customData" ).value< QVariantMap >() ); + emit info( oldReply->property( "requestId" ).toUInt(), oldReply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(), QVariant() ); return; } QString track_id = domNodeList.at(0).toElement().text(); @@ -130,10 +126,8 @@ MusixMatchPlugin::trackSearchSlot() url.addQueryItem( "apikey", m_apiKey ); url.addQueryItem( "track_id", track_id ); QNetworkReply* newReply = m_nam.data()->get( QNetworkRequest( url ) ); - newReply->setProperty( "origData", oldReply->property( "origData" ) ); - newReply->setProperty( "customData", oldReply->property( "customData" ) ); - newReply->setProperty( "caller", oldReply->property( "caller" ) ); newReply->setProperty( "requestId", oldReply->property( "requestId" ) ); + newReply->setProperty( "requestData", oldReply->property( "requestData" ) ); connect( newReply, SIGNAL( finished() ), SLOT( trackLyricsSlot() ) ); } @@ -143,19 +137,17 @@ MusixMatchPlugin::trackLyricsSlot() qDebug() << Q_FUNC_INFO; QNetworkReply* reply = qobject_cast< QNetworkReply* >( sender() ); if ( !reply ) - { - emit info( 0, QString(), Tomahawk::InfoSystem::InfoTrackLyrics, QVariant(), QVariant(), QVariantMap() ); - return; - } + return; //timeout will handle it + QDomDocument doc; doc.setContent( reply->readAll() ); QDomNodeList domNodeList = doc.elementsByTagName( "lyrics_body" ); if ( domNodeList.isEmpty() ) { - emit info( reply->property( "requestId" ).toUInt(), reply->property( "caller" ).toString(), Tomahawk::InfoSystem::InfoTrackLyrics, reply->property( "origData" ), QVariant(), reply->property( "customData" ).value< QVariantMap >() ); + emit info( reply->property( "requestId" ).toUInt(), reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(), QVariant() ); return; } QString lyrics = domNodeList.at(0).toElement().text(); qDebug() << "Emitting lyrics: " << lyrics; - emit info( reply->property( "requestId" ).toUInt(), reply->property( "caller" ).toString(), Tomahawk::InfoSystem::InfoTrackLyrics, reply->property( "origData" ), QVariant( lyrics ), reply->property( "customData" ).value() ); + emit info( reply->property( "requestId" ).toUInt(), reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(), QVariant( lyrics ) ); } diff --git a/src/libtomahawk/infosystem/infoplugins/generic/musixmatchplugin.h b/src/libtomahawk/infosystem/infoplugins/generic/musixmatchplugin.h index 8b033b054..a93e25c01 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/musixmatchplugin.h +++ b/src/libtomahawk/infosystem/infoplugins/generic/musixmatchplugin.h @@ -45,27 +45,24 @@ public slots: void namChangedSlot( QNetworkAccessManager *nam ); protected slots: - virtual void getInfo( uint requestId, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ); + virtual void getInfo( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData ); - virtual void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant data ) + virtual void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant data ) { Q_UNUSED( caller ); Q_UNUSED( type ); Q_UNUSED( data ); } -virtual void notInCacheSlot( uint requestId, const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) +virtual void notInCacheSlot( uint requestId, Tomahawk::InfoSystem::InfoCriteriaHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData ) { Q_UNUSED( requestId ); Q_UNUSED( criteria ); - Q_UNUSED( caller ); - Q_UNUSED( type ); - Q_UNUSED( input ); - Q_UNUSED( customData ); + Q_UNUSED( requestData ); } private: - bool isValidTrackData( uint requestId, const QString &caller, const QVariant &input, const QVariantMap &customData ); + bool isValidTrackData( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData ); QString m_apiKey; diff --git a/src/libtomahawk/infosystem/infoplugins/mac/adiumplugin.cpp b/src/libtomahawk/infosystem/infoplugins/mac/adiumplugin.cpp index 278dfd500..823968b03 100644 --- a/src/libtomahawk/infosystem/infoplugins/mac/adiumplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/mac/adiumplugin.cpp @@ -101,7 +101,7 @@ AdiumPlugin::settingsChanged() void -AdiumPlugin::pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input ) +AdiumPlugin::pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input ) { qDebug() << Q_FUNC_INFO; diff --git a/src/libtomahawk/infosystem/infoplugins/mac/adiumplugin.h b/src/libtomahawk/infosystem/infoplugins/mac/adiumplugin.h index 426fb3506..208891164 100644 --- a/src/libtomahawk/infosystem/infoplugins/mac/adiumplugin.h +++ b/src/libtomahawk/infosystem/infoplugins/mac/adiumplugin.h @@ -39,28 +39,22 @@ public: virtual ~AdiumPlugin(); protected slots: - virtual void getInfo( uint requestId, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) + virtual void getInfo( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData ) { Q_UNUSED( requestId ); - Q_UNUSED( caller ); - Q_UNUSED( type ); - Q_UNUSED( input ); - Q_UNUSED( customData ); + Q_UNUSED( requestData ); } - void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input ); + void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input ); public slots: void namChangedSlot( QNetworkAccessManager* /*nam*/ ) {} // unused - virtual void notInCacheSlot( uint requestId, const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) + virtual void notInCacheSlot( uint requestId, const Tomahawk::InfoSystem::InfoCriteriaHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData ) { Q_UNUSED( requestId ); Q_UNUSED( criteria ); - Q_UNUSED( caller ); - Q_UNUSED( type ); - Q_UNUSED( input ); - Q_UNUSED( customData ); + Q_UNUSED( requestData ); } private slots: diff --git a/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.cpp b/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.cpp index 56551fc19..82ce1bf3c 100644 --- a/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.cpp @@ -59,7 +59,7 @@ FdoNotifyPlugin::~FdoNotifyPlugin() } void -FdoNotifyPlugin::pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant pushData ) +FdoNotifyPlugin::pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant pushData ) { Q_UNUSED( caller ); qDebug() << Q_FUNC_INFO; diff --git a/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.h b/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.h index 16f57cfb2..89f0667a1 100644 --- a/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.h +++ b/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.h @@ -38,25 +38,19 @@ public: virtual void namChangedSlot( QNetworkAccessManager* ) {} protected slots: - virtual void getInfo( uint requestId, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) + virtual void getInfo( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData ) { Q_UNUSED( requestId ); - Q_UNUSED( caller ); - Q_UNUSED( type ); - Q_UNUSED( input ); - Q_UNUSED( customData ); + Q_UNUSED( requestData ); } - virtual void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant pushData ); + virtual void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant pushData ); - virtual void notInCacheSlot( uint requestId, const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) + virtual void notInCacheSlot( uint requestId, Tomahawk::InfoSystem::InfoCriteriaHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData ) { Q_UNUSED( requestId ); Q_UNUSED( criteria ); - Q_UNUSED( caller ); - Q_UNUSED( type ); - Q_UNUSED( input ); - Q_UNUSED( customData ); + Q_UNUSED( requestData ); } }; diff --git a/src/libtomahawk/infosystem/infosystem.cpp b/src/libtomahawk/infosystem/infosystem.cpp index 15b3502ec..bd8379405 100644 --- a/src/libtomahawk/infosystem/infosystem.cpp +++ b/src/libtomahawk/infosystem/infosystem.cpp @@ -50,8 +50,8 @@ InfoSystem::instance() } -InfoSystem::InfoSystem(QObject *parent) - : QObject(parent) +InfoSystem::InfoSystem( QObject *parent ) + : QObject( parent ) , m_infoSystemCacheThreadController( 0 ) , m_infoSystemWorkerThreadController( 0 ) { @@ -73,12 +73,12 @@ InfoSystem::InfoSystem(QObject *parent) connect( TomahawkSettings::instance(), SIGNAL( changed() ), SLOT( newNam() ) ); - connect( m_cache.data(), SIGNAL( info( uint, QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), - m_worker.data(), SLOT( infoSlot( uint, QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), Qt::UniqueConnection ); + connect( m_cache.data(), SIGNAL( info( uint, Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), + m_worker.data(), SLOT( infoSlot( uint, Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), Qt::UniqueConnection ); - connect( m_worker.data(), SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), - this, SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), Qt::UniqueConnection ); - connect( m_worker.data(), SIGNAL( finished( QString ) ), this, SIGNAL( finished( QString) ), Qt::UniqueConnection ); + connect( m_worker.data(), SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), + this, SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), Qt::UniqueConnection ); + connect( m_worker.data(), SIGNAL( finished( QString ) ), this, SIGNAL( finished( QString ) ), Qt::UniqueConnection ); } InfoSystem::~InfoSystem() @@ -119,18 +119,25 @@ InfoSystem::newNam() const void -InfoSystem::getInfo( const QString &caller, const InfoType type, const QVariant& input, QVariantMap customData, uint timeoutMillis ) +InfoSystem::getInfo( const InfoRequestData &requestData, uint timeoutMillis ) { qDebug() << Q_FUNC_INFO; - QMetaObject::invokeMethod( m_worker.data(), "getInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input ), Q_ARG( QVariantMap, customData ), Q_ARG( uint, timeoutMillis ) ); + QMetaObject::invokeMethod( m_worker.data(), "getInfo", Qt::QueuedConnection, Q_ARG( Tomahawk::InfoSystem::InfoRequestData, requestData ), Q_ARG( uint, timeoutMillis ) ); } void -InfoSystem::getInfo( const QString &caller, const InfoTypeMap &inputMap, QVariantMap customData, const InfoTimeoutMap &timeoutMap ) +InfoSystem::getInfo( const QString &caller, const InfoTypeMap &inputMap, const QVariantMap &customData, const InfoTimeoutMap &timeoutMap ) { + InfoRequestData requestData; + requestData.caller = caller; + requestData.customData = customData; Q_FOREACH( InfoType type, inputMap.keys() ) - QMetaObject::invokeMethod( m_worker.data(), "getInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, inputMap[ type ] ), Q_ARG( QVariantMap, customData ), Q_ARG( uint, ( timeoutMap.contains( type ) ? timeoutMap[ type ] : 3000 ) ) ); + { + requestData.type = type; + requestData.input = inputMap[ type ]; + QMetaObject::invokeMethod( m_worker.data(), "getInfo", Qt::QueuedConnection, Q_ARG( Tomahawk::InfoSystem::InfoRequestData, requestData ), Q_ARG( uint, ( timeoutMap.contains( type ) ? timeoutMap[ type ] : 3000 ) ) ); + } } diff --git a/src/libtomahawk/infosystem/infosystem.h b/src/libtomahawk/infosystem/infosystem.h index 2b5ca3ef9..9ca664f8c 100644 --- a/src/libtomahawk/infosystem/infosystem.h +++ b/src/libtomahawk/infosystem/infosystem.h @@ -132,15 +132,15 @@ public: QSet< InfoType > supportedPushTypes() const { return m_supportedPushTypes; } signals: - void getCachedInfo( uint requestId, Tomahawk::InfoSystem::InfoCriteriaHash criteria, qint64 newMaxAge, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariantMap customData ); - void info( uint requestId, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, QVariantMap customData ); + void getCachedInfo( uint requestId, Tomahawk::InfoSystem::InfoCriteriaHash criteria, qint64 newMaxAge, Tomahawk::InfoSystem::InfoRequestData requestData ); + void info( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ); - void updateCache( Tomahawk::InfoSystem::InfoCriteriaHash criteria, qint64, Tomahawk::InfoSystem::InfoType type, QVariant output ); + void updateCache( Tomahawk::InfoSystem::InfoCriteriaHash criteria, qint64 maxAge, Tomahawk::InfoSystem::InfoType type, QVariant output ); protected slots: - virtual void getInfo( uint requestId, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant data, const QVariantMap customData ) = 0; - virtual void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant data ) = 0; - virtual void notInCacheSlot( uint requestId, const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) = 0; + virtual void getInfo( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData ) = 0; + virtual void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant data ) = 0; + virtual void notInCacheSlot( uint requestId, Tomahawk::InfoSystem::InfoCriteriaHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData ) = 0; virtual void namChangedSlot( QNetworkAccessManager *nam ) = 0; @@ -165,13 +165,13 @@ public: InfoSystem( QObject *parent ); ~InfoSystem(); - void getInfo( const QString &caller, const InfoType type, const QVariant &input, QVariantMap customData, uint timeoutMillis = 3000 ); - void getInfo( const QString &caller, const InfoTypeMap &inputMap, QVariantMap customData, const InfoTimeoutMap &timeoutMap = InfoTimeoutMap() ); + void getInfo( const InfoRequestData &requestData, uint timeoutMillis = 3000 ); + void getInfo( const QString &caller, const InfoTypeMap &inputMap, const QVariantMap &customData, const InfoTimeoutMap &timeoutMap = InfoTimeoutMap() ); void pushInfo( const QString &caller, const InfoType type, const QVariant &input ); void pushInfo( const QString &caller, const InfoTypeMap &input ); signals: - void info( QString target, Tomahawk::InfoSystem::InfoType, QVariant input, QVariant output, QVariantMap customData ); + void info( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ); void finished( QString target ); public slots: @@ -208,6 +208,7 @@ inline uint qHash( Tomahawk::InfoSystem::InfoCriteriaHash hash ) return returnval; } +Q_DECLARE_METATYPE( Tomahawk::InfoSystem::InfoRequestData ); Q_DECLARE_METATYPE( Tomahawk::InfoSystem::InfoGenericMap ); Q_DECLARE_METATYPE( Tomahawk::InfoSystem::InfoCriteriaHash ); Q_DECLARE_METATYPE( QWeakPointer< Tomahawk::InfoSystem::InfoSystemCache > ); diff --git a/src/libtomahawk/infosystem/infosystemcache.cpp b/src/libtomahawk/infosystem/infosystemcache.cpp index 86f4cd2fa..aaca83d71 100644 --- a/src/libtomahawk/infosystem/infosystemcache.cpp +++ b/src/libtomahawk/infosystem/infosystemcache.cpp @@ -84,26 +84,26 @@ InfoSystemCache::pruneTimerFired() void -InfoSystemCache::getCachedInfoSlot( uint requestId, const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const qint64 newMaxAge, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ) +InfoSystemCache::getCachedInfoSlot( uint requestId, Tomahawk::InfoSystem::InfoCriteriaHash criteria, qint64 newMaxAge, Tomahawk::InfoSystem::InfoRequestData requestData ) { qDebug() << Q_FUNC_INFO; const QString criteriaHashVal = criteriaMd5( criteria ); - QHash< QString, QString > fileLocationHash = m_fileLocationCache[type]; + QHash< QString, QString > fileLocationHash = m_fileLocationCache[ requestData.type ]; if ( !fileLocationHash.contains( criteriaHashVal ) ) { if ( !fileLocationHash.isEmpty() ) { //We already know of some values, so no need to re-read the directory again as it's already happened - emit notInCache( requestId, criteria, caller, type, input, customData ); + emit notInCache( requestId, criteria, requestData ); return; } - const QString cacheDir = m_cacheBaseDir + QString::number( (int)type ); + const QString cacheDir = m_cacheBaseDir + QString::number( (int)requestData.type ); QDir dir( cacheDir ); if ( !dir.exists() ) { //Dir doesn't exist so clearly not in cache - emit notInCache( requestId, criteria, caller, type, input, customData ); + emit notInCache( requestId, criteria, requestData ); return; } @@ -111,20 +111,20 @@ InfoSystemCache::getCachedInfoSlot( uint requestId, const Tomahawk::InfoSystem:: foreach ( QFileInfo file, fileList ) { QString baseName = file.baseName(); - fileLocationHash[baseName] = file.canonicalFilePath(); + fileLocationHash[ baseName ] = file.canonicalFilePath(); } //Store what we've loaded up - m_fileLocationCache[type] = fileLocationHash; + m_fileLocationCache[ requestData.type ] = fileLocationHash; if ( !fileLocationHash.contains( criteriaHashVal ) ) { //Still didn't fine it? It's really not in the cache then - emit notInCache( requestId, criteria, caller, type, input, customData ); + emit notInCache( requestId, criteria, requestData ); return; } } - QFileInfo file( fileLocationHash[criteriaHashVal] ); + QFileInfo file( fileLocationHash[ criteriaHashVal ] ); qlonglong currMaxAge = file.suffix().toLongLong(); if ( currMaxAge < QDateTime::currentMSecsSinceEpoch() ) @@ -135,10 +135,10 @@ InfoSystemCache::getCachedInfoSlot( uint requestId, const Tomahawk::InfoSystem:: qDebug() << "Removed stale cache file " << file.canonicalFilePath(); fileLocationHash.remove( criteriaHashVal ); - m_fileLocationCache[type] = fileLocationHash; + m_fileLocationCache[ requestData.type ] = fileLocationHash; m_dataCache.remove( criteriaHashVal ); - emit notInCache( requestId, criteria, caller, type, input, customData ); + emit notInCache( requestId, criteria, requestData ); return; } else if ( newMaxAge > 0 ) @@ -148,31 +148,31 @@ InfoSystemCache::getCachedInfoSlot( uint requestId, const Tomahawk::InfoSystem:: if ( !QFile::rename( file.canonicalFilePath(), newFilePath ) ) { qDebug() << "Failed to move old cache file to new location!"; - emit notInCache( requestId, criteria, caller, type, input, customData ); + emit notInCache( requestId, criteria, requestData ); return; } - fileLocationHash[criteriaHashVal] = newFilePath; - m_fileLocationCache[type] = fileLocationHash; + fileLocationHash[ criteriaHashVal ] = newFilePath; + m_fileLocationCache[ requestData.type ] = fileLocationHash; } if ( !m_dataCache.contains( criteriaHashVal ) ) { - QSettings cachedSettings( fileLocationHash[criteriaHashVal], QSettings::IniFormat ); + QSettings cachedSettings( fileLocationHash[ criteriaHashVal ], QSettings::IniFormat ); QVariant output = cachedSettings.value( "data" ); m_dataCache.insert( criteriaHashVal, new QVariant( output ) ); - emit info( requestId, caller, type, input, output, customData ); + emit info( requestId, requestData, output ); } else { - emit info( requestId, caller, type, input, QVariant( *(m_dataCache[criteriaHashVal]) ), customData ); + emit info( requestId, requestData, QVariant( *(m_dataCache[criteriaHashVal]) ) ); } } void -InfoSystemCache::updateCacheSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const qint64 maxAge, const Tomahawk::InfoSystem::InfoType type, const QVariant output ) +InfoSystemCache::updateCacheSlot( Tomahawk::InfoSystem::InfoCriteriaHash criteria, qint64 maxAge, Tomahawk::InfoSystem::InfoType type, QVariant output ) { qDebug() << Q_FUNC_INFO; diff --git a/src/libtomahawk/infosystem/infosystemcache.h b/src/libtomahawk/infosystem/infosystemcache.h index dfb78e4b0..d3b822a61 100644 --- a/src/libtomahawk/infosystem/infosystemcache.h +++ b/src/libtomahawk/infosystem/infosystemcache.h @@ -43,12 +43,12 @@ public: virtual ~InfoSystemCache(); signals: - void notInCache( uint requestId, Tomahawk::InfoSystem::InfoCriteriaHash criteria, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariantMap customData ); - void info( uint requestId, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, QVariantMap customData ); + void notInCache( uint requestId, Tomahawk::InfoSystem::InfoCriteriaHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData ); + void info( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ); public slots: - void getCachedInfoSlot( uint requestId, const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const qint64 newMaxAge, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData ); - void updateCacheSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const qint64 maxAge, const Tomahawk::InfoSystem::InfoType type, const QVariant output ); + void getCachedInfoSlot( uint requestId, Tomahawk::InfoSystem::InfoCriteriaHash criteria, qint64 newMaxAge, Tomahawk::InfoSystem::InfoRequestData requestData ); + void updateCacheSlot( Tomahawk::InfoSystem::InfoCriteriaHash criteria, qint64 maxAge, Tomahawk::InfoSystem::InfoType type, QVariant output ); private slots: void pruneTimerFired(); diff --git a/src/libtomahawk/infosystem/infosystemworker.cpp b/src/libtomahawk/infosystem/infosystemworker.cpp index 6f880a161..399fb0318 100644 --- a/src/libtomahawk/infosystem/infosystemworker.cpp +++ b/src/libtomahawk/infosystem/infosystemworker.cpp @@ -94,23 +94,23 @@ InfoSystemWorker::init( QWeakPointer< Tomahawk::InfoSystem::InfoSystemCache> cac { connect( plugin.data(), - SIGNAL( info( uint, QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), + SIGNAL( info( uint, Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), this, - SLOT( infoSlot( uint, QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), + SLOT( infoSlot( uint, Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), Qt::UniqueConnection ); connect( plugin.data(), - SIGNAL( getCachedInfo( uint, Tomahawk::InfoSystem::InfoCriteriaHash, qint64, QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariantMap ) ), + SIGNAL( getCachedInfo( uint, Tomahawk::InfoSystem::InfoCriteriaHash, qint64, Tomahawk::InfoSystem::InfoRequestData ) ), cache.data(), - SLOT( getCachedInfoSlot( uint, Tomahawk::InfoSystem::InfoCriteriaHash, qint64, QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariantMap ) ) + SLOT( getCachedInfoSlot( uint, Tomahawk::InfoSystem::InfoCriteriaHash, qint64, Tomahawk::InfoSystem::InfoRequestData ) ) ); connect( cache.data(), - SIGNAL( notInCache( uint, Tomahawk::InfoSystem::InfoCriteriaHash, QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariantMap ) ), + SIGNAL( notInCache( uint, Tomahawk::InfoSystem::InfoCriteriaHash, Tomahawk::InfoSystem::InfoRequestData ) ), plugin.data(), - SLOT( notInCacheSlot( uint, Tomahawk::InfoSystem::InfoCriteriaHash, QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariantMap ) ) + SLOT( notInCacheSlot( uint, Tomahawk::InfoSystem::InfoCriteriaHash, Tomahawk::InfoSystem::InfoRequestData ) ) ); connect( plugin.data(), @@ -154,22 +154,22 @@ InfoSystemWorker::determineOrderedMatches( const InfoType type ) const void -InfoSystemWorker::getInfo( QString caller, InfoType type, QVariant input, QVariantMap customData, uint timeoutMillis ) +InfoSystemWorker::getInfo( Tomahawk::InfoSystem::InfoRequestData requestData, uint timeoutMillis ) { qDebug() << Q_FUNC_INFO; - QLinkedList< InfoPluginPtr > providers = determineOrderedMatches( type ); + QLinkedList< InfoPluginPtr > providers = determineOrderedMatches( requestData.type ); if ( providers.isEmpty() ) { - emit info( caller, type, QVariant(), QVariant(), customData ); - checkFinished( caller ); + emit info( requestData, QVariant() ); + checkFinished( requestData.caller ); return; } InfoPluginPtr ptr = providers.first(); if ( !ptr ) { - emit info( caller, type, QVariant(), QVariant(), customData ); - checkFinished( caller ); + emit info( requestData, QVariant() ); + checkFinished( requestData.caller ); return; } @@ -180,27 +180,27 @@ InfoSystemWorker::getInfo( QString caller, InfoType type, QVariant input, QVaria qint64 currMs = QDateTime::currentMSecsSinceEpoch(); m_timeRequestMapper.insert( currMs + timeoutMillis, requestId ); } - qDebug() << "assigning request with requestId " << requestId << " and type " << type; - m_dataTracker[ caller ][ type ] = m_dataTracker[ caller ][ type ] + 1; - qDebug() << "current count in dataTracker for type" << type << "is" << m_dataTracker[ caller ][ type ]; + qDebug() << "assigning request with requestId " << requestId << " and type " << requestData.type; + m_dataTracker[ requestData.caller ][ requestData.type ] = m_dataTracker[ requestData.caller ][ requestData.type ] + 1; + qDebug() << "current count in dataTracker for type" << requestData.type << "is" << m_dataTracker[ requestData.caller ][ requestData.type ]; InfoRequestData* data = new InfoRequestData; - data->caller = caller; - data->type = type; - data->input = input; - data->customData = customData; + data->caller = requestData.caller; + data->type = requestData.type; + data->input = requestData.input; + data->customData = requestData.customData; m_savedRequestMap[ requestId ] = data; - QMetaObject::invokeMethod( ptr.data(), "getInfo", Qt::QueuedConnection, Q_ARG( uint, requestId ), Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input ), Q_ARG( QVariantMap, customData ) ); + QMetaObject::invokeMethod( ptr.data(), "getInfo", Qt::QueuedConnection, Q_ARG( uint, requestId ), Q_ARG( Tomahawk::InfoSystem::InfoRequestData, requestData ) ); } void -InfoSystemWorker::pushInfo( const QString caller, const InfoType type, const QVariant input ) +InfoSystemWorker::pushInfo( QString caller, InfoType type, QVariant input ) { qDebug() << Q_FUNC_INFO; - Q_FOREACH( InfoPluginPtr ptr, m_infoPushMap[type] ) + Q_FOREACH( InfoPluginPtr ptr, m_infoPushMap[ type ] ) { if( ptr ) QMetaObject::invokeMethod( ptr.data(), "pushInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input ) ); @@ -209,10 +209,10 @@ InfoSystemWorker::pushInfo( const QString caller, const InfoType type, const QVa void -InfoSystemWorker::infoSlot( uint requestId, QString target, InfoType type, QVariant input, QVariant output, QVariantMap customData ) +InfoSystemWorker::infoSlot( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ) { qDebug() << Q_FUNC_INFO << " with requestId " << requestId; - if ( m_dataTracker[ target ][ type ] == 0 ) + if ( m_dataTracker[ requestData.caller ][ requestData.type ] == 0 ) { qDebug() << Q_FUNC_INFO << " caller was not waiting for that type of data!"; return; @@ -224,13 +224,13 @@ InfoSystemWorker::infoSlot( uint requestId, QString target, InfoType type, QVari } m_requestSatisfiedMap[ requestId ] = true; - emit info( target, type, input, output, customData ); + emit info( requestData, output ); - m_dataTracker[ target ][ type ] = m_dataTracker[ target ][ type ] - 1; - qDebug() << "current count in dataTracker for target " << target << " is " << m_dataTracker[ target ][ type ]; + m_dataTracker[ requestData.caller ][ requestData.type ] = m_dataTracker[ requestData.caller ][ requestData.type ] - 1; + qDebug() << "current count in dataTracker for target " << requestData.caller << " is " << m_dataTracker[ requestData.caller ][ requestData.type ]; delete m_savedRequestMap[ requestId ]; m_savedRequestMap.remove( requestId ); - checkFinished( target ); + checkFinished( requestData.caller ); } @@ -272,22 +272,26 @@ InfoSystemWorker::checkTimeoutsTimerFired() //doh, timed out qDebug() << Q_FUNC_INFO << " doh, timed out for requestId " << requestId; InfoRequestData *savedData = m_savedRequestMap[ requestId ]; - QString target = savedData->caller; - InfoType type = savedData->type; - emit info( target, type, savedData->input, QVariant(), savedData->customData ); + + InfoRequestData returnData; + returnData.caller = savedData->caller; + returnData.type = savedData->type; + returnData.input = savedData->input; + returnData.customData = savedData->customData; + emit info( returnData, QVariant() ); delete savedData; m_savedRequestMap.remove( requestId ); - m_dataTracker[ target ][ type ] = m_dataTracker[ target ][ type ] - 1; - qDebug() << "current count in dataTracker for target " << target << " is " << m_dataTracker[ target ][ type ]; + m_dataTracker[ returnData.caller ][ returnData.type ] = m_dataTracker[ returnData.caller ][ returnData.type ] - 1; + qDebug() << "current count in dataTracker for target " << returnData.caller << " is " << m_dataTracker[ returnData.caller ][ returnData.type ]; m_requestSatisfiedMap[ requestId ] = true; m_timeRequestMapper.remove( time, requestId ); if ( !m_timeRequestMapper.count( time ) ) m_timeRequestMapper.remove( time ); - checkFinished( target ); + checkFinished( returnData.caller ); } else { diff --git a/src/libtomahawk/infosystem/infosystemworker.h b/src/libtomahawk/infosystem/infosystemworker.h index 33af36bad..dd0de2b54 100644 --- a/src/libtomahawk/infosystem/infosystemworker.h +++ b/src/libtomahawk/infosystem/infosystemworker.h @@ -50,17 +50,17 @@ public: QNetworkAccessManager* nam() const; signals: - void info( QString target, Tomahawk::InfoSystem::InfoType, QVariant input, QVariant output, QVariantMap customData ); + void info( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ); void finished( QString target ); void namChanged( QNetworkAccessManager* ); public slots: void init( QWeakPointer< Tomahawk::InfoSystem::InfoSystemCache > cache ); - void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariantMap customData, uint timeoutMillis ); - void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input ); + void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData, uint timeoutMillis ); + void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input ); - void infoSlot( uint requestId, const QString target, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariant output, const QVariantMap customData ); + void infoSlot( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ); void newNam(); diff --git a/src/libtomahawk/playlist/albummodel.cpp b/src/libtomahawk/playlist/albummodel.cpp index 6eb3a3b38..81f559765 100644 --- a/src/libtomahawk/playlist/albummodel.cpp +++ b/src/libtomahawk/playlist/albummodel.cpp @@ -44,8 +44,8 @@ AlbumModel::AlbumModel( QObject* parent ) .scaled( QSize( 120, 120 ), Qt::IgnoreAspectRatio, Qt::SmoothTransformation ); connect( Tomahawk::InfoSystem::InfoSystem::instance(), - SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), - SLOT( infoSystemInfo( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ) ); + SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), + SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) ); connect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( finished( QString ) ), SLOT( infoSystemFinished( QString ) ) ); } @@ -311,13 +311,12 @@ AlbumModel::onAlbumsAdded( const QList& albums ) void -AlbumModel::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, QVariantMap customData ) +AlbumModel::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ) { - Q_UNUSED( customData ); - qDebug() << Q_FUNC_INFO << " with caller " << caller; + qDebug() << Q_FUNC_INFO << " with caller " << requestData.caller; - if ( caller != s_tmInfoIdentifier || - ( type != Tomahawk::InfoSystem::InfoAlbumCoverArt && type != Tomahawk::InfoSystem::InfoArtistImages ) ) + if ( requestData.caller != s_tmInfoIdentifier || + ( requestData.type != Tomahawk::InfoSystem::InfoAlbumCoverArt && requestData.type != Tomahawk::InfoSystem::InfoArtistImages ) ) { qDebug() << "Info of wrong type or not with our identifier"; return; @@ -329,7 +328,7 @@ AlbumModel::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, return; } - Tomahawk::InfoSystem::InfoCriteriaHash pptr = input.value< Tomahawk::InfoSystem::InfoCriteriaHash >(); + Tomahawk::InfoSystem::InfoCriteriaHash pptr = requestData.input.value< Tomahawk::InfoSystem::InfoCriteriaHash >(); QVariantMap returnedData = output.value< QVariantMap >(); const QByteArray ba = returnedData["imgbytes"].toByteArray(); if ( ba.length() ) diff --git a/src/libtomahawk/playlist/albummodel.h b/src/libtomahawk/playlist/albummodel.h index 95e3c8c1d..87e1d88f9 100644 --- a/src/libtomahawk/playlist/albummodel.h +++ b/src/libtomahawk/playlist/albummodel.h @@ -97,7 +97,7 @@ private slots: void onAlbumsAdded( const QList& albums ); void onDataChanged(); - void infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, QVariantMap customData ); + void infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ); void infoSystemFinished( QString target ); private: diff --git a/src/libtomahawk/playlist/albumview.cpp b/src/libtomahawk/playlist/albumview.cpp index 48879a42a..31d686985 100644 --- a/src/libtomahawk/playlist/albumview.cpp +++ b/src/libtomahawk/playlist/albumview.cpp @@ -162,9 +162,13 @@ AlbumView::onScrollTimeout() trackInfo["album"] = item->album()->name(); trackInfo["pptr"] = QString::number( (qlonglong)item ); - Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( - s_tmInfoIdentifier, Tomahawk::InfoSystem::InfoAlbumCoverArt, - QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ), QVariantMap() ); + Tomahawk::InfoSystem::InfoRequestData requestData; + requestData.caller = s_tmInfoIdentifier; + requestData.type = Tomahawk::InfoSystem::InfoAlbumCoverArt; + requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ); + requestData.customData = QVariantMap(); + + Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData ); } } } diff --git a/src/libtomahawk/playlist/artistview.cpp b/src/libtomahawk/playlist/artistview.cpp index 9e30adec0..806756dc0 100644 --- a/src/libtomahawk/playlist/artistview.cpp +++ b/src/libtomahawk/playlist/artistview.cpp @@ -249,9 +249,13 @@ ArtistView::onScrollTimeout() trackInfo["artist"] = item->artist()->name(); trackInfo["pptr"] = QString::number( (qlonglong)item ); - Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( - s_tmInfoIdentifier, Tomahawk::InfoSystem::InfoArtistImages, - QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ), QVariantMap() ); + Tomahawk::InfoSystem::InfoRequestData requestData; + requestData.caller = s_tmInfoIdentifier; + requestData.type = Tomahawk::InfoSystem::InfoArtistImages; + requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ); + requestData.customData = QVariantMap(); + + Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData ); } } diff --git a/src/libtomahawk/playlist/treemodel.cpp b/src/libtomahawk/playlist/treemodel.cpp index ce7f86918..a0418be5f 100644 --- a/src/libtomahawk/playlist/treemodel.cpp +++ b/src/libtomahawk/playlist/treemodel.cpp @@ -47,8 +47,8 @@ TreeModel::TreeModel( QObject* parent ) connect( AudioEngine::instance(), SIGNAL( stopped() ), SLOT( onPlaybackStopped() ), Qt::DirectConnection ); connect( Tomahawk::InfoSystem::InfoSystem::instance(), - SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), - SLOT( infoSystemInfo( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ) ); + SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), + SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) ); connect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( finished( QString ) ), SLOT( infoSystemFinished( QString ) ) ); } @@ -542,9 +542,13 @@ TreeModel::onAlbumsAdded( const QList& albums, const QVaria trackInfo["album"] = album->name(); trackInfo["pptr"] = QString::number( (qlonglong)albumitem ); - Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( - s_tmInfoIdentifier, Tomahawk::InfoSystem::InfoAlbumCoverArt, - QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ), QVariantMap() ); + Tomahawk::InfoSystem::InfoRequestData requestData; + requestData.caller = s_tmInfoIdentifier; + requestData.type = Tomahawk::InfoSystem::InfoAlbumCoverArt; + requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ); + requestData.customData = QVariantMap(); + + Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData ); } if ( !parent.isValid() || crows.second > 0 ) @@ -600,13 +604,12 @@ TreeModel::onTracksAdded( const QList& tracks, const QVaria void -TreeModel::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, QVariantMap customData ) +TreeModel::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ) { - Q_UNUSED( customData ); qDebug() << Q_FUNC_INFO; - if ( caller != s_tmInfoIdentifier || - ( type != Tomahawk::InfoSystem::InfoAlbumCoverArt && type != Tomahawk::InfoSystem::InfoArtistImages ) ) + if ( requestData.caller != s_tmInfoIdentifier || + ( requestData.type != Tomahawk::InfoSystem::InfoAlbumCoverArt && requestData.type != Tomahawk::InfoSystem::InfoArtistImages ) ) { qDebug() << "Info of wrong type or not with our identifier"; return; @@ -618,7 +621,7 @@ TreeModel::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, return; } - Tomahawk::InfoSystem::InfoCriteriaHash pptr = input.value< Tomahawk::InfoSystem::InfoCriteriaHash >(); + Tomahawk::InfoSystem::InfoCriteriaHash pptr = requestData.input.value< Tomahawk::InfoSystem::InfoCriteriaHash >(); QVariantMap returnedData = output.value< QVariantMap >(); const QByteArray ba = returnedData["imgbytes"].toByteArray(); qDebug() << "ba.length = " << ba.length(); diff --git a/src/libtomahawk/playlist/treemodel.h b/src/libtomahawk/playlist/treemodel.h index be8a10a09..8ade79568 100644 --- a/src/libtomahawk/playlist/treemodel.h +++ b/src/libtomahawk/playlist/treemodel.h @@ -125,7 +125,7 @@ private slots: 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, QVariantMap customData ); + void infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ); void infoSystemFinished( QString target ); void onPlaybackFinished( const Tomahawk::result_ptr& result ); diff --git a/src/libtomahawk/sourceplaylistinterface.cpp b/src/libtomahawk/sourceplaylistinterface.cpp index bf3fafb66..75c67839b 100644 --- a/src/libtomahawk/sourceplaylistinterface.cpp +++ b/src/libtomahawk/sourceplaylistinterface.cpp @@ -96,7 +96,6 @@ void SourcePlaylistInterface::onSourcePlaybackStarted( const Tomahawk::query_ptr& query ) { qDebug() << Q_FUNC_INFO; - connect( query.data(), SIGNAL( resultsAdded( const QList& ) ), SLOT( resolveResultsAdded( const QList& ) ) ); connect( query.data(), SIGNAL( resolvingFinished( bool ) ), SLOT( resolvingFinished( bool ) ) ); Pipeline::instance()->resolve( query, true ); m_gotNextItem = true; diff --git a/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.cpp b/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.cpp index c9664115f..2b1e7bdd0 100644 --- a/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.cpp +++ b/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.cpp @@ -64,8 +64,8 @@ ArtistInfoWidget::ArtistInfoWidget( const Tomahawk::artist_ptr& artist, QWidget* m_pixmap = QPixmap( RESPATH "images/no-album-art-placeholder.png" ).scaledToWidth( 48, Qt::SmoothTransformation ); connect( Tomahawk::InfoSystem::InfoSystem::instance(), - SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), - SLOT( infoSystemInfo( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ) ); + SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), + SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) ); connect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( finished( QString ) ), SLOT( infoSystemFinished( QString ) ) ); @@ -88,42 +88,39 @@ ArtistInfoWidget::load( const artist_ptr& artist ) Tomahawk::InfoSystem::InfoCriteriaHash artistInfo; artistInfo["artist"] = artist->name(); - InfoSystem::InfoTypeMap infoMap; - QVariantMap hash; - infoMap[InfoSystem::InfoArtistBiography] = artist->name(); + Tomahawk::InfoSystem::InfoRequestData requestData; + requestData.caller = s_aiInfoIdentifier; + requestData.customData = QVariantMap(); - Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( - s_aiInfoIdentifier, infoMap, hash ); + requestData.input = artist->name(); + requestData.type = Tomahawk::InfoSystem::InfoArtistBiography; + Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData ); + + requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( artistInfo ); + + requestData.type = Tomahawk::InfoSystem::InfoArtistImages; + Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData ); - Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( - s_aiInfoIdentifier, Tomahawk::InfoSystem::InfoArtistImages, - QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( artistInfo ), QVariantMap() ); + requestData.type = Tomahawk::InfoSystem::InfoArtistSimilars; + Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData ); - Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( - s_aiInfoIdentifier, Tomahawk::InfoSystem::InfoArtistSimilars, - QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( artistInfo ), QVariantMap() ); - - Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( - s_aiInfoIdentifier, Tomahawk::InfoSystem::InfoArtistSongs, - QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( artistInfo ), QVariantMap() ); + requestData.type = Tomahawk::InfoSystem::InfoArtistSongs; + Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData ); } void -ArtistInfoWidget::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, QVariantMap customData ) +ArtistInfoWidget::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ) { - Q_UNUSED( input ); - Q_UNUSED( customData ); - - if ( caller != s_aiInfoIdentifier ) + if ( requestData.caller != s_aiInfoIdentifier ) { // qDebug() << "Info of wrong type or not with our identifier"; return; } - qDebug() << Q_FUNC_INFO << caller << type << s_aiInfoIdentifier; + qDebug() << Q_FUNC_INFO << requestData.caller << requestData.type << s_aiInfoIdentifier; InfoSystem::InfoCriteriaHash trackInfo; - trackInfo = input.value< InfoSystem::InfoCriteriaHash >(); + trackInfo = requestData.input.value< InfoSystem::InfoCriteriaHash >(); if ( output.canConvert< QVariantMap >() ) { @@ -135,7 +132,7 @@ ArtistInfoWidget::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType } QVariantMap returnedData = output.value< QVariantMap >(); - switch ( type ) + switch ( requestData.type ) { case InfoSystem::InfoArtistBiography: { diff --git a/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.h b/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.h index df3ed01e2..d8c535424 100644 --- a/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.h +++ b/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.h @@ -86,7 +86,7 @@ protected: void changeEvent( QEvent* e ); private slots: - void infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, QVariantMap customData ); + void infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ); void infoSystemFinished( QString target ); private: diff --git a/src/scrobbler.cpp b/src/scrobbler.cpp index f3e6f268d..f79abe917 100644 --- a/src/scrobbler.cpp +++ b/src/scrobbler.cpp @@ -38,8 +38,8 @@ Scrobbler::Scrobbler( QObject* parent ) SLOT( engineTick( unsigned int ) ), Qt::QueuedConnection ); connect( Tomahawk::InfoSystem::InfoSystem::instance(), - SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ), - SLOT( infoSystemInfo( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, QVariantMap ) ) ); + SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), + SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) ); connect( AudioEngine::instance(), SIGNAL( started( const Tomahawk::result_ptr& ) ), SLOT( trackStarted( const Tomahawk::result_ptr& ) ), Qt::QueuedConnection ); @@ -80,9 +80,14 @@ Scrobbler::trackStarted( const Tomahawk::result_ptr& track ) trackInfo["artist"] = track->artist()->name(); trackInfo["album"] = track->album()->name(); trackInfo["duration"] = QString::number( track->duration() ); - Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( - s_scInfoIdentifier, Tomahawk::InfoSystem::InfoSubmitNowPlaying, - QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ) ); + + Tomahawk::InfoSystem::InfoRequestData requestData; + requestData.caller = s_scInfoIdentifier; + requestData.type = Tomahawk::InfoSystem::InfoArtistImages; + requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ); + requestData.customData = QVariantMap(); + + Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData ); m_scrobblePoint = ScrobblePoint( track->duration() / 2 ); } @@ -135,13 +140,10 @@ Scrobbler::scrobble() void -Scrobbler::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, QVariantMap customData ) +Scrobbler::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ) { - Q_UNUSED( type ); - Q_UNUSED( input ); Q_UNUSED( output ); - Q_UNUSED( customData ); - if ( caller == s_scInfoIdentifier ) + if ( requestData.caller == s_scInfoIdentifier ) qDebug() << Q_FUNC_INFO; } diff --git a/src/scrobbler.h b/src/scrobbler.h index 380b94267..87c78290b 100644 --- a/src/scrobbler.h +++ b/src/scrobbler.h @@ -45,7 +45,7 @@ public slots: void trackStopped(); void engineTick( unsigned int secondsElapsed ); - void infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, QVariantMap customData ); + void infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ); void infoSystemFinished( QString target ); private: diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index 157229548..ff5cacc7b 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -420,6 +420,7 @@ TomahawkApp::registerMetaTypes() qRegisterMetaType< QMap< QString, QMap< QString, QString > > >( "Tomahawk::InfoSystem::InfoGenericMap" ); qRegisterMetaType< QHash< QString, QString > >( "Tomahawk::InfoSystem::InfoCriteriaHash" ); qRegisterMetaType< Tomahawk::InfoSystem::InfoType >( "Tomahawk::InfoSystem::InfoType" ); + qRegisterMetaType< Tomahawk::InfoSystem::InfoRequestData >( "Tomahawk::InfoSystem::InfoRequestData" ); qRegisterMetaType< QWeakPointer< Tomahawk::InfoSystem::InfoSystemCache > >( "QWeakPointer< Tomahawk::InfoSystem::InfoSystemCache >" ); qRegisterMetaType< DirLister::Mode >("DirLister::Mode");