mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-09-07 12:40:45 +02:00
Compare commits
1 Commits
zeroconf-f
...
formatting
Author | SHA1 | Date | |
---|---|---|---|
|
c950ae0b2e |
@@ -67,7 +67,9 @@ GoogleWrapperSip::showAddFriendDialog()
|
||||
QString id = QInputDialog::getText( TomahawkUtils::tomahawkWindow(), tr( "Add Friend" ),
|
||||
tr( "Enter Google Address:" ), QLineEdit::Normal, "", &ok );
|
||||
if ( !ok )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "Attempting to add google contact to roster:" << id;
|
||||
addContact( id, SendInvite );
|
||||
@@ -111,7 +113,9 @@ GoogleWrapper::sipPlugin( bool create )
|
||||
if ( m_xmppSipPlugin.isNull() )
|
||||
{
|
||||
if ( !create )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
m_xmppSipPlugin = QPointer< XmppSipPlugin >( new GoogleWrapperSip( const_cast< GoogleWrapper* >( this ) ) );
|
||||
|
||||
|
@@ -35,13 +35,22 @@ class ACCOUNTDLLEXPORT GoogleWrapperFactory : public XmppAccountFactory
|
||||
Q_INTERFACES( Tomahawk::Accounts::AccountFactory )
|
||||
Q_PLUGIN_METADATA( IID "org.tomahawk-player.Player.AccountFactory" )
|
||||
|
||||
public:
|
||||
public:
|
||||
GoogleWrapperFactory() {}
|
||||
virtual ~GoogleWrapperFactory() {}
|
||||
|
||||
virtual QString prettyName() const { return "Google"; }
|
||||
virtual QString factoryId() const { return "googleaccount"; }
|
||||
QString description() const { return tr( "Connect to Google Talk to find your friends" ); }
|
||||
virtual QString prettyName() const
|
||||
{
|
||||
return "Google";
|
||||
}
|
||||
virtual QString factoryId() const
|
||||
{
|
||||
return "googleaccount";
|
||||
}
|
||||
QString description() const
|
||||
{
|
||||
return tr( "Connect to Google Talk to find your friends" );
|
||||
}
|
||||
virtual QPixmap icon() const;
|
||||
virtual Account* createAccount( const QString& pluginId );
|
||||
};
|
||||
@@ -49,32 +58,38 @@ public:
|
||||
class ACCOUNTDLLEXPORT GoogleWrapperSip : public XmppSipPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
public:
|
||||
GoogleWrapperSip( Tomahawk::Accounts::Account* account );
|
||||
virtual ~GoogleWrapperSip();
|
||||
|
||||
virtual QString inviteString() const;
|
||||
|
||||
public slots:
|
||||
public slots:
|
||||
void showAddFriendDialog();
|
||||
|
||||
protected:
|
||||
protected:
|
||||
QString defaultSuffix() const;
|
||||
};
|
||||
|
||||
class ACCOUNTDLLEXPORT GoogleWrapper : public XmppAccount
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
public:
|
||||
GoogleWrapper( const QString& pluginID );
|
||||
virtual ~GoogleWrapper();
|
||||
|
||||
virtual const QString name() const { return QString( "Google" ); }
|
||||
virtual const QString friendlyName() const { return "Google"; }
|
||||
virtual const QString name() const
|
||||
{
|
||||
return QString( "Google" );
|
||||
}
|
||||
virtual const QString friendlyName() const
|
||||
{
|
||||
return "Google";
|
||||
}
|
||||
|
||||
virtual SipPlugin* sipPlugin( bool create = true );
|
||||
|
||||
private:
|
||||
private:
|
||||
QPointer< GoogleWrapperSip > m_sipPlugin;
|
||||
};
|
||||
|
||||
|
@@ -43,14 +43,16 @@ using namespace Accounts;
|
||||
static QPixmap* s_icon = 0;
|
||||
HatchetAccount* HatchetAccount::s_instance = 0;
|
||||
|
||||
const QString c_loginServer("https://auth.hatchet.is/v1");
|
||||
const QString c_accessTokenServer("https://auth.hatchet.is/v1");
|
||||
const QString c_loginServer( "https://auth.hatchet.is/v1" );
|
||||
const QString c_accessTokenServer( "https://auth.hatchet.is/v1" );
|
||||
|
||||
HatchetAccountFactory::HatchetAccountFactory()
|
||||
{
|
||||
#ifndef ENABLE_HEADLESS
|
||||
if ( s_icon == 0 )
|
||||
{
|
||||
s_icon = new QPixmap( ":/hatchet-account/hatchet-icon-512x512.png" );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -86,21 +88,21 @@ HatchetAccount::HatchetAccount( const QString& accountId )
|
||||
setAccountServiceName( "Hatchet" );
|
||||
// We're connecting peers.
|
||||
setTypes( SipType );
|
||||
/*
|
||||
QFile pemFile( ":/hatchet-account/mandella.pem" );
|
||||
pemFile.open( QIODevice::ReadOnly );
|
||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "certs/mandella.pem: " << pemFile.readAll();
|
||||
pemFile.close();
|
||||
pemFile.open( QIODevice::ReadOnly );
|
||||
QCA::ConvertResult conversionResult;
|
||||
QCA::PublicKey publicKey = QCA::PublicKey::fromPEM(pemFile.readAll(), &conversionResult);
|
||||
if ( QCA::ConvertGood != conversionResult )
|
||||
{
|
||||
tLog() << Q_FUNC_INFO << "INVALID PUBKEY READ";
|
||||
return;
|
||||
}
|
||||
m_publicKey = new QCA::PublicKey( publicKey );
|
||||
*/
|
||||
/*
|
||||
QFile pemFile( ":/hatchet-account/mandella.pem" );
|
||||
pemFile.open( QIODevice::ReadOnly );
|
||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "certs/mandella.pem: " << pemFile.readAll();
|
||||
pemFile.close();
|
||||
pemFile.open( QIODevice::ReadOnly );
|
||||
QCA::ConvertResult conversionResult;
|
||||
QCA::PublicKey publicKey = QCA::PublicKey::fromPEM(pemFile.readAll(), &conversionResult);
|
||||
if ( QCA::ConvertGood != conversionResult )
|
||||
{
|
||||
tLog() << Q_FUNC_INFO << "INVALID PUBKEY READ";
|
||||
return;
|
||||
}
|
||||
m_publicKey = new QCA::PublicKey( publicKey );
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
@@ -121,7 +123,9 @@ AccountConfigWidget*
|
||||
HatchetAccount::configurationWidget()
|
||||
{
|
||||
if ( m_configWidget.isNull() )
|
||||
{
|
||||
m_configWidget = QPointer<HatchetAccountConfig>( new HatchetAccountConfig( this ) );
|
||||
}
|
||||
|
||||
return m_configWidget.data();
|
||||
}
|
||||
@@ -131,13 +135,17 @@ void
|
||||
HatchetAccount::authenticate()
|
||||
{
|
||||
if ( connectionState() == Connected )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !refreshToken().isEmpty() )
|
||||
{
|
||||
qDebug() << "Have saved credentials with refresh token:" << refreshToken();
|
||||
if ( sipPlugin() )
|
||||
{
|
||||
sipPlugin()->connectPlugin();
|
||||
}
|
||||
setAccountFriendlyName( username() );
|
||||
}
|
||||
else if ( !username().isEmpty() )
|
||||
@@ -152,7 +160,9 @@ void
|
||||
HatchetAccount::deauthenticate()
|
||||
{
|
||||
if ( !m_tomahawkSipPlugin.isNull() )
|
||||
{
|
||||
m_tomahawkSipPlugin->disconnectPlugin();
|
||||
}
|
||||
emit deauthenticated();
|
||||
}
|
||||
|
||||
@@ -179,7 +189,9 @@ HatchetAccount::sipPlugin( bool create )
|
||||
if ( m_tomahawkSipPlugin.isNull() )
|
||||
{
|
||||
if ( !create )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
tLog() << Q_FUNC_INFO;
|
||||
m_tomahawkSipPlugin = QPointer< HatchetSipPlugin >( new HatchetSipPlugin( this ) );
|
||||
@@ -249,7 +261,7 @@ HatchetAccount::mandellaTokenType() const
|
||||
|
||||
|
||||
void
|
||||
HatchetAccount::loginWithPassword( const QString& username, const QString& password, const QString &otp )
|
||||
HatchetAccount::loginWithPassword( const QString& username, const QString& password, const QString& otp )
|
||||
{
|
||||
//if ( username.isEmpty() || password.isEmpty() || !m_publicKey )
|
||||
if ( username.isEmpty() || password.isEmpty() )
|
||||
@@ -265,7 +277,7 @@ HatchetAccount::loginWithPassword( const QString& username, const QString& passw
|
||||
params[ "nonce" ] = QString( result.toByteArray().toBase64() );
|
||||
*/
|
||||
|
||||
QNetworkRequest req( QUrl( c_loginServer + "/authentication/password") );
|
||||
QNetworkRequest req( QUrl( c_loginServer + "/authentication/password" ) );
|
||||
req.setHeader( QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded" );
|
||||
|
||||
QUrl params;
|
||||
@@ -273,7 +285,9 @@ HatchetAccount::loginWithPassword( const QString& username, const QString& passw
|
||||
TomahawkUtils::urlAddQueryItem( params, "password", password );
|
||||
TomahawkUtils::urlAddQueryItem( params, "grant_type", "password" );
|
||||
if ( !otp.isEmpty() )
|
||||
{
|
||||
TomahawkUtils::urlAddQueryItem( params, "otp", otp );
|
||||
}
|
||||
|
||||
QByteArray data = TomahawkUtils::encodedQuery( params );
|
||||
|
||||
@@ -292,9 +306,9 @@ HatchetAccount::fetchAccessToken( const QString& type )
|
||||
return;
|
||||
}
|
||||
if ( mandellaAccessToken().isEmpty() ||
|
||||
(mandellaAccessTokenExpiration() < QDateTime::currentDateTime().toTime_t() &&
|
||||
(refreshToken().isEmpty() ||
|
||||
(refreshTokenExpiration() != 0 && refreshTokenExpiration() < QDateTime::currentDateTime().toTime_t()))) )
|
||||
( mandellaAccessTokenExpiration() < QDateTime::currentDateTime().toTime_t() &&
|
||||
( refreshToken().isEmpty() ||
|
||||
( refreshTokenExpiration() != 0 && refreshTokenExpiration() < QDateTime::currentDateTime().toTime_t() ) ) ) )
|
||||
{
|
||||
tLog() << "No valid combination of access/refresh tokens, not logging in";
|
||||
tLog() << "Mandella access token expiration:" << mandellaAccessTokenExpiration() << ", refresh token expiration:" << refreshTokenExpiration();
|
||||
@@ -315,7 +329,7 @@ HatchetAccount::fetchAccessToken( const QString& type )
|
||||
tLog() << "Fetching access tokens of type" << type;
|
||||
}
|
||||
|
||||
QNetworkRequest req( QUrl( c_accessTokenServer + "/tokens/" + (interceptionNeeded ? "refresh/" + QString::fromUtf8(mandellaTokenType()).toLower() : "fetch/" + type) ) );
|
||||
QNetworkRequest req( QUrl( c_accessTokenServer + "/tokens/" + ( interceptionNeeded ? "refresh/" + QString::fromUtf8( mandellaTokenType() ).toLower() : "fetch/" + type ) ) );
|
||||
QNetworkReply* reply;
|
||||
|
||||
if ( interceptionNeeded )
|
||||
@@ -332,9 +346,9 @@ HatchetAccount::fetchAccessToken( const QString& type )
|
||||
else
|
||||
{
|
||||
tLog() << "Fetching token of type" << type;
|
||||
req.setRawHeader( "Authorization", QString( mandellaTokenType() + " " + mandellaAccessToken()).toUtf8() );
|
||||
req.setRawHeader( "Authorization", QString( mandellaTokenType() + " " + mandellaAccessToken() ).toUtf8() );
|
||||
reply = Tomahawk::Utils::nam()->get( req );
|
||||
}
|
||||
}
|
||||
|
||||
NewClosure( reply, SIGNAL( finished() ), this, SLOT( onFetchAccessTokenFinished( QNetworkReply*, const QString& ) ), reply, type );
|
||||
}
|
||||
@@ -419,7 +433,9 @@ HatchetAccount::onPasswordLoginFinished( QNetworkReply* reply, const QString& us
|
||||
syncConfig();
|
||||
|
||||
if ( sipPlugin() )
|
||||
{
|
||||
sipPlugin()->connectPlugin();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@@ -42,16 +42,31 @@ class ACCOUNTDLLEXPORT HatchetAccountFactory : public AccountFactory
|
||||
Q_INTERFACES( Tomahawk::Accounts::AccountFactory )
|
||||
Q_PLUGIN_METADATA( IID "org.tomahawk-player.Player.AccountFactory" )
|
||||
|
||||
public:
|
||||
public:
|
||||
HatchetAccountFactory();
|
||||
virtual ~HatchetAccountFactory();
|
||||
|
||||
virtual QString factoryId() const { return "hatchetaccount"; }
|
||||
virtual QString prettyName() const { return "Hatchet"; }
|
||||
virtual QString description() const { return tr( "Connect to your Hatchet account" ); }
|
||||
virtual bool isUnique() const { return true; }
|
||||
AccountTypes types() const { return AccountTypes( SipType ); }
|
||||
// virtual bool allowUserCreation() const { return false; }
|
||||
virtual QString factoryId() const
|
||||
{
|
||||
return "hatchetaccount";
|
||||
}
|
||||
virtual QString prettyName() const
|
||||
{
|
||||
return "Hatchet";
|
||||
}
|
||||
virtual QString description() const
|
||||
{
|
||||
return tr( "Connect to your Hatchet account" );
|
||||
}
|
||||
virtual bool isUnique() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
AccountTypes types() const
|
||||
{
|
||||
return AccountTypes( SipType );
|
||||
}
|
||||
// virtual bool allowUserCreation() const { return false; }
|
||||
virtual QPixmap icon() const;
|
||||
|
||||
virtual Account* createAccount ( const QString& pluginId = QString() );
|
||||
@@ -60,12 +75,13 @@ public:
|
||||
class ACCOUNTDLLEXPORT HatchetAccount : public Account
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Service {
|
||||
public:
|
||||
enum Service
|
||||
{
|
||||
Facebook = 0
|
||||
};
|
||||
|
||||
HatchetAccount( const QString &accountId );
|
||||
HatchetAccount( const QString& accountId );
|
||||
virtual ~HatchetAccount();
|
||||
|
||||
static HatchetAccount* instance();
|
||||
@@ -79,26 +95,32 @@ public:
|
||||
void setConnectionState( Account::ConnectionState connectionState );
|
||||
ConnectionState connectionState() const;
|
||||
|
||||
virtual Tomahawk::InfoSystem::InfoPluginPtr infoPlugin() { return Tomahawk::InfoSystem::InfoPluginPtr(); }
|
||||
virtual Tomahawk::InfoSystem::InfoPluginPtr infoPlugin()
|
||||
{
|
||||
return Tomahawk::InfoSystem::InfoPluginPtr();
|
||||
}
|
||||
SipPlugin* sipPlugin( bool create = true );
|
||||
|
||||
AccountConfigWidget* configurationWidget();
|
||||
QWidget* aclWidget() { return 0; }
|
||||
QWidget* aclWidget()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
QString username() const;
|
||||
|
||||
void fetchAccessToken( const QString& type = "dreamcatcher" );
|
||||
|
||||
signals:
|
||||
signals:
|
||||
void authError( QString error, int statusCode, const QVariantMap );
|
||||
void deauthenticated();
|
||||
void accessTokenFetched();
|
||||
|
||||
private slots:
|
||||
private slots:
|
||||
void onPasswordLoginFinished( QNetworkReply*, const QString& username );
|
||||
void onFetchAccessTokenFinished( QNetworkReply*, const QString& type );
|
||||
|
||||
private:
|
||||
private:
|
||||
QByteArray refreshToken() const;
|
||||
uint refreshTokenExpiration() const;
|
||||
|
||||
@@ -107,7 +129,7 @@ private:
|
||||
|
||||
QByteArray mandellaTokenType() const;
|
||||
|
||||
void loginWithPassword( const QString& username, const QString& password, const QString &otp );
|
||||
void loginWithPassword( const QString& username, const QString& password, const QString& otp );
|
||||
|
||||
QVariantMap parseReply( QNetworkReply* reply, bool& ok ) const;
|
||||
|
||||
|
@@ -28,12 +28,14 @@
|
||||
using namespace Tomahawk;
|
||||
using namespace Accounts;
|
||||
|
||||
namespace {
|
||||
enum ButtonAction {
|
||||
Login,
|
||||
Register,
|
||||
Logout
|
||||
};
|
||||
namespace
|
||||
{
|
||||
enum ButtonAction
|
||||
{
|
||||
Login,
|
||||
Register,
|
||||
Logout
|
||||
};
|
||||
}
|
||||
|
||||
HatchetAccountConfig::HatchetAccountConfig( HatchetAccount* account )
|
||||
@@ -59,7 +61,9 @@ HatchetAccountConfig::HatchetAccountConfig( HatchetAccount* account )
|
||||
connect( m_account, SIGNAL( accessTokenFetched() ), this, SLOT( accountInfoUpdated() ) );
|
||||
|
||||
if ( !m_account->refreshToken().isEmpty() )
|
||||
{
|
||||
accountInfoUpdated();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ui->usernameEdit->setText( m_account->username() );
|
||||
@@ -131,7 +135,7 @@ HatchetAccountConfig::showLoggedIn()
|
||||
m_ui->errorLabel->clear();
|
||||
m_ui->errorLabel->hide();
|
||||
|
||||
m_ui->loginButton->setText( tr("Log out") );
|
||||
m_ui->loginButton->setText( tr( "Log out" ) );
|
||||
m_ui->loginButton->setProperty( "action", Logout );
|
||||
m_ui->loginButton->setDefault( true );
|
||||
}
|
||||
@@ -153,7 +157,7 @@ HatchetAccountConfig::showLoggedOut()
|
||||
|
||||
m_ui->errorLabel->clear();
|
||||
|
||||
m_ui->loginButton->setText( tr("Log in") );
|
||||
m_ui->loginButton->setText( tr( "Log in" ) );
|
||||
m_ui->loginButton->setProperty( "action", Login );
|
||||
m_ui->loginButton->setDefault( true );
|
||||
}
|
||||
@@ -168,7 +172,7 @@ HatchetAccountConfig::accountInfoUpdated()
|
||||
|
||||
|
||||
void
|
||||
HatchetAccountConfig::authError( const QString &error, int statusCode, const QVariantMap& resp )
|
||||
HatchetAccountConfig::authError( const QString& error, int statusCode, const QVariantMap& resp )
|
||||
{
|
||||
if ( statusCode == 400 && error == "otp_needed" )
|
||||
{
|
||||
@@ -178,17 +182,19 @@ HatchetAccountConfig::authError( const QString &error, int statusCode, const QVa
|
||||
m_ui->otpEdit->show();
|
||||
m_ui->passwordLabel->hide();
|
||||
m_ui->passwordEdit->hide();
|
||||
m_ui->loginButton->setText( tr("Continue") );
|
||||
m_ui->loginButton->setText( tr( "Continue" ) );
|
||||
return;
|
||||
}
|
||||
if ( statusCode == 401 )
|
||||
{
|
||||
m_account->deauthenticate();
|
||||
}
|
||||
QMessageBox::critical( this, "An error was encountered:", error );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
HatchetAccountConfig::showEvent( QShowEvent *event )
|
||||
HatchetAccountConfig::showEvent( QShowEvent* event )
|
||||
{
|
||||
AccountConfigWidget::showEvent( event );
|
||||
m_ui->loginButton->setDefault( true );
|
||||
|
@@ -26,23 +26,26 @@
|
||||
|
||||
class QNetworkReply;
|
||||
|
||||
namespace Ui {
|
||||
class HatchetAccountConfig;
|
||||
namespace Ui
|
||||
{
|
||||
class HatchetAccountConfig;
|
||||
}
|
||||
|
||||
namespace Tomahawk {
|
||||
namespace Accounts {
|
||||
namespace Tomahawk
|
||||
{
|
||||
namespace Accounts
|
||||
{
|
||||
|
||||
class HatchetAccount;
|
||||
|
||||
class HatchetAccountConfig : public AccountConfigWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
public:
|
||||
explicit HatchetAccountConfig( HatchetAccount* account );
|
||||
virtual ~HatchetAccountConfig();
|
||||
|
||||
private slots:
|
||||
private slots:
|
||||
void login();
|
||||
|
||||
void fieldsChanged();
|
||||
@@ -54,11 +57,11 @@ private slots:
|
||||
|
||||
void authError( const QString& error, int statusCode, const QVariantMap& resp );
|
||||
|
||||
protected:
|
||||
protected:
|
||||
//virtual void changeEvent( QEvent* event );
|
||||
virtual void showEvent( QShowEvent* event );
|
||||
|
||||
private:
|
||||
private:
|
||||
Ui::HatchetAccountConfig* m_ui;
|
||||
HatchetAccount* m_account;
|
||||
};
|
||||
|
@@ -39,7 +39,7 @@
|
||||
#include <QHostInfo>
|
||||
#include <QUuid>
|
||||
|
||||
HatchetSipPlugin::HatchetSipPlugin( Tomahawk::Accounts::Account *account )
|
||||
HatchetSipPlugin::HatchetSipPlugin( Tomahawk::Accounts::Account* account )
|
||||
: SipPlugin( account )
|
||||
, m_sipState( Closed )
|
||||
, m_version( 0 )
|
||||
@@ -49,7 +49,7 @@ HatchetSipPlugin::HatchetSipPlugin( Tomahawk::Accounts::Account *account )
|
||||
tLog() << Q_FUNC_INFO;
|
||||
|
||||
connect( m_account, SIGNAL( accessTokenFetched() ), this, SLOT( connectWebSocket() ) );
|
||||
connect( Servent::instance(), SIGNAL( dbSyncTriggered() ), this, SLOT( dbSyncTriggered() ));
|
||||
connect( Servent::instance(), SIGNAL( dbSyncTriggered() ), this, SLOT( dbSyncTriggered() ) );
|
||||
|
||||
/*
|
||||
QFile pemFile( ":/hatchet-account/dreamcatcher.pem" );
|
||||
@@ -125,9 +125,13 @@ HatchetSipPlugin::disconnectPlugin()
|
||||
{
|
||||
tLog() << Q_FUNC_INFO;
|
||||
if ( m_webSocketThreadController && m_webSocketThreadController->isRunning() )
|
||||
{
|
||||
emit disconnectWebSocket();
|
||||
}
|
||||
else
|
||||
{
|
||||
webSocketDisconnected();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -155,8 +159,8 @@ HatchetSipPlugin::connectWebSocket()
|
||||
|
||||
if ( !isValid() )
|
||||
{
|
||||
tLog() << Q_FUNC_INFO << "Invalid state, not continuing with connection";
|
||||
return;
|
||||
tLog() << Q_FUNC_INFO << "Invalid state, not continuing with connection";
|
||||
return;
|
||||
}
|
||||
|
||||
m_token = m_account->credentials()[ "dreamcatcher_access_token" ].toString();
|
||||
@@ -164,7 +168,7 @@ HatchetSipPlugin::connectWebSocket()
|
||||
|
||||
if ( m_token.isEmpty() )
|
||||
{
|
||||
tLog() << Q_FUNC_INFO << "Unable to find an access token";
|
||||
tLog() << Q_FUNC_INFO << "Unable to find an access token";
|
||||
disconnectPlugin();
|
||||
return;
|
||||
}
|
||||
@@ -263,7 +267,7 @@ HatchetSipPlugin::sendBytes( const QVariantMap& jsonMap ) const
|
||||
|
||||
|
||||
void
|
||||
HatchetSipPlugin::messageReceived( const QByteArray &msg )
|
||||
HatchetSipPlugin::messageReceived( const QByteArray& msg )
|
||||
{
|
||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "WebSocket message: " << msg;
|
||||
|
||||
@@ -344,7 +348,7 @@ HatchetSipPlugin::messageReceived( const QByteArray &msg )
|
||||
m_sipState = Connected;
|
||||
hatchetAccount()->setConnectionState( Tomahawk::Accounts::Account::Connected );
|
||||
m_reconnectTimer.setInterval( 0 );
|
||||
QTimer::singleShot(0, this, SLOT( dbSyncTriggered() ) );
|
||||
QTimer::singleShot( 0, this, SLOT( dbSyncTriggered() ) );
|
||||
return;
|
||||
}
|
||||
else
|
||||
@@ -361,7 +365,7 @@ HatchetSipPlugin::messageReceived( const QByteArray &msg )
|
||||
return;
|
||||
}
|
||||
else if ( !retMap.contains( "command" ) ||
|
||||
!retMap[ "command" ].canConvert< QString >() )
|
||||
!retMap[ "command" ].canConvert< QString >() )
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO << "Unable to convert and/or interepret command from server";
|
||||
return;
|
||||
@@ -370,11 +374,17 @@ HatchetSipPlugin::messageReceived( const QByteArray &msg )
|
||||
QString command = retMap[ "command" ].toString();
|
||||
|
||||
if ( command == "new-peer" )
|
||||
{
|
||||
newPeer( retMap );
|
||||
}
|
||||
else if ( command == "peer-authorization" )
|
||||
{
|
||||
peerAuthorization( retMap );
|
||||
}
|
||||
else if ( command == "synclastseen" )
|
||||
{
|
||||
sendOplog( retMap );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -407,7 +417,9 @@ HatchetSipPlugin::newPeer( const QVariantMap& valMap )
|
||||
|
||||
QStringList keys( QStringList() << "command" << "username" << "hostinfo" << "dbid" );
|
||||
if ( !checkKeys( keys, valMap ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Tomahawk::peerinfo_ptr peerInfo = Tomahawk::PeerInfo::get( this, dbid, Tomahawk::PeerInfo::AutoCreate );
|
||||
peerInfo->setContactId( username );
|
||||
@@ -421,18 +433,24 @@ HatchetSipPlugin::newPeer( const QVariantMap& valMap )
|
||||
foreach ( const QVariant listItem, hostinfo )
|
||||
{
|
||||
if ( !listItem.canConvert< QVariantMap >() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
QVariantMap hostpair = listItem.toMap();
|
||||
|
||||
if ( !hostpair.contains( "host" ) || !hostpair.contains( "port" ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const QString host = hostpair[ "host" ].toString();
|
||||
unsigned int port = hostpair[ "port" ].toUInt();
|
||||
|
||||
if ( host.isEmpty() || port == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
SipInfo sipInfo;
|
||||
sipInfo.setNodeId( dbid );
|
||||
@@ -449,7 +467,7 @@ HatchetSipPlugin::newPeer( const QVariantMap& valMap )
|
||||
|
||||
|
||||
void
|
||||
HatchetSipPlugin::sendSipInfos(const Tomahawk::peerinfo_ptr& receiver, const QList< SipInfo >& infos)
|
||||
HatchetSipPlugin::sendSipInfos( const Tomahawk::peerinfo_ptr& receiver, const QList< SipInfo >& infos )
|
||||
{
|
||||
if ( infos.size() == 0 )
|
||||
{
|
||||
@@ -466,7 +484,9 @@ HatchetSipPlugin::sendSipInfos(const Tomahawk::peerinfo_ptr& receiver, const QLi
|
||||
sendMap[ "offerkey" ] = infos[ 0 ].key();
|
||||
|
||||
if ( !sendBytes( sendMap ) )
|
||||
{
|
||||
tLog() << Q_FUNC_INFO << "Failed sending message";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -477,7 +497,9 @@ HatchetSipPlugin::peerAuthorization( const QVariantMap& valMap )
|
||||
|
||||
QStringList keys( QStringList() << "command" << "dbid" << "offerkey" );
|
||||
if ( !checkKeys( keys, valMap ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QString dbid = valMap[ "dbid" ].toString();
|
||||
|
||||
@@ -489,8 +511,10 @@ HatchetSipPlugin::peerAuthorization( const QVariantMap& valMap )
|
||||
}
|
||||
|
||||
QList< SipInfo > sipInfos = m_sipInfoHash[ dbid ];
|
||||
for (int i = 0; i < sipInfos.size(); i++)
|
||||
for ( int i = 0; i < sipInfos.size(); i++ )
|
||||
{
|
||||
sipInfos[i].setKey( valMap[ "offerkey" ].toString() );
|
||||
}
|
||||
peerInfo->setSipInfos( sipInfos );
|
||||
m_sipInfoHash.remove( dbid );
|
||||
}
|
||||
@@ -502,10 +526,14 @@ void
|
||||
HatchetSipPlugin::dbSyncTriggered()
|
||||
{
|
||||
if ( m_sipState != Connected )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !SourceList::instance() || SourceList::instance()->getLocal().isNull() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QVariantMap sourceMap;
|
||||
sourceMap[ "command" ] = "synctrigger";
|
||||
@@ -567,10 +595,14 @@ HatchetSipPlugin::oplogFetched( const QString& sinceguid, const QString& /* last
|
||||
revMap[ "payload" ] = op->payload;
|
||||
currBytes += op->payload.length();
|
||||
}
|
||||
if ( currBytes >= (int)(byteMax - 1000000) ) // tack on an extra 1M for safety as it seems qjson puts in spaces
|
||||
if ( currBytes >= ( int )( byteMax - 1000000 ) ) // tack on an extra 1M for safety as it seems qjson puts in spaces
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
revisions << revMap;
|
||||
{
|
||||
revisions << revMap;
|
||||
}
|
||||
}
|
||||
tDebug() << Q_FUNC_INFO << "Sending" << revisions.size() << "revisions";
|
||||
commandMap[ "revisions" ] = revisions;
|
||||
|
@@ -36,15 +36,16 @@ class ACCOUNTDLLEXPORT HatchetSipPlugin : public SipPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
enum SipState {
|
||||
enum SipState
|
||||
{
|
||||
AcquiringVersion,
|
||||
Registering,
|
||||
Connected,
|
||||
Closed
|
||||
};
|
||||
|
||||
public:
|
||||
HatchetSipPlugin( Tomahawk::Accounts::Account *account );
|
||||
public:
|
||||
HatchetSipPlugin( Tomahawk::Accounts::Account* account );
|
||||
|
||||
virtual ~HatchetSipPlugin();
|
||||
|
||||
@@ -52,28 +53,31 @@ public:
|
||||
|
||||
virtual void sendSipInfos( const Tomahawk::peerinfo_ptr& receiver, const QList< SipInfo >& infos );
|
||||
|
||||
public slots:
|
||||
public slots:
|
||||
virtual void connectPlugin();
|
||||
void disconnectPlugin();
|
||||
void checkSettings() {}
|
||||
void configurationChanged() {}
|
||||
bool addContact( const QString&, AddContactOptions, const QString& ) { return false; }
|
||||
bool addContact( const QString&, AddContactOptions, const QString& )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
void sendMsg( const QString&, const SipInfo& ) {}
|
||||
void webSocketConnected();
|
||||
void webSocketDisconnected();
|
||||
|
||||
signals:
|
||||
signals:
|
||||
void connectWebSocket() const;
|
||||
void disconnectWebSocket() const;
|
||||
void rawBytes( QByteArray bytes ) const;
|
||||
|
||||
private slots:
|
||||
private slots:
|
||||
void dbSyncTriggered();
|
||||
void messageReceived( const QByteArray& msg );
|
||||
void connectWebSocket();
|
||||
void oplogFetched( const QString& sinceguid, const QString& lastguid, const QList< dbop_ptr > ops );
|
||||
|
||||
private:
|
||||
private:
|
||||
bool sendBytes( const QVariantMap& jsonMap ) const;
|
||||
bool checkKeys( QStringList keys, const QVariantMap& map ) const;
|
||||
void newPeer( const QVariantMap& valMap );
|
||||
|
@@ -34,8 +34,8 @@ WebSocket::WebSocket( const QString& url, const QString& authorizationHeader )
|
||||
{
|
||||
tLog() << Q_FUNC_INFO << "WebSocket constructing";
|
||||
m_client = std::unique_ptr< hatchet_client >( new hatchet_client() );
|
||||
m_client->set_message_handler( std::bind(&onMessage, this, std::placeholders::_1, std::placeholders::_2 ) );
|
||||
m_client->set_close_handler( std::bind(&onClose, this, std::placeholders::_1 ) );
|
||||
m_client->set_message_handler( std::bind( &onMessage, this, std::placeholders::_1, std::placeholders::_2 ) );
|
||||
m_client->set_close_handler( std::bind( &onClose, this, std::placeholders::_1 ) );
|
||||
m_client->register_ostream( &m_outputStream );
|
||||
|
||||
m_connectionTimer.setSingleShot( true );
|
||||
@@ -61,7 +61,7 @@ WebSocket::~WebSocket()
|
||||
|
||||
|
||||
void
|
||||
WebSocket::setUrl( const QString &url )
|
||||
WebSocket::setUrl( const QString& url )
|
||||
{
|
||||
tLog() << Q_FUNC_INFO << "Setting url to" << url;
|
||||
if ( m_url == url )
|
||||
@@ -78,7 +78,7 @@ WebSocket::setUrl( const QString &url )
|
||||
|
||||
|
||||
void
|
||||
WebSocket::setAuthorizationHeader( const QString &authorizationHeader )
|
||||
WebSocket::setAuthorizationHeader( const QString& authorizationHeader )
|
||||
{
|
||||
tLog() << Q_FUNC_INFO << "Setting authorization header";
|
||||
if ( m_authorizationHeader == authorizationHeader )
|
||||
@@ -116,7 +116,7 @@ WebSocket::connectWs()
|
||||
|
||||
tLog() << Q_FUNC_INFO << "Establishing new connection";
|
||||
m_socket = QPointer< QSslSocket >( new QSslSocket( nullptr ) );
|
||||
m_socket->addCaCertificate( QSslCertificate::fromPath( ":/hatchet-account/startcomroot.pem").first() );
|
||||
m_socket->addCaCertificate( QSslCertificate::fromPath( ":/hatchet-account/startcomroot.pem" ).first() );
|
||||
QObject::connect( m_socket, SIGNAL( stateChanged( QAbstractSocket::SocketState ) ), SLOT( socketStateChanged( QAbstractSocket::SocketState ) ) );
|
||||
QObject::connect( m_socket, SIGNAL( sslErrors( const QList< QSslError >& ) ), SLOT( sslErrors( const QList< QSslError >& ) ) );
|
||||
QObject::connect( m_socket, SIGNAL( encrypted() ), SLOT( encrypted() ) );
|
||||
@@ -127,7 +127,7 @@ WebSocket::connectWs()
|
||||
|
||||
|
||||
void
|
||||
WebSocket::disconnectWs( websocketpp::close::status::value status, const QString &reason )
|
||||
WebSocket::disconnectWs( websocketpp::close::status::value status, const QString& reason )
|
||||
{
|
||||
tLog() << Q_FUNC_INFO << "Disconnecting";
|
||||
m_disconnecting = true;
|
||||
@@ -169,7 +169,9 @@ WebSocket::cleanup()
|
||||
m_outputStream.seekp( std::ios_base::end );
|
||||
m_queuedMessagesToSend.empty();
|
||||
if ( m_connection )
|
||||
{
|
||||
m_connection.reset();
|
||||
}
|
||||
|
||||
emit disconnected();
|
||||
}
|
||||
@@ -194,7 +196,9 @@ WebSocket::socketStateChanged( QAbstractSocket::SocketState state )
|
||||
break;
|
||||
case QAbstractSocket::UnconnectedState:
|
||||
if ( m_lastSocketState == QAbstractSocket::UnconnectedState )
|
||||
{
|
||||
return;
|
||||
}
|
||||
tLog() << Q_FUNC_INFO << "Socket now unconnected, cleaning up and emitting disconnected";
|
||||
m_socket->deleteLater();
|
||||
m_lastSocketState = QAbstractSocket::UnconnectedState;
|
||||
@@ -225,8 +229,8 @@ WebSocket::encrypted()
|
||||
tLog() << Q_FUNC_INFO << "Encrypted connection to Dreamcatcher established";
|
||||
error_code ec;
|
||||
|
||||
QUrl url(m_url);
|
||||
websocketpp::uri_ptr uri(new websocketpp::uri(false, url.host().toStdString(), url.port(), "/"));
|
||||
QUrl url( m_url );
|
||||
websocketpp::uri_ptr uri( new websocketpp::uri( false, url.host().toStdString(), url.port(), "/" ) );
|
||||
|
||||
m_connection = m_client->get_connection( uri, ec );
|
||||
if ( !m_connection || ec.value() != 0 )
|
||||
@@ -249,12 +253,14 @@ void
|
||||
WebSocket::readOutput()
|
||||
{
|
||||
if ( !m_connection )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::string outputString = m_outputStream.str();
|
||||
if ( outputString.size() > 0 )
|
||||
{
|
||||
m_outputStream.str("");
|
||||
m_outputStream.str( "" );
|
||||
|
||||
qint64 sizeWritten = m_socket->write( outputString.data(), outputString.size() );
|
||||
tDebug() << Q_FUNC_INFO << "Got " << outputString.size() << "from outstream, wrote" << sizeWritten << "bytes to the socket";
|
||||
@@ -327,7 +333,7 @@ WebSocket::socketReadyRead()
|
||||
|
||||
|
||||
void
|
||||
WebSocket::encodeMessage( const QByteArray &bytes )
|
||||
WebSocket::encodeMessage( const QByteArray& bytes )
|
||||
{
|
||||
if ( !m_connection )
|
||||
{
|
||||
@@ -358,7 +364,7 @@ onMessage( WebSocket* ws, websocketpp::connection_hdl, hatchet_client::message_p
|
||||
}
|
||||
|
||||
void
|
||||
onClose( WebSocket *ws, websocketpp::connection_hdl )
|
||||
onClose( WebSocket* ws, websocketpp::connection_hdl )
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO << "Handling message";
|
||||
QMetaObject::invokeMethod( ws, "disconnectSocket", Qt::QueuedConnection );
|
||||
|
@@ -38,23 +38,23 @@ void onClose( WebSocket* ws, websocketpp::connection_hdl );
|
||||
class WebSocket : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
public:
|
||||
explicit WebSocket( const QString& url, const QString& authorizationHeader = QString() );
|
||||
virtual ~WebSocket();
|
||||
|
||||
signals:
|
||||
signals:
|
||||
void connected();
|
||||
void disconnected();
|
||||
void decodedMessage( QByteArray bytes );
|
||||
|
||||
public slots:
|
||||
public slots:
|
||||
void setUrl( const QString& url );
|
||||
void setAuthorizationHeader( const QString& authorizationHeader );
|
||||
void connectWs();
|
||||
void disconnectWs( websocketpp::close::status::value status = websocketpp::close::status::normal, const QString& reason = QString( "Disconnecting" ) );
|
||||
void encodeMessage( const QByteArray& bytes );
|
||||
|
||||
private slots:
|
||||
private slots:
|
||||
void socketStateChanged( QAbstractSocket::SocketState state );
|
||||
void sslErrors( const QList< QSslError >& errors );
|
||||
void disconnectSocket();
|
||||
@@ -63,11 +63,11 @@ private slots:
|
||||
void readOutput();
|
||||
void socketReadyRead();
|
||||
|
||||
private:
|
||||
private:
|
||||
Q_DISABLE_COPY( WebSocket )
|
||||
|
||||
friend void onMessage( WebSocket *ws, websocketpp::connection_hdl, hatchet_client::message_ptr msg );
|
||||
friend void onClose( WebSocket *ws, websocketpp::connection_hdl );
|
||||
friend void onMessage( WebSocket* ws, websocketpp::connection_hdl, hatchet_client::message_ptr msg );
|
||||
friend void onClose( WebSocket* ws, websocketpp::connection_hdl );
|
||||
|
||||
bool m_disconnecting;
|
||||
QUrl m_url;
|
||||
|
@@ -39,23 +39,23 @@ WebSocketThreadController::~WebSocketThreadController()
|
||||
|
||||
|
||||
void
|
||||
WebSocketThreadController::setUrl( const QString &url )
|
||||
WebSocketThreadController::setUrl( const QString& url )
|
||||
{
|
||||
m_url = url;
|
||||
if ( m_webSocket )
|
||||
{
|
||||
QMetaObject::invokeMethod( m_webSocket, "setUrl", Qt::QueuedConnection, Q_ARG( QString, url ));
|
||||
QMetaObject::invokeMethod( m_webSocket, "setUrl", Qt::QueuedConnection, Q_ARG( QString, url ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WebSocketThreadController::setAuthorizationHeader( const QString &authorizationHeader )
|
||||
WebSocketThreadController::setAuthorizationHeader( const QString& authorizationHeader )
|
||||
{
|
||||
m_authorizationHeader = authorizationHeader;
|
||||
if ( m_webSocket )
|
||||
{
|
||||
QMetaObject::invokeMethod( m_webSocket, "setAuthorizationHeader", Qt::QueuedConnection, Q_ARG( QString, authorizationHeader ));
|
||||
QMetaObject::invokeMethod( m_webSocket, "setAuthorizationHeader", Qt::QueuedConnection, Q_ARG( QString, authorizationHeader ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -27,17 +27,17 @@ class WebSocketThreadController : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
public:
|
||||
explicit WebSocketThreadController( QObject* sip );
|
||||
virtual ~WebSocketThreadController();
|
||||
|
||||
void setUrl( const QString &url );
|
||||
void setAuthorizationHeader( const QString &authorizationHeader );
|
||||
void setUrl( const QString& url );
|
||||
void setAuthorizationHeader( const QString& authorizationHeader );
|
||||
|
||||
protected:
|
||||
protected:
|
||||
void run();
|
||||
|
||||
private:
|
||||
private:
|
||||
Q_DISABLE_COPY( WebSocketThreadController )
|
||||
|
||||
QPointer< WebSocket > m_webSocket;
|
||||
|
@@ -25,7 +25,7 @@
|
||||
#include <QInputDialog>
|
||||
|
||||
|
||||
TomahawkOAuthTwitter::TomahawkOAuthTwitter( QNetworkAccessManager *nam, QObject* parent )
|
||||
TomahawkOAuthTwitter::TomahawkOAuthTwitter( QNetworkAccessManager* nam, QObject* parent )
|
||||
: OAuthTwitter( QByteArray::fromBase64( "QzR2NFdmYTIxcmZJRGNrNEhNUjNB" ), QByteArray::fromBase64( "elhTalU2Ympydmc2VVZNSlg0SnVmcUh5amozaWV4dFkxNFNSOXVCRUFv" ), parent )
|
||||
{
|
||||
setNetworkAccessManager( nam );
|
||||
@@ -36,9 +36,11 @@ const QString
|
||||
TomahawkOAuthTwitter::authorizationWidget()
|
||||
{
|
||||
bool ok;
|
||||
const QString str = QInputDialog::getText(0, tr( "Twitter PIN" ), tr( "After authenticating on Twitter's web site,\nenter the displayed PIN number here:" ), QLineEdit::Normal, QString(), &ok);
|
||||
const QString str = QInputDialog::getText( 0, tr( "Twitter PIN" ), tr( "After authenticating on Twitter's web site,\nenter the displayed PIN number here:" ), QLineEdit::Normal, QString(), &ok );
|
||||
if ( ok && !str.isEmpty() )
|
||||
{
|
||||
return str;
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
@@ -30,15 +30,15 @@ class ACCOUNTDLLEXPORT TomahawkOAuthTwitter : public OAuthTwitter
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TomahawkOAuthTwitter( QNetworkAccessManager *nam = TomahawkUtils::nam() , QObject *parent = 0 );
|
||||
public:
|
||||
TomahawkOAuthTwitter( QNetworkAccessManager* nam = TomahawkUtils::nam() , QObject* parent = 0 );
|
||||
|
||||
~TomahawkOAuthTwitter() {}
|
||||
|
||||
protected:
|
||||
protected:
|
||||
virtual const QString authorizationWidget();
|
||||
|
||||
private slots:
|
||||
private slots:
|
||||
void error();
|
||||
};
|
||||
|
||||
|
@@ -46,7 +46,7 @@ TwitterAccountFactory::createAccount( const QString& accountId )
|
||||
}
|
||||
|
||||
|
||||
TwitterAccount::TwitterAccount( const QString &accountId )
|
||||
TwitterAccount::TwitterAccount( const QString& accountId )
|
||||
: Account( accountId )
|
||||
, m_isAuthenticated( false )
|
||||
, m_isAuthenticating( false )
|
||||
@@ -78,7 +78,9 @@ TwitterAccount::configDialogAuthedSignalSlot( bool authed )
|
||||
tDebug() << Q_FUNC_INFO;
|
||||
m_isAuthenticated = authed;
|
||||
if ( !credentials()[ "username" ].toString().isEmpty() )
|
||||
{
|
||||
setAccountFriendlyName( QString( "@%1" ).arg( credentials()[ "username" ].toString() ) );
|
||||
}
|
||||
syncConfig();
|
||||
emit configurationChanged();
|
||||
}
|
||||
@@ -87,24 +89,24 @@ TwitterAccount::configDialogAuthedSignalSlot( bool authed )
|
||||
Account::ConnectionState
|
||||
TwitterAccount::connectionState() const
|
||||
{
|
||||
// if ( m_twitterSipPlugin.isNull() )
|
||||
return Account::Disconnected;
|
||||
// if ( m_twitterSipPlugin.isNull() )
|
||||
return Account::Disconnected;
|
||||
|
||||
// return m_twitterSipPlugin.data()->connectionState();
|
||||
// return m_twitterSipPlugin.data()->connectionState();
|
||||
}
|
||||
|
||||
SipPlugin*
|
||||
TwitterAccount::sipPlugin()
|
||||
{
|
||||
// if ( m_twitterSipPlugin.isNull() )
|
||||
// {
|
||||
// qDebug() << "CHECKING:" << configuration() << configuration()[ "cachedpeers" ];
|
||||
// m_twitterSipPlugin = QPointer< TwitterSipPlugin >( new TwitterSipPlugin( this ) );
|
||||
// if ( m_twitterSipPlugin.isNull() )
|
||||
// {
|
||||
// qDebug() << "CHECKING:" << configuration() << configuration()[ "cachedpeers" ];
|
||||
// m_twitterSipPlugin = QPointer< TwitterSipPlugin >( new TwitterSipPlugin( this ) );
|
||||
|
||||
// connect( m_twitterSipPlugin.data(), SIGNAL( stateChanged( Tomahawk::Accounts::Account::ConnectionState ) ), this, SIGNAL( connectionStateChanged( Tomahawk::Accounts::Account::ConnectionState ) ) );
|
||||
// return m_twitterSipPlugin.data();
|
||||
// }
|
||||
// return m_twitterSipPlugin.data();
|
||||
// connect( m_twitterSipPlugin.data(), SIGNAL( stateChanged( Tomahawk::Accounts::Account::ConnectionState ) ), this, SIGNAL( connectionStateChanged( Tomahawk::Accounts::Account::ConnectionState ) ) );
|
||||
// return m_twitterSipPlugin.data();
|
||||
// }
|
||||
// return m_twitterSipPlugin.data();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -113,7 +115,9 @@ Tomahawk::InfoSystem::InfoPluginPtr
|
||||
TwitterAccount::infoPlugin()
|
||||
{
|
||||
if ( m_twitterInfoPlugin.isNull() )
|
||||
{
|
||||
m_twitterInfoPlugin = QPointer< Tomahawk::InfoSystem::TwitterInfoPlugin >( new Tomahawk::InfoSystem::TwitterInfoPlugin( this ) );
|
||||
}
|
||||
|
||||
return Tomahawk::InfoSystem::InfoPluginPtr( m_twitterInfoPlugin.data() );
|
||||
}
|
||||
@@ -159,8 +163,8 @@ TwitterAccount::authenticateSlot()
|
||||
{
|
||||
m_isAuthenticating = true;
|
||||
tDebug() << Q_FUNC_INFO << "Verifying credentials";
|
||||
QTweetAccountVerifyCredentials *credVerifier = new QTweetAccountVerifyCredentials( m_twitterAuth.data(), this );
|
||||
connect( credVerifier, SIGNAL( parsedUser( const QTweetUser & ) ), SLOT( connectAuthVerifyReply( const QTweetUser & ) ) );
|
||||
QTweetAccountVerifyCredentials* credVerifier = new QTweetAccountVerifyCredentials( m_twitterAuth.data(), this );
|
||||
connect( credVerifier, SIGNAL( parsedUser( const QTweetUser& ) ), SLOT( connectAuthVerifyReply( const QTweetUser& ) ) );
|
||||
credVerifier->verify();
|
||||
}
|
||||
}
|
||||
@@ -171,11 +175,13 @@ TwitterAccount::deauthenticate()
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO;
|
||||
|
||||
// if ( m_twitterSipPlugin )
|
||||
// sipPlugin()->disconnectPlugin();
|
||||
// if ( m_twitterSipPlugin )
|
||||
// sipPlugin()->disconnectPlugin();
|
||||
|
||||
if ( m_twitterInfoPlugin )
|
||||
{
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->removeInfoPlugin( m_twitterInfoPlugin.data() );
|
||||
}
|
||||
|
||||
m_isAuthenticated = false;
|
||||
m_isAuthenticating = false;
|
||||
@@ -190,14 +196,18 @@ TwitterAccount::refreshTwitterAuth()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << " begin";
|
||||
if( !m_twitterAuth.isNull() )
|
||||
{
|
||||
delete m_twitterAuth.data();
|
||||
}
|
||||
|
||||
Q_ASSERT( TomahawkUtils::nam() != 0 );
|
||||
tDebug() << Q_FUNC_INFO << " with nam " << TomahawkUtils::nam();
|
||||
m_twitterAuth = QPointer< TomahawkOAuthTwitter >( new TomahawkOAuthTwitter( TomahawkUtils::nam(), this ) );
|
||||
|
||||
if( m_twitterAuth.isNull() )
|
||||
return false;
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_twitterAuth.data()->setOAuthToken( credentials()[ "oauthtoken" ].toString().toLatin1() );
|
||||
m_twitterAuth.data()->setOAuthTokenSecret( credentials()[ "oauthtokensecret" ].toString().toLatin1() );
|
||||
@@ -207,7 +217,7 @@ TwitterAccount::refreshTwitterAuth()
|
||||
|
||||
|
||||
void
|
||||
TwitterAccount::connectAuthVerifyReply( const QTweetUser &user )
|
||||
TwitterAccount::connectAuthVerifyReply( const QTweetUser& user )
|
||||
{
|
||||
m_isAuthenticating = false;
|
||||
if ( user.id() == 0 )
|
||||
@@ -223,7 +233,7 @@ TwitterAccount::connectAuthVerifyReply( const QTweetUser &user )
|
||||
setConfiguration( config );
|
||||
sync();
|
||||
|
||||
// sipPlugin()->connectPlugin();
|
||||
// sipPlugin()->connectPlugin();
|
||||
|
||||
m_isAuthenticated = true;
|
||||
emit nowAuthenticated( m_twitterAuth, user );
|
||||
@@ -235,7 +245,9 @@ QPixmap
|
||||
TwitterAccount::icon() const
|
||||
{
|
||||
if ( connectionState() == Connected )
|
||||
{
|
||||
return m_onlinePixmap;
|
||||
}
|
||||
return m_offlinePixmap;
|
||||
}
|
||||
|
||||
|
@@ -42,15 +42,30 @@ class ACCOUNTDLLEXPORT TwitterAccountFactory : public AccountFactory
|
||||
Q_OBJECT
|
||||
Q_INTERFACES( Tomahawk::Accounts::AccountFactory )
|
||||
|
||||
public:
|
||||
public:
|
||||
TwitterAccountFactory() {}
|
||||
virtual ~TwitterAccountFactory() {}
|
||||
|
||||
QString prettyName() const { return "Twitter"; }
|
||||
QString factoryId() const { return "twitteraccount"; }
|
||||
QString description() const { return tr( "Send tweets from Tomahawk." ); }
|
||||
QPixmap icon() const { return QPixmap( ":/twitter-account/twitter-icon.png" ); }
|
||||
AccountTypes types() const { return AccountTypes( StatusPushType ); };
|
||||
QString prettyName() const
|
||||
{
|
||||
return "Twitter";
|
||||
}
|
||||
QString factoryId() const
|
||||
{
|
||||
return "twitteraccount";
|
||||
}
|
||||
QString description() const
|
||||
{
|
||||
return tr( "Send tweets from Tomahawk." );
|
||||
}
|
||||
QPixmap icon() const
|
||||
{
|
||||
return QPixmap( ":/twitter-account/twitter-icon.png" );
|
||||
}
|
||||
AccountTypes types() const
|
||||
{
|
||||
return AccountTypes( StatusPushType );
|
||||
};
|
||||
Account* createAccount( const QString& pluginId = QString() );
|
||||
};
|
||||
|
||||
@@ -58,43 +73,55 @@ class ACCOUNTDLLEXPORT TwitterAccount : public Account
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TwitterAccount( const QString &accountId );
|
||||
public:
|
||||
TwitterAccount( const QString& accountId );
|
||||
virtual ~TwitterAccount();
|
||||
|
||||
QPixmap icon() const;
|
||||
|
||||
void authenticate();
|
||||
void deauthenticate();
|
||||
bool isAuthenticated() const { return m_isAuthenticated; }
|
||||
bool isAuthenticated() const
|
||||
{
|
||||
return m_isAuthenticated;
|
||||
}
|
||||
|
||||
ConnectionState connectionState() const;
|
||||
|
||||
Tomahawk::InfoSystem::InfoPluginPtr infoPlugin();
|
||||
SipPlugin* sipPlugin();
|
||||
|
||||
AccountConfigWidget* configurationWidget() { return m_configWidget.data(); }
|
||||
QWidget* aclWidget() { return 0; }
|
||||
AccountConfigWidget* configurationWidget()
|
||||
{
|
||||
return m_configWidget.data();
|
||||
}
|
||||
QWidget* aclWidget()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool refreshTwitterAuth();
|
||||
TomahawkOAuthTwitter* twitterAuth() const { return m_twitterAuth.data(); }
|
||||
TomahawkOAuthTwitter* twitterAuth() const
|
||||
{
|
||||
return m_twitterAuth.data();
|
||||
}
|
||||
|
||||
signals:
|
||||
void nowAuthenticated( const QPointer< TomahawkOAuthTwitter >&, const QTweetUser &user );
|
||||
signals:
|
||||
void nowAuthenticated( const QPointer< TomahawkOAuthTwitter >&, const QTweetUser& user );
|
||||
void nowDeauthenticated();
|
||||
|
||||
private slots:
|
||||
private slots:
|
||||
void authenticateSlot();
|
||||
void configDialogAuthedSignalSlot( bool authed );
|
||||
void connectAuthVerifyReply( const QTweetUser &user );
|
||||
void connectAuthVerifyReply( const QTweetUser& user );
|
||||
|
||||
private:
|
||||
private:
|
||||
QIcon m_icon;
|
||||
bool m_isAuthenticated;
|
||||
bool m_isAuthenticating;
|
||||
QPointer< TomahawkOAuthTwitter > m_twitterAuth;
|
||||
QPointer< TwitterConfigWidget > m_configWidget;
|
||||
// QPointer< TwitterSipPlugin > m_twitterSipPlugin;
|
||||
// QPointer< TwitterSipPlugin > m_twitterSipPlugin;
|
||||
QPointer< Tomahawk::InfoSystem::TwitterInfoPlugin > m_twitterInfoPlugin;
|
||||
|
||||
// for settings access
|
||||
|
@@ -42,7 +42,7 @@ namespace Tomahawk
|
||||
namespace Accounts
|
||||
{
|
||||
|
||||
TwitterConfigWidget::TwitterConfigWidget( TwitterAccount* account, QWidget *parent ) :
|
||||
TwitterConfigWidget::TwitterConfigWidget( TwitterAccount* account, QWidget* parent ) :
|
||||
AccountConfigWidget( parent ),
|
||||
m_ui( new Ui::TwitterConfigWidget ),
|
||||
m_account( account )
|
||||
@@ -50,11 +50,11 @@ TwitterConfigWidget::TwitterConfigWidget( TwitterAccount* account, QWidget *pare
|
||||
m_ui->setupUi( this );
|
||||
|
||||
connect( m_ui->twitterAuthenticateButton, SIGNAL( pressed() ),
|
||||
this, SLOT( authDeauthTwitter() ) );
|
||||
this, SLOT( authDeauthTwitter() ) );
|
||||
connect( m_ui->twitterTweetGotTomahawkButton, SIGNAL( pressed() ),
|
||||
this, SLOT( startPostGotTomahawkStatus() ) );
|
||||
this, SLOT( startPostGotTomahawkStatus() ) );
|
||||
connect( m_ui->twitterTweetComboBox, SIGNAL( currentIndexChanged( int ) ),
|
||||
this, SLOT( tweetComboBoxIndexChanged( int ) ) );
|
||||
this, SLOT( tweetComboBoxIndexChanged( int ) ) );
|
||||
|
||||
m_ui->twitterTweetComboBox->setCurrentIndex( 0 );
|
||||
m_ui->twitterTweetGotTomahawkButton->setText( tr( "Tweet!" ) );
|
||||
@@ -62,8 +62,8 @@ TwitterConfigWidget::TwitterConfigWidget( TwitterAccount* account, QWidget *pare
|
||||
QVariantHash credentials = m_account->credentials();
|
||||
|
||||
if ( credentials[ "oauthtoken" ].toString().isEmpty() ||
|
||||
credentials[ "oauthtokensecret" ].toString().isEmpty() ||
|
||||
credentials[ "username" ].toString().isEmpty() )
|
||||
credentials[ "oauthtokensecret" ].toString().isEmpty() ||
|
||||
credentials[ "username" ].toString().isEmpty() )
|
||||
{
|
||||
m_ui->twitterStatusLabel->setText( tr( "Status: No saved credentials" ) );
|
||||
m_ui->twitterAuthenticateButton->setText( tr( "Authenticate" ) );
|
||||
@@ -93,16 +93,20 @@ void
|
||||
TwitterConfigWidget::authDeauthTwitter()
|
||||
{
|
||||
if ( m_ui->twitterAuthenticateButton->text() == tr( "Authenticate" ) ) //FIXME: don't rely on UI strings here!
|
||||
{
|
||||
authenticateTwitter();
|
||||
}
|
||||
else
|
||||
{
|
||||
deauthenticateTwitter();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TwitterConfigWidget::authenticateTwitter()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
TomahawkOAuthTwitter *twitAuth = new TomahawkOAuthTwitter( TomahawkUtils::nam(), this );
|
||||
TomahawkOAuthTwitter* twitAuth = new TomahawkOAuthTwitter( TomahawkUtils::nam(), this );
|
||||
twitAuth->authorizePin();
|
||||
|
||||
QVariantHash credentials = m_account->credentials();
|
||||
@@ -110,19 +114,19 @@ TwitterConfigWidget::authenticateTwitter()
|
||||
credentials[ "oauthtokensecret" ] = twitAuth->oauthTokenSecret();
|
||||
m_account->setCredentials( credentials );
|
||||
|
||||
QTweetAccountVerifyCredentials *credVerifier = new QTweetAccountVerifyCredentials( twitAuth, this );
|
||||
connect( credVerifier, SIGNAL( parsedUser( const QTweetUser & ) ), SLOT( authenticateVerifyReply( const QTweetUser & ) ) );
|
||||
QTweetAccountVerifyCredentials* credVerifier = new QTweetAccountVerifyCredentials( twitAuth, this );
|
||||
connect( credVerifier, SIGNAL( parsedUser( const QTweetUser& ) ), SLOT( authenticateVerifyReply( const QTweetUser& ) ) );
|
||||
connect( credVerifier, SIGNAL( error( QTweetNetBase::ErrorCode, QString ) ), SLOT( authenticateVerifyError( QTweetNetBase::ErrorCode, QString ) ) );
|
||||
credVerifier->verify();
|
||||
}
|
||||
|
||||
void
|
||||
TwitterConfigWidget::authenticateVerifyReply( const QTweetUser &user )
|
||||
TwitterConfigWidget::authenticateVerifyReply( const QTweetUser& user )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
if ( user.id() == 0 )
|
||||
{
|
||||
QMessageBox::critical( this, tr("Tweetin' Error"), tr("The credentials could not be verified.\nYou may wish to try re-authenticating.") );
|
||||
QMessageBox::critical( this, tr( "Tweetin' Error" ), tr( "The credentials could not be verified.\nYou may wish to try re-authenticating." ) );
|
||||
emit twitterAuthed( false );
|
||||
return;
|
||||
}
|
||||
@@ -148,11 +152,11 @@ TwitterConfigWidget::authenticateVerifyReply( const QTweetUser &user )
|
||||
}
|
||||
|
||||
void
|
||||
TwitterConfigWidget::authenticateVerifyError( QTweetNetBase::ErrorCode code, const QString &errorMsg )
|
||||
TwitterConfigWidget::authenticateVerifyError( QTweetNetBase::ErrorCode code, const QString& errorMsg )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
qDebug() << "Error validating credentials, error code is " << code << ", error message is " << errorMsg;
|
||||
m_ui->twitterStatusLabel->setText(tr("Status: Error validating credentials"));
|
||||
m_ui->twitterStatusLabel->setText( tr( "Status: Error validating credentials" ) );
|
||||
emit twitterAuthed( false );
|
||||
return;
|
||||
}
|
||||
@@ -167,7 +171,7 @@ TwitterConfigWidget::deauthenticateTwitter()
|
||||
credentials[ "username" ] = QString();
|
||||
m_account->setCredentials( credentials );
|
||||
|
||||
m_ui->twitterStatusLabel->setText(tr("Status: No saved credentials"));
|
||||
m_ui->twitterStatusLabel->setText( tr( "Status: No saved credentials" ) );
|
||||
m_ui->twitterAuthenticateButton->setText( tr( "Authenticate" ) );
|
||||
m_ui->twitterSyncGroupBox->setVisible( false );
|
||||
|
||||
@@ -180,16 +184,26 @@ TwitterConfigWidget::tweetComboBoxIndexChanged( int index )
|
||||
{
|
||||
Q_UNUSED( index );
|
||||
if ( m_ui->twitterTweetComboBox->currentText() == tr( "Global Tweet" ) ) //FIXME: use data!
|
||||
{
|
||||
m_ui->twitterUserTweetLineEdit->setVisible( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ui->twitterUserTweetLineEdit->setVisible( true );
|
||||
}
|
||||
|
||||
if ( m_ui->twitterTweetComboBox->currentText() == tr( "Direct Message" ) ) //FIXME: use data!
|
||||
{
|
||||
m_ui->twitterTweetGotTomahawkButton->setText( tr( "Send Message!" ) );
|
||||
}
|
||||
else if ( m_ui->twitterTweetComboBox->currentText() == tr( "@Mention" ) )
|
||||
{
|
||||
m_ui->twitterTweetGotTomahawkButton->setText( tr( "Send Mention!" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ui->twitterTweetGotTomahawkButton->setText( tr( "Tweet!" ) );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -200,7 +214,7 @@ TwitterConfigWidget::startPostGotTomahawkStatus()
|
||||
|
||||
if ( m_postGTtype != "Global Tweet" && ( m_ui->twitterUserTweetLineEdit->text().isEmpty() || m_ui->twitterUserTweetLineEdit->text() == "@" ) )
|
||||
{
|
||||
QMessageBox::critical( this, tr("Tweetin' Error"), tr("You must enter a user name for this type of tweet.") );
|
||||
QMessageBox::critical( this, tr( "Tweetin' Error" ), tr( "You must enter a user name for this type of tweet." ) );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -208,61 +222,65 @@ TwitterConfigWidget::startPostGotTomahawkStatus()
|
||||
QVariantHash credentials = m_account->credentials();
|
||||
|
||||
if ( credentials[ "oauthtoken" ].toString().isEmpty() ||
|
||||
credentials[ "oauthtokensecret" ].toString().isEmpty() ||
|
||||
credentials[ "username" ].toString().isEmpty() )
|
||||
credentials[ "oauthtokensecret" ].toString().isEmpty() ||
|
||||
credentials[ "username" ].toString().isEmpty() )
|
||||
{
|
||||
QMessageBox::critical( this, tr("Tweetin' Error"), tr("Your saved credentials could not be loaded.\nYou may wish to try re-authenticating.") );
|
||||
QMessageBox::critical( this, tr( "Tweetin' Error" ), tr( "Your saved credentials could not be loaded.\nYou may wish to try re-authenticating." ) );
|
||||
emit twitterAuthed( false );
|
||||
return;
|
||||
}
|
||||
TomahawkOAuthTwitter *twitAuth = new TomahawkOAuthTwitter( TomahawkUtils::nam(), this );
|
||||
TomahawkOAuthTwitter* twitAuth = new TomahawkOAuthTwitter( TomahawkUtils::nam(), this );
|
||||
twitAuth->setOAuthToken( credentials[ "oauthtoken" ].toString().toLatin1() );
|
||||
twitAuth->setOAuthTokenSecret( credentials[ "oauthtokensecret" ].toString().toLatin1() );
|
||||
QTweetAccountVerifyCredentials *credVerifier = new QTweetAccountVerifyCredentials( twitAuth, this );
|
||||
connect( credVerifier, SIGNAL( parsedUser(const QTweetUser &) ), SLOT( postGotTomahawkStatusAuthVerifyReply(const QTweetUser &) ) );
|
||||
QTweetAccountVerifyCredentials* credVerifier = new QTweetAccountVerifyCredentials( twitAuth, this );
|
||||
connect( credVerifier, SIGNAL( parsedUser( const QTweetUser& ) ), SLOT( postGotTomahawkStatusAuthVerifyReply( const QTweetUser& ) ) );
|
||||
credVerifier->verify();
|
||||
}
|
||||
|
||||
void
|
||||
TwitterConfigWidget::postGotTomahawkStatusAuthVerifyReply( const QTweetUser &user )
|
||||
TwitterConfigWidget::postGotTomahawkStatusAuthVerifyReply( const QTweetUser& user )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
if ( user.id() == 0 )
|
||||
{
|
||||
QMessageBox::critical( this, tr("Tweetin' Error"), tr("Your saved credentials could not be verified.\nYou may wish to try re-authenticating.") );
|
||||
QMessageBox::critical( this, tr( "Tweetin' Error" ), tr( "Your saved credentials could not be verified.\nYou may wish to try re-authenticating." ) );
|
||||
emit twitterAuthed( false );
|
||||
return;
|
||||
}
|
||||
TomahawkOAuthTwitter *twitAuth = new TomahawkOAuthTwitter( TomahawkUtils::nam(), this );
|
||||
TomahawkOAuthTwitter* twitAuth = new TomahawkOAuthTwitter( TomahawkUtils::nam(), this );
|
||||
QVariantHash credentials = m_account->credentials();
|
||||
twitAuth->setOAuthToken( credentials[ "oauthtoken" ].toString().toLatin1() );
|
||||
twitAuth->setOAuthTokenSecret( credentials[ "oauthtokensecret" ].toString().toLatin1() );
|
||||
if ( m_postGTtype != "Direct Message" )
|
||||
{
|
||||
QTweetStatusUpdate *statUpdate = new QTweetStatusUpdate( twitAuth, this );
|
||||
connect( statUpdate, SIGNAL( postedStatus(const QTweetStatus &) ), SLOT( postGotTomahawkStatusUpdateReply(const QTweetStatus &) ) );
|
||||
connect( statUpdate, SIGNAL( error(QTweetNetBase::ErrorCode, const QString&) ), SLOT( postGotTomahawkStatusUpdateError(QTweetNetBase::ErrorCode, const QString &) ) );
|
||||
QTweetStatusUpdate* statUpdate = new QTweetStatusUpdate( twitAuth, this );
|
||||
connect( statUpdate, SIGNAL( postedStatus( const QTweetStatus& ) ), SLOT( postGotTomahawkStatusUpdateReply( const QTweetStatus& ) ) );
|
||||
connect( statUpdate, SIGNAL( error( QTweetNetBase::ErrorCode, const QString& ) ), SLOT( postGotTomahawkStatusUpdateError( QTweetNetBase::ErrorCode, const QString& ) ) );
|
||||
QString uuid = QUuid::createUuid();
|
||||
QString message = QString( "Got Tomahawk? {" ) + Database::instance()->impl()->dbid() + QString( "} (" ) + uuid.mid( 1, 8 ) + QString( ")" ) + QString( " http://gettomahawk.com" );
|
||||
if ( m_postGTtype == "@Mention" )
|
||||
{
|
||||
QString user = m_ui->twitterUserTweetLineEdit->text();
|
||||
if ( user.startsWith( "@" ) )
|
||||
{
|
||||
user.remove( 0, 1 );
|
||||
}
|
||||
message = QString( "@" ) + user + QString( " " ) + message;
|
||||
}
|
||||
statUpdate->post( message );
|
||||
}
|
||||
else
|
||||
{
|
||||
QTweetDirectMessageNew *statUpdate = new QTweetDirectMessageNew( twitAuth, this );
|
||||
connect( statUpdate, SIGNAL( parsedDirectMessage(const QTweetDMStatus &)), SLOT( postGotTomahawkDirectMessageReply(const QTweetDMStatus &) ) );
|
||||
connect( statUpdate, SIGNAL( error(QTweetNetBase::ErrorCode, const QString&) ), SLOT( postGotTomahawkStatusUpdateError(QTweetNetBase::ErrorCode, const QString &) ) );
|
||||
QTweetDirectMessageNew* statUpdate = new QTweetDirectMessageNew( twitAuth, this );
|
||||
connect( statUpdate, SIGNAL( parsedDirectMessage( const QTweetDMStatus& ) ), SLOT( postGotTomahawkDirectMessageReply( const QTweetDMStatus& ) ) );
|
||||
connect( statUpdate, SIGNAL( error( QTweetNetBase::ErrorCode, const QString& ) ), SLOT( postGotTomahawkStatusUpdateError( QTweetNetBase::ErrorCode, const QString& ) ) );
|
||||
QString uuid = QUuid::createUuid();
|
||||
QString message = QString( "Got Tomahawk? {" ) + Database::instance()->impl()->dbid() + QString( "} (" ) + uuid.mid( 1, 8 ) + QString( ")" ) + QString( " http://gettomahawk.com" );
|
||||
QString user = m_ui->twitterUserTweetLineEdit->text();
|
||||
if ( user.startsWith( "@" ) )
|
||||
{
|
||||
user.remove( 0, 1 );
|
||||
}
|
||||
statUpdate->post( user, message );
|
||||
}
|
||||
}
|
||||
@@ -271,18 +289,26 @@ void
|
||||
TwitterConfigWidget::postGotTomahawkStatusUpdateReply( const QTweetStatus& status )
|
||||
{
|
||||
if ( status.id() == 0 )
|
||||
QMessageBox::critical( this, tr("Tweetin' Error"), tr("There was an error posting your status -- sorry!") );
|
||||
{
|
||||
QMessageBox::critical( this, tr( "Tweetin' Error" ), tr( "There was an error posting your status -- sorry!" ) );
|
||||
}
|
||||
else
|
||||
QMessageBox::information( this, tr("Tweeted!"), tr("Your tweet has been posted!") );
|
||||
{
|
||||
QMessageBox::information( this, tr( "Tweeted!" ), tr( "Your tweet has been posted!" ) );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TwitterConfigWidget::postGotTomahawkDirectMessageReply( const QTweetDMStatus& status )
|
||||
{
|
||||
if ( status.id() == 0 )
|
||||
QMessageBox::critical( this, tr("Tweetin' Error"), tr("There was an error posting your direct message -- sorry!") );
|
||||
{
|
||||
QMessageBox::critical( this, tr( "Tweetin' Error" ), tr( "There was an error posting your direct message -- sorry!" ) );
|
||||
}
|
||||
else
|
||||
QMessageBox::information( this, tr("Tweeted!"), tr("Your message has been posted!") );
|
||||
{
|
||||
QMessageBox::information( this, tr( "Tweeted!" ), tr( "Your message has been posted!" ) );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -290,7 +316,7 @@ TwitterConfigWidget::postGotTomahawkStatusUpdateError( QTweetNetBase::ErrorCode
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
qDebug() << "Error posting Got Tomahawk message, error code is " << code << ", error message is " << errorMsg;
|
||||
QMessageBox::critical( this, tr("Tweetin' Error"), tr("There was an error posting your status -- sorry!") );
|
||||
QMessageBox::critical( this, tr( "Tweetin' Error" ), tr( "There was an error posting your status -- sorry!" ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@
|
||||
*
|
||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2010-2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class TwitterConfigWidget;
|
||||
class TwitterConfigWidget;
|
||||
}
|
||||
|
||||
namespace Tomahawk
|
||||
@@ -47,32 +47,32 @@ class ACCOUNTDLLEXPORT TwitterConfigWidget : public AccountConfigWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TwitterConfigWidget( TwitterAccount* account = 0, QWidget *parent = 0 );
|
||||
public:
|
||||
explicit TwitterConfigWidget( TwitterAccount* account = 0, QWidget* parent = 0 );
|
||||
virtual ~TwitterConfigWidget();
|
||||
|
||||
signals:
|
||||
signals:
|
||||
void twitterAuthed( bool authed );
|
||||
|
||||
void sizeHintChanged();
|
||||
|
||||
private slots:
|
||||
private slots:
|
||||
void authDeauthTwitter();
|
||||
void startPostGotTomahawkStatus();
|
||||
void authenticateVerifyReply( const QTweetUser &user );
|
||||
void authenticateVerifyError( QTweetNetBase::ErrorCode code, const QString &errorMsg );
|
||||
void postGotTomahawkStatusAuthVerifyReply( const QTweetUser &user );
|
||||
void postGotTomahawkStatusUpdateReply( const QTweetStatus &status );
|
||||
void postGotTomahawkDirectMessageReply( const QTweetDMStatus &status );
|
||||
void postGotTomahawkStatusUpdateError( QTweetNetBase::ErrorCode, const QString &errorMsg );
|
||||
void authenticateVerifyReply( const QTweetUser& user );
|
||||
void authenticateVerifyError( QTweetNetBase::ErrorCode code, const QString& errorMsg );
|
||||
void postGotTomahawkStatusAuthVerifyReply( const QTweetUser& user );
|
||||
void postGotTomahawkStatusUpdateReply( const QTweetStatus& status );
|
||||
void postGotTomahawkDirectMessageReply( const QTweetDMStatus& status );
|
||||
void postGotTomahawkStatusUpdateError( QTweetNetBase::ErrorCode, const QString& errorMsg );
|
||||
void tweetComboBoxIndexChanged( int index );
|
||||
|
||||
private:
|
||||
private:
|
||||
void authenticateTwitter();
|
||||
void deauthenticateTwitter();
|
||||
|
||||
Ui::TwitterConfigWidget *m_ui;
|
||||
TwitterAccount *m_account;
|
||||
Ui::TwitterConfigWidget* m_ui;
|
||||
TwitterAccount* m_account;
|
||||
QString m_postGTtype;
|
||||
};
|
||||
|
||||
|
@@ -60,8 +60,8 @@ TwitterInfoPlugin::init()
|
||||
|
||||
if ( refreshTwitterAuth() )
|
||||
{
|
||||
QTweetAccountVerifyCredentials *credVerifier = new QTweetAccountVerifyCredentials( m_twitterAuth.data(), this );
|
||||
connect( credVerifier, SIGNAL( parsedUser( const QTweetUser & ) ), SLOT( connectAuthVerifyReply( const QTweetUser & ) ) );
|
||||
QTweetAccountVerifyCredentials* credVerifier = new QTweetAccountVerifyCredentials( m_twitterAuth.data(), this );
|
||||
connect( credVerifier, SIGNAL( parsedUser( const QTweetUser& ) ), SLOT( connectAuthVerifyReply( const QTweetUser& ) ) );
|
||||
credVerifier->verify();
|
||||
}
|
||||
}
|
||||
@@ -78,14 +78,18 @@ TwitterInfoPlugin::refreshTwitterAuth()
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO << "begin" << this;
|
||||
if ( !m_twitterAuth.isNull() )
|
||||
{
|
||||
delete m_twitterAuth.data();
|
||||
}
|
||||
|
||||
Q_ASSERT( TomahawkUtils::nam() != 0 );
|
||||
tDebug() << Q_FUNC_INFO << "with nam" << TomahawkUtils::nam() << this;
|
||||
m_twitterAuth = QPointer< TomahawkOAuthTwitter >( new TomahawkOAuthTwitter( TomahawkUtils::nam(), this ) );
|
||||
|
||||
if ( m_twitterAuth.isNull() )
|
||||
return false;
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_twitterAuth.data()->setOAuthToken( m_account->credentials()[ "oauthtoken" ].toString().toLatin1() );
|
||||
m_twitterAuth.data()->setOAuthTokenSecret( m_account->credentials()[ "oauthtokensecret" ].toString().toLatin1() );
|
||||
@@ -95,7 +99,7 @@ TwitterInfoPlugin::refreshTwitterAuth()
|
||||
|
||||
|
||||
void
|
||||
TwitterInfoPlugin::connectAuthVerifyReply( const QTweetUser &user )
|
||||
TwitterInfoPlugin::connectAuthVerifyReply( const QTweetUser& user )
|
||||
{
|
||||
if ( user.id() == 0 )
|
||||
{
|
||||
@@ -157,18 +161,20 @@ TwitterInfoPlugin::pushInfo( Tomahawk::InfoSystem::InfoPushData pushData )
|
||||
{
|
||||
info = map[ "trackinfo" ].value< Tomahawk::InfoSystem::InfoStringHash >();
|
||||
msg = tr( "Listening to \"%1\" by %2 and loving it! %3" )
|
||||
.arg( info[ "title" ] )
|
||||
.arg( info[ "artist" ] )
|
||||
.arg( pushInfoPair.first.contains( "shorturl" ) ?
|
||||
pushInfoPair.first[ "shorturl" ].toUrl().toString() :
|
||||
GlobalActionManager::instance()->openLink( info[ "title" ], info[ "artist" ], info[ "album" ] ).toString() );
|
||||
.arg( info[ "title" ] )
|
||||
.arg( info[ "artist" ] )
|
||||
.arg( pushInfoPair.first.contains( "shorturl" ) ?
|
||||
pushInfoPair.first[ "shorturl" ].toUrl().toString() :
|
||||
GlobalActionManager::instance()->openLink( info[ "title" ], info[ "artist" ], info[ "album" ] ).toString() );
|
||||
}
|
||||
else
|
||||
{
|
||||
msg = map[ "message" ].toString();
|
||||
}
|
||||
|
||||
QTweetStatusUpdate *statUpdate = new QTweetStatusUpdate( m_twitterAuth.data(), this );
|
||||
connect( statUpdate, SIGNAL( postedStatus(const QTweetStatus &) ), SLOT( postLovedStatusUpdateReply(const QTweetStatus &) ) );
|
||||
connect( statUpdate, SIGNAL( error(QTweetNetBase::ErrorCode, const QString&) ), SLOT( postLovedStatusUpdateError(QTweetNetBase::ErrorCode, const QString &) ) );
|
||||
QTweetStatusUpdate* statUpdate = new QTweetStatusUpdate( m_twitterAuth.data(), this );
|
||||
connect( statUpdate, SIGNAL( postedStatus( const QTweetStatus& ) ), SLOT( postLovedStatusUpdateReply( const QTweetStatus& ) ) );
|
||||
connect( statUpdate, SIGNAL( error( QTweetNetBase::ErrorCode, const QString& ) ), SLOT( postLovedStatusUpdateError( QTweetNetBase::ErrorCode, const QString& ) ) );
|
||||
tDebug() << Q_FUNC_INFO << "Posting message:" << msg;
|
||||
statUpdate->post( msg );
|
||||
}
|
||||
@@ -178,9 +184,13 @@ void
|
||||
TwitterInfoPlugin::postLovedStatusUpdateReply( const QTweetStatus& status )
|
||||
{
|
||||
if ( status.id() == 0 )
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO << "Failed to post loved status";
|
||||
}
|
||||
else
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO << "Successfully posted loved status";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@@ -27,52 +27,55 @@
|
||||
#include <QTweetLib/qtweetstatus.h>
|
||||
#include <QTweetLib/qtweetnetbase.h>
|
||||
|
||||
namespace Tomahawk {
|
||||
namespace Tomahawk
|
||||
{
|
||||
|
||||
namespace Accounts {
|
||||
class TwitterAccount;
|
||||
namespace Accounts
|
||||
{
|
||||
class TwitterAccount;
|
||||
}
|
||||
|
||||
namespace InfoSystem
|
||||
{
|
||||
|
||||
class TwitterInfoPlugin : public InfoPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TwitterInfoPlugin( Tomahawk::Accounts::TwitterAccount* account );
|
||||
virtual ~TwitterInfoPlugin();
|
||||
|
||||
public slots:
|
||||
void notInCacheSlot( const Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
{
|
||||
Q_UNUSED( criteria );
|
||||
Q_UNUSED( requestData );
|
||||
}
|
||||
|
||||
namespace InfoSystem {
|
||||
|
||||
class TwitterInfoPlugin : public InfoPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TwitterInfoPlugin( Tomahawk::Accounts::TwitterAccount* account );
|
||||
virtual ~TwitterInfoPlugin();
|
||||
|
||||
public slots:
|
||||
void notInCacheSlot( const Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
{
|
||||
Q_UNUSED( criteria );
|
||||
Q_UNUSED( requestData );
|
||||
}
|
||||
|
||||
protected slots:
|
||||
void init();
|
||||
void pushInfo( Tomahawk::InfoSystem::InfoPushData pushData );
|
||||
void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
{
|
||||
Q_UNUSED( requestData );
|
||||
}
|
||||
|
||||
private slots:
|
||||
void connectAuthVerifyReply( const QTweetUser &user );
|
||||
void postLovedStatusUpdateReply( const QTweetStatus& status );
|
||||
void postLovedStatusUpdateError( QTweetNetBase::ErrorCode code, const QString& errorMsg );
|
||||
|
||||
private:
|
||||
bool refreshTwitterAuth();
|
||||
bool isValid() const;
|
||||
|
||||
Tomahawk::Accounts::TwitterAccount* m_account;
|
||||
QPointer< TomahawkOAuthTwitter > m_twitterAuth;
|
||||
};
|
||||
|
||||
protected slots:
|
||||
void init();
|
||||
void pushInfo( Tomahawk::InfoSystem::InfoPushData pushData );
|
||||
void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
{
|
||||
Q_UNUSED( requestData );
|
||||
}
|
||||
|
||||
private slots:
|
||||
void connectAuthVerifyReply( const QTweetUser& user );
|
||||
void postLovedStatusUpdateReply( const QTweetStatus& status );
|
||||
void postLovedStatusUpdateError( QTweetNetBase::ErrorCode code, const QString& errorMsg );
|
||||
|
||||
private:
|
||||
bool refreshTwitterAuth();
|
||||
bool isValid() const;
|
||||
|
||||
Tomahawk::Accounts::TwitterAccount* m_account;
|
||||
QPointer< TomahawkOAuthTwitter > m_twitterAuth;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // TWITTERINFOPLUGIN_H
|
||||
|
@@ -60,7 +60,7 @@ TwitterSipPlugin::TwitterSipPlugin( Tomahawk::Accounts::Account* account )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
connect( account, SIGNAL( nowAuthenticated( const QPointer< TomahawkOAuthTwitter > &, const QTweetUser & ) ), SLOT( accountAuthenticated( const QPointer< TomahawkOAuthTwitter > &, const QTweetUser & ) ) );
|
||||
connect( account, SIGNAL( nowAuthenticated( const QPointer< TomahawkOAuthTwitter >&, const QTweetUser& ) ), SLOT( accountAuthenticated( const QPointer< TomahawkOAuthTwitter >&, const QTweetUser& ) ) );
|
||||
|
||||
m_configuration = account->configuration();
|
||||
qDebug() << "SIP configuration:" << m_configuration << m_configuration[ "cachedpeers" ];
|
||||
@@ -145,15 +145,25 @@ TwitterSipPlugin::disconnectPlugin()
|
||||
m_connectTimer.stop();
|
||||
m_dmPollTimer.stop();
|
||||
if( !m_friendsTimeline.isNull() )
|
||||
{
|
||||
delete m_friendsTimeline.data();
|
||||
}
|
||||
if( !m_mentions.isNull() )
|
||||
{
|
||||
delete m_mentions.data();
|
||||
}
|
||||
if( !m_directMessages.isNull() )
|
||||
{
|
||||
delete m_directMessages.data();
|
||||
}
|
||||
if( !m_directMessageNew.isNull() )
|
||||
{
|
||||
delete m_directMessageNew.data();
|
||||
}
|
||||
if( !m_directMessageDestroy.isNull() )
|
||||
{
|
||||
delete m_directMessageDestroy.data();
|
||||
}
|
||||
|
||||
m_cachedTwitterAuth = 0;
|
||||
|
||||
@@ -165,12 +175,14 @@ TwitterSipPlugin::disconnectPlugin()
|
||||
}
|
||||
|
||||
void
|
||||
TwitterSipPlugin::accountAuthenticated( const QPointer< TomahawkOAuthTwitter > &twitterAuth, const QTweetUser &user )
|
||||
TwitterSipPlugin::accountAuthenticated( const QPointer< TomahawkOAuthTwitter >& twitterAuth, const QTweetUser& user )
|
||||
{
|
||||
Q_UNUSED( user );
|
||||
|
||||
if ( !m_account->enabled() || !m_account->isAuthenticated() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_cachedTwitterAuth = twitterAuth;
|
||||
|
||||
@@ -179,12 +191,12 @@ TwitterSipPlugin::accountAuthenticated( const QPointer< TomahawkOAuthTwitter > &
|
||||
m_directMessages = QPointer<QTweetDirectMessages>( new QTweetDirectMessages( m_cachedTwitterAuth.data(), this ) );
|
||||
m_directMessageNew = QPointer<QTweetDirectMessageNew>( new QTweetDirectMessageNew( m_cachedTwitterAuth.data(), this ) );
|
||||
m_directMessageDestroy = QPointer<QTweetDirectMessageDestroy>( new QTweetDirectMessageDestroy( m_cachedTwitterAuth.data(), this ) );
|
||||
connect( m_friendsTimeline.data(), SIGNAL( parsedStatuses(const QList< QTweetStatus > &) ), SLOT( friendsTimelineStatuses(const QList<QTweetStatus> &) ) );
|
||||
connect( m_mentions.data(), SIGNAL( parsedStatuses(const QList< QTweetStatus > &) ), SLOT( mentionsStatuses(const QList<QTweetStatus> &) ) );
|
||||
connect( m_directMessages.data(), SIGNAL( parsedDirectMessages(const QList<QTweetDMStatus> &)), SLOT( directMessages(const QList<QTweetDMStatus> &) ) );
|
||||
connect( m_directMessageNew.data(), SIGNAL( parsedDirectMessage(const QTweetDMStatus &)), SLOT( directMessagePosted(const QTweetDMStatus &) ) );
|
||||
connect( m_directMessageNew.data(), SIGNAL( error(QTweetNetBase::ErrorCode, const QString &) ), SLOT( directMessagePostError(QTweetNetBase::ErrorCode, const QString &) ) );
|
||||
connect( m_directMessageDestroy.data(), SIGNAL( parsedDirectMessage(const QTweetDMStatus &) ), SLOT( directMessageDestroyed(const QTweetDMStatus &) ) );
|
||||
connect( m_friendsTimeline.data(), SIGNAL( parsedStatuses( const QList< QTweetStatus >& ) ), SLOT( friendsTimelineStatuses( const QList<QTweetStatus>& ) ) );
|
||||
connect( m_mentions.data(), SIGNAL( parsedStatuses( const QList< QTweetStatus >& ) ), SLOT( mentionsStatuses( const QList<QTweetStatus>& ) ) );
|
||||
connect( m_directMessages.data(), SIGNAL( parsedDirectMessages( const QList<QTweetDMStatus>& ) ), SLOT( directMessages( const QList<QTweetDMStatus>& ) ) );
|
||||
connect( m_directMessageNew.data(), SIGNAL( parsedDirectMessage( const QTweetDMStatus& ) ), SLOT( directMessagePosted( const QTweetDMStatus& ) ) );
|
||||
connect( m_directMessageNew.data(), SIGNAL( error( QTweetNetBase::ErrorCode, const QString& ) ), SLOT( directMessagePostError( QTweetNetBase::ErrorCode, const QString& ) ) );
|
||||
connect( m_directMessageDestroy.data(), SIGNAL( parsedDirectMessage( const QTweetDMStatus& ) ), SLOT( directMessageDestroyed( const QTweetDMStatus& ) ) );
|
||||
m_state = Tomahawk::Accounts::Account::Connected;
|
||||
emit stateChanged( m_state );
|
||||
QStringList peerList = m_cachedPeers.keys();
|
||||
@@ -203,31 +215,43 @@ void
|
||||
TwitterSipPlugin::checkTimerFired()
|
||||
{
|
||||
if ( !isValid() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_cachedFriendsSinceId == 0 )
|
||||
{
|
||||
m_cachedFriendsSinceId = m_configuration[ "cachedfriendssinceid" ].toLongLong();
|
||||
}
|
||||
|
||||
qDebug() << "TwitterSipPlugin looking at friends timeline since id " << m_cachedFriendsSinceId;
|
||||
|
||||
if ( !m_friendsTimeline.isNull() )
|
||||
{
|
||||
m_friendsTimeline.data()->fetch( m_cachedFriendsSinceId, 0, 800 );
|
||||
}
|
||||
|
||||
if ( m_cachedMentionsSinceId == 0 )
|
||||
{
|
||||
m_cachedMentionsSinceId = m_configuration[ "cachedmentionssinceid" ].toLongLong();
|
||||
}
|
||||
|
||||
qDebug() << "TwitterSipPlugin looking at mentions timeline since id " << m_cachedMentionsSinceId;
|
||||
|
||||
if ( !m_mentions.isNull() )
|
||||
{
|
||||
m_mentions.data()->fetch( m_cachedMentionsSinceId, 0, 800 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TwitterSipPlugin::registerOffers( const QStringList &peerList )
|
||||
TwitterSipPlugin::registerOffers( const QStringList& peerList )
|
||||
{
|
||||
if ( !isValid() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach( QString screenName, peerList )
|
||||
{
|
||||
@@ -277,9 +301,13 @@ TwitterSipPlugin::connectTimerFired()
|
||||
if ( !isValid() || m_cachedPeers.isEmpty() )
|
||||
{
|
||||
if ( !isValid() )
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO << " is not valid";
|
||||
}
|
||||
if ( m_cachedPeers.isEmpty() )
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO << " has empty cached peers";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -291,7 +319,7 @@ TwitterSipPlugin::connectTimerFired()
|
||||
}
|
||||
|
||||
void
|
||||
TwitterSipPlugin::parseGotTomahawk( const QRegExp ®ex, const QString &screenName, const QString &text )
|
||||
TwitterSipPlugin::parseGotTomahawk( const QRegExp& regex, const QString& screenName, const QString& text )
|
||||
{
|
||||
QString myScreenName = m_configuration[ "screenname" ].toString();
|
||||
qDebug() << "TwitterSipPlugin found an exact matching Got Tomahawk? mention or direct message from user " << screenName << ", now parsing";
|
||||
@@ -318,7 +346,9 @@ TwitterSipPlugin::parseGotTomahawk( const QRegExp ®ex, const QString &screenN
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "TwitterSipPlugin parsed node " << node << " out of the tweet";
|
||||
}
|
||||
|
||||
if ( node == Database::instance()->impl()->dbid() )
|
||||
{
|
||||
@@ -333,14 +363,16 @@ TwitterSipPlugin::parseGotTomahawk( const QRegExp ®ex, const QString &screenN
|
||||
//force a re-send of info but no need to re-register
|
||||
peerData["resend"] = QVariant::fromValue< bool >( true );
|
||||
if ( peerData["node"].toString() != node )
|
||||
{
|
||||
peerData["rekey"] = QVariant::fromValue< bool >( true );
|
||||
}
|
||||
}
|
||||
peerData["node"] = QVariant::fromValue< QString >( node );
|
||||
QMetaObject::invokeMethod( this, "registerOffer", Q_ARG( QString, screenName ), Q_ARG( QVariantHash, peerData ) );
|
||||
}
|
||||
|
||||
void
|
||||
TwitterSipPlugin::friendsTimelineStatuses( const QList< QTweetStatus > &statuses )
|
||||
TwitterSipPlugin::friendsTimelineStatuses( const QList< QTweetStatus >& statuses )
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO;
|
||||
QRegExp regex( s_gotTomahawkRegex, Qt::CaseSensitive, QRegExp::RegExp2 );
|
||||
@@ -349,21 +381,29 @@ TwitterSipPlugin::friendsTimelineStatuses( const QList< QTweetStatus > &statuses
|
||||
foreach ( QTweetStatus status, statuses )
|
||||
{
|
||||
if ( !regex.exactMatch( status.text() ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !latestHash.contains( status.user().screenName() ) )
|
||||
{
|
||||
latestHash[status.user().screenName()] = status;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( status.id() > latestHash[status.user().screenName()].id() )
|
||||
{
|
||||
latestHash[status.user().screenName()] = status;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach( QTweetStatus status, latestHash.values() )
|
||||
{
|
||||
if ( status.id() > m_cachedFriendsSinceId )
|
||||
{
|
||||
m_cachedFriendsSinceId = status.id();
|
||||
}
|
||||
|
||||
tDebug() << "TwitterSipPlugin checking mention from " << status.user().screenName() << " with content " << status.text();
|
||||
parseGotTomahawk( regex, status.user().screenName(), status.text() );
|
||||
@@ -374,7 +414,7 @@ TwitterSipPlugin::friendsTimelineStatuses( const QList< QTweetStatus > &statuses
|
||||
}
|
||||
|
||||
void
|
||||
TwitterSipPlugin::mentionsStatuses( const QList< QTweetStatus > &statuses )
|
||||
TwitterSipPlugin::mentionsStatuses( const QList< QTweetStatus >& statuses )
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO;
|
||||
QRegExp regex( s_gotTomahawkRegex, Qt::CaseSensitive, QRegExp::RegExp2 );
|
||||
@@ -383,21 +423,29 @@ TwitterSipPlugin::mentionsStatuses( const QList< QTweetStatus > &statuses )
|
||||
foreach ( QTweetStatus status, statuses )
|
||||
{
|
||||
if ( !regex.exactMatch( status.text() ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !latestHash.contains( status.user().screenName() ) )
|
||||
{
|
||||
latestHash[status.user().screenName()] = status;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( status.id() > latestHash[status.user().screenName()].id() )
|
||||
{
|
||||
latestHash[status.user().screenName()] = status;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach( QTweetStatus status, latestHash.values() )
|
||||
{
|
||||
if ( status.id() > m_cachedMentionsSinceId )
|
||||
{
|
||||
m_cachedMentionsSinceId = status.id();
|
||||
}
|
||||
|
||||
tDebug() << "TwitterSipPlugin checking mention from " << status.user().screenName() << " with content " << status.text();
|
||||
parseGotTomahawk( regex, status.user().screenName(), status.text() );
|
||||
@@ -411,19 +459,25 @@ void
|
||||
TwitterSipPlugin::pollDirectMessages()
|
||||
{
|
||||
if ( !isValid() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_cachedDirectMessagesSinceId == 0 )
|
||||
{
|
||||
m_cachedDirectMessagesSinceId = m_configuration[ "cacheddirectmessagessinceid" ].toLongLong();
|
||||
}
|
||||
|
||||
tDebug() << "TwitterSipPlugin looking for direct messages since id " << m_cachedDirectMessagesSinceId;
|
||||
|
||||
if ( !m_directMessages.isNull() )
|
||||
{
|
||||
m_directMessages.data()->fetch( m_cachedDirectMessagesSinceId, 0, 800 );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TwitterSipPlugin::directMessages( const QList< QTweetDMStatus > &messages )
|
||||
TwitterSipPlugin::directMessages( const QList< QTweetDMStatus >& messages )
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO;
|
||||
|
||||
@@ -435,24 +489,36 @@ TwitterSipPlugin::directMessages( const QList< QTweetDMStatus > &messages )
|
||||
{
|
||||
if ( !regex.exactMatch( status.text() ) )
|
||||
{
|
||||
QStringList splitList = status.text().split(':');
|
||||
QStringList splitList = status.text().split( ':' );
|
||||
if ( splitList.length() != 5 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ( splitList[0] != "TOMAHAWKPEER" )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ( !splitList[1].startsWith( "Host=" ) || !splitList[2].startsWith( "Port=" ) || !splitList[3].startsWith( "Node=" ) || !splitList[4].startsWith( "PKey=" ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
int port = splitList[2].mid( 5 ).toInt();
|
||||
if ( port == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !latestHash.contains( status.senderScreenName() ) )
|
||||
{
|
||||
latestHash[status.senderScreenName()] = status;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( status.id() > latestHash[status.senderScreenName()].id() )
|
||||
{
|
||||
latestHash[status.senderScreenName()] = status;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -460,22 +526,26 @@ TwitterSipPlugin::directMessages( const QList< QTweetDMStatus > &messages )
|
||||
{
|
||||
qDebug() << "TwitterSipPlugin checking direct message from " << status.senderScreenName() << " with content " << status.text();
|
||||
if ( status.id() > m_cachedDirectMessagesSinceId )
|
||||
{
|
||||
m_cachedDirectMessagesSinceId = status.id();
|
||||
}
|
||||
|
||||
if ( regex.exactMatch( status.text() ) )
|
||||
{
|
||||
parseGotTomahawk( regex, status.sender().screenName(), status.text() );
|
||||
}
|
||||
else
|
||||
{
|
||||
QStringList splitList = status.text().split(':');
|
||||
QStringList splitList = status.text().split( ':' );
|
||||
qDebug() << "TwitterSipPlugin found " << splitList.length() << " parts to the message; the parts are:";
|
||||
foreach( QString part, splitList )
|
||||
qDebug() << part;
|
||||
qDebug() << part;
|
||||
//validity is checked above
|
||||
int port = splitList[2].mid( 5 ).toInt();
|
||||
QString host = splitList[1].mid( 5 );
|
||||
QString node = splitList[3].mid( 5 );
|
||||
QString pkey = splitList[4].mid( 5 );
|
||||
QStringList splitNode = node.split('*');
|
||||
QStringList splitNode = node.split( '*' );
|
||||
if ( splitNode.length() != 2 )
|
||||
{
|
||||
qDebug() << "Old-style node info found, ignoring";
|
||||
@@ -485,8 +555,8 @@ TwitterSipPlugin::directMessages( const QList< QTweetDMStatus > &messages )
|
||||
|
||||
|
||||
QVariantHash peerData = ( m_cachedPeers.contains( status.senderScreenName() ) ) ?
|
||||
m_cachedPeers[status.senderScreenName()].toHash() :
|
||||
QVariantHash();
|
||||
m_cachedPeers[status.senderScreenName()].toHash() :
|
||||
QVariantHash();
|
||||
|
||||
peerData["host"] = QVariant::fromValue< QString >( host );
|
||||
peerData["port"] = QVariant::fromValue< int >( port );
|
||||
@@ -500,7 +570,9 @@ TwitterSipPlugin::directMessages( const QList< QTweetDMStatus > &messages )
|
||||
{
|
||||
qDebug() << "TwitterSipPlugin found message destined for this node; destroying it";
|
||||
if ( !m_directMessageDestroy.isNull() )
|
||||
{
|
||||
m_directMessageDestroy.data()->destroyMessage( status.id() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -510,7 +582,7 @@ TwitterSipPlugin::directMessages( const QList< QTweetDMStatus > &messages )
|
||||
}
|
||||
|
||||
void
|
||||
TwitterSipPlugin::registerOffer( const QString &screenName, const QVariantHash &peerData )
|
||||
TwitterSipPlugin::registerOffer( const QString& screenName, const QVariantHash& peerData )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
@@ -521,7 +593,9 @@ TwitterSipPlugin::registerOffer( const QString &screenName, const QVariantHash &
|
||||
QString friendlyName = QString( '@' + screenName );
|
||||
|
||||
if ( !m_cachedAvatars.contains( screenName ) )
|
||||
{
|
||||
QMetaObject::invokeMethod( this, "fetchAvatar", Q_ARG( QString, screenName ) );
|
||||
}
|
||||
|
||||
QVariantHash _peerData( peerData );
|
||||
|
||||
@@ -539,8 +613,8 @@ TwitterSipPlugin::registerOffer( const QString &screenName, const QVariantHash &
|
||||
}
|
||||
|
||||
if ( !_peerData.contains( "okey" ) ||
|
||||
!_peerData.contains( "onod" ) ||
|
||||
( _peerData.contains( "onod" ) && _peerData["onod"] != Database::instance()->impl()->dbid() ) )
|
||||
!_peerData.contains( "onod" ) ||
|
||||
( _peerData.contains( "onod" ) && _peerData["onod"] != Database::instance()->impl()->dbid() ) )
|
||||
{
|
||||
QString okey = QUuid::createUuid().toString().split( '-' ).last();
|
||||
okey.chop( 1 );
|
||||
@@ -560,8 +634,10 @@ TwitterSipPlugin::registerOffer( const QString &screenName, const QVariantHash &
|
||||
if ( !_peerData.contains( "ohst" ) || !_peerData.contains( "oprt" ) ||
|
||||
_peerData["ohst"].toString() != Servent::instance()->externalAddress() ||
|
||||
_peerData["oprt"].toInt() != Servent::instance()->externalPort()
|
||||
)
|
||||
)
|
||||
{
|
||||
needToSend = true;
|
||||
}
|
||||
|
||||
if( needToAddToCache && _peerData.contains( "node" ) )
|
||||
{
|
||||
@@ -569,16 +645,20 @@ TwitterSipPlugin::registerOffer( const QString &screenName, const QVariantHash &
|
||||
m_keyCache << Servent::instance()->createConnectionKey( friendlyName, _peerData["node"].toString(), _peerData["okey"].toString(), false );
|
||||
}
|
||||
|
||||
if( needToSend && _peerData.contains( "node") )
|
||||
if( needToSend && _peerData.contains( "node" ) )
|
||||
{
|
||||
qDebug() << "TwitterSipPlugin needs to send and has node";
|
||||
_peerData["ohst"] = QVariant::fromValue< QString >( Servent::instance()->externalAddress() );
|
||||
_peerData["oprt"] = QVariant::fromValue< int >( Servent::instance()->externalPort() );
|
||||
peersChanged = true;
|
||||
if( !Servent::instance()->externalAddress().isEmpty() && !Servent::instance()->externalPort() == 0 )
|
||||
{
|
||||
QMetaObject::invokeMethod( this, "sendOffer", Q_ARG( QString, screenName ), Q_ARG( QVariantHash, _peerData ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "TwitterSipPlugin did not send offer because external address is " << Servent::instance()->externalAddress() << " and external port is " << Servent::instance()->externalPort();
|
||||
}
|
||||
}
|
||||
|
||||
if ( peersChanged )
|
||||
@@ -590,37 +670,41 @@ TwitterSipPlugin::registerOffer( const QString &screenName, const QVariantHash &
|
||||
}
|
||||
|
||||
if ( m_state == Tomahawk::Accounts::Account::Connected && _peerData.contains( "host" ) && _peerData.contains( "port" ) && _peerData.contains( "pkey" ) )
|
||||
{
|
||||
QMetaObject::invokeMethod( this, "makeConnection", Q_ARG( QString, screenName ), Q_ARG( QVariantHash, _peerData ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
TwitterSipPlugin::sendOffer( const QString &screenName, const QVariantHash &peerData )
|
||||
TwitterSipPlugin::sendOffer( const QString& screenName, const QVariantHash& peerData )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
QString offerString = QString( "TOMAHAWKPEER:Host=%1:Port=%2:Node=%3*%4:PKey=%5" ).arg( peerData["ohst"].toString() )
|
||||
.arg( peerData["oprt"].toString() )
|
||||
.arg( Database::instance()->impl()->dbid() )
|
||||
.arg( peerData["node"].toString().left( 8 ) )
|
||||
.arg( peerData["okey"].toString() );
|
||||
.arg( peerData["oprt"].toString() )
|
||||
.arg( Database::instance()->impl()->dbid() )
|
||||
.arg( peerData["node"].toString().left( 8 ) )
|
||||
.arg( peerData["okey"].toString() );
|
||||
qDebug() << "TwitterSipPlugin sending message to " << screenName << ": " << offerString;
|
||||
if( !m_directMessageNew.isNull() )
|
||||
{
|
||||
m_directMessageNew.data()->post( screenName, offerString );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TwitterSipPlugin::makeConnection( const QString &screenName, const QVariantHash &peerData )
|
||||
TwitterSipPlugin::makeConnection( const QString& screenName, const QVariantHash& peerData )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
if ( !peerData.contains( "host" ) || !peerData.contains( "port" ) || !peerData.contains( "pkey" ) || !peerData.contains( "node" ) ||
|
||||
peerData["host"].toString().isEmpty() || peerData["port"].toString().isEmpty() || peerData["pkey"].toString().isEmpty() || peerData["node"].toString().isEmpty() )
|
||||
peerData["host"].toString().isEmpty() || peerData["port"].toString().isEmpty() || peerData["pkey"].toString().isEmpty() || peerData["node"].toString().isEmpty() )
|
||||
{
|
||||
qDebug() << "TwitterSipPlugin could not find host and/or port and/or pkey and/or node for peer " << screenName;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( peerData["host"].toString() == Servent::instance()->externalAddress() &&
|
||||
peerData["port"].toInt() == Servent::instance()->externalPort() )
|
||||
peerData["port"].toInt() == Servent::instance()->externalPort() )
|
||||
{
|
||||
qDebug() << "TwitterSipPlugin asked to make connection to our own host and port, ignoring " << screenName;
|
||||
return;
|
||||
@@ -644,7 +728,7 @@ TwitterSipPlugin::directMessagePosted( const QTweetDMStatus& message )
|
||||
}
|
||||
|
||||
void
|
||||
TwitterSipPlugin::directMessagePostError( QTweetNetBase::ErrorCode errorCode, const QString &message )
|
||||
TwitterSipPlugin::directMessagePostError( QTweetNetBase::ErrorCode errorCode, const QString& message )
|
||||
{
|
||||
Q_UNUSED( errorCode );
|
||||
Q_UNUSED( message );
|
||||
@@ -664,22 +748,26 @@ TwitterSipPlugin::fetchAvatar( const QString& screenName )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
if ( !isValid() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QTweetUserShow *userShowFetch = new QTweetUserShow( m_cachedTwitterAuth.data(), this );
|
||||
QTweetUserShow* userShowFetch = new QTweetUserShow( m_cachedTwitterAuth.data(), this );
|
||||
connect( userShowFetch, SIGNAL( parsedUserInfo( QTweetUser ) ), SLOT( avatarUserDataSlot( QTweetUser ) ) );
|
||||
userShowFetch->fetch( screenName );
|
||||
}
|
||||
|
||||
void
|
||||
TwitterSipPlugin::avatarUserDataSlot( const QTweetUser &user )
|
||||
TwitterSipPlugin::avatarUserDataSlot( const QTweetUser& user )
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO;
|
||||
if ( !isValid() || user.profileImageUrl().isEmpty())
|
||||
if ( !isValid() || user.profileImageUrl().isEmpty() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QNetworkRequest request( user.profileImageUrl() );
|
||||
QNetworkReply *reply = m_cachedTwitterAuth.data()->networkAccessManager()->get( request );
|
||||
QNetworkReply* reply = m_cachedTwitterAuth.data()->networkAccessManager()->get( request );
|
||||
reply->setProperty( "screenname", user.screenName() );
|
||||
connect( reply, SIGNAL( finished() ), this, SLOT( profilePicReply() ) );
|
||||
}
|
||||
@@ -689,7 +777,7 @@ void
|
||||
TwitterSipPlugin::profilePicReply()
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO;
|
||||
QNetworkReply *reply = qobject_cast< QNetworkReply* >( sender() );
|
||||
QNetworkReply* reply = qobject_cast< QNetworkReply* >( sender() );
|
||||
if ( !reply || reply->error() != QNetworkReply::NoError || !reply->property( "screenname" ).isValid() )
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO << " reply not valid or came back with error";
|
||||
@@ -710,7 +798,9 @@ TwitterSipPlugin::configurationChanged()
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO;
|
||||
if ( m_state != Tomahawk::Accounts::Account::Disconnected )
|
||||
{
|
||||
m_account->deauthenticate();
|
||||
}
|
||||
connectPlugin();
|
||||
}
|
||||
|
||||
|
@@ -44,8 +44,8 @@ class ACCOUNTDLLEXPORT TwitterSipPlugin : public SipPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TwitterSipPlugin( Tomahawk::Accounts::Account *account );
|
||||
public:
|
||||
TwitterSipPlugin( Tomahawk::Accounts::Account* account );
|
||||
|
||||
virtual ~TwitterSipPlugin() {}
|
||||
|
||||
@@ -53,10 +53,10 @@ public:
|
||||
virtual Tomahawk::Accounts::Account::ConnectionState connectionState() const;
|
||||
virtual QString inviteString() const;
|
||||
|
||||
signals:
|
||||
signals:
|
||||
void stateChanged( Tomahawk::Accounts::Account::ConnectionState );
|
||||
|
||||
public slots:
|
||||
public slots:
|
||||
virtual void connectPlugin();
|
||||
void disconnectPlugin();
|
||||
void configurationChanged();
|
||||
@@ -67,12 +67,12 @@ public slots:
|
||||
Q_UNUSED( info );
|
||||
}
|
||||
|
||||
void broadcastMsg( const QString &msg )
|
||||
void broadcastMsg( const QString& msg )
|
||||
{
|
||||
Q_UNUSED( msg );
|
||||
}
|
||||
|
||||
bool addContact( const QString &peerId, AddContactOptions options, const QString& msg = QString() )
|
||||
bool addContact( const QString& peerId, AddContactOptions options, const QString& msg = QString() )
|
||||
{
|
||||
Q_UNUSED( peerId );
|
||||
Q_UNUSED( msg );
|
||||
@@ -83,29 +83,29 @@ public slots:
|
||||
|
||||
void checkSettings();
|
||||
|
||||
private slots:
|
||||
void accountAuthenticated( const QPointer< TomahawkOAuthTwitter > &twitterAuth, const QTweetUser &user );
|
||||
private slots:
|
||||
void accountAuthenticated( const QPointer< TomahawkOAuthTwitter >& twitterAuth, const QTweetUser& user );
|
||||
void checkTimerFired();
|
||||
void connectTimerFired();
|
||||
void friendsTimelineStatuses( const QList< QTweetStatus > &statuses );
|
||||
void mentionsStatuses( const QList< QTweetStatus > &statuses );
|
||||
void friendsTimelineStatuses( const QList< QTweetStatus >& statuses );
|
||||
void mentionsStatuses( const QList< QTweetStatus >& statuses );
|
||||
void pollDirectMessages();
|
||||
void directMessages( const QList< QTweetDMStatus > &messages );
|
||||
void directMessagePosted( const QTweetDMStatus &message );
|
||||
void directMessagePostError( QTweetNetBase::ErrorCode errorCode, const QString &message );
|
||||
void directMessageDestroyed( const QTweetDMStatus &message );
|
||||
void registerOffers( const QStringList &peerList );
|
||||
void registerOffer( const QString &screenName, const QVariantHash &peerdata );
|
||||
void sendOffer( const QString &screenName, const QVariantHash &peerdata );
|
||||
void makeConnection( const QString &screenName, const QVariantHash &peerdata );
|
||||
void fetchAvatar( const QString &screenName );
|
||||
void avatarUserDataSlot( const QTweetUser &user );
|
||||
void directMessages( const QList< QTweetDMStatus >& messages );
|
||||
void directMessagePosted( const QTweetDMStatus& message );
|
||||
void directMessagePostError( QTweetNetBase::ErrorCode errorCode, const QString& message );
|
||||
void directMessageDestroyed( const QTweetDMStatus& message );
|
||||
void registerOffers( const QStringList& peerList );
|
||||
void registerOffer( const QString& screenName, const QVariantHash& peerdata );
|
||||
void sendOffer( const QString& screenName, const QVariantHash& peerdata );
|
||||
void makeConnection( const QString& screenName, const QVariantHash& peerdata );
|
||||
void fetchAvatar( const QString& screenName );
|
||||
void avatarUserDataSlot( const QTweetUser& user );
|
||||
void profilePicReply();
|
||||
|
||||
private:
|
||||
private:
|
||||
void syncConfig();
|
||||
bool refreshTwitterAuth();
|
||||
void parseGotTomahawk( const QRegExp ®ex, const QString &screenName, const QString &text );
|
||||
void parseGotTomahawk( const QRegExp& regex, const QString& screenName, const QString& text );
|
||||
|
||||
QPointer< TomahawkOAuthTwitter > m_cachedTwitterAuth;
|
||||
|
||||
|
@@ -39,7 +39,7 @@ XmppAccountFactory::createAccount( const QString& accountId )
|
||||
}
|
||||
|
||||
|
||||
XmppAccount::XmppAccount( const QString &accountId )
|
||||
XmppAccount::XmppAccount( const QString& accountId )
|
||||
: Account( accountId )
|
||||
{
|
||||
setAccountServiceName( "Jabber (XMPP)" );
|
||||
@@ -61,7 +61,9 @@ QPixmap
|
||||
XmppAccount::icon() const
|
||||
{
|
||||
if ( connectionState() == Connected )
|
||||
{
|
||||
return m_onlinePixmap;
|
||||
}
|
||||
return m_offlinePixmap;
|
||||
}
|
||||
|
||||
@@ -70,7 +72,9 @@ void
|
||||
XmppAccount::authenticate()
|
||||
{
|
||||
if ( connectionState() != Account::Connected )
|
||||
{
|
||||
sipPlugin()->connectPlugin();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -78,7 +82,9 @@ void
|
||||
XmppAccount::deauthenticate()
|
||||
{
|
||||
if ( connectionState() != Account::Disconnected && !m_xmppSipPlugin.isNull() )
|
||||
{
|
||||
m_xmppSipPlugin->disconnectPlugin();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -92,7 +98,9 @@ Account::ConnectionState
|
||||
XmppAccount::connectionState() const
|
||||
{
|
||||
if ( m_xmppSipPlugin.isNull() )
|
||||
{
|
||||
return Account::Disconnected;
|
||||
}
|
||||
|
||||
return m_xmppSipPlugin.data()->connectionState();
|
||||
}
|
||||
@@ -101,7 +109,9 @@ void
|
||||
XmppAccount::saveConfig()
|
||||
{
|
||||
if ( !m_configWidget.isNull() )
|
||||
{
|
||||
static_cast< XmppConfigWidget* >( m_configWidget.data() )->saveConfig();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -109,7 +119,9 @@ InfoSystem::InfoPluginPtr
|
||||
XmppAccount::infoPlugin()
|
||||
{
|
||||
if( !m_xmppSipPlugin.isNull() )
|
||||
{
|
||||
return m_xmppSipPlugin.data()->infoPlugin();
|
||||
}
|
||||
|
||||
return InfoSystem::InfoPluginPtr();
|
||||
}
|
||||
@@ -121,7 +133,9 @@ XmppAccount::sipPlugin( bool create )
|
||||
if ( m_xmppSipPlugin.isNull() )
|
||||
{
|
||||
if ( !create )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
m_xmppSipPlugin = QPointer< XmppSipPlugin >( new XmppSipPlugin( this ) );
|
||||
|
||||
|
@@ -45,15 +45,30 @@ class ACCOUNTDLLEXPORT XmppAccountFactory : public AccountFactory
|
||||
|
||||
// for settings access
|
||||
friend class XmppConfigWidget;
|
||||
public:
|
||||
public:
|
||||
XmppAccountFactory() {}
|
||||
virtual ~XmppAccountFactory() {}
|
||||
|
||||
QString prettyName() const { return "Jabber (XMPP)"; }
|
||||
QString description() const { return tr( "Log on to your Jabber/XMPP account to connect to your friends" ); }
|
||||
QString factoryId() const { return "xmppaccount"; }
|
||||
QPixmap icon() const { return QPixmap( ":/xmpp-account/xmpp-icon.png" ); }
|
||||
AccountTypes types() const { return AccountTypes( SipType | StatusPushType ); }
|
||||
QString prettyName() const
|
||||
{
|
||||
return "Jabber (XMPP)";
|
||||
}
|
||||
QString description() const
|
||||
{
|
||||
return tr( "Log on to your Jabber/XMPP account to connect to your friends" );
|
||||
}
|
||||
QString factoryId() const
|
||||
{
|
||||
return "xmppaccount";
|
||||
}
|
||||
QPixmap icon() const
|
||||
{
|
||||
return QPixmap( ":/xmpp-account/xmpp-icon.png" );
|
||||
}
|
||||
AccountTypes types() const
|
||||
{
|
||||
return AccountTypes( SipType | StatusPushType );
|
||||
}
|
||||
Account* createAccount( const QString& pluginId = QString() );
|
||||
};
|
||||
|
||||
@@ -61,8 +76,8 @@ class ACCOUNTDLLEXPORT XmppAccount : public Account
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
XmppAccount( const QString &accountId );
|
||||
public:
|
||||
XmppAccount( const QString& accountId );
|
||||
virtual ~XmppAccount();
|
||||
|
||||
QPixmap icon() const;
|
||||
@@ -75,13 +90,19 @@ public:
|
||||
|
||||
SipPlugin* sipPlugin( bool create = true );
|
||||
|
||||
AccountConfigWidget* configurationWidget() { return m_configWidget.data(); }
|
||||
QWidget* aclWidget() { return 0; }
|
||||
AccountConfigWidget* configurationWidget()
|
||||
{
|
||||
return m_configWidget.data();
|
||||
}
|
||||
QWidget* aclWidget()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
void saveConfig();
|
||||
|
||||
virtual Tomahawk::Accounts::Account::ConnectionState connectionState() const;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
QPointer< AccountConfigWidget > m_configWidget; // so the google wrapper can change the config dialog a bit
|
||||
QPointer< XmppSipPlugin > m_xmppSipPlugin;
|
||||
QPointer< Tomahawk::InfoSystem::XmppInfoPlugin > m_xmppInfoPlugin;
|
||||
|
@@ -35,7 +35,7 @@ namespace Tomahawk
|
||||
namespace Accounts
|
||||
{
|
||||
|
||||
XmppConfigWidget::XmppConfigWidget( XmppAccount* account, QWidget *parent )
|
||||
XmppConfigWidget::XmppConfigWidget( XmppAccount* account, QWidget* parent )
|
||||
: AccountConfigWidget( parent )
|
||||
, m_ui( new Ui::XmppConfigWidget )
|
||||
, m_account( account )
|
||||
@@ -47,8 +47,8 @@ XmppConfigWidget::XmppConfigWidget( XmppAccount* account, QWidget *parent )
|
||||
m_ui->xmppPassword->setText( account->credentials().contains( "password" ) ? account->credentials()[ "password" ].toString() : QString() );
|
||||
m_ui->xmppServer->setText( account->configuration().contains( "server" ) ? account->configuration()[ "server" ].toString() : QString() );
|
||||
m_ui->xmppPort->setValue( account->configuration().contains( "port" ) ? account->configuration()[ "port" ].toInt() : 5222 );
|
||||
m_ui->xmppPublishTracksCheckbox->setChecked( account->configuration().contains( "publishtracks" ) ? account->configuration()[ "publishtracks" ].toBool() : true);
|
||||
m_ui->xmppEnforceSecureCheckbox->setChecked( account->configuration().contains( "enforcesecure" ) ? account->configuration()[ "enforcesecure" ].toBool() : false);
|
||||
m_ui->xmppPublishTracksCheckbox->setChecked( account->configuration().contains( "publishtracks" ) ? account->configuration()[ "publishtracks" ].toBool() : true );
|
||||
m_ui->xmppEnforceSecureCheckbox->setChecked( account->configuration().contains( "enforcesecure" ) ? account->configuration()[ "enforcesecure" ].toBool() : false );
|
||||
m_ui->jidExistsLabel->hide();
|
||||
m_ui->xmppConfigFrame->hide();
|
||||
|
||||
@@ -71,7 +71,7 @@ XmppConfigWidget::XmppConfigWidget( XmppAccount* account, QWidget *parent )
|
||||
m_ui->xmppBlurb->hide();
|
||||
m_ui->xmppConfigFrame->show();
|
||||
m_ui->xmppConfigLabel->setText( tr( "Account provided by %1." )
|
||||
.arg( cs->prettyName() ) );
|
||||
.arg( cs->prettyName() ) );
|
||||
m_ui->xmppConfigIcon->setPixmap( cs->icon().scaled( TomahawkUtils::defaultIconSize(), Qt::KeepAspectRatio, Qt::SmoothTransformation ) );
|
||||
m_ui->xmppConfigLaunchDialog->setIcon( TomahawkUtils::defaultPixmap( TomahawkUtils::Configure ) );
|
||||
connect( m_ui->xmppConfigLaunchDialog, SIGNAL( clicked() ),
|
||||
@@ -108,7 +108,7 @@ XmppConfigWidget::saveConfig()
|
||||
|
||||
m_account->setAccountFriendlyName( m_ui->xmppUsername->text() );
|
||||
m_account->setCredentials( credentials );
|
||||
m_account->setConfiguration( configuration);
|
||||
m_account->setConfiguration( configuration );
|
||||
m_account->sync();
|
||||
|
||||
static_cast< XmppSipPlugin* >( m_account->sipPlugin() )->checkSettings();
|
||||
@@ -116,23 +116,25 @@ XmppConfigWidget::saveConfig()
|
||||
|
||||
|
||||
void
|
||||
XmppConfigWidget::onCheckJidExists( const QString &jid )
|
||||
XmppConfigWidget::onCheckJidExists( const QString& jid )
|
||||
{
|
||||
QList< Tomahawk::Accounts::Account* > accounts = Tomahawk::Accounts::AccountManager::instance()->accounts( Tomahawk::Accounts::SipType );
|
||||
foreach( Tomahawk::Accounts::Account* account, accounts )
|
||||
foreach( Tomahawk::Accounts::Account * account, accounts )
|
||||
{
|
||||
if ( account->accountId() == m_account->accountId() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
QString savedUsername = account->credentials()[ "username" ].toString();
|
||||
QStringList savedSplitUsername = account->credentials()[ "username" ].toString().split("@");
|
||||
QStringList savedSplitUsername = account->credentials()[ "username" ].toString().split( "@" );
|
||||
QString savedServer = account->configuration()[ "server" ].toString();
|
||||
int savedPort = account->configuration()[ "port" ].toInt();
|
||||
|
||||
if ( ( savedUsername == jid || savedSplitUsername.contains( jid ) ) &&
|
||||
savedServer == m_ui->xmppServer->text() &&
|
||||
savedPort == m_ui->xmppPort->value() &&
|
||||
!jid.trimmed().isEmpty() )
|
||||
savedServer == m_ui->xmppServer->text() &&
|
||||
savedPort == m_ui->xmppPort->value() &&
|
||||
!jid.trimmed().isEmpty() )
|
||||
{
|
||||
m_ui->jidExistsLabel->show();
|
||||
// the already jid exists
|
||||
|
@@ -26,7 +26,7 @@
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class XmppConfigWidget;
|
||||
class XmppConfigWidget;
|
||||
}
|
||||
|
||||
namespace Tomahawk
|
||||
@@ -43,24 +43,24 @@ class ACCOUNTDLLEXPORT XmppConfigWidget : public AccountConfigWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit XmppConfigWidget( XmppAccount* account = 0, QWidget *parent = 0 );
|
||||
public:
|
||||
explicit XmppConfigWidget( XmppAccount* account = 0, QWidget* parent = 0 );
|
||||
virtual ~XmppConfigWidget();
|
||||
|
||||
void saveConfig();
|
||||
|
||||
virtual void checkForErrors();
|
||||
|
||||
signals:
|
||||
signals:
|
||||
void dataError( bool exists );
|
||||
|
||||
private slots:
|
||||
private slots:
|
||||
void onCheckJidExists( const QString& jid );
|
||||
void launchExternalConfigDialog();
|
||||
|
||||
private:
|
||||
Ui::XmppConfigWidget *m_ui;
|
||||
XmppAccount *m_account;
|
||||
private:
|
||||
Ui::XmppConfigWidget* m_ui;
|
||||
XmppAccount* m_account;
|
||||
|
||||
bool m_serverWasEditedByUser;
|
||||
|
||||
|
@@ -27,7 +27,7 @@
|
||||
|
||||
// Forward Declarations breaking QSharedPointer
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 5, 0, 0 )
|
||||
#include "Source.h"
|
||||
#include "Source.h"
|
||||
#endif
|
||||
|
||||
|
||||
@@ -63,7 +63,9 @@ Tomahawk::InfoSystem::XmppInfoPlugin::init()
|
||||
}
|
||||
|
||||
if ( m_sipPlugin.isNull() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
connect( this, SIGNAL( publishTune( QUrl, Tomahawk::InfoSystem::InfoStringHash ) ), m_sipPlugin.data(), SLOT( publishTune( QUrl, Tomahawk::InfoSystem::InfoStringHash ) ), Qt::QueuedConnection );
|
||||
}
|
||||
@@ -95,7 +97,7 @@ Tomahawk::InfoSystem::XmppInfoPlugin::pushInfo( Tomahawk::InfoSystem::InfoPushDa
|
||||
|
||||
|
||||
void
|
||||
Tomahawk::InfoSystem::XmppInfoPlugin::audioStarted( const Tomahawk::InfoSystem::PushInfoPair &pushInfoPair )
|
||||
Tomahawk::InfoSystem::XmppInfoPlugin::audioStarted( const Tomahawk::InfoSystem::PushInfoPair& pushInfoPair )
|
||||
{
|
||||
if ( !pushInfoPair.second.canConvert< QVariantMap >() )
|
||||
{
|
||||
@@ -120,9 +122,13 @@ Tomahawk::InfoSystem::XmppInfoPlugin::audioStarted( const Tomahawk::InfoSystem::
|
||||
|
||||
QUrl url;
|
||||
if ( pushInfoPair.first.contains( "shorturl" ) )
|
||||
{
|
||||
url = pushInfoPair.first[ "shorturl" ].toUrl();
|
||||
}
|
||||
else
|
||||
{
|
||||
url = GlobalActionManager::instance()->openLink( info.value( "title" ), info.value( "artist" ), info.value( "album" ) );
|
||||
}
|
||||
|
||||
emit publishTune( url, info );
|
||||
}
|
||||
@@ -142,14 +148,14 @@ Tomahawk::InfoSystem::XmppInfoPlugin::audioStopped()
|
||||
|
||||
|
||||
void
|
||||
Tomahawk::InfoSystem::XmppInfoPlugin::getInfo(Tomahawk::InfoSystem::InfoRequestData requestData)
|
||||
Tomahawk::InfoSystem::XmppInfoPlugin::getInfo( Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
{
|
||||
Q_UNUSED( requestData );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Tomahawk::InfoSystem::XmppInfoPlugin::notInCacheSlot(const Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData)
|
||||
Tomahawk::InfoSystem::XmppInfoPlugin::notInCacheSlot( const Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
{
|
||||
Q_UNUSED( criteria );
|
||||
Q_UNUSED( requestData );
|
||||
|
@@ -26,40 +26,42 @@
|
||||
|
||||
class XmppSipPlugin;
|
||||
|
||||
namespace Tomahawk {
|
||||
namespace Tomahawk
|
||||
{
|
||||
|
||||
namespace InfoSystem {
|
||||
namespace InfoSystem
|
||||
{
|
||||
|
||||
class XmppInfoPlugin : public InfoPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
class XmppInfoPlugin : public InfoPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
XmppInfoPlugin(XmppSipPlugin* parent);
|
||||
virtual ~XmppInfoPlugin();
|
||||
public:
|
||||
XmppInfoPlugin( XmppSipPlugin* parent );
|
||||
virtual ~XmppInfoPlugin();
|
||||
|
||||
signals:
|
||||
void publishTune( QUrl url, Tomahawk::InfoSystem::InfoStringHash trackInfo );
|
||||
signals:
|
||||
void publishTune( QUrl url, Tomahawk::InfoSystem::InfoStringHash trackInfo );
|
||||
|
||||
public slots:
|
||||
void notInCacheSlot( const Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
public slots:
|
||||
void notInCacheSlot( const Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
|
||||
protected slots:
|
||||
void init();
|
||||
void pushInfo( Tomahawk::InfoSystem::InfoPushData pushData );
|
||||
void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
protected slots:
|
||||
void init();
|
||||
void pushInfo( Tomahawk::InfoSystem::InfoPushData pushData );
|
||||
void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
|
||||
private slots:
|
||||
void audioStarted( const Tomahawk::InfoSystem::PushInfoPair& pushInfoPair );
|
||||
void audioStopped();
|
||||
void audioPaused();
|
||||
private slots:
|
||||
void audioStarted( const Tomahawk::InfoSystem::PushInfoPair& pushInfoPair );
|
||||
void audioStopped();
|
||||
void audioPaused();
|
||||
|
||||
private:
|
||||
QPointer< XmppSipPlugin > m_sipPlugin;
|
||||
QTimer m_pauseTimer;
|
||||
};
|
||||
private:
|
||||
QPointer< XmppSipPlugin > m_sipPlugin;
|
||||
QTimer m_pauseTimer;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@@ -63,7 +63,7 @@ AvatarManager::fetchVCard( const QString& jid )
|
||||
{
|
||||
Jreen::IQ iq( Jreen::IQ::Get, jid );
|
||||
iq.addExtension( new Jreen::VCard() );
|
||||
Jreen::IQReply *reply = m_client->send( iq );
|
||||
Jreen::IQReply* reply = m_client->send( iq );
|
||||
|
||||
connect( reply, SIGNAL( received( Jreen::IQ ) ), SLOT( onNewIq( Jreen::IQ ) ) );
|
||||
}
|
||||
@@ -80,19 +80,21 @@ AvatarManager::onNewPresence( const Jreen::Presence& presence )
|
||||
Jreen::VCardUpdate::Ptr update = presence.payload<Jreen::VCardUpdate>();
|
||||
if ( update )
|
||||
{
|
||||
// qDebug() << "vcard: found update for" << presence.from().full();
|
||||
// qDebug() << "vcard: found update for" << presence.from().full();
|
||||
if ( !isCached( update->photoHash() ) )
|
||||
{
|
||||
// qDebug() << presence.from().full() << "vcard: photo not cached, starting request..." << update->photoHash();
|
||||
// qDebug() << presence.from().full() << "vcard: photo not cached, starting request..." << update->photoHash();
|
||||
fetchVCard( presence.from().bare() );
|
||||
}
|
||||
else
|
||||
{
|
||||
// qDebug() << presence.from().full() << "vcard: photo already cached no request necessary " << update->photoHash();
|
||||
// qDebug() << presence.from().full() << "vcard: photo already cached no request necessary " << update->photoHash();
|
||||
m_JidsAvatarHashes.insert( update->photoHash(), presence.from().bare() );
|
||||
|
||||
if ( !this->avatar( presence.from().bare() ).isNull() )
|
||||
{
|
||||
emit newAvatar( presence.from().bare() );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -110,20 +112,22 @@ AvatarManager::onNewIq( const Jreen::IQ& iq )
|
||||
if ( vcard )
|
||||
{
|
||||
iq.accept();
|
||||
// qDebug() << Q_FUNC_INFO << "Got vcard from " << iq.from().full();
|
||||
// qDebug() << Q_FUNC_INFO << "Got vcard from " << iq.from().full();
|
||||
|
||||
QString id = iq.from().full();
|
||||
QString avatarHash;
|
||||
|
||||
const Jreen::VCard::Photo &photo = vcard->photo();
|
||||
const Jreen::VCard::Photo& photo = vcard->photo();
|
||||
if ( !photo.data().isEmpty() )
|
||||
{
|
||||
// qDebug() << "vcard: got photo data" << id;
|
||||
// qDebug() << "vcard: got photo data" << id;
|
||||
|
||||
avatarHash = QCryptographicHash::hash( photo.data(), QCryptographicHash::Sha1 ).toHex();
|
||||
|
||||
if ( !m_cacheDir.exists() )
|
||||
{
|
||||
m_cacheDir.mkpath( avatarDir( avatarHash ).absolutePath() );
|
||||
}
|
||||
|
||||
QFile file( avatarPath( avatarHash ) );
|
||||
if ( file.open( QIODevice::WriteOnly ) )
|
||||
@@ -202,5 +206,5 @@ AvatarManager::isCached( const QString& avatarHash ) const
|
||||
void
|
||||
AvatarManager::onNewAvatar( const QString& /* jid */ )
|
||||
{
|
||||
// qDebug() << Q_FUNC_INFO << "Found new Avatar..." << jid;
|
||||
// qDebug() << Q_FUNC_INFO << "Found new Avatar..." << jid;
|
||||
}
|
||||
|
@@ -29,24 +29,24 @@
|
||||
|
||||
class ACCOUNTDLLEXPORT AvatarManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AvatarManager(Jreen::Client* client);
|
||||
public:
|
||||
AvatarManager( Jreen::Client* client );
|
||||
virtual ~AvatarManager();
|
||||
|
||||
QPixmap avatar(const QString& jid) const;
|
||||
QPixmap avatar( const QString& jid ) const;
|
||||
|
||||
signals:
|
||||
signals:
|
||||
void newAvatar( const QString& jid );
|
||||
|
||||
private slots:
|
||||
private slots:
|
||||
void onNewPresence( const Jreen::Presence& presence );
|
||||
void onNewIq(const Jreen::IQ& iq);
|
||||
void onNewIq( const Jreen::IQ& iq );
|
||||
void onNewConnection();
|
||||
void onNewAvatar( const QString& jid );
|
||||
|
||||
private:
|
||||
private:
|
||||
void fetchVCard( const QString& jid );
|
||||
QString avatarHash( const QString& jid ) const;
|
||||
QString avatarPath( const QString& avatarHash ) const;
|
||||
|
@@ -27,7 +27,7 @@ TomahawkXmppMessage::TomahawkXmppMessage()
|
||||
{
|
||||
}
|
||||
|
||||
TomahawkXmppMessage::TomahawkXmppMessage( const QList<SipInfo> &sipInfos )
|
||||
TomahawkXmppMessage::TomahawkXmppMessage( const QList<SipInfo>& sipInfos )
|
||||
: m_sipInfos( sipInfos )
|
||||
{
|
||||
}
|
||||
@@ -47,16 +47,24 @@ const QString
|
||||
TomahawkXmppMessage::key() const
|
||||
{
|
||||
if ( m_sipInfos.isEmpty() )
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_sipInfos.first().key();
|
||||
}
|
||||
}
|
||||
|
||||
const QString
|
||||
TomahawkXmppMessage::uniqname() const
|
||||
{
|
||||
if ( m_sipInfos.isEmpty() )
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_sipInfos.first().nodeId();
|
||||
}
|
||||
}
|
||||
|
@@ -31,29 +31,29 @@
|
||||
|
||||
class ACCOUNTDLLEXPORT TomahawkXmppMessage : public Jreen::Payload
|
||||
{
|
||||
J_PAYLOAD(TomahawkXmppMessage)
|
||||
public:
|
||||
TomahawkXmppMessage();
|
||||
TomahawkXmppMessage(const QList<SipInfo>& sipInfos);
|
||||
~TomahawkXmppMessage();
|
||||
J_PAYLOAD( TomahawkXmppMessage )
|
||||
public:
|
||||
TomahawkXmppMessage();
|
||||
TomahawkXmppMessage( const QList<SipInfo>& sipInfos );
|
||||
~TomahawkXmppMessage();
|
||||
|
||||
/**
|
||||
* The SipInfo objects that are wrapped in this XmppMessage
|
||||
*/
|
||||
const QList<SipInfo> sipInfos() const;
|
||||
/**
|
||||
* The SipInfo objects that are wrapped in this XmppMessage
|
||||
*/
|
||||
const QList<SipInfo> sipInfos() const;
|
||||
|
||||
/**
|
||||
* The name of the peer contained in this message
|
||||
*/
|
||||
const QString key() const;
|
||||
/**
|
||||
* The name of the peer contained in this message
|
||||
*/
|
||||
const QString key() const;
|
||||
|
||||
/**
|
||||
* The name of the peer contained in this message
|
||||
*/
|
||||
const QString uniqname() const;
|
||||
/**
|
||||
* The name of the peer contained in this message
|
||||
*/
|
||||
const QString uniqname() const;
|
||||
|
||||
private:
|
||||
QList<SipInfo> m_sipInfos;
|
||||
private:
|
||||
QList<SipInfo> m_sipInfos;
|
||||
};
|
||||
|
||||
#endif // ENTITYTIME_H
|
||||
|
@@ -43,18 +43,18 @@ TomahawkXmppMessageFactory::~TomahawkXmppMessageFactory()
|
||||
|
||||
QStringList TomahawkXmppMessageFactory::features() const
|
||||
{
|
||||
return QStringList(TOMAHAWK_SIP_MESSAGE_NS);
|
||||
return QStringList( TOMAHAWK_SIP_MESSAGE_NS );
|
||||
}
|
||||
|
||||
bool TomahawkXmppMessageFactory::canParse(const QStringRef &name, const QStringRef &uri, const QXmlStreamAttributes &attributes)
|
||||
bool TomahawkXmppMessageFactory::canParse( const QStringRef& name, const QStringRef& uri, const QXmlStreamAttributes& attributes )
|
||||
{
|
||||
Q_UNUSED(uri);
|
||||
Q_UNUSED(attributes);
|
||||
return name == QLatin1String("tomahawk") && uri == TOMAHAWK_SIP_MESSAGE_NS;
|
||||
Q_UNUSED( uri );
|
||||
Q_UNUSED( attributes );
|
||||
return name == QLatin1String( "tomahawk" ) && uri == TOMAHAWK_SIP_MESSAGE_NS;
|
||||
}
|
||||
|
||||
void TomahawkXmppMessageFactory::handleStartElement(const QStringRef &name, const QStringRef &uri,
|
||||
const QXmlStreamAttributes &attributes)
|
||||
void TomahawkXmppMessageFactory::handleStartElement( const QStringRef& name, const QStringRef& uri,
|
||||
const QXmlStreamAttributes& attributes )
|
||||
{
|
||||
m_depth++;
|
||||
if ( m_depth == 1 )
|
||||
@@ -73,7 +73,7 @@ void TomahawkXmppMessageFactory::handleStartElement(const QStringRef &name, cons
|
||||
m_key = attributes.value( QLatin1String( "pwd" ) ).toString();
|
||||
}
|
||||
}
|
||||
else if(m_depth == 3)
|
||||
else if( m_depth == 3 )
|
||||
{
|
||||
if ( name == QLatin1String( "candidate" ) )
|
||||
{
|
||||
@@ -88,14 +88,16 @@ void TomahawkXmppMessageFactory::handleStartElement(const QStringRef &name, cons
|
||||
m_sipInfos.append( info );
|
||||
}
|
||||
}
|
||||
Q_UNUSED(uri);
|
||||
Q_UNUSED(attributes);
|
||||
Q_UNUSED( uri );
|
||||
Q_UNUSED( attributes );
|
||||
}
|
||||
|
||||
void TomahawkXmppMessageFactory::handleEndElement(const QStringRef &name, const QStringRef &uri)
|
||||
void TomahawkXmppMessageFactory::handleEndElement( const QStringRef& name, const QStringRef& uri )
|
||||
{
|
||||
if ( m_depth == 3 )
|
||||
{
|
||||
m_state = AtTransport;
|
||||
}
|
||||
else if ( m_depth == 2 )
|
||||
{
|
||||
m_state = AtNowhere;
|
||||
@@ -110,12 +112,12 @@ void TomahawkXmppMessageFactory::handleEndElement(const QStringRef &name, const
|
||||
m_sipInfos.append( info );
|
||||
}
|
||||
}
|
||||
Q_UNUSED(name);
|
||||
Q_UNUSED(uri);
|
||||
Q_UNUSED( name );
|
||||
Q_UNUSED( uri );
|
||||
m_depth--;
|
||||
}
|
||||
|
||||
void TomahawkXmppMessageFactory::handleCharacterData(const QStringRef &text)
|
||||
void TomahawkXmppMessageFactory::handleCharacterData( const QStringRef& text )
|
||||
{
|
||||
/*if (m_state == AtUtc) {
|
||||
//m_utc = Util::fromStamp(text.toString());
|
||||
@@ -125,12 +127,12 @@ void TomahawkXmppMessageFactory::handleCharacterData(const QStringRef &text)
|
||||
//QTime delta = QTime::fromString(str.mid(1), QLatin1String("hh:mm"));
|
||||
//m_tzo = multiple * (delta.hour() * 60 + delta.minute());
|
||||
}*/
|
||||
Q_UNUSED(text);
|
||||
Q_UNUSED( text );
|
||||
}
|
||||
|
||||
void TomahawkXmppMessageFactory::serialize(Payload *extension, QXmlStreamWriter *writer)
|
||||
void TomahawkXmppMessageFactory::serialize( Payload* extension, QXmlStreamWriter* writer )
|
||||
{
|
||||
TomahawkXmppMessage *sipMessage = se_cast<TomahawkXmppMessage*>(extension);
|
||||
TomahawkXmppMessage* sipMessage = se_cast<TomahawkXmppMessage*>( extension );
|
||||
|
||||
writer->writeStartElement( QLatin1String( "tomahawk" ) );
|
||||
writer->writeDefaultNamespace( TOMAHAWK_SIP_MESSAGE_NS );
|
||||
@@ -160,7 +162,9 @@ void TomahawkXmppMessageFactory::serialize(Payload *extension, QXmlStreamWriter
|
||||
foreach ( SipInfo info, sipInfos )
|
||||
{
|
||||
if ( info.isVisible() )
|
||||
{
|
||||
serializeSipInfo( info, writer );
|
||||
}
|
||||
}
|
||||
|
||||
if ( lastInfo.isValid() )
|
||||
@@ -183,7 +187,7 @@ TomahawkXmppMessageFactory::createPayload()
|
||||
}
|
||||
|
||||
void
|
||||
TomahawkXmppMessageFactory::serializeSipInfo(SipInfo &info, QXmlStreamWriter *writer)
|
||||
TomahawkXmppMessageFactory::serializeSipInfo( SipInfo& info, QXmlStreamWriter* writer )
|
||||
{
|
||||
if ( info.isVisible() )
|
||||
{
|
||||
|
@@ -29,18 +29,18 @@
|
||||
|
||||
class ACCOUNTDLLEXPORT TomahawkXmppMessageFactory : public Jreen::PayloadFactory<TomahawkXmppMessage>
|
||||
{
|
||||
public:
|
||||
public:
|
||||
TomahawkXmppMessageFactory();
|
||||
virtual ~TomahawkXmppMessageFactory();
|
||||
QStringList features() const;
|
||||
bool canParse(const QStringRef &name, const QStringRef &uri, const QXmlStreamAttributes &attributes);
|
||||
void handleStartElement(const QStringRef &name, const QStringRef &uri, const QXmlStreamAttributes &attributes);
|
||||
void handleEndElement(const QStringRef &name, const QStringRef &uri);
|
||||
void handleCharacterData(const QStringRef &text);
|
||||
void serialize(Jreen::Payload *extension, QXmlStreamWriter *writer);
|
||||
bool canParse( const QStringRef& name, const QStringRef& uri, const QXmlStreamAttributes& attributes );
|
||||
void handleStartElement( const QStringRef& name, const QStringRef& uri, const QXmlStreamAttributes& attributes );
|
||||
void handleEndElement( const QStringRef& name, const QStringRef& uri );
|
||||
void handleCharacterData( const QStringRef& text );
|
||||
void serialize( Jreen::Payload* extension, QXmlStreamWriter* writer );
|
||||
Jreen::Payload::Ptr createPayload();
|
||||
private:
|
||||
void serializeSipInfo(SipInfo& info, QXmlStreamWriter *writer);
|
||||
private:
|
||||
void serializeSipInfo( SipInfo& info, QXmlStreamWriter* writer );
|
||||
|
||||
enum State { AtNowhere, AtTransport, AtCandidate } m_state;
|
||||
|
||||
|
@@ -34,330 +34,372 @@
|
||||
using namespace Jreen;
|
||||
|
||||
|
||||
XmlConsole::XmlConsole(Client* client, QWidget *parent) :
|
||||
QWidget(parent),
|
||||
m_ui(new Ui::XmlConsole),
|
||||
m_client(client), m_filter(0x1f)
|
||||
XmlConsole::XmlConsole( Client* client, QWidget* parent ) :
|
||||
QWidget( parent ),
|
||||
m_ui( new Ui::XmlConsole ),
|
||||
m_client( client ), m_filter( 0x1f )
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
m_ui->setupUi( this );
|
||||
|
||||
m_client->addXmlStreamHandler(this);
|
||||
m_client->addXmlStreamHandler( this );
|
||||
|
||||
QPalette pal = palette();
|
||||
pal.setColor(QPalette::Base, Qt::black);
|
||||
pal.setColor(QPalette::Text, Qt::white);
|
||||
m_ui->xmlBrowser->viewport()->setPalette(pal);
|
||||
QTextDocument *doc = m_ui->xmlBrowser->document();
|
||||
doc->setDocumentLayout(new QPlainTextDocumentLayout(doc));
|
||||
doc->clear();
|
||||
QPalette pal = palette();
|
||||
pal.setColor( QPalette::Base, Qt::black );
|
||||
pal.setColor( QPalette::Text, Qt::white );
|
||||
m_ui->xmlBrowser->viewport()->setPalette( pal );
|
||||
QTextDocument* doc = m_ui->xmlBrowser->document();
|
||||
doc->setDocumentLayout( new QPlainTextDocumentLayout( doc ) );
|
||||
doc->clear();
|
||||
|
||||
QTextFrameFormat format = doc->rootFrame()->frameFormat();
|
||||
format.setBackground(QColor(Qt::black));
|
||||
format.setMargin(0);
|
||||
doc->rootFrame()->setFrameFormat(format);
|
||||
QMenu *menu = new QMenu(m_ui->filterButton);
|
||||
menu->setSeparatorsCollapsible(false);
|
||||
menu->addSeparator()->setText(tr("Filter"));
|
||||
QActionGroup *group = new QActionGroup(menu);
|
||||
QAction *disabled = group->addAction(menu->addAction(tr("Disabled")));
|
||||
disabled->setCheckable(true);
|
||||
disabled->setData(Disabled);
|
||||
QAction *jid = group->addAction(menu->addAction(tr("By JID")));
|
||||
jid->setCheckable(true);
|
||||
jid->setData(ByJid);
|
||||
QAction *xmlns = group->addAction(menu->addAction(tr("By namespace uri")));
|
||||
xmlns->setCheckable(true);
|
||||
xmlns->setData(ByXmlns);
|
||||
QAction *attrb = group->addAction(menu->addAction(tr("By all attributes")));
|
||||
attrb->setCheckable(true);
|
||||
attrb->setData(ByAllAttributes);
|
||||
disabled->setChecked(true);
|
||||
connect(group, SIGNAL(triggered(QAction*)), this, SLOT(onActionGroupTriggered(QAction*)));
|
||||
menu->addSeparator()->setText(tr("Visible stanzas"));
|
||||
group = new QActionGroup(menu);
|
||||
group->setExclusive(false);
|
||||
QAction *iq = group->addAction(menu->addAction(tr("Information query")));
|
||||
iq->setCheckable(true);
|
||||
iq->setData(XmlNode::Iq);
|
||||
iq->setChecked(true);
|
||||
QAction *message = group->addAction(menu->addAction(tr("Message")));
|
||||
message->setCheckable(true);
|
||||
message->setData(XmlNode::Message);
|
||||
message->setChecked(true);
|
||||
QAction *presence = group->addAction(menu->addAction(tr("Presence")));
|
||||
presence->setCheckable(true);
|
||||
presence->setData(XmlNode::Presence);
|
||||
presence->setChecked(true);
|
||||
QAction *custom = group->addAction(menu->addAction(tr("Custom")));
|
||||
custom->setCheckable(true);
|
||||
custom->setData(XmlNode::Custom);
|
||||
custom->setChecked(true);
|
||||
connect(group, SIGNAL(triggered(QAction*)), this, SLOT(onActionGroupTriggered(QAction*)));
|
||||
m_ui->filterButton->setMenu(menu);
|
||||
m_stackBracketsColor = QColor(0x666666);
|
||||
m_stackIncoming.bodyColor = QColor(0xbb66bb);
|
||||
m_stackIncoming.tagColor = QColor(0x006666);
|
||||
m_stackIncoming.attributeColor = QColor(0x009933);
|
||||
m_stackIncoming.paramColor = QColor(0xcc0000);
|
||||
m_stackOutgoing.bodyColor = QColor(0x999999);
|
||||
m_stackOutgoing.tagColor = QColor(0x22aa22);
|
||||
m_stackOutgoing.attributeColor = QColor(0xffff33);
|
||||
m_stackOutgoing.paramColor = QColor(0xdd8811);
|
||||
QTextFrameFormat format = doc->rootFrame()->frameFormat();
|
||||
format.setBackground( QColor( Qt::black ) );
|
||||
format.setMargin( 0 );
|
||||
doc->rootFrame()->setFrameFormat( format );
|
||||
QMenu* menu = new QMenu( m_ui->filterButton );
|
||||
menu->setSeparatorsCollapsible( false );
|
||||
menu->addSeparator()->setText( tr( "Filter" ) );
|
||||
QActionGroup* group = new QActionGroup( menu );
|
||||
QAction* disabled = group->addAction( menu->addAction( tr( "Disabled" ) ) );
|
||||
disabled->setCheckable( true );
|
||||
disabled->setData( Disabled );
|
||||
QAction* jid = group->addAction( menu->addAction( tr( "By JID" ) ) );
|
||||
jid->setCheckable( true );
|
||||
jid->setData( ByJid );
|
||||
QAction* xmlns = group->addAction( menu->addAction( tr( "By namespace uri" ) ) );
|
||||
xmlns->setCheckable( true );
|
||||
xmlns->setData( ByXmlns );
|
||||
QAction* attrb = group->addAction( menu->addAction( tr( "By all attributes" ) ) );
|
||||
attrb->setCheckable( true );
|
||||
attrb->setData( ByAllAttributes );
|
||||
disabled->setChecked( true );
|
||||
connect( group, SIGNAL( triggered( QAction* ) ), this, SLOT( onActionGroupTriggered( QAction* ) ) );
|
||||
menu->addSeparator()->setText( tr( "Visible stanzas" ) );
|
||||
group = new QActionGroup( menu );
|
||||
group->setExclusive( false );
|
||||
QAction* iq = group->addAction( menu->addAction( tr( "Information query" ) ) );
|
||||
iq->setCheckable( true );
|
||||
iq->setData( XmlNode::Iq );
|
||||
iq->setChecked( true );
|
||||
QAction* message = group->addAction( menu->addAction( tr( "Message" ) ) );
|
||||
message->setCheckable( true );
|
||||
message->setData( XmlNode::Message );
|
||||
message->setChecked( true );
|
||||
QAction* presence = group->addAction( menu->addAction( tr( "Presence" ) ) );
|
||||
presence->setCheckable( true );
|
||||
presence->setData( XmlNode::Presence );
|
||||
presence->setChecked( true );
|
||||
QAction* custom = group->addAction( menu->addAction( tr( "Custom" ) ) );
|
||||
custom->setCheckable( true );
|
||||
custom->setData( XmlNode::Custom );
|
||||
custom->setChecked( true );
|
||||
connect( group, SIGNAL( triggered( QAction* ) ), this, SLOT( onActionGroupTriggered( QAction* ) ) );
|
||||
m_ui->filterButton->setMenu( menu );
|
||||
m_stackBracketsColor = QColor( 0x666666 );
|
||||
m_stackIncoming.bodyColor = QColor( 0xbb66bb );
|
||||
m_stackIncoming.tagColor = QColor( 0x006666 );
|
||||
m_stackIncoming.attributeColor = QColor( 0x009933 );
|
||||
m_stackIncoming.paramColor = QColor( 0xcc0000 );
|
||||
m_stackOutgoing.bodyColor = QColor( 0x999999 );
|
||||
m_stackOutgoing.tagColor = QColor( 0x22aa22 );
|
||||
m_stackOutgoing.attributeColor = QColor( 0xffff33 );
|
||||
m_stackOutgoing.paramColor = QColor( 0xdd8811 );
|
||||
|
||||
QAction *action = new QAction(tr("Close"),this);
|
||||
connect(action, SIGNAL(triggered()), SLOT(close()));
|
||||
addAction(action);
|
||||
QAction* action = new QAction( tr( "Close" ), this );
|
||||
connect( action, SIGNAL( triggered() ), SLOT( close() ) );
|
||||
addAction( action );
|
||||
}
|
||||
|
||||
XmlConsole::~XmlConsole()
|
||||
{
|
||||
delete m_ui;
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
void XmlConsole::handleStreamBegin()
|
||||
{
|
||||
m_stackIncoming.reader.clear();
|
||||
m_stackOutgoing.reader.clear();
|
||||
m_stackIncoming.depth = 0;
|
||||
m_stackOutgoing.depth = 0;
|
||||
qDeleteAll(m_stackIncoming.tokens);
|
||||
qDeleteAll(m_stackOutgoing.tokens);
|
||||
m_stackIncoming.tokens.clear();
|
||||
m_stackOutgoing.tokens.clear();
|
||||
m_stackIncoming.reader.clear();
|
||||
m_stackOutgoing.reader.clear();
|
||||
m_stackIncoming.depth = 0;
|
||||
m_stackOutgoing.depth = 0;
|
||||
qDeleteAll( m_stackIncoming.tokens );
|
||||
qDeleteAll( m_stackOutgoing.tokens );
|
||||
m_stackIncoming.tokens.clear();
|
||||
m_stackOutgoing.tokens.clear();
|
||||
}
|
||||
|
||||
void XmlConsole::handleStreamEnd()
|
||||
{
|
||||
m_stackIncoming.reader.clear();
|
||||
m_stackOutgoing.reader.clear();
|
||||
m_stackIncoming.depth = 0;
|
||||
m_stackOutgoing.depth = 0;
|
||||
qDeleteAll(m_stackIncoming.tokens);
|
||||
qDeleteAll(m_stackOutgoing.tokens);
|
||||
m_stackIncoming.tokens.clear();
|
||||
m_stackOutgoing.tokens.clear();
|
||||
m_stackIncoming.reader.clear();
|
||||
m_stackOutgoing.reader.clear();
|
||||
m_stackIncoming.depth = 0;
|
||||
m_stackOutgoing.depth = 0;
|
||||
qDeleteAll( m_stackIncoming.tokens );
|
||||
qDeleteAll( m_stackOutgoing.tokens );
|
||||
m_stackIncoming.tokens.clear();
|
||||
m_stackOutgoing.tokens.clear();
|
||||
}
|
||||
|
||||
void XmlConsole::handleIncomingData(const char *data, qint64 size)
|
||||
void XmlConsole::handleIncomingData( const char* data, qint64 size )
|
||||
{
|
||||
stackProcess(QByteArray::fromRawData(data, size), true);
|
||||
stackProcess( QByteArray::fromRawData( data, size ), true );
|
||||
}
|
||||
|
||||
void XmlConsole::handleOutgoingData(const char *data, qint64 size)
|
||||
void XmlConsole::handleOutgoingData( const char* data, qint64 size )
|
||||
{
|
||||
stackProcess(QByteArray::fromRawData(data, size), false);
|
||||
stackProcess( QByteArray::fromRawData( data, size ), false );
|
||||
}
|
||||
|
||||
QString generate_stacked_space(int depth)
|
||||
QString generate_stacked_space( int depth )
|
||||
{
|
||||
return QString(depth * 2, QLatin1Char(' '));
|
||||
return QString( depth * 2, QLatin1Char( ' ' ) );
|
||||
}
|
||||
|
||||
void XmlConsole::stackProcess(const QByteArray &data, bool incoming)
|
||||
void XmlConsole::stackProcess( const QByteArray& data, bool incoming )
|
||||
{
|
||||
StackEnvironment *d = &(incoming ? m_stackIncoming : m_stackOutgoing);
|
||||
d->reader.addData(data);
|
||||
StackToken *token;
|
||||
// debug() << incoming << data;
|
||||
// debug() << "==================================================================";
|
||||
while (d->reader.readNext() > QXmlStreamReader::Invalid) {
|
||||
// qDebug() << incoming << d->reader.tokenString();
|
||||
switch(d->reader.tokenType()) {
|
||||
case QXmlStreamReader::StartElement:
|
||||
// dbg << d->reader.name().toString() << d->depth
|
||||
// << d->reader.attributes().value(QLatin1String("from")).toString();
|
||||
d->depth++;
|
||||
if (d->depth > 1) {
|
||||
if (!d->tokens.isEmpty() && d->tokens.last()->type == QXmlStreamReader::Characters)
|
||||
delete d->tokens.takeLast();
|
||||
d->tokens << new StackToken(d->reader);
|
||||
}
|
||||
break;
|
||||
case QXmlStreamReader::EndElement:
|
||||
// dbg << d->reader.name().toString() << d->depth;
|
||||
if (d->tokens.isEmpty())
|
||||
break;
|
||||
token = d->tokens.last();
|
||||
if (token->type == QXmlStreamReader::StartElement && !token->startTag.empty)
|
||||
token->startTag.empty = true;
|
||||
else if (d->depth > 1)
|
||||
d->tokens << new StackToken(d->reader);
|
||||
if (d->depth == 2) {
|
||||
QTextCursor cursor(m_ui->xmlBrowser->document());
|
||||
cursor.movePosition(QTextCursor::End);
|
||||
cursor.beginEditBlock();
|
||||
QTextCharFormat zeroFormat = cursor.charFormat();
|
||||
zeroFormat.setForeground(QColor(Qt::white));
|
||||
QTextCharFormat bodyFormat = zeroFormat;
|
||||
bodyFormat.setForeground(d->bodyColor);
|
||||
QTextCharFormat tagFormat = zeroFormat;
|
||||
tagFormat.setForeground(d->tagColor);
|
||||
QTextCharFormat attributeFormat = zeroFormat;
|
||||
attributeFormat.setForeground(d->attributeColor);
|
||||
QTextCharFormat paramsFormat = zeroFormat;
|
||||
paramsFormat.setForeground(d->paramColor);
|
||||
QTextCharFormat bracketFormat = zeroFormat;
|
||||
bracketFormat.setForeground(m_stackBracketsColor);
|
||||
QString singleSpace = QLatin1String(" ");
|
||||
cursor.insertBlock();
|
||||
int depth = 0;
|
||||
QString currentXmlns;
|
||||
QXmlStreamReader::TokenType lastType = QXmlStreamReader::StartElement;
|
||||
for (int i = 0; i < d->tokens.size(); i++) {
|
||||
token = d->tokens.at(i);
|
||||
if (token->type == QXmlStreamReader::StartElement) {
|
||||
QString space = generate_stacked_space(depth);
|
||||
cursor.insertText(QLatin1String("\n"));
|
||||
cursor.insertText(space);
|
||||
cursor.insertText(QLatin1String("<"), bracketFormat);
|
||||
cursor.insertText(token->startTag.name->toString(), tagFormat);
|
||||
const QStringRef &xmlns = *token->startTag.xmlns;
|
||||
if (i == 0 || xmlns != currentXmlns) {
|
||||
currentXmlns = xmlns.toString();
|
||||
cursor.insertText(singleSpace);
|
||||
cursor.insertText(QLatin1String("xmlns"), attributeFormat);
|
||||
cursor.insertText(QLatin1String("="), zeroFormat);
|
||||
cursor.insertText(QLatin1String("'"), paramsFormat);
|
||||
cursor.insertText(currentXmlns, paramsFormat);
|
||||
cursor.insertText(QLatin1String("'"), paramsFormat);
|
||||
}
|
||||
QXmlStreamAttributes *attributes = token->startTag.attributes;
|
||||
for (int j = 0; j < attributes->count(); j++) {
|
||||
const QXmlStreamAttribute &attr = attributes->at(j);
|
||||
cursor.insertText(singleSpace);
|
||||
cursor.insertText(attr.name().toString(), attributeFormat);
|
||||
cursor.insertText(QLatin1String("="), zeroFormat);
|
||||
cursor.insertText(QLatin1String("'"), paramsFormat);
|
||||
cursor.insertText(attr.value().toString(), paramsFormat);
|
||||
cursor.insertText(QLatin1String("'"), paramsFormat);
|
||||
}
|
||||
if (token->startTag.empty) {
|
||||
cursor.insertText(QLatin1String("/>"), bracketFormat);
|
||||
} else {
|
||||
cursor.insertText(QLatin1String(">"), bracketFormat);
|
||||
depth++;
|
||||
}
|
||||
} else if (token->type == QXmlStreamReader::EndElement) {
|
||||
if (lastType == QXmlStreamReader::EndElement) {
|
||||
QString space = generate_stacked_space(depth - 1);
|
||||
cursor.insertText(QLatin1String("\n"));
|
||||
cursor.insertText(space);
|
||||
}
|
||||
cursor.insertText(QLatin1String("</"), bracketFormat);
|
||||
cursor.insertText(token->endTag.name->toString(), tagFormat);
|
||||
cursor.insertText(QLatin1String(">"), bracketFormat);
|
||||
depth--;
|
||||
} else if (token->type == QXmlStreamReader::Characters) {
|
||||
cursor.setCharFormat(bodyFormat);
|
||||
QString text = token->charachters.text->toString();
|
||||
if (text.contains(QLatin1Char('\n'))) {
|
||||
QString space = generate_stacked_space(depth);
|
||||
space.prepend(QLatin1Char('\n'));
|
||||
QStringList lines = text.split(QLatin1Char('\n'));
|
||||
for (int j = 0; j < lines.size(); j++) {
|
||||
cursor.insertText(space);
|
||||
cursor.insertText(lines.at(j));
|
||||
}
|
||||
space.chop(1);
|
||||
cursor.insertText(space);
|
||||
} else {
|
||||
cursor.insertText(text);
|
||||
}
|
||||
}
|
||||
lastType = token->type;
|
||||
if (lastType == QXmlStreamReader::StartElement && token->startTag.empty)
|
||||
lastType = QXmlStreamReader::EndElement;
|
||||
delete token;
|
||||
}
|
||||
cursor.endEditBlock();
|
||||
d->tokens.clear();
|
||||
}
|
||||
d->depth--;
|
||||
break;
|
||||
case QXmlStreamReader::Characters:
|
||||
token = d->tokens.isEmpty() ? 0 : d->tokens.last();
|
||||
if (token && token->type == QXmlStreamReader::StartElement && !token->startTag.empty) {
|
||||
if (*token->startTag.name == QLatin1String("auth")
|
||||
&& *token->startTag.xmlns == QLatin1String("urn:ietf:params:xml:ns:xmpp-sasl")) {
|
||||
d->tokens << new StackToken(QLatin1String("<<Private data>>"));
|
||||
} else {
|
||||
d->tokens << new StackToken(d->reader);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
// qDebug() << d->reader.tokenString();
|
||||
// if (d->reader.tokenType() == QXmlStreamReader::Invalid)
|
||||
// dbg << d->reader.error() << d->reader.errorString();
|
||||
if (!incoming && d->depth > 1) {
|
||||
qFatal("outgoing depth %d on\n\"%s\"", d->depth,
|
||||
qPrintable(QString::fromUtf8(data, data.size())));
|
||||
}
|
||||
StackEnvironment* d = &( incoming ? m_stackIncoming : m_stackOutgoing );
|
||||
d->reader.addData( data );
|
||||
StackToken* token;
|
||||
// debug() << incoming << data;
|
||||
// debug() << "==================================================================";
|
||||
while ( d->reader.readNext() > QXmlStreamReader::Invalid )
|
||||
{
|
||||
// qDebug() << incoming << d->reader.tokenString();
|
||||
switch( d->reader.tokenType() )
|
||||
{
|
||||
case QXmlStreamReader::StartElement:
|
||||
// dbg << d->reader.name().toString() << d->depth
|
||||
// << d->reader.attributes().value(QLatin1String("from")).toString();
|
||||
d->depth++;
|
||||
if ( d->depth > 1 )
|
||||
{
|
||||
if ( !d->tokens.isEmpty() && d->tokens.last()->type == QXmlStreamReader::Characters )
|
||||
{
|
||||
delete d->tokens.takeLast();
|
||||
}
|
||||
d->tokens << new StackToken( d->reader );
|
||||
}
|
||||
break;
|
||||
case QXmlStreamReader::EndElement:
|
||||
// dbg << d->reader.name().toString() << d->depth;
|
||||
if ( d->tokens.isEmpty() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
token = d->tokens.last();
|
||||
if ( token->type == QXmlStreamReader::StartElement && !token->startTag.empty )
|
||||
{
|
||||
token->startTag.empty = true;
|
||||
}
|
||||
else if ( d->depth > 1 )
|
||||
{
|
||||
d->tokens << new StackToken( d->reader );
|
||||
}
|
||||
if ( d->depth == 2 )
|
||||
{
|
||||
QTextCursor cursor( m_ui->xmlBrowser->document() );
|
||||
cursor.movePosition( QTextCursor::End );
|
||||
cursor.beginEditBlock();
|
||||
QTextCharFormat zeroFormat = cursor.charFormat();
|
||||
zeroFormat.setForeground( QColor( Qt::white ) );
|
||||
QTextCharFormat bodyFormat = zeroFormat;
|
||||
bodyFormat.setForeground( d->bodyColor );
|
||||
QTextCharFormat tagFormat = zeroFormat;
|
||||
tagFormat.setForeground( d->tagColor );
|
||||
QTextCharFormat attributeFormat = zeroFormat;
|
||||
attributeFormat.setForeground( d->attributeColor );
|
||||
QTextCharFormat paramsFormat = zeroFormat;
|
||||
paramsFormat.setForeground( d->paramColor );
|
||||
QTextCharFormat bracketFormat = zeroFormat;
|
||||
bracketFormat.setForeground( m_stackBracketsColor );
|
||||
QString singleSpace = QLatin1String( " " );
|
||||
cursor.insertBlock();
|
||||
int depth = 0;
|
||||
QString currentXmlns;
|
||||
QXmlStreamReader::TokenType lastType = QXmlStreamReader::StartElement;
|
||||
for ( int i = 0; i < d->tokens.size(); i++ )
|
||||
{
|
||||
token = d->tokens.at( i );
|
||||
if ( token->type == QXmlStreamReader::StartElement )
|
||||
{
|
||||
QString space = generate_stacked_space( depth );
|
||||
cursor.insertText( QLatin1String( "\n" ) );
|
||||
cursor.insertText( space );
|
||||
cursor.insertText( QLatin1String( "<" ), bracketFormat );
|
||||
cursor.insertText( token->startTag.name->toString(), tagFormat );
|
||||
const QStringRef& xmlns = *token->startTag.xmlns;
|
||||
if ( i == 0 || xmlns != currentXmlns )
|
||||
{
|
||||
currentXmlns = xmlns.toString();
|
||||
cursor.insertText( singleSpace );
|
||||
cursor.insertText( QLatin1String( "xmlns" ), attributeFormat );
|
||||
cursor.insertText( QLatin1String( "=" ), zeroFormat );
|
||||
cursor.insertText( QLatin1String( "'" ), paramsFormat );
|
||||
cursor.insertText( currentXmlns, paramsFormat );
|
||||
cursor.insertText( QLatin1String( "'" ), paramsFormat );
|
||||
}
|
||||
QXmlStreamAttributes* attributes = token->startTag.attributes;
|
||||
for ( int j = 0; j < attributes->count(); j++ )
|
||||
{
|
||||
const QXmlStreamAttribute& attr = attributes->at( j );
|
||||
cursor.insertText( singleSpace );
|
||||
cursor.insertText( attr.name().toString(), attributeFormat );
|
||||
cursor.insertText( QLatin1String( "=" ), zeroFormat );
|
||||
cursor.insertText( QLatin1String( "'" ), paramsFormat );
|
||||
cursor.insertText( attr.value().toString(), paramsFormat );
|
||||
cursor.insertText( QLatin1String( "'" ), paramsFormat );
|
||||
}
|
||||
if ( token->startTag.empty )
|
||||
{
|
||||
cursor.insertText( QLatin1String( "/>" ), bracketFormat );
|
||||
}
|
||||
else
|
||||
{
|
||||
cursor.insertText( QLatin1String( ">" ), bracketFormat );
|
||||
depth++;
|
||||
}
|
||||
}
|
||||
else if ( token->type == QXmlStreamReader::EndElement )
|
||||
{
|
||||
if ( lastType == QXmlStreamReader::EndElement )
|
||||
{
|
||||
QString space = generate_stacked_space( depth - 1 );
|
||||
cursor.insertText( QLatin1String( "\n" ) );
|
||||
cursor.insertText( space );
|
||||
}
|
||||
cursor.insertText( QLatin1String( "</" ), bracketFormat );
|
||||
cursor.insertText( token->endTag.name->toString(), tagFormat );
|
||||
cursor.insertText( QLatin1String( ">" ), bracketFormat );
|
||||
depth--;
|
||||
}
|
||||
else if ( token->type == QXmlStreamReader::Characters )
|
||||
{
|
||||
cursor.setCharFormat( bodyFormat );
|
||||
QString text = token->charachters.text->toString();
|
||||
if ( text.contains( QLatin1Char( '\n' ) ) )
|
||||
{
|
||||
QString space = generate_stacked_space( depth );
|
||||
space.prepend( QLatin1Char( '\n' ) );
|
||||
QStringList lines = text.split( QLatin1Char( '\n' ) );
|
||||
for ( int j = 0; j < lines.size(); j++ )
|
||||
{
|
||||
cursor.insertText( space );
|
||||
cursor.insertText( lines.at( j ) );
|
||||
}
|
||||
space.chop( 1 );
|
||||
cursor.insertText( space );
|
||||
}
|
||||
else
|
||||
{
|
||||
cursor.insertText( text );
|
||||
}
|
||||
}
|
||||
lastType = token->type;
|
||||
if ( lastType == QXmlStreamReader::StartElement && token->startTag.empty )
|
||||
{
|
||||
lastType = QXmlStreamReader::EndElement;
|
||||
}
|
||||
delete token;
|
||||
}
|
||||
cursor.endEditBlock();
|
||||
d->tokens.clear();
|
||||
}
|
||||
d->depth--;
|
||||
break;
|
||||
case QXmlStreamReader::Characters:
|
||||
token = d->tokens.isEmpty() ? 0 : d->tokens.last();
|
||||
if ( token && token->type == QXmlStreamReader::StartElement && !token->startTag.empty )
|
||||
{
|
||||
if ( *token->startTag.name == QLatin1String( "auth" )
|
||||
&& *token->startTag.xmlns == QLatin1String( "urn:ietf:params:xml:ns:xmpp-sasl" ) )
|
||||
{
|
||||
d->tokens << new StackToken( QLatin1String( "<<Private data>>" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
d->tokens << new StackToken( d->reader );
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
// qDebug() << d->reader.tokenString();
|
||||
// if (d->reader.tokenType() == QXmlStreamReader::Invalid)
|
||||
// dbg << d->reader.error() << d->reader.errorString();
|
||||
if ( !incoming && d->depth > 1 )
|
||||
{
|
||||
qFatal( "outgoing depth %d on\n\"%s\"", d->depth,
|
||||
qPrintable( QString::fromUtf8( data, data.size() ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
void XmlConsole::changeEvent(QEvent *e)
|
||||
void XmlConsole::changeEvent( QEvent* e )
|
||||
{
|
||||
QWidget::changeEvent(e);
|
||||
switch (e->type()) {
|
||||
case QEvent::LanguageChange:
|
||||
m_ui->retranslateUi(this);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
QWidget::changeEvent( e );
|
||||
switch ( e->type() )
|
||||
{
|
||||
case QEvent::LanguageChange:
|
||||
m_ui->retranslateUi( this );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void XmlConsole::onActionGroupTriggered(QAction *action)
|
||||
void XmlConsole::onActionGroupTriggered( QAction* action )
|
||||
{
|
||||
int type = action->data().toInt();
|
||||
if (type >= 0x10) {
|
||||
m_filter = (m_filter & 0xf) | type;
|
||||
m_ui->lineEdit->setEnabled(type != 0x10);
|
||||
} else {
|
||||
m_filter = m_filter ^ type;
|
||||
}
|
||||
on_lineEdit_textChanged(m_ui->lineEdit->text());
|
||||
int type = action->data().toInt();
|
||||
if ( type >= 0x10 )
|
||||
{
|
||||
m_filter = ( m_filter & 0xf ) | type;
|
||||
m_ui->lineEdit->setEnabled( type != 0x10 );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_filter = m_filter ^ type;
|
||||
}
|
||||
on_lineEdit_textChanged( m_ui->lineEdit->text() );
|
||||
}
|
||||
|
||||
void XmlConsole::on_lineEdit_textChanged(const QString &text)
|
||||
void XmlConsole::on_lineEdit_textChanged( const QString& text )
|
||||
{
|
||||
int filterType = m_filter & 0xf0;
|
||||
JID filterJid = (filterType == ByJid) ? text : QString();
|
||||
for (int i = 0; i < m_nodes.size(); i++) {
|
||||
XmlNode &node = m_nodes[i];
|
||||
bool ok = true;
|
||||
switch (filterType) {
|
||||
case ByXmlns:
|
||||
ok = node.xmlns.contains(text);
|
||||
break;
|
||||
case ByJid:
|
||||
ok = node.jid.full() == filterJid.full() || node.jid.bare() == filterJid.full();
|
||||
break;
|
||||
case ByAllAttributes:
|
||||
ok = node.attributes.contains(text);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ok &= bool(node.type & m_filter);
|
||||
node.block.setVisible(ok);
|
||||
node.block.setLineCount(ok ? node.lineCount : 0);
|
||||
// qDebug() << node.block.lineCount();
|
||||
}
|
||||
QAbstractTextDocumentLayout *layout = m_ui->xmlBrowser->document()->documentLayout();
|
||||
Q_ASSERT(qobject_cast<QPlainTextDocumentLayout*>(layout));
|
||||
qobject_cast<QPlainTextDocumentLayout*>(layout)->requestUpdate();
|
||||
int filterType = m_filter & 0xf0;
|
||||
JID filterJid = ( filterType == ByJid ) ? text : QString();
|
||||
for ( int i = 0; i < m_nodes.size(); i++ )
|
||||
{
|
||||
XmlNode& node = m_nodes[i];
|
||||
bool ok = true;
|
||||
switch ( filterType )
|
||||
{
|
||||
case ByXmlns:
|
||||
ok = node.xmlns.contains( text );
|
||||
break;
|
||||
case ByJid:
|
||||
ok = node.jid.full() == filterJid.full() || node.jid.bare() == filterJid.full();
|
||||
break;
|
||||
case ByAllAttributes:
|
||||
ok = node.attributes.contains( text );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ok &= bool( node.type & m_filter );
|
||||
node.block.setVisible( ok );
|
||||
node.block.setLineCount( ok ? node.lineCount : 0 );
|
||||
// qDebug() << node.block.lineCount();
|
||||
}
|
||||
QAbstractTextDocumentLayout* layout = m_ui->xmlBrowser->document()->documentLayout();
|
||||
Q_ASSERT( qobject_cast<QPlainTextDocumentLayout*>( layout ) );
|
||||
qobject_cast<QPlainTextDocumentLayout*>( layout )->requestUpdate();
|
||||
}
|
||||
|
||||
void XmlConsole::on_saveButton_clicked()
|
||||
{
|
||||
QString fileName = QFileDialog::getSaveFileName(this, tr("Save XMPP log to file"),
|
||||
QString(), tr("OpenDocument Format (*.odf);;HTML file (*.html);;Plain text (*.txt)"));
|
||||
if (!fileName.isEmpty()) {
|
||||
QTextDocumentWriter writer(fileName);
|
||||
writer.write(m_ui->xmlBrowser->document());
|
||||
}
|
||||
QString fileName = QFileDialog::getSaveFileName( this, tr( "Save XMPP log to file" ),
|
||||
QString(), tr( "OpenDocument Format (*.odf);;HTML file (*.html);;Plain text (*.txt)" ) );
|
||||
if ( !fileName.isEmpty() )
|
||||
{
|
||||
QTextDocumentWriter writer( fileName );
|
||||
writer.write( m_ui->xmlBrowser->document() );
|
||||
}
|
||||
}
|
||||
|
@@ -29,7 +29,8 @@
|
||||
#include <QDateTime>
|
||||
#include <QTextBlock>
|
||||
|
||||
namespace Ui {
|
||||
namespace Ui
|
||||
{
|
||||
class XmlConsole;
|
||||
}
|
||||
|
||||
@@ -39,148 +40,162 @@ class ACCOUNTDLLEXPORT XmlConsole : public QWidget, public Jreen::XmlStreamHandl
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
XmlConsole(Jreen::Client* client, QWidget *parent = 0);
|
||||
~XmlConsole();
|
||||
public:
|
||||
XmlConsole( Jreen::Client* client, QWidget* parent = 0 );
|
||||
~XmlConsole();
|
||||
|
||||
virtual void handleStreamBegin();
|
||||
virtual void handleStreamEnd();
|
||||
virtual void handleIncomingData(const char *data, qint64 size);
|
||||
virtual void handleOutgoingData(const char *data, qint64 size);
|
||||
virtual void handleStreamBegin();
|
||||
virtual void handleStreamEnd();
|
||||
virtual void handleIncomingData( const char* data, qint64 size );
|
||||
virtual void handleOutgoingData( const char* data, qint64 size );
|
||||
|
||||
protected:
|
||||
void changeEvent(QEvent *e);
|
||||
private:
|
||||
void stackProcess(const QByteArray &data, bool incoming);
|
||||
protected:
|
||||
void changeEvent( QEvent* e );
|
||||
private:
|
||||
void stackProcess( const QByteArray& data, bool incoming );
|
||||
|
||||
struct XmlNode
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
Iq = 1,
|
||||
Presence = 2,
|
||||
Message = 4,
|
||||
Custom = 8
|
||||
};
|
||||
QDateTime time;
|
||||
Type type;
|
||||
bool incoming;
|
||||
QSet<QString> xmlns;
|
||||
Jreen::JID jid;
|
||||
QSet<QString> attributes;
|
||||
QTextBlock block;
|
||||
int lineCount;
|
||||
};
|
||||
enum FilterType
|
||||
{
|
||||
Disabled = 0x10,
|
||||
ByJid = 0x20,
|
||||
ByXmlns = 0x30,
|
||||
ByAllAttributes = 0x40
|
||||
};
|
||||
struct XmlNode
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
Iq = 1,
|
||||
Presence = 2,
|
||||
Message = 4,
|
||||
Custom = 8
|
||||
};
|
||||
QDateTime time;
|
||||
Type type;
|
||||
bool incoming;
|
||||
QSet<QString> xmlns;
|
||||
Jreen::JID jid;
|
||||
QSet<QString> attributes;
|
||||
QTextBlock block;
|
||||
int lineCount;
|
||||
};
|
||||
enum FilterType
|
||||
{
|
||||
Disabled = 0x10,
|
||||
ByJid = 0x20,
|
||||
ByXmlns = 0x30,
|
||||
ByAllAttributes = 0x40
|
||||
};
|
||||
|
||||
enum State
|
||||
{
|
||||
WaitingForStanza,
|
||||
ReadFeatures,
|
||||
ReadStanza,
|
||||
ReadCustom
|
||||
};
|
||||
enum State
|
||||
{
|
||||
WaitingForStanza,
|
||||
ReadFeatures,
|
||||
ReadStanza,
|
||||
ReadCustom
|
||||
};
|
||||
|
||||
struct StackToken
|
||||
{
|
||||
StackToken(QXmlStreamReader &reader)
|
||||
{
|
||||
type = reader.tokenType();
|
||||
if (type == QXmlStreamReader::StartElement) {
|
||||
QStringRef tmp = reader.name();
|
||||
startTag.namePointer = new QString(*tmp.string());
|
||||
startTag.name = new QStringRef(startTag.namePointer, tmp.position(), tmp.length());
|
||||
tmp = reader.namespaceUri();
|
||||
startTag.xmlnsPointer = new QString(*tmp.string());
|
||||
startTag.xmlns = new QStringRef(startTag.xmlnsPointer, tmp.position(), tmp.length());
|
||||
startTag.attributes = new QXmlStreamAttributes(reader.attributes());
|
||||
startTag.empty = false;
|
||||
} else if (type == QXmlStreamReader::Characters) {
|
||||
QStringRef tmp = reader.text();
|
||||
charachters.textPointer = new QString(*tmp.string());
|
||||
charachters.text = new QStringRef(charachters.textPointer, tmp.position(), tmp.length());
|
||||
} else if (type == QXmlStreamReader::EndElement) {
|
||||
QStringRef tmp = reader.name();
|
||||
endTag.namePointer = new QString(*tmp.string());
|
||||
endTag.name = new QStringRef(endTag.namePointer, tmp.position(), tmp.length());
|
||||
}
|
||||
}
|
||||
struct StackToken
|
||||
{
|
||||
StackToken( QXmlStreamReader& reader )
|
||||
{
|
||||
type = reader.tokenType();
|
||||
if ( type == QXmlStreamReader::StartElement )
|
||||
{
|
||||
QStringRef tmp = reader.name();
|
||||
startTag.namePointer = new QString( *tmp.string() );
|
||||
startTag.name = new QStringRef( startTag.namePointer, tmp.position(), tmp.length() );
|
||||
tmp = reader.namespaceUri();
|
||||
startTag.xmlnsPointer = new QString( *tmp.string() );
|
||||
startTag.xmlns = new QStringRef( startTag.xmlnsPointer, tmp.position(), tmp.length() );
|
||||
startTag.attributes = new QXmlStreamAttributes( reader.attributes() );
|
||||
startTag.empty = false;
|
||||
}
|
||||
else if ( type == QXmlStreamReader::Characters )
|
||||
{
|
||||
QStringRef tmp = reader.text();
|
||||
charachters.textPointer = new QString( *tmp.string() );
|
||||
charachters.text = new QStringRef( charachters.textPointer, tmp.position(), tmp.length() );
|
||||
}
|
||||
else if ( type == QXmlStreamReader::EndElement )
|
||||
{
|
||||
QStringRef tmp = reader.name();
|
||||
endTag.namePointer = new QString( *tmp.string() );
|
||||
endTag.name = new QStringRef( endTag.namePointer, tmp.position(), tmp.length() );
|
||||
}
|
||||
}
|
||||
|
||||
StackToken(const QString &name)
|
||||
{
|
||||
type = QXmlStreamReader::Characters;
|
||||
charachters.textPointer = new QString(name);
|
||||
charachters.text = new QStringRef(charachters.textPointer);
|
||||
}
|
||||
StackToken( const QString& name )
|
||||
{
|
||||
type = QXmlStreamReader::Characters;
|
||||
charachters.textPointer = new QString( name );
|
||||
charachters.text = new QStringRef( charachters.textPointer );
|
||||
}
|
||||
|
||||
~StackToken()
|
||||
{
|
||||
if (type == QXmlStreamReader::StartElement) {
|
||||
delete startTag.namePointer;
|
||||
delete startTag.name;
|
||||
delete startTag.xmlnsPointer;
|
||||
delete startTag.xmlns;
|
||||
delete startTag.attributes;
|
||||
} else if (type == QXmlStreamReader::Characters) {
|
||||
delete charachters.textPointer;
|
||||
delete charachters.text;
|
||||
} else if (type == QXmlStreamReader::EndElement) {
|
||||
delete endTag.namePointer;
|
||||
delete endTag.name;
|
||||
}
|
||||
}
|
||||
~StackToken()
|
||||
{
|
||||
if ( type == QXmlStreamReader::StartElement )
|
||||
{
|
||||
delete startTag.namePointer;
|
||||
delete startTag.name;
|
||||
delete startTag.xmlnsPointer;
|
||||
delete startTag.xmlns;
|
||||
delete startTag.attributes;
|
||||
}
|
||||
else if ( type == QXmlStreamReader::Characters )
|
||||
{
|
||||
delete charachters.textPointer;
|
||||
delete charachters.text;
|
||||
}
|
||||
else if ( type == QXmlStreamReader::EndElement )
|
||||
{
|
||||
delete endTag.namePointer;
|
||||
delete endTag.name;
|
||||
}
|
||||
}
|
||||
|
||||
QXmlStreamReader::TokenType type;
|
||||
union {
|
||||
struct {
|
||||
QString *namePointer;
|
||||
QStringRef *name;
|
||||
QString *xmlnsPointer;
|
||||
QStringRef *xmlns;
|
||||
QXmlStreamAttributes *attributes;
|
||||
bool empty;
|
||||
} startTag;
|
||||
struct {
|
||||
QString *textPointer;
|
||||
QStringRef *text;
|
||||
} charachters;
|
||||
struct {
|
||||
QString *namePointer;
|
||||
QStringRef *name;
|
||||
} endTag;
|
||||
};
|
||||
};
|
||||
QXmlStreamReader::TokenType type;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
QString* namePointer;
|
||||
QStringRef* name;
|
||||
QString* xmlnsPointer;
|
||||
QStringRef* xmlns;
|
||||
QXmlStreamAttributes* attributes;
|
||||
bool empty;
|
||||
} startTag;
|
||||
struct
|
||||
{
|
||||
QString* textPointer;
|
||||
QStringRef* text;
|
||||
} charachters;
|
||||
struct
|
||||
{
|
||||
QString* namePointer;
|
||||
QStringRef* name;
|
||||
} endTag;
|
||||
};
|
||||
};
|
||||
|
||||
struct StackEnvironment
|
||||
{
|
||||
QXmlStreamReader reader;
|
||||
State state;
|
||||
int depth;
|
||||
QList<StackToken*> tokens;
|
||||
QColor bodyColor;
|
||||
QColor tagColor;
|
||||
QColor attributeColor;
|
||||
QColor paramColor;
|
||||
};
|
||||
struct StackEnvironment
|
||||
{
|
||||
QXmlStreamReader reader;
|
||||
State state;
|
||||
int depth;
|
||||
QList<StackToken*> tokens;
|
||||
QColor bodyColor;
|
||||
QColor tagColor;
|
||||
QColor attributeColor;
|
||||
QColor paramColor;
|
||||
};
|
||||
|
||||
Ui::XmlConsole *m_ui;
|
||||
Jreen::Client *m_client;
|
||||
QList<XmlNode> m_nodes;
|
||||
StackEnvironment m_stackIncoming;
|
||||
StackEnvironment m_stackOutgoing;
|
||||
QColor m_stackBracketsColor;
|
||||
int m_filter;
|
||||
Ui::XmlConsole* m_ui;
|
||||
Jreen::Client* m_client;
|
||||
QList<XmlNode> m_nodes;
|
||||
StackEnvironment m_stackIncoming;
|
||||
StackEnvironment m_stackOutgoing;
|
||||
QColor m_stackBracketsColor;
|
||||
int m_filter;
|
||||
|
||||
private slots:
|
||||
void on_lineEdit_textChanged(const QString &);
|
||||
void onActionGroupTriggered(QAction *action);
|
||||
void on_saveButton_clicked();
|
||||
private slots:
|
||||
void on_lineEdit_textChanged( const QString& );
|
||||
void onActionGroupTriggered( QAction* action );
|
||||
void on_saveButton_clicked();
|
||||
};
|
||||
|
||||
|
||||
|
@@ -57,9 +57,9 @@
|
||||
#include <QTimer>
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
#include <QInputDialog>
|
||||
#include <QLineEdit>
|
||||
#include <QMessageBox>
|
||||
#include <QInputDialog>
|
||||
#include <QLineEdit>
|
||||
#include <QMessageBox>
|
||||
#endif
|
||||
|
||||
using namespace Tomahawk;
|
||||
@@ -74,7 +74,7 @@ using namespace Accounts;
|
||||
|
||||
#if QT_VERSION <= QT_VERSION_CHECK( 5, 0, 0 )
|
||||
void
|
||||
JreenMessageHandler( QtMsgType type, const char *msg )
|
||||
JreenMessageHandler( QtMsgType type, const char* msg )
|
||||
{
|
||||
switch ( type )
|
||||
{
|
||||
@@ -166,9 +166,9 @@ XmppSipPlugin::XmppSipPlugin( Account* account )
|
||||
connect( m_client, SIGNAL( iqReceived( Jreen::IQ ) ), SLOT( onNewIq( Jreen::IQ ) ) );
|
||||
|
||||
connect( m_roster, SIGNAL( presenceReceived( Jreen::RosterItem::Ptr, Jreen::Presence ) ),
|
||||
SLOT( onPresenceReceived( Jreen::RosterItem::Ptr, Jreen::Presence ) ) );
|
||||
SLOT( onPresenceReceived( Jreen::RosterItem::Ptr, Jreen::Presence ) ) );
|
||||
connect( m_roster, SIGNAL( subscriptionReceived( Jreen::RosterItem::Ptr, Jreen::Presence ) ),
|
||||
SLOT( onSubscriptionReceived( Jreen::RosterItem::Ptr, Jreen::Presence ) ) );
|
||||
SLOT( onSubscriptionReceived( Jreen::RosterItem::Ptr, Jreen::Presence ) ) );
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
connect( m_avatarManager, SIGNAL( newAvatar( QString ) ), SLOT( onNewAvatar( QString ) ) );
|
||||
@@ -210,7 +210,9 @@ InfoSystem::InfoPluginPtr
|
||||
XmppSipPlugin::infoPlugin()
|
||||
{
|
||||
if ( m_infoPlugin.isNull() )
|
||||
{
|
||||
m_infoPlugin = QPointer< Tomahawk::InfoSystem::XmppInfoPlugin >( new Tomahawk::InfoSystem::XmppInfoPlugin( this ) );
|
||||
}
|
||||
|
||||
return InfoSystem::InfoPluginPtr( m_infoPlugin.data() );
|
||||
}
|
||||
@@ -246,7 +248,9 @@ XmppSipPlugin::connectPlugin()
|
||||
QTimer::singleShot( 1000, m_client, SLOT( connectToServer() ) );
|
||||
|
||||
if ( m_client->connection() )
|
||||
{
|
||||
connect( m_client->connection(), SIGNAL( error( Jreen::Connection::SocketError ) ), SLOT( onError( Jreen::Connection::SocketError ) ), Qt::UniqueConnection );
|
||||
}
|
||||
|
||||
m_state = Account::Connecting;
|
||||
emit stateChanged( m_state );
|
||||
@@ -332,7 +336,7 @@ XmppSipPlugin::onDisconnect( Jreen::Client::DisconnectReason reason )
|
||||
switch( reason )
|
||||
{
|
||||
case Jreen::Client::User:
|
||||
foreach( const Jreen::JID &peer, m_peers.keys() )
|
||||
foreach( const Jreen::JID & peer, m_peers.keys() )
|
||||
{
|
||||
handlePeerStatus( peer, Jreen::Presence::Unavailable );
|
||||
}
|
||||
@@ -375,7 +379,9 @@ XmppSipPlugin::onDisconnect( Jreen::Client::DisconnectReason reason )
|
||||
removeMenuHelper();
|
||||
|
||||
if ( !m_infoPlugin.isNull() )
|
||||
{
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->removeInfoPlugin( infoPlugin() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -453,13 +459,15 @@ XmppSipPlugin::sendSipInfos( const Tomahawk::peerinfo_ptr& receiver, const QList
|
||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << receiver << info;
|
||||
|
||||
if ( !m_client )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TomahawkXmppMessage* sipMessage = new TomahawkXmppMessage( info );
|
||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Send sip messsage to" << receiver;
|
||||
Jreen::IQ iq( Jreen::IQ::Set, receiver->id() );
|
||||
iq.addExtension( sipMessage );
|
||||
Jreen::IQReply *reply = m_client->send( iq );
|
||||
Jreen::IQReply* reply = m_client->send( iq );
|
||||
reply->setData( SipMessageSent );
|
||||
connect( reply, SIGNAL( received( Jreen::IQ ) ), SLOT( onNewIq( Jreen::IQ ) ) );
|
||||
}
|
||||
@@ -499,7 +507,9 @@ XmppSipPlugin::showAddFriendDialog()
|
||||
tr( "Enter Xmpp ID:" ), QLineEdit::Normal, "", &ok ).trimmed();
|
||||
|
||||
if ( !ok )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "Attempting to add xmpp contact to roster:" << id;
|
||||
addContact( id, SendInvite );
|
||||
@@ -510,7 +520,7 @@ XmppSipPlugin::showAddFriendDialog()
|
||||
void
|
||||
XmppSipPlugin::publishTune( const QUrl& url, const InfoSystem::InfoStringHash& trackInfo )
|
||||
{
|
||||
if ( m_account->configuration().value("publishtracks").toBool() == false )
|
||||
if ( m_account->configuration().value( "publishtracks" ).toBool() == false )
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO << m_client->jid().full() << "Not publishing now playing info (disabled in account config)";
|
||||
return;
|
||||
@@ -553,7 +563,7 @@ void
|
||||
XmppSipPlugin::showXmlConsole()
|
||||
{
|
||||
#ifndef ENABLE_HEADLESS
|
||||
m_xmlConsole->show();
|
||||
m_xmlConsole->show();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -650,7 +660,7 @@ XmppSipPlugin::addMenuHelper()
|
||||
#ifndef ENABLE_HEADLESS
|
||||
if ( !m_menu )
|
||||
{
|
||||
m_menu = new QMenu( QString( "%1 (" ).arg( friendlyName() ).append( readUsername() ).append(")" ) );
|
||||
m_menu = new QMenu( QString( "%1 (" ).arg( friendlyName() ).append( readUsername() ).append( ")" ) );
|
||||
|
||||
QAction* addFriendAction = m_menu->addAction( tr( "Add Friend..." ) );
|
||||
connect( addFriendAction, SIGNAL( triggered() ), SLOT( showAddFriendDialog() ) );
|
||||
@@ -686,13 +696,17 @@ void
|
||||
XmppSipPlugin::onNewMessage( const Jreen::Message& message )
|
||||
{
|
||||
if ( m_state != Account::Connected )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QString from = message.from().full();
|
||||
QString msg = message.body();
|
||||
|
||||
if ( msg.isEmpty() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( message.subtype() == Jreen::Message::Error )
|
||||
{
|
||||
@@ -711,7 +725,7 @@ XmppSipPlugin::onNewMessage( const Jreen::Message& message )
|
||||
" are trying to reach is probably not signed on, so please try again later!" ) );
|
||||
|
||||
// this is not a sip message, so we send it directly through the client
|
||||
m_client->send( Jreen::Message ( Jreen::Message::Error, Jreen::JID( to ), response) );
|
||||
m_client->send( Jreen::Message ( Jreen::Message::Error, Jreen::JID( to ), response ) );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -722,9 +736,11 @@ XmppSipPlugin::onNewMessage( const Jreen::Message& message )
|
||||
void
|
||||
XmppSipPlugin::onPresenceReceived( const Jreen::RosterItem::Ptr& item, const Jreen::Presence& presence )
|
||||
{
|
||||
Q_UNUSED(item);
|
||||
Q_UNUSED( item );
|
||||
if ( m_state != Account::Connected )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Jreen::JID jid = presence.from();
|
||||
QString fulljid( jid.full() );
|
||||
@@ -732,7 +748,9 @@ XmppSipPlugin::onPresenceReceived( const Jreen::RosterItem::Ptr& item, const Jre
|
||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "New presence:" << fulljid << presence.subtype();
|
||||
|
||||
if ( jid == m_client->jid() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( presence.error() )
|
||||
{
|
||||
@@ -747,13 +765,15 @@ XmppSipPlugin::onPresenceReceived( const Jreen::RosterItem::Ptr& item, const Jre
|
||||
m_jidsNames.insert( jid.bare(), item->name() );
|
||||
|
||||
// find peers for the jid and update their friendlyName
|
||||
foreach ( const Jreen::JID& peer, m_peers.keys() )
|
||||
foreach ( const Jreen::JID & peer, m_peers.keys() )
|
||||
{
|
||||
if ( peer.bare() == jid.bare() )
|
||||
{
|
||||
Tomahawk::peerinfo_ptr peerInfo = PeerInfo::get( this, peer.full() );
|
||||
if( !peerInfo.isNull() )
|
||||
{
|
||||
peerInfo->setFriendlyName( item->name() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -770,15 +790,17 @@ XmppSipPlugin::onPresenceReceived( const Jreen::RosterItem::Ptr& item, const Jre
|
||||
Jreen::IQ featuresIq( Jreen::IQ::Get, jid );
|
||||
featuresIq.addExtension( new Jreen::Disco::Info( node ) );
|
||||
|
||||
Jreen::IQReply *reply = m_client->send( featuresIq );
|
||||
Jreen::IQReply* reply = m_client->send( featuresIq );
|
||||
reply->setData( RequestDisco );
|
||||
connect( reply, SIGNAL( received( Jreen::IQ ) ), SLOT( onNewIq( Jreen::IQ ) ) );
|
||||
}
|
||||
else if ( !caps )
|
||||
{
|
||||
// qDebug() << Q_FUNC_INFO << "Running tomahawk: no" << "no caps";
|
||||
// qDebug() << Q_FUNC_INFO << "Running tomahawk: no" << "no caps";
|
||||
if ( presenceMeansOnline( m_peers[ jid ] ) )
|
||||
{
|
||||
handlePeerStatus( jid, Jreen::Presence::Unavailable );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -787,23 +809,29 @@ void
|
||||
XmppSipPlugin::onSubscriptionReceived( const Jreen::RosterItem::Ptr& item, const Jreen::Presence& presence )
|
||||
{
|
||||
if ( m_state != Account::Connected )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( item )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << presence.from().full() << "subs" << item->subscription() << "ask" << item->ask();
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << "item empty";
|
||||
}
|
||||
|
||||
// don't do anything if the contact is already subscribed to us
|
||||
if ( presence.subtype() != Jreen::Presence::Subscribe ||
|
||||
( item && (item->subscription() == Jreen::RosterItem::From || item->subscription() == Jreen::RosterItem::Both ) ) )
|
||||
( item && ( item->subscription() == Jreen::RosterItem::From || item->subscription() == Jreen::RosterItem::Both ) ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// check if the requester is already on the roster
|
||||
if ( item &&
|
||||
( item->subscription() == Jreen::RosterItem::To || ( item->subscription() == Jreen::RosterItem::None && !item->ask().isEmpty() ) ) )
|
||||
( item->subscription() == Jreen::RosterItem::To || ( item->subscription() == Jreen::RosterItem::None && !item->ask().isEmpty() ) ) )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << presence.from().bare() << "already on the roster so we assume ack'ing subscription request is okay...";
|
||||
m_roster->allowSubscription( presence.from(), true );
|
||||
@@ -813,13 +841,13 @@ XmppSipPlugin::onSubscriptionReceived( const Jreen::RosterItem::Ptr& item, const
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
// preparing the confirm box for the user
|
||||
QMessageBox *confirmBox = new QMessageBox(
|
||||
QMessageBox::Question,
|
||||
tr( "Authorize User" ),
|
||||
QString( tr( "Do you want to add <b>%1</b> to your friend list?" ) ).arg( presence.from().bare() ),
|
||||
QMessageBox::Yes | QMessageBox::No,
|
||||
TomahawkUtils::tomahawkWindow()
|
||||
);
|
||||
QMessageBox* confirmBox = new QMessageBox(
|
||||
QMessageBox::Question,
|
||||
tr( "Authorize User" ),
|
||||
QString( tr( "Do you want to add <b>%1</b> to your friend list?" ) ).arg( presence.from().bare() ),
|
||||
QMessageBox::Yes | QMessageBox::No,
|
||||
TomahawkUtils::tomahawkWindow()
|
||||
);
|
||||
|
||||
// add confirmBox to m_subscriptionConfirmBoxes
|
||||
m_subscriptionConfirmBoxes.insert( presence.from(), confirmBox );
|
||||
@@ -839,7 +867,7 @@ XmppSipPlugin::onSubscriptionRequestConfirmed( int result )
|
||||
QList< QMessageBox* > confirmBoxes = m_subscriptionConfirmBoxes.values();
|
||||
Jreen::JID jid;
|
||||
|
||||
foreach ( QMessageBox* currentBox, confirmBoxes )
|
||||
foreach ( QMessageBox * currentBox, confirmBoxes )
|
||||
{
|
||||
if ( currentBox == sender() )
|
||||
{
|
||||
@@ -871,17 +899,21 @@ void
|
||||
XmppSipPlugin::onNewIq( const Jreen::IQ& iq )
|
||||
{
|
||||
if ( m_state != Account::Connected )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Jreen::IQReply *reply = qobject_cast< Jreen::IQReply* >( sender() );
|
||||
Jreen::IQReply* reply = qobject_cast< Jreen::IQReply* >( sender() );
|
||||
int context = reply ? reply->data().toInt() : NoContext;
|
||||
|
||||
if ( context == RequestDisco )
|
||||
{
|
||||
// qDebug() << Q_FUNC_INFO << "Received disco IQ...";
|
||||
Jreen::Disco::Info *discoInfo = iq.payload< Jreen::Disco::Info >().data();
|
||||
// qDebug() << Q_FUNC_INFO << "Received disco IQ...";
|
||||
Jreen::Disco::Info* discoInfo = iq.payload< Jreen::Disco::Info >().data();
|
||||
if ( !discoInfo )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
iq.accept();
|
||||
Jreen::JID jid = iq.from();
|
||||
@@ -995,11 +1027,13 @@ XmppSipPlugin::handlePeerStatus( const Jreen::JID& jid, Jreen::Presence::Type pr
|
||||
QString fulljid = jid.full();
|
||||
|
||||
if ( fulljid.contains( "public.talk.google.com" ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// "going offline" event
|
||||
if ( !presenceMeansOnline( presenceType ) &&
|
||||
( !m_peers.contains( jid ) || presenceMeansOnline( m_peers.value( jid ) ) ) )
|
||||
( !m_peers.contains( jid ) || presenceMeansOnline( m_peers.value( jid ) ) ) )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << "* Peer goes offline:" << fulljid;
|
||||
|
||||
@@ -1030,7 +1064,7 @@ XmppSipPlugin::handlePeerStatus( const Jreen::JID& jid, Jreen::Presence::Type pr
|
||||
|
||||
// "coming online" event
|
||||
if ( presenceMeansOnline( presenceType ) &&
|
||||
( !m_peers.contains( jid ) || !presenceMeansOnline( m_peers.value( jid ) ) ) )
|
||||
( !m_peers.contains( jid ) || !presenceMeansOnline( m_peers.value( jid ) ) ) )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << "* Peer goes online:" << fulljid;
|
||||
|
||||
@@ -1046,13 +1080,15 @@ XmppSipPlugin::handlePeerStatus( const Jreen::JID& jid, Jreen::Presence::Type pr
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
if ( !m_avatarManager->avatar( jid.bare() ).isNull() )
|
||||
{
|
||||
onNewAvatar( jid.bare() );
|
||||
}
|
||||
#endif
|
||||
|
||||
// request software version
|
||||
Jreen::IQ versionIq( Jreen::IQ::Get, jid );
|
||||
versionIq.addExtension( new Jreen::SoftwareVersion() );
|
||||
Jreen::IQReply *reply = m_client->send( versionIq );
|
||||
Jreen::IQReply* reply = m_client->send( versionIq );
|
||||
reply->setData( RequestVersion );
|
||||
connect( reply, SIGNAL( received( Jreen::IQ ) ), SLOT( onNewIq( Jreen::IQ ) ) );
|
||||
|
||||
@@ -1068,21 +1104,25 @@ void
|
||||
XmppSipPlugin::onNewAvatar( const QString& jid )
|
||||
{
|
||||
#ifndef ENABLE_HEADLESS
|
||||
// qDebug() << Q_FUNC_INFO << jid;
|
||||
// qDebug() << Q_FUNC_INFO << jid;
|
||||
if ( m_state != Account::Connected )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Q_ASSERT( !m_avatarManager->avatar( jid ).isNull() );
|
||||
|
||||
// find peers for the jid
|
||||
QList< Jreen::JID > peers = m_peers.keys();
|
||||
foreach ( const Jreen::JID& peer, peers )
|
||||
foreach ( const Jreen::JID & peer, peers )
|
||||
{
|
||||
if ( peer.bare() == jid )
|
||||
{
|
||||
Tomahawk::peerinfo_ptr peerInfo = PeerInfo::get( this, peer.full() );
|
||||
if ( !peerInfo.isNull() )
|
||||
{
|
||||
peerInfo->setAvatar( m_avatarManager->avatar( jid ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -28,7 +28,7 @@
|
||||
#include "AvatarManager.h"
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
#include "XmlConsole.h"
|
||||
#include "XmlConsole.h"
|
||||
#endif
|
||||
|
||||
#include "accounts/AccountDllMacro.h"
|
||||
@@ -51,7 +51,7 @@
|
||||
#include <jreen/pubsubmanager.h>
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
#include <QMessageBox>
|
||||
#include <QMessageBox>
|
||||
#endif
|
||||
|
||||
|
||||
@@ -59,14 +59,17 @@ class ACCOUNTDLLEXPORT XmppSipPlugin : public SipPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
friend class Tomahawk::InfoSystem::XmppInfoPlugin;
|
||||
friend class Tomahawk::InfoSystem::XmppInfoPlugin;
|
||||
|
||||
public:
|
||||
public:
|
||||
XmppSipPlugin( Tomahawk::Accounts::Account* account );
|
||||
virtual ~XmppSipPlugin();
|
||||
|
||||
//FIXME: Make this more correct
|
||||
virtual bool isValid() const { return true; }
|
||||
virtual bool isValid() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
virtual QString inviteString() const;
|
||||
|
||||
Tomahawk::InfoSystem::InfoPluginPtr infoPlugin();
|
||||
@@ -78,14 +81,14 @@ public:
|
||||
// used by XmppAccount to expose connection state and controls
|
||||
Tomahawk::Accounts::Account::ConnectionState connectionState() const;
|
||||
|
||||
signals:
|
||||
signals:
|
||||
void jidChanged( const QString& );
|
||||
|
||||
// Used by XmppAccount
|
||||
void stateChanged( Tomahawk::Accounts::Account::ConnectionState state );
|
||||
void error( int errorId, const QString& errorStr );
|
||||
|
||||
public slots:
|
||||
public slots:
|
||||
virtual void connectPlugin();
|
||||
virtual void disconnectPlugin();
|
||||
virtual void checkSettings();
|
||||
@@ -97,10 +100,10 @@ public slots:
|
||||
void showAddFriendDialog();
|
||||
void publishTune( const QUrl& url, const Tomahawk::InfoSystem::InfoStringHash& trackInfo );
|
||||
|
||||
protected:
|
||||
protected:
|
||||
virtual QString defaultSuffix() const;
|
||||
|
||||
private slots:
|
||||
private slots:
|
||||
void showXmlConsole();
|
||||
void onConnect();
|
||||
void onDisconnect( Jreen::Client::DisconnectReason reason );
|
||||
@@ -114,7 +117,7 @@ private slots:
|
||||
void onNewIq( const Jreen::IQ& iq );
|
||||
void onNewAvatar( const QString& jid );
|
||||
|
||||
private:
|
||||
private:
|
||||
bool readXmlConsoleEnabled();
|
||||
QString readUsername();
|
||||
QString readPassword();
|
||||
|
@@ -37,9 +37,9 @@
|
||||
|
||||
class Node : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
public:
|
||||
Node( const QString& i, const QString& n, int p )
|
||||
: ip( i ), nid( n ), port( p )
|
||||
{
|
||||
@@ -51,17 +51,21 @@ public:
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
}
|
||||
|
||||
signals:
|
||||
signals:
|
||||
void tomahawkHostFound( const QString&, int, const QString&, const QString& );
|
||||
|
||||
public slots:
|
||||
public slots:
|
||||
void resolved( QHostInfo i )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << "zeroconf-derived IP has resolved to name " << i.hostName();
|
||||
if ( i.hostName().length() )
|
||||
{
|
||||
emit tomahawkHostFound( ip, port, i.hostName(), nid );
|
||||
}
|
||||
else
|
||||
{
|
||||
emit tomahawkHostFound( ip, port, "Unknown", nid );
|
||||
}
|
||||
this->deleteLater();
|
||||
}
|
||||
|
||||
@@ -71,7 +75,7 @@ public slots:
|
||||
QHostInfo::lookupHost( ip, this, SLOT( resolved( QHostInfo ) ) );
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
QString ip;
|
||||
QString nid;
|
||||
int port;
|
||||
@@ -80,9 +84,9 @@ private:
|
||||
|
||||
class ACCOUNTDLLEXPORT TomahawkZeroconf : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
public:
|
||||
TomahawkZeroconf( int port, QObject* parent = 0 )
|
||||
: QObject( parent ), m_sock( this ), m_port( port )
|
||||
{
|
||||
@@ -97,34 +101,36 @@ public:
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
}
|
||||
|
||||
public slots:
|
||||
public slots:
|
||||
void advertise()
|
||||
{
|
||||
qDebug() << "Advertising us on the LAN (both versions)";
|
||||
// Keep newer versions first
|
||||
QByteArray advert = QString( "TOMAHAWKADVERT:%1:%2:%3" )
|
||||
.arg( m_port )
|
||||
.arg( Tomahawk::Database::instance()->impl()->dbid() )
|
||||
.arg( QHostInfo::localHostName() )
|
||||
.toLatin1();
|
||||
.arg( m_port )
|
||||
.arg( Tomahawk::Database::instance()->impl()->dbid() )
|
||||
.arg( QHostInfo::localHostName() )
|
||||
.toLatin1();
|
||||
m_sock.writeDatagram( advert.data(), advert.size(), QHostAddress::Broadcast, ZCONF_PORT );
|
||||
|
||||
advert = QString( "TOMAHAWKADVERT:%1:%2" )
|
||||
.arg( m_port )
|
||||
.arg( Tomahawk::Database::instance()->impl()->dbid() )
|
||||
.toLatin1();
|
||||
.arg( m_port )
|
||||
.arg( Tomahawk::Database::instance()->impl()->dbid() )
|
||||
.toLatin1();
|
||||
m_sock.writeDatagram( advert.data(), advert.size(), QHostAddress::Broadcast, ZCONF_PORT );
|
||||
}
|
||||
|
||||
signals:
|
||||
signals:
|
||||
// IP, port, name, session
|
||||
void tomahawkHostFound( const QString&, int, const QString&, const QString& );
|
||||
|
||||
private slots:
|
||||
private slots:
|
||||
void readPacket()
|
||||
{
|
||||
if ( !m_sock.hasPendingDatagrams() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray datagram;
|
||||
datagram.resize( m_sock.pendingDatagramSize() );
|
||||
@@ -135,17 +141,19 @@ private slots:
|
||||
|
||||
// Ignore our own requests
|
||||
if ( QNetworkInterface::allAddresses().contains( sender ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// only process msgs originating on the LAN:
|
||||
if ( datagram.startsWith( "TOMAHAWKADVERT:" ) &&
|
||||
Servent::isIPWhitelisted( sender ) )
|
||||
Servent::isIPWhitelisted( sender ) )
|
||||
{
|
||||
QStringList parts = QString::fromLatin1( datagram ).split( ':' );
|
||||
if ( parts.length() == 4 )
|
||||
{
|
||||
bool ok;
|
||||
int port = parts.at(1).toInt( &ok );
|
||||
int port = parts.at( 1 ).toInt( &ok );
|
||||
if ( ok && Tomahawk::Database::instance()->impl()->dbid() != parts.at( 2 ) )
|
||||
{
|
||||
emit tomahawkHostFound( sender.toString(), port, parts.at( 3 ), parts.at( 2 ) );
|
||||
@@ -154,11 +162,11 @@ private slots:
|
||||
else if ( parts.length() == 3 )
|
||||
{
|
||||
bool ok;
|
||||
int port = parts.at(1).toInt( &ok );
|
||||
int port = parts.at( 1 ).toInt( &ok );
|
||||
if ( ok && Tomahawk::Database::instance()->impl()->dbid() != parts.at( 2 ) )
|
||||
{
|
||||
qDebug() << "ADVERT received:" << sender << port;
|
||||
Node *n = new Node( sender.toString(), parts.at( 2 ), port );
|
||||
Node* n = new Node( sender.toString(), parts.at( 2 ), port );
|
||||
connect( n, SIGNAL( tomahawkHostFound( QString, int, QString, QString ) ),
|
||||
this, SIGNAL( tomahawkHostFound( QString, int, QString, QString ) ) );
|
||||
n->resolve();
|
||||
@@ -167,10 +175,12 @@ private slots:
|
||||
}
|
||||
|
||||
if ( m_sock.hasPendingDatagrams() )
|
||||
{
|
||||
QTimer::singleShot( 0, this, SLOT( readPacket() ) );
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
QUdpSocket m_sock;
|
||||
int m_port;
|
||||
};
|
||||
|
@@ -94,14 +94,14 @@ ZeroconfPlugin::connectPlugin()
|
||||
delete m_zeroconf;
|
||||
m_zeroconf = new TomahawkZeroconf( Servent::instance()->port(), this );
|
||||
QObject::connect( m_zeroconf, SIGNAL( tomahawkHostFound( QString, int, QString, QString ) ),
|
||||
SLOT( lanHostFound( QString, int, QString, QString ) ) );
|
||||
SLOT( lanHostFound( QString, int, QString, QString ) ) );
|
||||
|
||||
advertise();
|
||||
m_state = Account::Connected;
|
||||
|
||||
foreach( const QStringList& nodeSet, m_cachedNodes )
|
||||
foreach( const QStringList & nodeSet, m_cachedNodes )
|
||||
{
|
||||
lanHostFound( nodeSet[0], nodeSet[1].toInt(), nodeSet[2], nodeSet[3]);
|
||||
lanHostFound( nodeSet[0], nodeSet[1].toInt(), nodeSet[2], nodeSet[3] );
|
||||
}
|
||||
m_cachedNodes.clear();
|
||||
|
||||
@@ -142,7 +142,9 @@ void
|
||||
ZeroconfPlugin::lanHostFound( const QString& host, int port, const QString& name, const QString& nodeid )
|
||||
{
|
||||
if ( sender() != m_zeroconf )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "Found LAN host:" << host << port << nodeid;
|
||||
|
||||
|
@@ -40,7 +40,7 @@ class ACCOUNTDLLEXPORT ZeroconfPlugin : public SipPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
public:
|
||||
ZeroconfPlugin( ZeroconfAccount* acc );
|
||||
|
||||
virtual ~ZeroconfPlugin();
|
||||
@@ -50,14 +50,17 @@ public:
|
||||
virtual const QString accountName() const;
|
||||
virtual const QString serviceName() const;
|
||||
virtual Account::ConnectionState connectionState() const;
|
||||
virtual bool isValid() const { return true; }
|
||||
virtual bool isValid() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#ifndef ENABLE_HEADLESS
|
||||
virtual QIcon icon() const;
|
||||
#endif
|
||||
virtual void checkSettings() {}
|
||||
virtual void configurationChanged() {}
|
||||
|
||||
public slots:
|
||||
public slots:
|
||||
void connectPlugin();
|
||||
void disconnectPlugin();
|
||||
|
||||
@@ -65,12 +68,15 @@ public slots:
|
||||
|
||||
virtual void sendSipInfos( const Tomahawk::peerinfo_ptr& /* receiver */, const QList<SipInfo>& /* info */ ) {}
|
||||
void broadcastMsg( const QString& ) {}
|
||||
bool addContact( const QString&, AddContactOptions, const QString& ) { return false; }
|
||||
bool addContact( const QString&, AddContactOptions, const QString& )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
private slots:
|
||||
private slots:
|
||||
void lanHostFound( const QString& host, int port, const QString& name, const QString& nodeid );
|
||||
|
||||
private:
|
||||
private:
|
||||
TomahawkZeroconf* m_zeroconf;
|
||||
Account::ConnectionState m_state;
|
||||
QVector<QStringList> m_cachedNodes;
|
||||
|
@@ -31,7 +31,9 @@ ZeroconfFactory::ZeroconfFactory()
|
||||
{
|
||||
#ifndef ENABLE_HEADLESS
|
||||
if ( s_icon == 0 )
|
||||
{
|
||||
s_icon = new QPixmap( ":/zeroconf-account/zeroconf-icon.png" );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -84,7 +86,9 @@ void
|
||||
ZeroconfAccount::authenticate()
|
||||
{
|
||||
if ( !isAuthenticated() )
|
||||
{
|
||||
sipPlugin()->connectPlugin();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -92,7 +96,9 @@ void
|
||||
ZeroconfAccount::deauthenticate()
|
||||
{
|
||||
if ( isAuthenticated() && !m_sipPlugin.isNull() )
|
||||
{
|
||||
m_sipPlugin->disconnectPlugin();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -107,7 +113,9 @@ Account::ConnectionState
|
||||
ZeroconfAccount::connectionState() const
|
||||
{
|
||||
if ( m_sipPlugin.isNull() )
|
||||
{
|
||||
return Disconnected;
|
||||
}
|
||||
|
||||
// TODO can we get called before sipPlugin()?
|
||||
return m_sipPlugin->connectionState();
|
||||
@@ -117,9 +125,12 @@ ZeroconfAccount::connectionState() const
|
||||
SipPlugin*
|
||||
ZeroconfAccount::sipPlugin( bool create )
|
||||
{
|
||||
if ( m_sipPlugin.isNull() ) {
|
||||
if ( m_sipPlugin.isNull() )
|
||||
{
|
||||
if ( !create )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
m_sipPlugin = QPointer< ZeroconfPlugin >( new ZeroconfPlugin( this ) );
|
||||
}
|
||||
|
@@ -37,17 +37,32 @@ class ACCOUNTDLLEXPORT ZeroconfFactory : public AccountFactory
|
||||
Q_OBJECT
|
||||
Q_INTERFACES( Tomahawk::Accounts::AccountFactory )
|
||||
|
||||
public:
|
||||
public:
|
||||
ZeroconfFactory();
|
||||
virtual ~ZeroconfFactory();
|
||||
|
||||
virtual QString factoryId() const { return "zeroconfaccount"; }
|
||||
virtual QString prettyName() const { return tr( "Local Network" ); }
|
||||
QString description() const { return tr( "Automatically connect to Tomahawks on the local network" ); }
|
||||
virtual bool isUnique() const { return true; }
|
||||
AccountTypes types() const { return AccountTypes( SipType ); };
|
||||
virtual QString factoryId() const
|
||||
{
|
||||
return "zeroconfaccount";
|
||||
}
|
||||
virtual QString prettyName() const
|
||||
{
|
||||
return tr( "Local Network" );
|
||||
}
|
||||
QString description() const
|
||||
{
|
||||
return tr( "Automatically connect to Tomahawks on the local network" );
|
||||
}
|
||||
virtual bool isUnique() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
AccountTypes types() const
|
||||
{
|
||||
return AccountTypes( SipType );
|
||||
};
|
||||
#ifndef ENABLE_HEADLESS
|
||||
virtual QPixmap icon() const;
|
||||
virtual QPixmap icon() const;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -57,8 +72,8 @@ virtual QPixmap icon() const;
|
||||
class ACCOUNTDLLEXPORT ZeroconfAccount : public Account
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ZeroconfAccount( const QString &accountId );
|
||||
public:
|
||||
ZeroconfAccount( const QString& accountId );
|
||||
virtual ~ZeroconfAccount();
|
||||
|
||||
QPixmap icon() const;
|
||||
@@ -68,13 +83,22 @@ public:
|
||||
bool isAuthenticated() const;
|
||||
ConnectionState connectionState() const;
|
||||
|
||||
virtual Tomahawk::InfoSystem::InfoPluginPtr infoPlugin() { return Tomahawk::InfoSystem::InfoPluginPtr(); }
|
||||
virtual Tomahawk::InfoSystem::InfoPluginPtr infoPlugin()
|
||||
{
|
||||
return Tomahawk::InfoSystem::InfoPluginPtr();
|
||||
}
|
||||
SipPlugin* sipPlugin( bool create = true );
|
||||
|
||||
AccountConfigWidget* configurationWidget() { return 0; }
|
||||
QWidget* aclWidget() { return 0; }
|
||||
AccountConfigWidget* configurationWidget()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
QWidget* aclWidget()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
QPointer< ZeroconfPlugin > m_sipPlugin;
|
||||
};
|
||||
|
||||
|
@@ -42,21 +42,21 @@ CrashReporter::CrashReporter( const QUrl& url, const QStringList& args )
|
||||
ui.progressBar->setValue( 0 );
|
||||
ui.progressLabel->setPalette( Qt::gray );
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
#ifdef Q_OS_MAC
|
||||
QFont f = ui.bottomLabel->font();
|
||||
f.setPointSize( 10 );
|
||||
ui.bottomLabel->setFont( f );
|
||||
f.setPointSize( 11 );
|
||||
ui.progressLabel->setFont( f );
|
||||
ui.progressLabel->setIndent( 3 );
|
||||
#else
|
||||
#else
|
||||
ui.vboxLayout->setSpacing( 16 );
|
||||
ui.hboxLayout1->setSpacing( 16 );
|
||||
ui.progressBar->setTextVisible( false );
|
||||
ui.progressLabel->setIndent( 1 );
|
||||
ui.bottomLabel->setDisabled( true );
|
||||
ui.bottomLabel->setIndent( 1 );
|
||||
#endif //Q_OS_MAC
|
||||
#endif //Q_OS_MAC
|
||||
|
||||
m_request = new QNetworkRequest( m_url );
|
||||
|
||||
@@ -115,14 +115,14 @@ CrashReporter::send()
|
||||
{
|
||||
body += "--thkboundary\r\n";
|
||||
body += "Content-Disposition: form-data; name=\"" +
|
||||
pair.first + "\"\r\n\r\n" +
|
||||
pair.second + "\r\n";
|
||||
pair.first + "\"\r\n\r\n" +
|
||||
pair.second + "\r\n";
|
||||
}
|
||||
|
||||
// add minidump file
|
||||
body += "--thkboundary\r\n";
|
||||
body += "Content-Disposition: form-data; name=\"upload_file_minidump\"; filename=\""
|
||||
+ QFileInfo( m_minidump ).fileName() + "\"\r\n";
|
||||
+ QFileInfo( m_minidump ).fileName() + "\"\r\n";
|
||||
body += "Content-Type: application/octet-stream\r\n";
|
||||
body += "\r\n";
|
||||
body += contents( m_minidump );
|
||||
@@ -179,7 +179,9 @@ CrashReporter::onDone()
|
||||
onFail( m_reply->error(), m_reply->errorString() );
|
||||
}
|
||||
else
|
||||
{
|
||||
ui.progressLabel->setText( tr( "Sent! <b>Many thanks</b>." ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@@ -31,11 +31,11 @@ class CrashReporter : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
public:
|
||||
CrashReporter( const QUrl& url, const QStringList& argv );
|
||||
virtual ~CrashReporter( );
|
||||
|
||||
private:
|
||||
private:
|
||||
Ui::CrashReporter ui;
|
||||
|
||||
QString m_minidump;
|
||||
@@ -45,10 +45,10 @@ private:
|
||||
QNetworkReply* m_reply;
|
||||
QUrl m_url;
|
||||
|
||||
public slots:
|
||||
public slots:
|
||||
void send();
|
||||
|
||||
private slots:
|
||||
private slots:
|
||||
void onDone();
|
||||
void onProgress( qint64 done, qint64 total );
|
||||
void onFail( int error, const QString& errorString );
|
||||
|
@@ -59,7 +59,7 @@ ChartsPlugin::ChartsPlugin()
|
||||
|
||||
m_chartVersion = "2.6.6";
|
||||
m_supportedGetTypes << InfoChart << InfoChartCapabilities;
|
||||
m_cacheIdentifier = TomahawkUtils::md5( QString("ChartsPlugin" + m_chartVersion ).toUtf8() );
|
||||
m_cacheIdentifier = TomahawkUtils::md5( QString( "ChartsPlugin" + m_chartVersion ).toUtf8() );
|
||||
}
|
||||
|
||||
|
||||
@@ -75,27 +75,29 @@ ChartsPlugin::init()
|
||||
QVariant data = TomahawkUtils::Cache::instance()->getData( m_cacheIdentifier, "chart_sources" );
|
||||
if ( data.canConvert< QList< Tomahawk::InfoSystem::InfoStringHash > >() )
|
||||
{
|
||||
const QList< Tomahawk::InfoSystem::InfoStringHash > sourceList = data.value< QList< Tomahawk::InfoSystem::InfoStringHash > >();
|
||||
foreach ( const Tomahawk::InfoSystem::InfoStringHash &sourceHash, sourceList )
|
||||
{
|
||||
bool ok;
|
||||
qlonglong maxAge = getMaxAge( QString( sourceHash[ "chart_expires" ] ).toLongLong( &ok ) );
|
||||
if ( !ok || maxAge <= 0 )
|
||||
{
|
||||
// This source has expired.
|
||||
m_refetchSource << sourceHash[ "chart_source" ];
|
||||
}
|
||||
m_chartResources << sourceHash;
|
||||
}
|
||||
const QList< Tomahawk::InfoSystem::InfoStringHash > sourceList = data.value< QList< Tomahawk::InfoSystem::InfoStringHash > >();
|
||||
foreach ( const Tomahawk::InfoSystem::InfoStringHash & sourceHash, sourceList )
|
||||
{
|
||||
bool ok;
|
||||
qlonglong maxAge = getMaxAge( QString( sourceHash[ "chart_expires" ] ).toLongLong( &ok ) );
|
||||
if ( !ok || maxAge <= 0 )
|
||||
{
|
||||
// This source has expired.
|
||||
m_refetchSource << sourceHash[ "chart_source" ];
|
||||
}
|
||||
m_chartResources << sourceHash;
|
||||
}
|
||||
|
||||
data = TomahawkUtils::Cache::instance()->getData( m_cacheIdentifier, "allCharts" );
|
||||
data = TomahawkUtils::Cache::instance()->getData( m_cacheIdentifier, "allCharts" );
|
||||
|
||||
if ( data.canConvert< QVariantMap >() )
|
||||
{
|
||||
m_allChartsMap = data.toMap();
|
||||
if ( !m_allChartsMap.empty() )
|
||||
m_fetchAll = false;
|
||||
}
|
||||
if ( data.canConvert< QVariantMap >() )
|
||||
{
|
||||
m_allChartsMap = data.toMap();
|
||||
if ( !m_allChartsMap.empty() )
|
||||
{
|
||||
m_fetchAll = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -137,7 +139,7 @@ ChartsPlugin::getInfo( Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ( const Tomahawk::InfoSystem::InfoStringHash &sourceHash, m_chartResources )
|
||||
foreach ( const Tomahawk::InfoSystem::InfoStringHash & sourceHash, m_chartResources )
|
||||
{
|
||||
if ( sourceHash[ "chart_source" ] == hash[ "chart_source" ] )
|
||||
{
|
||||
@@ -240,7 +242,7 @@ ChartsPlugin::fetchChartCapabilitiesFromCache( Tomahawk::InfoSystem::InfoRequest
|
||||
}
|
||||
|
||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Checking cache for " << "InfoChartCapabilities" << m_chartVersion;
|
||||
emit getCachedInfo( criteria, Q_INT64_C(172800000) /* 2 days */, requestData );
|
||||
emit getCachedInfo( criteria, Q_INT64_C( 172800000 ) /* 2 days */, requestData );
|
||||
}
|
||||
|
||||
|
||||
@@ -309,7 +311,7 @@ ChartsPlugin::chartSourcesList()
|
||||
|
||||
m_chartResources.clear();
|
||||
|
||||
foreach ( const QVariant &rsource, sources )
|
||||
foreach ( const QVariant & rsource, sources )
|
||||
{
|
||||
/// Each item has an expiration, on next request for cache, it will be checked */
|
||||
const QString source = rsource.toString();
|
||||
@@ -320,13 +322,13 @@ ChartsPlugin::chartSourcesList()
|
||||
|
||||
const QString headerExpiration = reply->rawHeader( QString( tmpSource ).toLocal8Bit() );
|
||||
const qlonglong maxAge = getMaxAge( headerExpiration.toLocal8Bit() );
|
||||
const qlonglong expires = headerExpiration.toLongLong(&ok);
|
||||
const qlonglong expires = headerExpiration.toLongLong( &ok );
|
||||
Tomahawk::InfoSystem::InfoStringHash source_expire;
|
||||
|
||||
if ( ok )
|
||||
{
|
||||
source_expire[ "chart_source" ] = source;
|
||||
source_expire[ "chart_expires" ] = QString::number(expires);
|
||||
source_expire[ "chart_expires" ] = QString::number( expires );
|
||||
m_chartResources << source_expire;
|
||||
|
||||
if( !m_fetchAll )
|
||||
@@ -367,12 +369,14 @@ ChartsPlugin::chartSourcesList()
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO << "Encountered error fetching chart sources list";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ChartsPlugin::fetchSource(const QString& source)
|
||||
ChartsPlugin::fetchSource( const QString& source )
|
||||
{
|
||||
QUrl url = QUrl( QString( CHART_URL "charts/%1" ).arg( source ) );
|
||||
TomahawkUtils::urlAddQueryItem( url, "version", TomahawkUtils::appFriendlyVersion() );
|
||||
@@ -392,9 +396,9 @@ ChartsPlugin::fetchExpiredSources()
|
||||
{
|
||||
if ( !m_refetchSource.isEmpty() )
|
||||
{
|
||||
foreach ( const QString& source, m_refetchSource )
|
||||
foreach ( const QString & source, m_refetchSource )
|
||||
{
|
||||
fetchSource(source);
|
||||
fetchSource( source );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -407,7 +411,7 @@ ChartsPlugin::fetchAllChartSources()
|
||||
{
|
||||
foreach ( const Tomahawk::InfoSystem::InfoStringHash source, m_chartResources )
|
||||
{
|
||||
fetchSource(source[ "chart_source" ]);
|
||||
fetchSource( source[ "chart_source" ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -478,7 +482,7 @@ ChartsPlugin::chartsList()
|
||||
QHash< QString, QVariantMap > extraType;
|
||||
QStringList processed;
|
||||
|
||||
foreach ( const QVariant& chartObj, response.values() )
|
||||
foreach ( const QVariant & chartObj, response.values() )
|
||||
{
|
||||
if ( !chartObj.toMap().isEmpty() )
|
||||
{
|
||||
@@ -497,14 +501,20 @@ ChartsPlugin::chartsList()
|
||||
if ( geo == "jp" && type == "Tracks" )
|
||||
{
|
||||
if ( processed.contains( name ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
processed << name;
|
||||
}
|
||||
|
||||
if ( !geo.isEmpty() )
|
||||
{
|
||||
extra = countryName( geo );
|
||||
}
|
||||
else
|
||||
{
|
||||
extra = chart.value( "extra" ).toString();
|
||||
}
|
||||
|
||||
InfoStringHash c;
|
||||
c[ "id" ] = id;
|
||||
@@ -521,14 +531,14 @@ ChartsPlugin::chartsList()
|
||||
}
|
||||
|
||||
// If this item has expired, set it to 0.
|
||||
c[ "expires" ] = ( ok ? QString::number (expires ) : QString::number( 0 ) );
|
||||
c[ "expires" ] = ( ok ? QString::number ( expires ) : QString::number( 0 ) );
|
||||
|
||||
QList< Tomahawk::InfoSystem::InfoStringHash > extraTypeData = extraType[ extra ][ type ].value< QList< Tomahawk::InfoSystem::InfoStringHash > >();
|
||||
extraTypeData.append( c );
|
||||
extraType[ extra ][ type ] = QVariant::fromValue< QList< Tomahawk::InfoSystem::InfoStringHash > >( extraTypeData );
|
||||
|
||||
}
|
||||
foreach ( const QString& c, extraType.keys() )
|
||||
foreach ( const QString & c, extraType.keys() )
|
||||
{
|
||||
charts[ c ] = extraType[ c ];
|
||||
}
|
||||
@@ -543,7 +553,7 @@ ChartsPlugin::chartsList()
|
||||
QList< InfoStringHash > trackCharts;
|
||||
QList< InfoStringHash > artistCharts;
|
||||
|
||||
foreach ( const QVariant& chartObj, response.values() )
|
||||
foreach ( const QVariant & chartObj, response.values() )
|
||||
{
|
||||
if ( !chartObj.toMap().isEmpty() )
|
||||
{
|
||||
@@ -567,20 +577,32 @@ ChartsPlugin::chartsList()
|
||||
}
|
||||
|
||||
if ( type == "Albums" )
|
||||
{
|
||||
albumCharts.append( c );
|
||||
}
|
||||
else if ( type == "Tracks" )
|
||||
{
|
||||
trackCharts.append( c );
|
||||
}
|
||||
else if ( type == "Artists" )
|
||||
{
|
||||
artistCharts.append( c );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( !artistCharts.isEmpty() )
|
||||
{
|
||||
charts.insert( tr( "Artists" ), QVariant::fromValue< QList< Tomahawk::InfoSystem::InfoStringHash > >( artistCharts ) );
|
||||
}
|
||||
if ( !albumCharts.isEmpty() )
|
||||
{
|
||||
charts.insert( tr( "Albums" ), QVariant::fromValue< QList< Tomahawk::InfoSystem::InfoStringHash > >( albumCharts ) );
|
||||
}
|
||||
if ( !trackCharts.isEmpty() )
|
||||
{
|
||||
charts.insert( tr( "Tracks" ), QVariant::fromValue< QList< Tomahawk::InfoSystem::InfoStringHash > >( trackCharts ) );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -613,7 +635,7 @@ ChartsPlugin::chartsList()
|
||||
criteria[ "InfoChartVersion" ] = m_chartVersion;
|
||||
|
||||
/// We can cache it the lot for 2 days, it will be checked on next request
|
||||
emit updateCache( criteria, Q_INT64_C(172800000) /* 2 days */, request.type, m_allChartsMap );
|
||||
emit updateCache( criteria, Q_INT64_C( 172800000 ) /* 2 days */, request.type, m_allChartsMap );
|
||||
}
|
||||
|
||||
TomahawkUtils::Cache::instance()->putData( m_cacheIdentifier, 172800000 /* 2 days */, "allCharts", m_allChartsMap );
|
||||
@@ -654,15 +676,23 @@ ChartsPlugin::chartReturned()
|
||||
/// @todo: We allready know the type, append it to breadcrumb hash
|
||||
|
||||
if ( res.value( "type" ).toString() == "Album" )
|
||||
{
|
||||
setChartType( Album );
|
||||
}
|
||||
else if ( res.value( "type" ).toString() == "Track" )
|
||||
{
|
||||
setChartType( Track );
|
||||
}
|
||||
else if ( res.value( "type" ).toString() == "Artist" )
|
||||
{
|
||||
setChartType( Artist );
|
||||
}
|
||||
else
|
||||
{
|
||||
setChartType( None );
|
||||
}
|
||||
|
||||
foreach ( const QVariant& chartR, chartResponse )
|
||||
foreach ( const QVariant & chartR, chartResponse )
|
||||
{
|
||||
QString title, artist, album, streamUrl;
|
||||
QVariantMap chartMap = chartR.toMap();
|
||||
@@ -749,7 +779,7 @@ ChartsPlugin::chartReturned()
|
||||
criteria[ "chart_expires" ] = ( ok ? QString::number( expires ) : QString::number( 0 ) );
|
||||
|
||||
/// If the item has expired, cache it for one hour and try and refetch later
|
||||
emit updateCache( criteria, (maxAge == Q_INT64_C(0) ? Q_INT64_C(3600000) /* One hour */ : maxAge), requestData.type, returnedData );
|
||||
emit updateCache( criteria, ( maxAge == Q_INT64_C( 0 ) ? Q_INT64_C( 3600000 ) /* One hour */ : maxAge ), requestData.type, returnedData );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -768,7 +798,9 @@ QString
|
||||
ChartsPlugin::countryName( const QString& cc )
|
||||
{
|
||||
if ( m_cachedCountries.contains( cc ) )
|
||||
{
|
||||
return m_cachedCountries[ cc ];
|
||||
}
|
||||
|
||||
QString name = Tomahawk::CountryUtils::fullCountryFromCode( cc );
|
||||
for ( int i = 1; i < name.size(); i++ )
|
||||
@@ -785,7 +817,7 @@ ChartsPlugin::countryName( const QString& cc )
|
||||
|
||||
|
||||
qlonglong
|
||||
ChartsPlugin::getMaxAge( const QByteArray &rawHeader ) const
|
||||
ChartsPlugin::getMaxAge( const QByteArray& rawHeader ) const
|
||||
{
|
||||
bool ok;
|
||||
qlonglong expires = QString( rawHeader ).toLongLong( &ok );
|
||||
@@ -799,12 +831,12 @@ ChartsPlugin::getMaxAge( const QByteArray &rawHeader ) const
|
||||
qlonglong
|
||||
ChartsPlugin::getMaxAge( const qlonglong expires ) const
|
||||
{
|
||||
qlonglong currentEpoch = QDateTime::currentMSecsSinceEpoch()/1000;
|
||||
qlonglong expiresInSeconds = expires-currentEpoch;
|
||||
qlonglong currentEpoch = QDateTime::currentMSecsSinceEpoch() / 1000;
|
||||
qlonglong expiresInSeconds = expires - currentEpoch;
|
||||
|
||||
if ( expiresInSeconds > 0 )
|
||||
{
|
||||
return ( qlonglong )expiresInSeconds*1000;
|
||||
return ( qlonglong )expiresInSeconds * 1000;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@@ -41,21 +41,28 @@ class INFOPLUGINDLLEXPORT ChartsPlugin : public InfoPlugin
|
||||
Q_OBJECT
|
||||
Q_INTERFACES( Tomahawk::InfoSystem::InfoPlugin )
|
||||
|
||||
public:
|
||||
public:
|
||||
ChartsPlugin();
|
||||
virtual ~ChartsPlugin();
|
||||
|
||||
enum ChartType {
|
||||
enum ChartType
|
||||
{
|
||||
None = 0x00,
|
||||
Track = 0x01,
|
||||
Album = 0x02,
|
||||
Artist = 0x04
|
||||
};
|
||||
|
||||
void setChartType( ChartType type ) { m_chartType = type; }
|
||||
ChartType chartType() const { return m_chartType; }
|
||||
void setChartType( ChartType type )
|
||||
{
|
||||
m_chartType = type;
|
||||
}
|
||||
ChartType chartType() const
|
||||
{
|
||||
return m_chartType;
|
||||
}
|
||||
|
||||
protected slots:
|
||||
protected slots:
|
||||
virtual void init();
|
||||
virtual void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
virtual void notInCacheSlot( Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
@@ -80,7 +87,7 @@ protected slots:
|
||||
*/
|
||||
void chartReturned();
|
||||
|
||||
private:
|
||||
private:
|
||||
/**
|
||||
* Fetch list of chart sources (e.g., itunes, billboard)
|
||||
* Populates the m_chartResources member.
|
||||
@@ -104,7 +111,7 @@ private:
|
||||
|
||||
QString countryName( const QString& cc );
|
||||
|
||||
qlonglong getMaxAge( const QByteArray &rawHeader ) const;
|
||||
qlonglong getMaxAge( const QByteArray& rawHeader ) const;
|
||||
qlonglong getMaxAge( const qlonglong expires ) const;
|
||||
|
||||
QVariantMap m_allChartsMap;
|
||||
|
@@ -68,7 +68,7 @@ DiscogsPlugin::getInfo( Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
criteria["artist"] = hash["artist"];
|
||||
criteria["album"] = hash["album"];
|
||||
|
||||
emit getCachedInfo( criteria, Q_INT64_C(2419200000), requestData );
|
||||
emit getCachedInfo( criteria, Q_INT64_C( 2419200000 ), requestData );
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -114,7 +114,7 @@ DiscogsPlugin::notInCacheSlot( InfoStringHash criteria, InfoRequestData requestD
|
||||
|
||||
|
||||
void
|
||||
DiscogsPlugin::albumSearchSlot( const InfoRequestData &requestData, QNetworkReply *reply )
|
||||
DiscogsPlugin::albumSearchSlot( const InfoRequestData& requestData, QNetworkReply* reply )
|
||||
{
|
||||
QJson::Parser p;
|
||||
QVariantMap results = p.parse( reply ).toMap();
|
||||
@@ -169,11 +169,13 @@ DiscogsPlugin::albumInfoSlot( const InfoRequestData& requestData, QNetworkReply*
|
||||
}
|
||||
|
||||
QStringList trackNameList;
|
||||
foreach ( const QVariant& v, release[ "tracklist" ].toList() )
|
||||
foreach ( const QVariant & v, release[ "tracklist" ].toList() )
|
||||
{
|
||||
const QVariantMap track = v.toMap();
|
||||
if ( track.contains( "title" ) )
|
||||
{
|
||||
trackNameList << track[ "title" ].toString();
|
||||
}
|
||||
}
|
||||
|
||||
QVariantMap returnedData;
|
||||
@@ -185,7 +187,7 @@ DiscogsPlugin::albumInfoSlot( const InfoRequestData& requestData, QNetworkReply*
|
||||
criteria["artist"] = requestData.input.value< Tomahawk::InfoSystem::InfoStringHash>()["artist"];
|
||||
criteria["album"] = requestData.input.value< Tomahawk::InfoSystem::InfoStringHash>()["album"];
|
||||
|
||||
emit updateCache( criteria, Q_INT64_C(0), requestData.type, returnedData );
|
||||
emit updateCache( criteria, Q_INT64_C( 0 ), requestData.type, returnedData );
|
||||
}
|
||||
|
||||
|
||||
|
@@ -39,21 +39,21 @@ class INFOPLUGINDLLEXPORT DiscogsPlugin : public InfoPlugin
|
||||
Q_OBJECT
|
||||
Q_INTERFACES( Tomahawk::InfoSystem::InfoPlugin )
|
||||
|
||||
public:
|
||||
public:
|
||||
DiscogsPlugin();
|
||||
virtual ~DiscogsPlugin();
|
||||
|
||||
protected slots:
|
||||
protected slots:
|
||||
virtual void init() {}
|
||||
virtual void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
virtual void notInCacheSlot( InfoStringHash criteria, InfoRequestData requestData );
|
||||
|
||||
virtual void pushInfo( Tomahawk::InfoSystem::InfoPushData ) {}
|
||||
private slots:
|
||||
void albumSearchSlot( const Tomahawk::InfoSystem::InfoRequestData& , QNetworkReply* );
|
||||
void albumInfoSlot( const Tomahawk::InfoSystem::InfoRequestData& , QNetworkReply* );
|
||||
private slots:
|
||||
void albumSearchSlot( const Tomahawk::InfoSystem::InfoRequestData&, QNetworkReply* );
|
||||
void albumInfoSlot( const Tomahawk::InfoSystem::InfoRequestData&, QNetworkReply* );
|
||||
|
||||
private:
|
||||
private:
|
||||
bool isValidTrackData( Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
};
|
||||
|
||||
|
@@ -83,25 +83,27 @@ EchonestPlugin::getInfo( Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
|
||||
|
||||
void
|
||||
EchonestPlugin::getSongProfile( const Tomahawk::InfoSystem::InfoRequestData &requestData, const QString &item )
|
||||
EchonestPlugin::getSongProfile( const Tomahawk::InfoSystem::InfoRequestData& requestData, const QString& item )
|
||||
{
|
||||
//WARNING: Totally not implemented yet
|
||||
Q_UNUSED( item );
|
||||
|
||||
if( !isValidTrackData( requestData ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Track track( input.toString() );
|
||||
// Artist artist( customData.input()->property("artistName").toString() );
|
||||
// reply->setProperty("artist", QVariant::fromValue<Artist>(artist));
|
||||
// reply->setProperty( "input", input );
|
||||
// m_replyMap[reply] = customData;
|
||||
// connect(reply, SIGNAL(finished()), SLOT(getArtistBiographySlot()));
|
||||
// Track track( input.toString() );
|
||||
// Artist artist( customData.input()->property("artistName").toString() );
|
||||
// reply->setProperty("artist", QVariant::fromValue<Artist>(artist));
|
||||
// reply->setProperty( "input", input );
|
||||
// m_replyMap[reply] = customData;
|
||||
// connect(reply, SIGNAL(finished()), SLOT(getArtistBiographySlot()));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
EchonestPlugin::getArtistBiography( const Tomahawk::InfoSystem::InfoRequestData &requestData )
|
||||
EchonestPlugin::getArtistBiography( const Tomahawk::InfoSystem::InfoRequestData& requestData )
|
||||
{
|
||||
if ( !requestData.input.canConvert< Tomahawk::InfoSystem::InfoStringHash >() )
|
||||
{
|
||||
@@ -114,7 +116,7 @@ EchonestPlugin::getArtistBiography( const Tomahawk::InfoSystem::InfoRequestData
|
||||
}
|
||||
|
||||
Echonest::Artist artist( hash["artist"] );
|
||||
QNetworkReply *reply = artist.fetchBiographies();
|
||||
QNetworkReply* reply = artist.fetchBiographies();
|
||||
reply->setProperty( "artist", QVariant::fromValue< Echonest::Artist >( artist ) );
|
||||
reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) );
|
||||
connect( reply, SIGNAL( finished() ), SLOT( getArtistBiographySlot() ) );
|
||||
@@ -122,10 +124,12 @@ EchonestPlugin::getArtistBiography( const Tomahawk::InfoSystem::InfoRequestData
|
||||
|
||||
|
||||
void
|
||||
EchonestPlugin::getArtistFamiliarity( const Tomahawk::InfoSystem::InfoRequestData &requestData )
|
||||
EchonestPlugin::getArtistFamiliarity( const Tomahawk::InfoSystem::InfoRequestData& requestData )
|
||||
{
|
||||
if( !isValidArtistData( requestData ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "Fetching artist familiarity!" << requestData.input;
|
||||
Echonest::Artist artist( requestData.input.toString() );
|
||||
@@ -137,10 +141,12 @@ EchonestPlugin::getArtistFamiliarity( const Tomahawk::InfoSystem::InfoRequestDat
|
||||
|
||||
|
||||
void
|
||||
EchonestPlugin::getArtistHotttnesss( const Tomahawk::InfoSystem::InfoRequestData &requestData )
|
||||
EchonestPlugin::getArtistHotttnesss( const Tomahawk::InfoSystem::InfoRequestData& requestData )
|
||||
{
|
||||
if( !isValidArtistData( requestData ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Echonest::Artist artist( requestData.input.toString() );
|
||||
QNetworkReply* reply = artist.fetchHotttnesss();
|
||||
@@ -151,10 +157,12 @@ EchonestPlugin::getArtistHotttnesss( const Tomahawk::InfoSystem::InfoRequestData
|
||||
|
||||
|
||||
void
|
||||
EchonestPlugin::getArtistTerms( const Tomahawk::InfoSystem::InfoRequestData &requestData )
|
||||
EchonestPlugin::getArtistTerms( const Tomahawk::InfoSystem::InfoRequestData& requestData )
|
||||
{
|
||||
if( !isValidArtistData( requestData ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Echonest::Artist artist( requestData.input.toString() );
|
||||
QNetworkReply* reply = artist.fetchTerms( Echonest::Artist::Weight );
|
||||
@@ -165,7 +173,7 @@ EchonestPlugin::getArtistTerms( const Tomahawk::InfoSystem::InfoRequestData &req
|
||||
|
||||
|
||||
void
|
||||
EchonestPlugin::getMiscTopTerms( const Tomahawk::InfoSystem::InfoRequestData &requestData )
|
||||
EchonestPlugin::getMiscTopTerms( const Tomahawk::InfoSystem::InfoRequestData& requestData )
|
||||
{
|
||||
QNetworkReply* reply = Echonest::Artist::topTerms( 20 );
|
||||
reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) );
|
||||
@@ -180,7 +188,7 @@ EchonestPlugin::getArtistBiographySlot()
|
||||
Echonest::Artist artist = artistFromReply( reply );
|
||||
Echonest::BiographyList biographies = artist.biographies();
|
||||
QVariantMap biographyMap;
|
||||
Q_FOREACH( const Echonest::Biography& biography, biographies )
|
||||
Q_FOREACH( const Echonest::Biography & biography, biographies )
|
||||
{
|
||||
QVariantHash siteData;
|
||||
siteData[ "site" ] = biography.site();
|
||||
@@ -227,7 +235,8 @@ EchonestPlugin::getArtistTermsSlot()
|
||||
Echonest::Artist artist = artistFromReply( reply );
|
||||
Echonest::TermList terms = artist.terms();
|
||||
QVariantMap termsMap;
|
||||
Q_FOREACH( const Echonest::Term& term, terms ) {
|
||||
Q_FOREACH( const Echonest::Term & term, terms )
|
||||
{
|
||||
QVariantHash termHash;
|
||||
termHash[ "weight" ] = QString::number( term.weight() );
|
||||
termHash[ "frequency" ] = QString::number( term.frequency() );
|
||||
@@ -245,7 +254,8 @@ EchonestPlugin::getMiscTopSlot()
|
||||
QNetworkReply* reply = qobject_cast<QNetworkReply*>( sender() );
|
||||
Echonest::TermList terms = Echonest::Artist::parseTopTerms( reply );
|
||||
QVariantMap termsMap;
|
||||
Q_FOREACH( const Echonest::Term& term, terms ) {
|
||||
Q_FOREACH( const Echonest::Term & term, terms )
|
||||
{
|
||||
QVariantHash termHash;
|
||||
termHash[ "weight" ] = QString::number( term.weight() );
|
||||
termHash[ "frequency" ] = QString::number( term.frequency() );
|
||||
@@ -258,7 +268,7 @@ EchonestPlugin::getMiscTopSlot()
|
||||
|
||||
|
||||
bool
|
||||
EchonestPlugin::isValidArtistData( const Tomahawk::InfoSystem::InfoRequestData &requestData )
|
||||
EchonestPlugin::isValidArtistData( const Tomahawk::InfoSystem::InfoRequestData& requestData )
|
||||
{
|
||||
if ( requestData.input.isNull() || !requestData.input.isValid() || !requestData.input.canConvert< QString >() )
|
||||
{
|
||||
@@ -276,7 +286,7 @@ EchonestPlugin::isValidArtistData( const Tomahawk::InfoSystem::InfoRequestData &
|
||||
|
||||
|
||||
bool
|
||||
EchonestPlugin::isValidTrackData( const Tomahawk::InfoSystem::InfoRequestData &requestData )
|
||||
EchonestPlugin::isValidTrackData( const Tomahawk::InfoSystem::InfoRequestData& requestData )
|
||||
{
|
||||
if ( requestData.input.isNull() || !requestData.input.isValid() || !requestData.input.canConvert< QString >() )
|
||||
{
|
||||
@@ -301,10 +311,13 @@ EchonestPlugin::isValidTrackData( const Tomahawk::InfoSystem::InfoRequestData &r
|
||||
Echonest::Artist
|
||||
EchonestPlugin::artistFromReply( QNetworkReply* reply )
|
||||
{
|
||||
Echonest::Artist artist = reply->property("artist").value<Echonest::Artist>();
|
||||
try {
|
||||
Echonest::Artist artist = reply->property( "artist" ).value<Echonest::Artist>();
|
||||
try
|
||||
{
|
||||
artist.parseProfile( reply );
|
||||
} catch( const Echonest::ParseError& e ) {
|
||||
}
|
||||
catch( const Echonest::ParseError& e )
|
||||
{
|
||||
qWarning() << "Caught parser error from echonest!" << e.what();
|
||||
}
|
||||
return artist;
|
||||
|
@@ -42,13 +42,13 @@ class INFOPLUGINDLLEXPORT EchonestPlugin : public InfoPlugin
|
||||
Q_OBJECT
|
||||
Q_INTERFACES( Tomahawk::InfoSystem::InfoPlugin )
|
||||
|
||||
public:
|
||||
public:
|
||||
EchonestPlugin();
|
||||
virtual ~EchonestPlugin();
|
||||
|
||||
protected slots:
|
||||
protected slots:
|
||||
virtual void init();
|
||||
|
||||
|
||||
virtual void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
|
||||
virtual void pushInfo( Tomahawk::InfoSystem::InfoPushData pushData )
|
||||
@@ -62,19 +62,19 @@ protected slots:
|
||||
Q_UNUSED( requestData );
|
||||
}
|
||||
|
||||
private:
|
||||
void getSongProfile( const Tomahawk::InfoSystem::InfoRequestData &requestData, const QString &item = QString() );
|
||||
void getArtistBiography( const Tomahawk::InfoSystem::InfoRequestData &requestData );
|
||||
void getArtistFamiliarity( const Tomahawk::InfoSystem::InfoRequestData &requestData );
|
||||
void getArtistHotttnesss( const Tomahawk::InfoSystem::InfoRequestData &requestData );
|
||||
void getArtistTerms( const Tomahawk::InfoSystem::InfoRequestData &requestData );
|
||||
void getMiscTopTerms( const Tomahawk::InfoSystem::InfoRequestData &requestData );
|
||||
private:
|
||||
void getSongProfile( const Tomahawk::InfoSystem::InfoRequestData& requestData, const QString& item = QString() );
|
||||
void getArtistBiography( const Tomahawk::InfoSystem::InfoRequestData& requestData );
|
||||
void getArtistFamiliarity( const Tomahawk::InfoSystem::InfoRequestData& requestData );
|
||||
void getArtistHotttnesss( const Tomahawk::InfoSystem::InfoRequestData& requestData );
|
||||
void getArtistTerms( const Tomahawk::InfoSystem::InfoRequestData& requestData );
|
||||
void getMiscTopTerms( const Tomahawk::InfoSystem::InfoRequestData& requestData );
|
||||
|
||||
bool isValidArtistData( const Tomahawk::InfoSystem::InfoRequestData &requestData );
|
||||
bool isValidTrackData( const Tomahawk::InfoSystem::InfoRequestData &requestData );
|
||||
bool isValidArtistData( const Tomahawk::InfoSystem::InfoRequestData& requestData );
|
||||
bool isValidTrackData( const Tomahawk::InfoSystem::InfoRequestData& requestData );
|
||||
Echonest::Artist artistFromReply( QNetworkReply* );
|
||||
|
||||
private slots:
|
||||
private slots:
|
||||
void getArtistBiographySlot();
|
||||
void getArtistFamiliaritySlot();
|
||||
void getArtistHotttnesssSlot();
|
||||
|
@@ -176,7 +176,7 @@ HypemPlugin::fetchChart( Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
criteria["chart_source"] = hash["chart_source"];
|
||||
/// @todo
|
||||
/// set cache time based on wether requested type is 3day, lastweek or recent.
|
||||
emit getCachedInfo( criteria, Q_INT64_C(86400000), requestData );
|
||||
emit getCachedInfo( criteria, Q_INT64_C( 86400000 ), requestData );
|
||||
}
|
||||
|
||||
void
|
||||
@@ -189,7 +189,7 @@ HypemPlugin::fetchChartCapabilities( Tomahawk::InfoSystem::InfoRequestData reque
|
||||
}
|
||||
|
||||
Tomahawk::InfoSystem::InfoStringHash criteria;
|
||||
emit getCachedInfo( criteria, Q_INT64_C(0), requestData );
|
||||
emit getCachedInfo( criteria, Q_INT64_C( 0 ), requestData );
|
||||
}
|
||||
|
||||
void
|
||||
@@ -202,7 +202,7 @@ HypemPlugin::notInCacheSlot( QHash<QString, QString> criteria, Tomahawk::InfoSys
|
||||
{
|
||||
/// Fetch the chart, we need source and id
|
||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "InfoChart not in cache! Fetching...";
|
||||
QUrl url = QUrl( QString( HYPEM_URL "%1/%2" ).arg( criteria["chart_id"].toLower() ).arg(HYPEM_END_URL) );
|
||||
QUrl url = QUrl( QString( HYPEM_URL "%1/%2" ).arg( criteria["chart_id"].toLower() ).arg( HYPEM_END_URL ) );
|
||||
qDebug() << Q_FUNC_INFO << "Getting chart url" << url;
|
||||
|
||||
QNetworkReply* reply = Tomahawk::Utils::nam()->get( QNetworkRequest( url ) );
|
||||
@@ -245,32 +245,40 @@ HypemPlugin::chartTypes()
|
||||
|
||||
QVariantMap charts;
|
||||
|
||||
foreach(QVariant types, m_types )
|
||||
foreach( QVariant types, m_types )
|
||||
{
|
||||
QList< InfoStringHash > chart_types;
|
||||
QList< InfoStringHash > pop_charts;
|
||||
InfoStringHash c;
|
||||
|
||||
if(types.toString() != "Artists")
|
||||
if( types.toString() != "Artists" )
|
||||
{
|
||||
|
||||
if(types.toString() == "Tracks")
|
||||
if( types.toString() == "Tracks" )
|
||||
{
|
||||
|
||||
foreach(QVariant trackType, m_trackTypes)
|
||||
foreach( QVariant trackType, m_trackTypes )
|
||||
{
|
||||
QString typeId;
|
||||
if(trackType.toString() == "Last 3 Days")
|
||||
if( trackType.toString() == "Last 3 Days" )
|
||||
{
|
||||
typeId = "popular/3day";
|
||||
}
|
||||
|
||||
if(trackType.toString() == "Last Week")
|
||||
if( trackType.toString() == "Last Week" )
|
||||
{
|
||||
typeId = "popular/lastweek";
|
||||
}
|
||||
|
||||
if(trackType.toString() == "No Remixes")
|
||||
if( trackType.toString() == "No Remixes" )
|
||||
{
|
||||
typeId = "popular/noremix";
|
||||
}
|
||||
|
||||
if(trackType.toString() == "On Twitter")
|
||||
if( trackType.toString() == "On Twitter" )
|
||||
{
|
||||
typeId = "popular/twitter";
|
||||
}
|
||||
|
||||
c[ "id" ] = typeId;
|
||||
c[ "label" ] = trackType.toString();
|
||||
@@ -281,9 +289,9 @@ HypemPlugin::chartTypes()
|
||||
chart_types.append( pop_charts );
|
||||
|
||||
}
|
||||
else if(types.toString() == "Recent by Tag")
|
||||
else if( types.toString() == "Recent by Tag" )
|
||||
{
|
||||
foreach(QVariant tagTypes, m_byTagTypes)
|
||||
foreach( QVariant tagTypes, m_byTagTypes )
|
||||
{
|
||||
|
||||
c[ "id" ] = "tags/" + tagTypes.toString().toLower();
|
||||
@@ -294,7 +302,8 @@ HypemPlugin::chartTypes()
|
||||
|
||||
}
|
||||
|
||||
}else
|
||||
}
|
||||
else
|
||||
{
|
||||
InfoStringHash c;
|
||||
c[ "id" ] = "popular/artists";
|
||||
@@ -338,9 +347,13 @@ HypemPlugin::chartReturned()
|
||||
QStringList top_artists;
|
||||
|
||||
if ( url.contains( "artists" ) )
|
||||
{
|
||||
setChartType( Artist );
|
||||
}
|
||||
else
|
||||
{
|
||||
setChartType( Track );
|
||||
}
|
||||
|
||||
foreach ( QVariant result, res )
|
||||
{
|
||||
@@ -363,7 +376,9 @@ HypemPlugin::chartReturned()
|
||||
|
||||
|
||||
if ( chartType() == Artist )
|
||||
{
|
||||
top_artists << artist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -394,10 +409,12 @@ HypemPlugin::chartReturned()
|
||||
criteria[ "chart_source" ] = origData[ "chart_source" ];
|
||||
/// @todo
|
||||
/// set cache time based on wether requested type is 3day, lastweek or recent.
|
||||
emit updateCache( criteria, Q_INT64_C(86400000), requestData.type, returnedData );
|
||||
emit updateCache( criteria, Q_INT64_C( 86400000 ), requestData.type, returnedData );
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "Network error in fetching chart:" << reply->url().toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@@ -41,25 +41,32 @@ class INFOPLUGINDLLEXPORT HypemPlugin : public InfoPlugin
|
||||
Q_OBJECT
|
||||
Q_INTERFACES( Tomahawk::InfoSystem::InfoPlugin )
|
||||
|
||||
public:
|
||||
public:
|
||||
HypemPlugin();
|
||||
virtual ~HypemPlugin();
|
||||
|
||||
enum ChartType {
|
||||
enum ChartType
|
||||
{
|
||||
None = 0x00,
|
||||
Track = 0x01,
|
||||
Album = 0x02,
|
||||
Artist = 0x04
|
||||
|
||||
};
|
||||
void setChartType( ChartType type ) { m_chartType = type; }
|
||||
ChartType chartType() const { return m_chartType; }
|
||||
void setChartType( ChartType type )
|
||||
{
|
||||
m_chartType = type;
|
||||
}
|
||||
ChartType chartType() const
|
||||
{
|
||||
return m_chartType;
|
||||
}
|
||||
|
||||
public slots:
|
||||
public slots:
|
||||
void chartReturned();
|
||||
void chartTypes();
|
||||
|
||||
protected slots:
|
||||
protected slots:
|
||||
virtual void init();
|
||||
virtual void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
virtual void notInCacheSlot( Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
@@ -69,7 +76,7 @@ protected slots:
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
private:
|
||||
void fetchChart( Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
void fetchChartCapabilities( Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
void dataError( Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
|
@@ -65,7 +65,7 @@ MusicBrainzPlugin::getInfo( Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
Tomahawk::InfoSystem::InfoStringHash criteria;
|
||||
criteria["artist"] = hash["artist"];
|
||||
|
||||
emit getCachedInfo( criteria, Q_INT64_C(2419200000), requestData );
|
||||
emit getCachedInfo( criteria, Q_INT64_C( 2419200000 ), requestData );
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ MusicBrainzPlugin::getInfo( Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
criteria["artist"] = hash["artist"];
|
||||
criteria["album"] = hash["album"];
|
||||
|
||||
emit getCachedInfo( criteria, Q_INT64_C(2419200000), requestData );
|
||||
emit getCachedInfo( criteria, Q_INT64_C( 2419200000 ), requestData );
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -97,7 +97,7 @@ MusicBrainzPlugin::notInCacheSlot( InfoStringHash criteria, InfoRequestData requ
|
||||
{
|
||||
case InfoArtistReleases:
|
||||
{
|
||||
querySt.append( QString( "artist:\"%1\"" ).arg(criteria["artist"]) );
|
||||
querySt.append( QString( "artist:\"%1\"" ).arg( criteria["artist"] ) );
|
||||
querySt.append( " AND (type:album OR type:ep)" );
|
||||
querySt.append( " AND status:official" );
|
||||
querySt.append( " AND NOT secondarytype:live" );
|
||||
@@ -120,8 +120,8 @@ MusicBrainzPlugin::notInCacheSlot( InfoStringHash criteria, InfoRequestData requ
|
||||
}
|
||||
case InfoAlbumSongs:
|
||||
{
|
||||
querySt.append( QString( "release:\"%1\"" ).arg(criteria["album"]) );
|
||||
querySt.append( QString( " AND artist:\"%1\"" ).arg(criteria["artist"]) );
|
||||
querySt.append( QString( "release:\"%1\"" ).arg( criteria["album"] ) );
|
||||
querySt.append( QString( " AND artist:\"%1\"" ).arg( criteria["artist"] ) );
|
||||
// not pre-filtering will yield more than 100 results which we dont handle atm. But since we only take the first result anyway that wont hurt
|
||||
|
||||
QString requestString( "http://musicbrainz.org/ws/2/release" );
|
||||
@@ -154,7 +154,9 @@ MusicBrainzPlugin::gotReleaseGroupsSlot()
|
||||
{
|
||||
QNetworkReply* oldReply = qobject_cast<QNetworkReply*>( sender() );
|
||||
if ( !oldReply )
|
||||
return; //timeout will handle it
|
||||
{
|
||||
return; //timeout will handle it
|
||||
}
|
||||
|
||||
QDomDocument doc;
|
||||
doc.setContent( oldReply->readAll() );
|
||||
@@ -172,14 +174,14 @@ MusicBrainzPlugin::gotReleaseGroupsSlot()
|
||||
{
|
||||
case InfoArtistReleases:
|
||||
{
|
||||
QString popularId = releaseGroupsNL.at(0).firstChildElement( "artist-credit" ).firstChildElement( "name-credit" ).firstChildElement( "artist" ).attribute( "id" );
|
||||
QString popularId = releaseGroupsNL.at( 0 ).firstChildElement( "artist-credit" ).firstChildElement( "name-credit" ).firstChildElement( "artist" ).attribute( "id" );
|
||||
|
||||
QStringList albums;
|
||||
for ( int i = 0; i < releaseGroupsNL.count(); i++ )
|
||||
{
|
||||
QString groupTitle = releaseGroupsNL.at(i).firstChildElement("title").text();
|
||||
QString a = releaseGroupsNL.at(i).firstChildElement( "artist-credit" ).firstChildElement( "name-credit" ).firstChildElement( "artist" ).firstChildElement( "name" ).text();
|
||||
QString id = releaseGroupsNL.at(i).firstChildElement( "artist-credit" ).firstChildElement( "name-credit" ).firstChildElement( "artist" ).attribute( "id" );
|
||||
QString groupTitle = releaseGroupsNL.at( i ).firstChildElement( "title" ).text();
|
||||
QString a = releaseGroupsNL.at( i ).firstChildElement( "artist-credit" ).firstChildElement( "name-credit" ).firstChildElement( "artist" ).firstChildElement( "name" ).text();
|
||||
QString id = releaseGroupsNL.at( i ).firstChildElement( "artist-credit" ).firstChildElement( "name-credit" ).firstChildElement( "artist" ).attribute( "id" );
|
||||
if ( !albums.contains( groupTitle ) && id == popularId && a.normalized( QString::NormalizationForm_KC ) == hash["artist"].normalized( QString::NormalizationForm_KC ) )
|
||||
{
|
||||
albums << groupTitle;
|
||||
@@ -194,7 +196,7 @@ MusicBrainzPlugin::gotReleaseGroupsSlot()
|
||||
Tomahawk::InfoSystem::InfoStringHash origData = requestData.input.value< Tomahawk::InfoSystem::InfoStringHash>();
|
||||
Tomahawk::InfoSystem::InfoStringHash criteria;
|
||||
criteria["artist"] = origData["artist"];
|
||||
emit updateCache( criteria, Q_INT64_C(0), requestData.type, returnedData );
|
||||
emit updateCache( criteria, Q_INT64_C( 0 ), requestData.type, returnedData );
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -212,7 +214,9 @@ MusicBrainzPlugin::gotReleasesSlot()
|
||||
{
|
||||
QNetworkReply* oldReply = qobject_cast<QNetworkReply*>( sender() );
|
||||
if ( !oldReply )
|
||||
return; //timeout will handle it
|
||||
{
|
||||
return; //timeout will handle it
|
||||
}
|
||||
|
||||
QDomDocument doc;
|
||||
doc.setContent( oldReply->readAll() );
|
||||
@@ -230,7 +234,7 @@ MusicBrainzPlugin::gotReleasesSlot()
|
||||
case InfoAlbumSongs:
|
||||
{
|
||||
// we can simply use the first result as they are sorted by score
|
||||
QString release_id = releasesNL.at(0).toElement().attribute( "id" );
|
||||
QString release_id = releasesNL.at( 0 ).toElement().attribute( "id" );
|
||||
|
||||
QString requestString = QString( "http://musicbrainz.org/ws/2/release/%1" ).arg( release_id );
|
||||
QUrl url( requestString );
|
||||
@@ -259,7 +263,9 @@ MusicBrainzPlugin::gotRecordingsSlot()
|
||||
{
|
||||
QNetworkReply* reply = qobject_cast< QNetworkReply* >( sender() );
|
||||
if ( !reply )
|
||||
return; //timeout will handle it
|
||||
{
|
||||
return; //timeout will handle it
|
||||
}
|
||||
|
||||
QDomDocument doc;
|
||||
doc.setContent( reply->readAll() );
|
||||
@@ -272,15 +278,15 @@ MusicBrainzPlugin::gotRecordingsSlot()
|
||||
}
|
||||
|
||||
|
||||
QDomNodeList tracksNL = mediumList.at(0).toElement().elementsByTagName( "track" );
|
||||
QDomNodeList tracksNL = mediumList.at( 0 ).toElement().elementsByTagName( "track" );
|
||||
QStringList tracksSL;
|
||||
for ( int i = 0; i < tracksNL.count(); i++ )
|
||||
{
|
||||
QString track = tracksNL.at(i).firstChildElement( "recording" ).firstChildElement( "title" ).text();
|
||||
QString track = tracksNL.at( i ).firstChildElement( "recording" ).firstChildElement( "title" ).text();
|
||||
if ( !tracksSL.contains( track ) )
|
||||
{
|
||||
tracksSL << track;
|
||||
tDebug(LOGVERBOSE) << Q_FUNC_INFO << track;
|
||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << track;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -293,7 +299,7 @@ MusicBrainzPlugin::gotRecordingsSlot()
|
||||
Tomahawk::InfoSystem::InfoStringHash criteria;
|
||||
criteria["artist"] = origData["artist"];
|
||||
criteria["album"] = origData["album"];
|
||||
emit updateCache( criteria, Q_INT64_C(0), requestData.type, returnedData );
|
||||
emit updateCache( criteria, Q_INT64_C( 0 ), requestData.type, returnedData );
|
||||
}
|
||||
|
||||
Q_EXPORT_PLUGIN2( Tomahawk::InfoSystem::InfoPlugin, Tomahawk::InfoSystem::MusicBrainzPlugin )
|
||||
|
@@ -39,11 +39,11 @@ class INFOPLUGINDLLEXPORT MusicBrainzPlugin : public InfoPlugin
|
||||
Q_OBJECT
|
||||
Q_INTERFACES( Tomahawk::InfoSystem::InfoPlugin )
|
||||
|
||||
public:
|
||||
public:
|
||||
MusicBrainzPlugin();
|
||||
virtual ~MusicBrainzPlugin();
|
||||
|
||||
protected slots:
|
||||
protected slots:
|
||||
virtual void init() {}
|
||||
virtual void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
virtual void notInCacheSlot( InfoStringHash criteria, InfoRequestData requestData );
|
||||
@@ -54,7 +54,7 @@ protected slots:
|
||||
}
|
||||
|
||||
|
||||
private slots:
|
||||
private slots:
|
||||
|
||||
void gotReleaseGroupsSlot();
|
||||
void gotReleasesSlot();
|
||||
|
@@ -51,7 +51,9 @@ MusixMatchPlugin::getInfo( Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO;
|
||||
if( !isValidTrackData( requestData ) || requestData.type != Tomahawk::InfoSystem::InfoTrackLyrics )
|
||||
{
|
||||
return;
|
||||
}
|
||||
InfoStringHash hash = requestData.input.value< Tomahawk::InfoSystem::InfoStringHash >();
|
||||
|
||||
QString artist = hash["artist"];
|
||||
@@ -80,7 +82,7 @@ bool
|
||||
MusixMatchPlugin::isValidTrackData( Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO;
|
||||
|
||||
|
||||
if ( !requestData.input.canConvert< Tomahawk::InfoSystem::InfoStringHash >() )
|
||||
{
|
||||
emit info( requestData, QVariant() );
|
||||
@@ -111,18 +113,20 @@ MusixMatchPlugin::trackSearchSlot()
|
||||
tDebug() << Q_FUNC_INFO;
|
||||
QNetworkReply* oldReply = qobject_cast<QNetworkReply*>( sender() );
|
||||
if ( !oldReply )
|
||||
return; //timeout will handle it
|
||||
{
|
||||
return; //timeout will handle it
|
||||
}
|
||||
|
||||
QDomDocument doc;
|
||||
doc.setContent(oldReply->readAll());
|
||||
doc.setContent( oldReply->readAll() );
|
||||
qDebug() << doc.toString();
|
||||
QDomNodeList domNodeList = doc.elementsByTagName("track_id");
|
||||
QDomNodeList domNodeList = doc.elementsByTagName( "track_id" );
|
||||
if ( domNodeList.isEmpty() )
|
||||
{
|
||||
emit info( oldReply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(), QVariant() );
|
||||
return;
|
||||
}
|
||||
QString track_id = domNodeList.at(0).toElement().text();
|
||||
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 );
|
||||
|
||||
@@ -141,7 +145,9 @@ MusixMatchPlugin::trackLyricsSlot()
|
||||
tDebug() << Q_FUNC_INFO;
|
||||
QNetworkReply* reply = qobject_cast< QNetworkReply* >( sender() );
|
||||
if ( !reply )
|
||||
return; //timeout will handle it
|
||||
{
|
||||
return; //timeout will handle it
|
||||
}
|
||||
|
||||
QDomDocument doc;
|
||||
doc.setContent( reply->readAll() );
|
||||
@@ -151,7 +157,7 @@ MusixMatchPlugin::trackLyricsSlot()
|
||||
emit info( reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(), QVariant() );
|
||||
return;
|
||||
}
|
||||
QString lyrics = domNodeList.at(0).toElement().text();
|
||||
QString lyrics = domNodeList.at( 0 ).toElement().text();
|
||||
emit info( reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(), QVariant( lyrics ) );
|
||||
}
|
||||
|
||||
|
@@ -40,15 +40,15 @@ class INFOPLUGINDLLEXPORT MusixMatchPlugin : public InfoPlugin
|
||||
Q_OBJECT
|
||||
Q_INTERFACES( Tomahawk::InfoSystem::InfoPlugin )
|
||||
|
||||
public:
|
||||
public:
|
||||
MusixMatchPlugin();
|
||||
virtual ~MusixMatchPlugin();
|
||||
|
||||
public slots:
|
||||
public slots:
|
||||
void trackSearchSlot();
|
||||
void trackLyricsSlot();
|
||||
|
||||
protected slots:
|
||||
protected slots:
|
||||
virtual void init() {}
|
||||
virtual void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
|
||||
@@ -57,15 +57,15 @@ protected slots:
|
||||
Q_UNUSED( pushData );
|
||||
}
|
||||
|
||||
virtual void notInCacheSlot( Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
virtual void notInCacheSlot( Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
{
|
||||
Q_UNUSED( criteria );
|
||||
Q_UNUSED( requestData );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
private:
|
||||
bool isValidTrackData( Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
|
||||
|
||||
QString m_apiKey;
|
||||
};
|
||||
|
||||
|
@@ -94,18 +94,18 @@ NewReleasesPlugin::init()
|
||||
QVariant data = TomahawkUtils::Cache::instance()->getData( "NewReleasesPlugin", "nr_sources" );
|
||||
if ( data.canConvert< QList< Tomahawk::InfoSystem::InfoStringHash > >() )
|
||||
{
|
||||
const QList< Tomahawk::InfoSystem::InfoStringHash > sourceList = data.value< QList< Tomahawk::InfoSystem::InfoStringHash > >();
|
||||
foreach ( const Tomahawk::InfoSystem::InfoStringHash &sourceHash, sourceList )
|
||||
{
|
||||
bool ok;
|
||||
qlonglong maxAge = getMaxAge( QString( sourceHash[ "nr_expires" ] ).toLongLong( &ok ) );
|
||||
if ( !ok || maxAge <= 0 )
|
||||
{
|
||||
// This source has expired.
|
||||
m_refetchSource << sourceHash[ "nr_source" ];
|
||||
}
|
||||
m_nrSources << sourceHash;
|
||||
}
|
||||
const QList< Tomahawk::InfoSystem::InfoStringHash > sourceList = data.value< QList< Tomahawk::InfoSystem::InfoStringHash > >();
|
||||
foreach ( const Tomahawk::InfoSystem::InfoStringHash & sourceHash, sourceList )
|
||||
{
|
||||
bool ok;
|
||||
qlonglong maxAge = getMaxAge( QString( sourceHash[ "nr_expires" ] ).toLongLong( &ok ) );
|
||||
if ( !ok || maxAge <= 0 )
|
||||
{
|
||||
// This source has expired.
|
||||
m_refetchSource << sourceHash[ "nr_source" ];
|
||||
}
|
||||
m_nrSources << sourceHash;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -138,42 +138,42 @@ NewReleasesPlugin::getInfo( InfoRequestData requestData )
|
||||
|
||||
switch( requestData.type )
|
||||
{
|
||||
case InfoNewRelease:
|
||||
/// We need something to check if the request is actually ment to go to this plugin
|
||||
if ( !hash.contains( "nr_source" ) )
|
||||
{
|
||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Hash did not contain required param!";
|
||||
dataError( requestData );
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ( const Tomahawk::InfoSystem::InfoStringHash &sourceHash, m_nrSources )
|
||||
case InfoNewRelease:
|
||||
/// We need something to check if the request is actually ment to go to this plugin
|
||||
if ( !hash.contains( "nr_source" ) )
|
||||
{
|
||||
if ( sourceHash[ "nr_source" ] == hash[ "nr_source" ] )
|
||||
{
|
||||
foundSource = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !foundSource )
|
||||
{
|
||||
tDebug ( LOGVERBOSE ) << Q_FUNC_INFO << "Hash did not contain source " << hash["nr_source"];
|
||||
dataError ( requestData );
|
||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Hash did not contain required param!";
|
||||
dataError( requestData );
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ( const Tomahawk::InfoSystem::InfoStringHash & sourceHash, m_nrSources )
|
||||
{
|
||||
if ( sourceHash[ "nr_source" ] == hash[ "nr_source" ] )
|
||||
{
|
||||
foundSource = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
fetchNRFromCache( requestData );
|
||||
break;
|
||||
if ( !foundSource )
|
||||
{
|
||||
tDebug ( LOGVERBOSE ) << Q_FUNC_INFO << "Hash did not contain source " << hash["nr_source"];
|
||||
dataError ( requestData );
|
||||
break;
|
||||
}
|
||||
|
||||
case InfoNewReleaseCapabilities:
|
||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Requesting InfoNewReleaseCapabilities from cache";
|
||||
fetchNRCapabilitiesFromCache( requestData );
|
||||
break;
|
||||
}
|
||||
fetchNRFromCache( requestData );
|
||||
break;
|
||||
|
||||
default:
|
||||
dataError( requestData );
|
||||
case InfoNewReleaseCapabilities:
|
||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Requesting InfoNewReleaseCapabilities from cache";
|
||||
fetchNRCapabilitiesFromCache( requestData );
|
||||
break;
|
||||
|
||||
default:
|
||||
dataError( requestData );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,7 +244,7 @@ NewReleasesPlugin::fetchNRCapabilitiesFromCache( InfoRequestData requestData )
|
||||
}
|
||||
|
||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Fetching fetchNRCapabilitiesFromCache";
|
||||
emit getCachedInfo ( criteria, Q_INT64_C(172800000) /* 2 days */, requestData );
|
||||
emit getCachedInfo ( criteria, Q_INT64_C( 172800000 ) /* 2 days */, requestData );
|
||||
}
|
||||
|
||||
|
||||
@@ -316,7 +316,7 @@ NewReleasesPlugin::nrSourcesList()
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( const QVariant &rsource, sources )
|
||||
foreach ( const QVariant & rsource, sources )
|
||||
{
|
||||
|
||||
/**
|
||||
@@ -335,7 +335,7 @@ NewReleasesPlugin::nrSourcesList()
|
||||
{
|
||||
for ( int i = 0; i < m_nrSources.size(); i++ )
|
||||
{
|
||||
const Tomahawk::InfoSystem::InfoStringHash &hash = m_nrSources.at( i );
|
||||
const Tomahawk::InfoSystem::InfoStringHash& hash = m_nrSources.at( i );
|
||||
if ( hash[ "nr_source" ] == source )
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO << "Removing invalid source" << source;
|
||||
@@ -356,13 +356,13 @@ NewReleasesPlugin::nrSourcesList()
|
||||
const QString headerExpiration = reply->rawHeader( QString( tmpSource ).toLocal8Bit() );
|
||||
|
||||
const qlonglong maxAge = getMaxAge( headerExpiration.toLocal8Bit() );
|
||||
const qlonglong expires = headerExpiration.toLongLong(&ok);
|
||||
const qlonglong expires = headerExpiration.toLongLong( &ok );
|
||||
Tomahawk::InfoSystem::InfoStringHash source_expire;
|
||||
|
||||
if ( ok )
|
||||
{
|
||||
source_expire[ "nr_source" ] = source;
|
||||
source_expire[ "nr_expires" ] = QString::number(expires);
|
||||
source_expire[ "nr_expires" ] = QString::number( expires );
|
||||
m_nrSources << source_expire;
|
||||
}
|
||||
|
||||
@@ -469,7 +469,7 @@ NewReleasesPlugin::nrList()
|
||||
{
|
||||
// Itunes has geographic-area based releases. So we build a breadcrumb of
|
||||
// iTunes - Country - Featured/Just Released/New Releases - Genre
|
||||
foreach ( const QVariant &nrObj, res.values() )
|
||||
foreach ( const QVariant & nrObj, res.values() )
|
||||
{
|
||||
if ( !nrObj.toMap().isEmpty() )
|
||||
{
|
||||
@@ -483,7 +483,9 @@ NewReleasesPlugin::nrList()
|
||||
|
||||
// We only have albums in newReleases
|
||||
if ( type != "Albums" || name.isEmpty() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
QString extra;
|
||||
if ( !geo.isEmpty() )
|
||||
@@ -491,7 +493,8 @@ NewReleasesPlugin::nrList()
|
||||
if ( !m_cachedCountries.contains( geo ) )
|
||||
{
|
||||
extra = Tomahawk::CountryUtils::fullCountryFromCode( geo );
|
||||
if ( extra.isEmpty() || extra.isNull() ){
|
||||
if ( extra.isEmpty() || extra.isNull() )
|
||||
{
|
||||
qWarning() << "Geo string seems to be off!" << geo;
|
||||
continue;
|
||||
}
|
||||
@@ -523,10 +526,12 @@ NewReleasesPlugin::nrList()
|
||||
/**
|
||||
* If this item has expired, set it to 0.
|
||||
*/
|
||||
nr[ "expires" ] = ( ok ? QString::number (expires ) : QString::number( 0 ) );
|
||||
nr[ "expires" ] = ( ok ? QString::number ( expires ) : QString::number( 0 ) );
|
||||
|
||||
if ( isDefault )
|
||||
{
|
||||
nr[ "default" ] = "true";
|
||||
}
|
||||
|
||||
|
||||
QList< Tomahawk::InfoSystem::InfoStringHash > extraTypeData = extraType[ nrExtraType ][ extra ].value< QList< Tomahawk::InfoSystem::InfoStringHash > >();
|
||||
@@ -543,7 +548,7 @@ NewReleasesPlugin::nrList()
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( const QString& nr, extraType.keys() )
|
||||
foreach ( const QString & nr, extraType.keys() )
|
||||
{
|
||||
newreleases[ nr ] = extraType[ nr ];
|
||||
}
|
||||
@@ -556,7 +561,7 @@ NewReleasesPlugin::nrList()
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ( const QVariant &nrObj, res.values() )
|
||||
foreach ( const QVariant & nrObj, res.values() )
|
||||
{
|
||||
if ( !nrObj.toMap().isEmpty() )
|
||||
{
|
||||
@@ -581,7 +586,9 @@ NewReleasesPlugin::nrList()
|
||||
extraType[ extra ][ type ] = QVariant::fromValue< QList< Tomahawk::InfoSystem::InfoStringHash > >( extraTypeData );
|
||||
}
|
||||
else
|
||||
{
|
||||
albumNRs.append( nr );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -591,14 +598,16 @@ NewReleasesPlugin::nrList()
|
||||
|
||||
}
|
||||
|
||||
foreach ( const QString& c, extraType.keys() )
|
||||
foreach ( const QString & c, extraType.keys() )
|
||||
{
|
||||
newreleases[ c ] = extraType[ c ];
|
||||
}
|
||||
}
|
||||
|
||||
if ( !albumNRs.isEmpty() )
|
||||
{
|
||||
newreleases.insert ( tr ( "Albums" ), QVariant::fromValue< QList< Tomahawk::InfoSystem::InfoStringHash > >( albumNRs ) );
|
||||
}
|
||||
|
||||
/// @note For displaying purposes, upper the first letter
|
||||
/// @note Remeber to lower it when fetching this!
|
||||
@@ -629,14 +638,14 @@ NewReleasesPlugin::nrList()
|
||||
/**
|
||||
* We can cache it the lot for 2 days, it will be checked on next request
|
||||
*/
|
||||
emit updateCache( criteria, Q_INT64_C(172800000) /* 2 days */, request.type, m_allNRsMap );
|
||||
emit updateCache( criteria, Q_INT64_C( 172800000 ) /* 2 days */, request.type, m_allNRsMap );
|
||||
}
|
||||
m_cachedRequests.clear();
|
||||
}
|
||||
}
|
||||
|
||||
qlonglong
|
||||
NewReleasesPlugin::getMaxAge( const QByteArray &rawHeader ) const
|
||||
NewReleasesPlugin::getMaxAge( const QByteArray& rawHeader ) const
|
||||
{
|
||||
bool ok;
|
||||
qlonglong expires = QString( rawHeader ).toLongLong( &ok );
|
||||
@@ -650,12 +659,12 @@ NewReleasesPlugin::getMaxAge( const QByteArray &rawHeader ) const
|
||||
qlonglong
|
||||
NewReleasesPlugin::getMaxAge( const qlonglong expires ) const
|
||||
{
|
||||
qlonglong currentEpoch = QDateTime::currentMSecsSinceEpoch()/1000;
|
||||
qlonglong expiresInSeconds = expires-currentEpoch;
|
||||
qlonglong currentEpoch = QDateTime::currentMSecsSinceEpoch() / 1000;
|
||||
qlonglong expiresInSeconds = expires - currentEpoch;
|
||||
|
||||
if ( expiresInSeconds > 0 )
|
||||
{
|
||||
return ( qlonglong )expiresInSeconds*1000;
|
||||
return ( qlonglong )expiresInSeconds * 1000;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -722,10 +731,12 @@ NewReleasesPlugin::nrReturned()
|
||||
/**
|
||||
* If the item has expired, cache it for one hour and try and refetch later
|
||||
*/
|
||||
emit updateCache( criteria, (maxAge == Q_INT64_C(0) ? (3600000) /* One hour */ : maxAge), requestData.type, returnedData );
|
||||
emit updateCache( criteria, ( maxAge == Q_INT64_C( 0 ) ? ( 3600000 ) /* One hour */ : maxAge ), requestData.type, returnedData );
|
||||
}
|
||||
else
|
||||
{
|
||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Network error in fetching newrelease:" << reply->url().toString();
|
||||
}
|
||||
}
|
||||
|
||||
Q_EXPORT_PLUGIN2( Tomahawk::InfoSystem::InfoPlugin, Tomahawk::InfoSystem::NewReleasesPlugin )
|
||||
|
@@ -43,11 +43,11 @@ class INFOPLUGINDLLEXPORT NewReleasesPlugin : public InfoPlugin
|
||||
Q_OBJECT
|
||||
Q_INTERFACES( Tomahawk::InfoSystem::InfoPlugin )
|
||||
|
||||
public:
|
||||
public:
|
||||
NewReleasesPlugin();
|
||||
virtual ~NewReleasesPlugin();
|
||||
|
||||
protected slots:
|
||||
protected slots:
|
||||
virtual void init();
|
||||
virtual void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
virtual void notInCacheSlot( Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
@@ -72,7 +72,7 @@ protected slots:
|
||||
*/
|
||||
void nrReturned();
|
||||
|
||||
private:
|
||||
private:
|
||||
/**
|
||||
* Requests newrelease list for each source in m_chartSources
|
||||
*/
|
||||
@@ -86,7 +86,7 @@ private:
|
||||
void fetchNRCapabilitiesFromCache( Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
void dataError( Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
|
||||
qlonglong getMaxAge( const QByteArray &rawHeader ) const;
|
||||
qlonglong getMaxAge( const QByteArray& rawHeader ) const;
|
||||
qlonglong getMaxAge( const qlonglong expires ) const;
|
||||
|
||||
QList< Tomahawk::InfoSystem::InfoStringHash > m_nrSources;
|
||||
|
@@ -68,7 +68,7 @@ RoviPlugin::getInfo( Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
criteria["artist"] = hash["artist"];
|
||||
criteria["album"] = hash["album"];
|
||||
|
||||
emit getCachedInfo( criteria, Q_INT64_C(0), requestData );
|
||||
emit getCachedInfo( criteria, Q_INT64_C( 0 ), requestData );
|
||||
}
|
||||
|
||||
|
||||
@@ -105,7 +105,9 @@ void
|
||||
RoviPlugin::albumLookupError( QNetworkReply::NetworkError error )
|
||||
{
|
||||
if ( error == QNetworkReply::NoError )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QNetworkReply* reply = qobject_cast<QNetworkReply*>( sender() );
|
||||
Q_ASSERT( reply );
|
||||
@@ -124,7 +126,9 @@ RoviPlugin::albumLookupFinished()
|
||||
Q_ASSERT( reply );
|
||||
|
||||
if ( reply->error() != QNetworkReply::NoError )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Tomahawk::InfoSystem::InfoRequestData requestData = reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >();
|
||||
|
||||
@@ -157,11 +161,13 @@ RoviPlugin::albumLookupFinished()
|
||||
|
||||
|
||||
QStringList trackNameList;
|
||||
foreach ( const QVariant& track, tracks )
|
||||
foreach ( const QVariant & track, tracks )
|
||||
{
|
||||
const QVariantMap trackData = track.toMap();
|
||||
if ( trackData.contains( "title" ) )
|
||||
{
|
||||
trackNameList << trackData[ "title" ].toString();
|
||||
}
|
||||
}
|
||||
|
||||
QVariantMap returnedData;
|
||||
@@ -173,7 +179,7 @@ RoviPlugin::albumLookupFinished()
|
||||
criteria["artist"] = requestData.input.value< Tomahawk::InfoSystem::InfoStringHash>()["artist"];
|
||||
criteria["album"] = requestData.input.value< Tomahawk::InfoSystem::InfoStringHash>()["album"];
|
||||
|
||||
emit updateCache( criteria, Q_INT64_C(0), requestData.type, returnedData );
|
||||
emit updateCache( criteria, Q_INT64_C( 0 ), requestData.type, returnedData );
|
||||
}
|
||||
|
||||
|
||||
|
@@ -41,13 +41,13 @@ class INFOPLUGINDLLEXPORT RoviPlugin : public InfoPlugin
|
||||
Q_OBJECT
|
||||
Q_INTERFACES( Tomahawk::InfoSystem::InfoPlugin )
|
||||
|
||||
public:
|
||||
public:
|
||||
RoviPlugin();
|
||||
virtual ~RoviPlugin();
|
||||
|
||||
protected:
|
||||
protected:
|
||||
virtual void init() {}
|
||||
|
||||
|
||||
virtual void notInCacheSlot( Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
|
||||
virtual void pushInfo( Tomahawk::InfoSystem::InfoPushData pushData )
|
||||
@@ -57,10 +57,10 @@ protected:
|
||||
|
||||
virtual void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
|
||||
private slots:
|
||||
private slots:
|
||||
void albumLookupFinished();
|
||||
void albumLookupError( QNetworkReply::NetworkError );
|
||||
private:
|
||||
private:
|
||||
QNetworkReply* makeRequest( QUrl url );
|
||||
QByteArray generateSig() const;
|
||||
|
||||
|
@@ -117,7 +117,7 @@ SpotifyPlugin::fetchChart( Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
criteria["chart_id"] = hash["chart_id"];
|
||||
criteria["chart_source"] = hash["chart_source"];
|
||||
|
||||
emit getCachedInfo( criteria, Q_INT64_C(86400000) /* Expire chart cache in 1 day */, requestData );
|
||||
emit getCachedInfo( criteria, Q_INT64_C( 86400000 ) /* Expire chart cache in 1 day */, requestData );
|
||||
}
|
||||
|
||||
|
||||
@@ -132,7 +132,7 @@ SpotifyPlugin::fetchChartCapabilities( Tomahawk::InfoSystem::InfoRequestData req
|
||||
|
||||
Tomahawk::InfoSystem::InfoStringHash criteria;
|
||||
criteria[ "InfoChartCapabilities" ] = "spotifyplugin";
|
||||
emit getCachedInfo( criteria, Q_INT64_C(604800000), requestData );
|
||||
emit getCachedInfo( criteria, Q_INT64_C( 604800000 ), requestData );
|
||||
}
|
||||
|
||||
|
||||
@@ -159,7 +159,9 @@ SpotifyPlugin::notInCacheSlot( Tomahawk::InfoSystem::InfoStringHash criteria, To
|
||||
|
||||
// we never need to re-fetch
|
||||
if ( !m_allChartsMap.isEmpty() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/// We need to fetch possible types before they are asked for
|
||||
tDebug() << "SpotifyPlugin: InfoChart fetching possible resources";
|
||||
@@ -215,44 +217,48 @@ SpotifyPlugin::chartTypes()
|
||||
QVariantMap charts;
|
||||
foreach( QVariant geos, chartObj.value( "Charts" ).toList().takeLast().toMap().value( "geo" ).toList() )
|
||||
{
|
||||
const QString geo = geos.toMap().value( "name" ).toString();
|
||||
const QString geoId = geos.toMap().value( "id" ).toString();
|
||||
QString country;
|
||||
const QString geo = geos.toMap().value( "name" ).toString();
|
||||
const QString geoId = geos.toMap().value( "id" ).toString();
|
||||
QString country;
|
||||
|
||||
if( geo == "For me" )
|
||||
continue; /// country = geo; Lets use this later, when we can get the spotify username from tomahawk
|
||||
else if( geo == "Everywhere" )
|
||||
country = geo;
|
||||
else
|
||||
{
|
||||
QLocale l( QString( "en_%1" ).arg( geo ) );
|
||||
country = Tomahawk::CountryUtils::fullCountryFromCode( geo );
|
||||
if( geo == "For me" )
|
||||
{
|
||||
continue; /// country = geo; Lets use this later, when we can get the spotify username from tomahawk
|
||||
}
|
||||
else if( geo == "Everywhere" )
|
||||
{
|
||||
country = geo;
|
||||
}
|
||||
else
|
||||
{
|
||||
QLocale l( QString( "en_%1" ).arg( geo ) );
|
||||
country = Tomahawk::CountryUtils::fullCountryFromCode( geo );
|
||||
|
||||
for ( int i = 1; i < country.size(); i++ )
|
||||
{
|
||||
if ( country.at( i ).isUpper() )
|
||||
{
|
||||
country.insert( i, " " );
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
for ( int i = 1; i < country.size(); i++ )
|
||||
{
|
||||
if ( country.at( i ).isUpper() )
|
||||
{
|
||||
country.insert( i, " " );
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QList< InfoStringHash > chart_types;
|
||||
foreach( QVariant types, chartObj.value( "Charts" ).toList().takeFirst().toMap().value( "types" ).toList() )
|
||||
{
|
||||
QString type = types.toMap().value( "id" ).toString();
|
||||
QString label = types.toMap().value( "name" ).toString();
|
||||
QList< InfoStringHash > chart_types;
|
||||
foreach( QVariant types, chartObj.value( "Charts" ).toList().takeFirst().toMap().value( "types" ).toList() )
|
||||
{
|
||||
QString type = types.toMap().value( "id" ).toString();
|
||||
QString label = types.toMap().value( "name" ).toString();
|
||||
|
||||
InfoStringHash c;
|
||||
c[ "id" ] = type + "/" + geoId;
|
||||
c[ "label" ] = label;
|
||||
c[ "type" ] = type;
|
||||
InfoStringHash c;
|
||||
c[ "id" ] = type + "/" + geoId;
|
||||
c[ "label" ] = label;
|
||||
c[ "type" ] = type;
|
||||
|
||||
chart_types.append( c );
|
||||
}
|
||||
chart_types.append( c );
|
||||
}
|
||||
|
||||
charts.insert( country.toUtf8(), QVariant::fromValue<QList< InfoStringHash > >( chart_types ) );
|
||||
charts.insert( country.toUtf8(), QVariant::fromValue<QList< InfoStringHash > >( chart_types ) );
|
||||
}
|
||||
|
||||
QVariantMap defaultMap;
|
||||
@@ -273,7 +279,7 @@ SpotifyPlugin::chartTypes()
|
||||
emit info( request, m_allChartsMap );
|
||||
Tomahawk::InfoSystem::InfoStringHash criteria;
|
||||
criteria[ "InfoChartCapabilities" ] = "spotifyplugin";
|
||||
emit updateCache( criteria, Q_INT64_C(604800000), request.type, m_allChartsMap );
|
||||
emit updateCache( criteria, Q_INT64_C( 604800000 ), request.type, m_allChartsMap );
|
||||
}
|
||||
m_cachedRequests.clear();
|
||||
}
|
||||
@@ -305,13 +311,21 @@ SpotifyPlugin::chartReturned()
|
||||
QStringList top_artists;
|
||||
|
||||
if( url.contains( "albums" ) )
|
||||
{
|
||||
setChartType( Album );
|
||||
}
|
||||
else if( url.contains( "tracks" ) )
|
||||
{
|
||||
setChartType( Track );
|
||||
}
|
||||
else if( url.contains( "artists" ) )
|
||||
{
|
||||
setChartType( Artist );
|
||||
}
|
||||
else
|
||||
{
|
||||
setChartType( None );
|
||||
}
|
||||
|
||||
foreach( QVariant result, res.value( "toplist" ).toMap().value( "result" ).toList() )
|
||||
{
|
||||
@@ -380,10 +394,12 @@ SpotifyPlugin::chartReturned()
|
||||
Tomahawk::InfoSystem::InfoStringHash origData = requestData.input.value< Tomahawk::InfoSystem::InfoStringHash >();
|
||||
criteria[ "chart_id" ] = origData[ "chart_id" ];
|
||||
criteria[ "chart_source" ] = origData[ "chart_source" ];
|
||||
emit updateCache( criteria, Q_INT64_C(86400000), requestData.type, returnedData );
|
||||
emit updateCache( criteria, Q_INT64_C( 86400000 ), requestData.type, returnedData );
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "Network error in fetching chart:" << reply->url().toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@@ -43,25 +43,32 @@ class INFOPLUGINDLLEXPORT SpotifyPlugin : public InfoPlugin
|
||||
Q_OBJECT
|
||||
Q_INTERFACES( Tomahawk::InfoSystem::InfoPlugin )
|
||||
|
||||
public:
|
||||
public:
|
||||
SpotifyPlugin();
|
||||
virtual ~SpotifyPlugin();
|
||||
|
||||
enum ChartType {
|
||||
enum ChartType
|
||||
{
|
||||
None = 0x00,
|
||||
Track = 0x01,
|
||||
Album = 0x02,
|
||||
Artist = 0x04
|
||||
|
||||
};
|
||||
void setChartType( ChartType type ) { m_chartType = type; }
|
||||
ChartType chartType() const { return m_chartType; }
|
||||
void setChartType( ChartType type )
|
||||
{
|
||||
m_chartType = type;
|
||||
}
|
||||
ChartType chartType() const
|
||||
{
|
||||
return m_chartType;
|
||||
}
|
||||
|
||||
public slots:
|
||||
public slots:
|
||||
void chartReturned();
|
||||
void chartTypes();
|
||||
|
||||
protected slots:
|
||||
protected slots:
|
||||
virtual void init() {}
|
||||
virtual void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
virtual void notInCacheSlot( Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
@@ -70,7 +77,7 @@ protected slots:
|
||||
Q_UNUSED( pushData );
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
void fetchChart( Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
void fetchChartCapabilities( Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
void dataError( Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
|
@@ -70,7 +70,7 @@ FdoNotifyPlugin::FdoNotifyPlugin()
|
||||
|
||||
// Query the window manager for its capabilties in styling notifications.
|
||||
notifications_interface = new org::freedesktop::Notifications( "org.freedesktop.Notifications", "/org/freedesktop/Notifications",
|
||||
QDBusConnection::sessionBus(), this );
|
||||
QDBusConnection::sessionBus(), this );
|
||||
QDBusPendingReply<QStringList> reply = notifications_interface->GetCapabilities();
|
||||
|
||||
QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher( reply, this );
|
||||
@@ -106,7 +106,9 @@ FdoNotifyPlugin::pushInfo( Tomahawk::InfoSystem::InfoPushData pushData )
|
||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "showing notification:" << TomahawkSettings::instance()->songChangeNotificationEnabled();
|
||||
|
||||
if ( !TomahawkSettings::instance()->songChangeNotificationEnabled() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QVariant inputData = pushData.infoPair.second;
|
||||
|
||||
@@ -145,7 +147,7 @@ FdoNotifyPlugin::pushInfo( Tomahawk::InfoSystem::InfoPushData pushData )
|
||||
int
|
||||
FdoNotifyPlugin::getNotificationIconHeight()
|
||||
{
|
||||
return 6 * TomahawkUtils::defaultFontHeight();
|
||||
return 6 * TomahawkUtils::defaultFontHeight();
|
||||
}
|
||||
|
||||
|
||||
@@ -172,22 +174,32 @@ void FdoNotifyPlugin::inboxReceived( const QVariant& input )
|
||||
{
|
||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO;
|
||||
if ( !input.canConvert< QVariantMap >() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QVariantMap map = input.toMap();
|
||||
|
||||
if ( !map.contains( "trackinfo" ) || !map[ "trackinfo" ].canConvert< Tomahawk::InfoSystem::InfoStringHash >() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( !map.contains( "sourceinfo" ) || !map[ "sourceinfo" ].canConvert< Tomahawk::InfoSystem::InfoStringHash >() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
InfoStringHash hash = map[ "trackinfo" ].value< Tomahawk::InfoSystem::InfoStringHash >();
|
||||
if ( !hash.contains( "title" ) || !hash.contains( "artist" ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
InfoStringHash src = map[ "sourceinfo" ].value< Tomahawk::InfoSystem::InfoStringHash >();
|
||||
if ( !src.contains( "friendlyname" ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QString messageText;
|
||||
// If the window manager supports notification styling then use it.
|
||||
@@ -195,10 +207,10 @@ void FdoNotifyPlugin::inboxReceived( const QVariant& input )
|
||||
{
|
||||
// Remark: If using xml-based markup in notifications, the supplied strings need to be escaped.
|
||||
messageText = tr( "%1 sent you\n%2%4 %3.", "%1 is a nickname, %2 is a title, %3 is an artist, %4 is the preposition used to link track and artist ('by' in english)" )
|
||||
.arg( Qt::escape( src["friendlyname"] ) )
|
||||
.arg( Qt::escape( hash[ "title" ] ) )
|
||||
.arg( Qt::escape( hash[ "artist" ] ) )
|
||||
.arg( QString( "\n<i>%1</i>" ).arg( tr( "by", "preposition to link track and artist" ) ) );
|
||||
.arg( Qt::escape( src["friendlyname"] ) )
|
||||
.arg( Qt::escape( hash[ "title" ] ) )
|
||||
.arg( Qt::escape( hash[ "artist" ] ) )
|
||||
.arg( QString( "\n<i>%1</i>" ).arg( tr( "by", "preposition to link track and artist" ) ) );
|
||||
|
||||
// Dirty hack(TM) so that KNotify/QLabel recognizes the message as Rich Text
|
||||
messageText = QString( "<i></i>%1" ).arg( messageText );
|
||||
@@ -206,9 +218,9 @@ void FdoNotifyPlugin::inboxReceived( const QVariant& input )
|
||||
else
|
||||
{
|
||||
messageText = tr( "%1 sent you \"%2\" by %3.", "%1 is a nickname, %2 is a title, %3 is an artist" )
|
||||
.arg( src["friendlyname"] )
|
||||
.arg( hash[ "title" ] )
|
||||
.arg( hash[ "artist" ] );
|
||||
.arg( src["friendlyname"] )
|
||||
.arg( hash[ "title" ] )
|
||||
.arg( hash[ "artist" ] );
|
||||
}
|
||||
|
||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "sending message" << messageText;
|
||||
@@ -236,15 +248,21 @@ FdoNotifyPlugin::nowPlaying( const QVariant& input )
|
||||
{
|
||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO;
|
||||
if ( !input.canConvert< QVariantMap >() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QVariantMap map = input.toMap();
|
||||
if ( !map.contains( "trackinfo" ) || !map[ "trackinfo" ].canConvert< Tomahawk::InfoSystem::InfoStringHash >() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
InfoStringHash hash = map[ "trackinfo" ].value< Tomahawk::InfoSystem::InfoStringHash >();
|
||||
if ( !hash.contains( "title" ) || !hash.contains( "artist" ) || !hash.contains( "album" ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QString messageText;
|
||||
// If the window manager supports notification styling then use it.
|
||||
@@ -253,13 +271,15 @@ FdoNotifyPlugin::nowPlaying( const QVariant& input )
|
||||
// Remark: If using xml-based markup in notifications, the supplied strings need to be escaped.
|
||||
QString album;
|
||||
if ( !hash[ "album" ].isEmpty() )
|
||||
{
|
||||
album = QString( "\n<i>%1</i> %2" ).arg( tr( "on", "'on' is followed by an album name" ) ).arg( Qt::escape( hash[ "album" ] ) );
|
||||
}
|
||||
|
||||
messageText = tr( "%1%4 %2%3.", "%1 is a title, %2 is an artist and %3 is replaced by either the previous message or nothing, %4 is the preposition used to link track and artist ('by' in english)" )
|
||||
.arg( Qt::escape( hash[ "title" ] ) )
|
||||
.arg( Qt::escape( hash[ "artist" ] ) )
|
||||
.arg( album )
|
||||
.arg( QString( "\n<i>%1</i>" ).arg( tr( "by", "preposition to link track and artist" ) ) );
|
||||
.arg( Qt::escape( hash[ "title" ] ) )
|
||||
.arg( Qt::escape( hash[ "artist" ] ) )
|
||||
.arg( album )
|
||||
.arg( QString( "\n<i>%1</i>" ).arg( tr( "by", "preposition to link track and artist" ) ) );
|
||||
|
||||
// Dirty hack(TM) so that KNotify/QLabel recognizes the message as Rich Text
|
||||
messageText = QString( "<i></i>%1" ).arg( messageText );
|
||||
@@ -268,12 +288,14 @@ FdoNotifyPlugin::nowPlaying( const QVariant& input )
|
||||
{
|
||||
QString album;
|
||||
if ( !hash[ "album" ].isEmpty() )
|
||||
{
|
||||
album = QString( " %1" ).arg( tr( "on \"%1\"", "%1 is an album name" ).arg( hash[ "album" ] ) );
|
||||
}
|
||||
|
||||
messageText = tr( "\"%1\" by %2%3.", "%1 is a title, %2 is an artist and %3 is replaced by either the previous message or nothing" )
|
||||
.arg( hash[ "title" ] )
|
||||
.arg( hash[ "artist" ] )
|
||||
.arg( album );
|
||||
.arg( hash[ "title" ] )
|
||||
.arg( hash[ "artist" ] )
|
||||
.arg( album );
|
||||
}
|
||||
|
||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "sending message" << messageText;
|
||||
@@ -284,23 +306,27 @@ FdoNotifyPlugin::nowPlaying( const QVariant& input )
|
||||
// If there is a cover availble use it, else use Tomahawk logo as default.
|
||||
QImage image;
|
||||
if ( map.contains( "coveruri" ) && map[ "coveruri" ].canConvert< QString >() )
|
||||
{
|
||||
image = QImage( map[ "coveruri" ].toString(), "PNG" );
|
||||
}
|
||||
else
|
||||
{
|
||||
image = QImage( RESPATH "icons/tomahawk-icon-512x512.png" );
|
||||
}
|
||||
// Convert image to QVariant and scale to a consistent size.
|
||||
hints[ "image_data" ] = ImageConverter::variantForImage( image.scaledToHeight( getNotificationIconHeight() ) );
|
||||
|
||||
|
||||
QDBusPendingReply<> reply = notifications_interface->Notify(
|
||||
"Tomahawk", // app_name
|
||||
m_nowPlayingId, // notification_id
|
||||
"", // app_icon
|
||||
"Tomahawk - Now Playing", // summary
|
||||
messageText, // body
|
||||
QStringList(), // actions
|
||||
hints, // hints
|
||||
-1 // expire_timeout
|
||||
);
|
||||
"Tomahawk", // app_name
|
||||
m_nowPlayingId, // notification_id
|
||||
"", // app_icon
|
||||
"Tomahawk - Now Playing", // summary
|
||||
messageText, // body
|
||||
QStringList(), // actions
|
||||
hints, // hints
|
||||
-1 // expire_timeout
|
||||
);
|
||||
|
||||
QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher( reply, this );
|
||||
connect( watcher, SIGNAL( finished( QDBusPendingCallWatcher* ) ), SLOT( dbusPlayingReplyReceived( QDBusPendingCallWatcher* ) ) );
|
||||
@@ -319,13 +345,15 @@ FdoNotifyPlugin::dbusPlayingReplyReceived( QDBusPendingCallWatcher* watcher )
|
||||
|
||||
if ( reply.type() == QDBusMessage::ErrorMessage )
|
||||
{
|
||||
tLog(LOGVERBOSE) << "Failed to grab media keys" << reply.errorName() << reply.errorMessage();
|
||||
tLog( LOGVERBOSE ) << "Failed to grab media keys" << reply.errorName() << reply.errorMessage();
|
||||
return;
|
||||
}
|
||||
|
||||
const QVariantList& list = reply.arguments();
|
||||
if ( !list.isEmpty() )
|
||||
{
|
||||
m_nowPlayingId = list.first().toInt();
|
||||
}
|
||||
}
|
||||
|
||||
} //ns InfoSystem
|
||||
|
@@ -39,11 +39,11 @@ class INFOPLUGINDLLEXPORT FdoNotifyPlugin : public InfoPlugin
|
||||
Q_OBJECT
|
||||
Q_INTERFACES( Tomahawk::InfoSystem::InfoPlugin )
|
||||
|
||||
public:
|
||||
public:
|
||||
FdoNotifyPlugin();
|
||||
virtual ~FdoNotifyPlugin();
|
||||
|
||||
protected slots:
|
||||
protected slots:
|
||||
virtual void init() {}
|
||||
|
||||
virtual void dbusPlayingReplyReceived( QDBusPendingCallWatcher* watcher );
|
||||
@@ -62,7 +62,7 @@ protected slots:
|
||||
Q_UNUSED( requestData );
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
int getNotificationIconHeight();
|
||||
|
||||
void notifyUser( const QString& messageText );
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
Copyright (C) 2009 by Aurélien Gâteau <aurelien.gateau@canonical.com>
|
||||
Copyright 2010-2012, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
@@ -34,76 +34,78 @@ namespace ImageConverter
|
||||
*/
|
||||
struct SpecImage
|
||||
{
|
||||
int width, height, rowStride;
|
||||
bool hasAlpha;
|
||||
int bitsPerSample, channels;
|
||||
QByteArray data;
|
||||
int width, height, rowStride;
|
||||
bool hasAlpha;
|
||||
int bitsPerSample, channels;
|
||||
QByteArray data;
|
||||
};
|
||||
|
||||
QDBusArgument &operator<<(QDBusArgument &argument, const SpecImage &image)
|
||||
QDBusArgument& operator<<( QDBusArgument& argument, const SpecImage& image )
|
||||
{
|
||||
argument.beginStructure();
|
||||
argument << image.width << image.height << image.rowStride << image.hasAlpha;
|
||||
argument << image.bitsPerSample << image.channels << image.data;
|
||||
argument.endStructure();
|
||||
return argument;
|
||||
argument.beginStructure();
|
||||
argument << image.width << image.height << image.rowStride << image.hasAlpha;
|
||||
argument << image.bitsPerSample << image.channels << image.data;
|
||||
argument.endStructure();
|
||||
return argument;
|
||||
}
|
||||
|
||||
const QDBusArgument &operator>>(const QDBusArgument &argument, SpecImage &image)
|
||||
const QDBusArgument& operator>>( const QDBusArgument& argument, SpecImage& image )
|
||||
{
|
||||
argument.beginStructure();
|
||||
argument >> image.width >> image.height >> image.rowStride >> image.hasAlpha;
|
||||
argument >> image.bitsPerSample >> image.channels >> image.data;
|
||||
argument.endStructure();
|
||||
return argument;
|
||||
argument.beginStructure();
|
||||
argument >> image.width >> image.height >> image.rowStride >> image.hasAlpha;
|
||||
argument >> image.bitsPerSample >> image.channels >> image.data;
|
||||
argument.endStructure();
|
||||
return argument;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// This must be before the QVariant::fromValue below (#211726)
|
||||
Q_DECLARE_METATYPE(ImageConverter::SpecImage)
|
||||
Q_DECLARE_METATYPE( ImageConverter::SpecImage )
|
||||
|
||||
namespace ImageConverter
|
||||
{
|
||||
QVariant variantForImage(const QImage &_image)
|
||||
QVariant variantForImage( const QImage& _image )
|
||||
{
|
||||
qDBusRegisterMetaType<SpecImage>();
|
||||
qDBusRegisterMetaType<SpecImage>();
|
||||
|
||||
QImage image = _image.convertToFormat(QImage::Format_ARGB32);
|
||||
QImage image = _image.convertToFormat( QImage::Format_ARGB32 );
|
||||
|
||||
int rowStride = image.width() * 4;
|
||||
int rowStride = image.width() * 4;
|
||||
|
||||
// Notification spec stores pixels in R,G,B,A order, regardless of
|
||||
// endianess
|
||||
// Qt represents pixels as 32 bit unsigned int. So the order depend on
|
||||
// endianess:
|
||||
// - In big endian the order is A,R,G,B
|
||||
// - In little endian the order is B,G,R,A
|
||||
QByteArray data;
|
||||
data.resize(rowStride * image.height());
|
||||
char* dst = data.data();
|
||||
for (int y=0; y<image.height(); ++y) {
|
||||
QRgb* src = (QRgb*)image.scanLine(y);
|
||||
QRgb* end = src + image.width();
|
||||
for (;src != end; ++src) {
|
||||
// Probably slow, but free of endianess issues
|
||||
*dst++ = qRed(*src);
|
||||
*dst++ = qGreen(*src);
|
||||
*dst++ = qBlue(*src);
|
||||
*dst++ = qAlpha(*src);
|
||||
}
|
||||
}
|
||||
// Notification spec stores pixels in R,G,B,A order, regardless of
|
||||
// endianess
|
||||
// Qt represents pixels as 32 bit unsigned int. So the order depend on
|
||||
// endianess:
|
||||
// - In big endian the order is A,R,G,B
|
||||
// - In little endian the order is B,G,R,A
|
||||
QByteArray data;
|
||||
data.resize( rowStride * image.height() );
|
||||
char* dst = data.data();
|
||||
for ( int y = 0; y < image.height(); ++y )
|
||||
{
|
||||
QRgb* src = ( QRgb* )image.scanLine( y );
|
||||
QRgb* end = src + image.width();
|
||||
for ( ; src != end; ++src )
|
||||
{
|
||||
// Probably slow, but free of endianess issues
|
||||
*dst++ = qRed( *src );
|
||||
*dst++ = qGreen( *src );
|
||||
*dst++ = qBlue( *src );
|
||||
*dst++ = qAlpha( *src );
|
||||
}
|
||||
}
|
||||
|
||||
SpecImage specImage;
|
||||
specImage.width = image.width();
|
||||
specImage.height = image.height();
|
||||
specImage.rowStride = rowStride;
|
||||
specImage.hasAlpha = true;
|
||||
specImage.bitsPerSample = 8;
|
||||
specImage.channels = 4;
|
||||
specImage.data = data;
|
||||
SpecImage specImage;
|
||||
specImage.width = image.width();
|
||||
specImage.height = image.height();
|
||||
specImage.rowStride = rowStride;
|
||||
specImage.hasAlpha = true;
|
||||
specImage.bitsPerSample = 8;
|
||||
specImage.channels = 4;
|
||||
specImage.data = data;
|
||||
|
||||
return QVariant::fromValue(specImage);
|
||||
return QVariant::fromValue( specImage );
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
Copyright (C) 2009 by Aurélien Gâteau <aurelien.gateau@canonical.com>
|
||||
Copyright 2010-2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
@@ -30,7 +30,7 @@ namespace ImageConverter
|
||||
* Returns a variant representing an image using the format describe in the
|
||||
* galago spec
|
||||
*/
|
||||
QVariant variantForImage(const QImage &image);
|
||||
QVariant variantForImage( const QImage& image );
|
||||
|
||||
} // namespace
|
||||
|
||||
|
@@ -75,23 +75,23 @@ MprisPlugin::init()
|
||||
|
||||
// Listen to volume changes
|
||||
connect( AudioEngine::instance(), SIGNAL( volumeChanged( int ) ),
|
||||
SLOT( onVolumeChanged( int ) ) );
|
||||
SLOT( onVolumeChanged( int ) ) );
|
||||
|
||||
// When the playlist changes, signals for several properties are sent
|
||||
connect( AudioEngine::instance(), SIGNAL( playlistChanged( Tomahawk::playlistinterface_ptr ) ),
|
||||
SLOT( onPlaylistChanged( Tomahawk::playlistinterface_ptr ) ) );
|
||||
SLOT( onPlaylistChanged( Tomahawk::playlistinterface_ptr ) ) );
|
||||
|
||||
// When a track is added or removed, CanGoNext updated signal is sent
|
||||
Tomahawk::playlistinterface_ptr playlist = AudioEngine::instance()->playlist();
|
||||
if ( !playlist.isNull() )
|
||||
{
|
||||
connect( playlist.data(), SIGNAL( itemCountChanged( unsigned int ) ),
|
||||
SLOT( onTrackCountChanged( unsigned int ) ) );
|
||||
SLOT( onTrackCountChanged( unsigned int ) ) );
|
||||
}
|
||||
|
||||
// Connect to AudioEngine's seeked signal
|
||||
connect( AudioEngine::instance(), SIGNAL( seeked( qint64 ) ),
|
||||
SLOT( onSeeked( qint64 ) ) );
|
||||
SLOT( onSeeked( qint64 ) ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -205,7 +205,9 @@ MprisPlugin::canSeek() const
|
||||
{
|
||||
Tomahawk::playlistinterface_ptr p = AudioEngine::instance()->playlist();
|
||||
if ( p.isNull() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return p->seekRestrictions() != PlaylistModes::NoSeek;
|
||||
|
||||
}
|
||||
@@ -216,7 +218,9 @@ MprisPlugin::loopStatus() const
|
||||
{
|
||||
Tomahawk::playlistinterface_ptr p = AudioEngine::instance()->playlist();
|
||||
if ( p.isNull() )
|
||||
{
|
||||
return "None";
|
||||
}
|
||||
PlaylistModes::RepeatMode mode = p->repeatMode();
|
||||
switch( mode )
|
||||
{
|
||||
@@ -243,13 +247,21 @@ MprisPlugin::setLoopStatus( const QString& value )
|
||||
{
|
||||
Tomahawk::playlistinterface_ptr p = AudioEngine::instance()->playlist();
|
||||
if ( p.isNull() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( value == "Track" )
|
||||
{
|
||||
p->setRepeatMode( PlaylistModes::RepeatOne );
|
||||
}
|
||||
else if ( value == "Playlist" )
|
||||
{
|
||||
p->setRepeatMode( PlaylistModes::RepeatAll );
|
||||
}
|
||||
else if ( value == "None" )
|
||||
{
|
||||
p->setRepeatMode( PlaylistModes::NoRepeat );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -267,8 +279,8 @@ MprisPlugin::metadata() const
|
||||
Tomahawk::result_ptr track = AudioEngine::instance()->currentTrack();
|
||||
if ( track )
|
||||
{
|
||||
metadataMap.insert( "mpris:trackid", QVariant::fromValue(QDBusObjectPath(QString( "/track/" ) + track->id().replace( "-", "" ))) );
|
||||
metadataMap.insert( "mpris:length", static_cast<qlonglong>(track->track()->duration()) * 1000000 );
|
||||
metadataMap.insert( "mpris:trackid", QVariant::fromValue( QDBusObjectPath( QString( "/track/" ) + track->id().replace( "-", "" ) ) ) );
|
||||
metadataMap.insert( "mpris:length", static_cast<qlonglong>( track->track()->duration() ) * 1000000 );
|
||||
metadataMap.insert( "xesam:album", track->track()->album() );
|
||||
metadataMap.insert( "xesam:artist", QStringList( track->track()->artist() ) );
|
||||
metadataMap.insert( "xesam:title", track->track()->track() );
|
||||
@@ -278,7 +290,9 @@ MprisPlugin::metadata() const
|
||||
{
|
||||
QFile coverFile( m_coverTempFile );
|
||||
if ( coverFile.exists() && coverFile.fileName().contains( track->track()->artist() + "_" + track->track()->album() + "_tomahawk_cover.png" ) )
|
||||
{
|
||||
metadataMap.insert( "mpris:artUrl", QString( QUrl::fromLocalFile( m_coverTempFile ).toEncoded() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -304,7 +318,7 @@ qlonglong
|
||||
MprisPlugin::position() const
|
||||
{
|
||||
// Convert Tomahawk's milliseconds to microseconds
|
||||
return (qlonglong) ( AudioEngine::instance()->currentTime() * 1000 );
|
||||
return ( qlonglong ) ( AudioEngine::instance()->currentTime() * 1000 );
|
||||
}
|
||||
|
||||
|
||||
@@ -327,7 +341,9 @@ MprisPlugin::shuffle() const
|
||||
{
|
||||
Tomahawk::playlistinterface_ptr p = AudioEngine::instance()->playlist();
|
||||
if ( p.isNull() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return p->shuffled();
|
||||
}
|
||||
|
||||
@@ -337,7 +353,9 @@ MprisPlugin::setShuffle( bool value )
|
||||
{
|
||||
Tomahawk::playlistinterface_ptr p = AudioEngine::instance()->playlist();
|
||||
if ( p.isNull() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
return p->setShuffled( value );
|
||||
}
|
||||
|
||||
@@ -345,7 +363,7 @@ MprisPlugin::setShuffle( bool value )
|
||||
double
|
||||
MprisPlugin::volume() const
|
||||
{
|
||||
return static_cast<double>(AudioEngine::instance()->volume()) / 100.0;
|
||||
return static_cast<double>( AudioEngine::instance()->volume() ) / 100.0;
|
||||
}
|
||||
|
||||
|
||||
@@ -402,16 +420,24 @@ void
|
||||
MprisPlugin::Seek( qlonglong Offset )
|
||||
{
|
||||
if ( !canSeek() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
qlonglong seekTime = position() + Offset;
|
||||
if ( seekTime < 0 )
|
||||
{
|
||||
AudioEngine::instance()->seek( 0 );
|
||||
else if ( seekTime > AudioEngine::instance()->currentTrackTotalTime()*1000 )
|
||||
}
|
||||
else if ( seekTime > AudioEngine::instance()->currentTrackTotalTime() * 1000 )
|
||||
{
|
||||
Next();
|
||||
}
|
||||
// seekTime is in microseconds, but we work internally in milliseconds
|
||||
else
|
||||
AudioEngine::instance()->seek( (qint64) ( seekTime / 1000 ) );
|
||||
{
|
||||
AudioEngine::instance()->seek( ( qint64 ) ( seekTime / 1000 ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -420,15 +446,21 @@ void
|
||||
MprisPlugin::SetPosition( const QDBusObjectPath& TrackId, qlonglong Position )
|
||||
{
|
||||
if ( !canSeek() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( TrackId.path() != QString( "/track/" ) + AudioEngine::instance()->currentTrack()->id().replace( "-", "" ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ( Position < 0) || ( Position > AudioEngine::instance()->currentTrackTotalTime()*1000 ) )
|
||||
if ( ( Position < 0 ) || ( Position > AudioEngine::instance()->currentTrackTotalTime() * 1000 ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AudioEngine::instance()->seek( (qint64) (Position / 1000 ) );
|
||||
AudioEngine::instance()->seek( ( qint64 ) ( Position / 1000 ) );
|
||||
|
||||
}
|
||||
|
||||
@@ -449,28 +481,30 @@ MprisPlugin::pushInfo( Tomahawk::InfoSystem::InfoPushData pushData )
|
||||
switch ( pushData.type )
|
||||
{
|
||||
case InfoNowPlaying:
|
||||
isPlayingInfo = true;
|
||||
audioStarted( pushData.infoPair.second );
|
||||
break;
|
||||
isPlayingInfo = true;
|
||||
audioStarted( pushData.infoPair.second );
|
||||
break;
|
||||
case InfoNowPaused:
|
||||
isPlayingInfo = true;
|
||||
audioPaused();
|
||||
break;
|
||||
isPlayingInfo = true;
|
||||
audioPaused();
|
||||
break;
|
||||
case InfoNowResumed:
|
||||
isPlayingInfo = true;
|
||||
audioResumed( pushData.infoPair.second );
|
||||
break;
|
||||
isPlayingInfo = true;
|
||||
audioResumed( pushData.infoPair.second );
|
||||
break;
|
||||
case InfoNowStopped:
|
||||
isPlayingInfo = true;
|
||||
audioStopped();
|
||||
break;
|
||||
isPlayingInfo = true;
|
||||
audioStopped();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( isPlayingInfo )
|
||||
{
|
||||
notifyPropertyChanged( "org.mpris.MediaPlayer2.Player", "PlaybackStatus" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -487,21 +521,29 @@ void
|
||||
MprisPlugin::audioStarted( const QVariant& input )
|
||||
{
|
||||
if ( !input.canConvert< QVariantMap >() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QVariantMap map = input.toMap();
|
||||
|
||||
if ( !map.contains( "trackinfo" ) || !map[ "trackinfo" ].canConvert< Tomahawk::InfoSystem::InfoStringHash >() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
InfoStringHash hash = map[ "trackinfo" ].value< Tomahawk::InfoSystem::InfoStringHash >();
|
||||
if ( !hash.contains( "title" ) || !hash.contains( "artist" ) || !hash.contains( "album" ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_playbackStatus = "Playing";
|
||||
|
||||
if ( map.contains( "coveruri" ) )
|
||||
{
|
||||
m_coverTempFile = map[ "coveruri" ].toString();
|
||||
}
|
||||
|
||||
notifyPropertyChanged( "org.mpris.MediaPlayer2.Player", "Metadata" );
|
||||
}
|
||||
@@ -550,7 +592,7 @@ MprisPlugin::onPlaylistChanged( Tomahawk::playlistinterface_ptr playlist )
|
||||
|
||||
if ( !playlist.isNull() )
|
||||
connect( playlist.data(), SIGNAL( itemCountChanged( unsigned int ) ),
|
||||
SLOT( onTrackCountChanged( unsigned int ) ) );
|
||||
SLOT( onTrackCountChanged( unsigned int ) ) );
|
||||
|
||||
// Notify relevant changes
|
||||
notifyPropertyChanged( "org.mpris.MediaPlayer2.Player", "LoopStatus" );
|
||||
@@ -572,7 +614,7 @@ MprisPlugin::onTrackCountChanged( unsigned int tracks )
|
||||
void
|
||||
MprisPlugin::onSeeked( qint64 ms )
|
||||
{
|
||||
qlonglong us = (qlonglong) ( ms*1000 );
|
||||
qlonglong us = ( qlonglong ) ( ms * 1000 );
|
||||
emit Seeked( us );
|
||||
}
|
||||
|
||||
@@ -581,15 +623,15 @@ void
|
||||
MprisPlugin::notifyPropertyChanged( const QString& interface, const QString& propertyName )
|
||||
{
|
||||
QDBusMessage signal = QDBusMessage::createSignal(
|
||||
"/org/mpris/MediaPlayer2",
|
||||
"org.freedesktop.DBus.Properties",
|
||||
"PropertiesChanged" );
|
||||
"/org/mpris/MediaPlayer2",
|
||||
"org.freedesktop.DBus.Properties",
|
||||
"PropertiesChanged" );
|
||||
signal << interface;
|
||||
QVariantMap changedProps;
|
||||
changedProps.insert(propertyName, property(propertyName.toLatin1()));
|
||||
changedProps.insert( propertyName, property( propertyName.toLatin1() ) );
|
||||
signal << changedProps;
|
||||
signal << QStringList();
|
||||
QDBusConnection::sessionBus().send(signal);
|
||||
QDBusConnection::sessionBus().send( signal );
|
||||
}
|
||||
|
||||
} //ns InfoSystem
|
||||
|
@@ -29,7 +29,7 @@
|
||||
|
||||
// Forward Declarations breaking QSharedPointer
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 5, 0, 0 )
|
||||
#include "PlaylistInterface.h"
|
||||
#include "PlaylistInterface.h"
|
||||
#endif
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ class INFOPLUGINDLLEXPORT MprisPlugin : public InfoPlugin
|
||||
Q_OBJECT
|
||||
Q_INTERFACES( Tomahawk::InfoSystem::InfoPlugin )
|
||||
|
||||
public:
|
||||
public:
|
||||
MprisPlugin();
|
||||
virtual ~MprisPlugin();
|
||||
|
||||
@@ -129,7 +129,7 @@ public:
|
||||
double volume() const;
|
||||
void setVolume( double value );
|
||||
|
||||
public slots:
|
||||
public slots:
|
||||
virtual void notInCacheSlot( const Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
{
|
||||
Q_UNUSED( criteria );
|
||||
@@ -151,7 +151,7 @@ public slots:
|
||||
void SetPosition( const QDBusObjectPath& TrackId, qlonglong Position );
|
||||
void Stop();
|
||||
|
||||
protected slots:
|
||||
protected slots:
|
||||
virtual void init();
|
||||
|
||||
virtual void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
@@ -160,17 +160,17 @@ protected slots:
|
||||
}
|
||||
void pushInfo( Tomahawk::InfoSystem::InfoPushData pushData );
|
||||
|
||||
private slots:
|
||||
private slots:
|
||||
void stateChanged( AudioState newState, AudioState oldState );
|
||||
void onVolumeChanged( int volume );
|
||||
void onPlaylistChanged( Tomahawk::playlistinterface_ptr );
|
||||
void onTrackCountChanged( unsigned int tracks );
|
||||
void onSeeked( qint64 ms );
|
||||
|
||||
signals:
|
||||
signals:
|
||||
void Seeked( qlonglong Position );
|
||||
|
||||
private:
|
||||
private:
|
||||
// Get Info
|
||||
|
||||
// Push Info
|
||||
|
@@ -35,13 +35,13 @@
|
||||
QString adium_beforeStatus;
|
||||
QString adium_afterStatus;
|
||||
|
||||
static void setStatus(const QString &status)
|
||||
static void setStatus( const QString& status )
|
||||
{
|
||||
// The command that updates the status
|
||||
QString scriptqstr;
|
||||
scriptqstr.append(adium_beforeStatus);
|
||||
scriptqstr.append(status);
|
||||
scriptqstr.append(adium_afterStatus);
|
||||
scriptqstr.append( adium_beforeStatus );
|
||||
scriptqstr.append( status );
|
||||
scriptqstr.append( adium_afterStatus );
|
||||
|
||||
const char* scriptstr = scriptqstr.toUtf8();
|
||||
script( scriptstr );
|
||||
@@ -59,21 +59,21 @@ AdiumPlugin::AdiumPlugin()
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
adium_beforeStatus = "if appIsRunning(\"Adium\") then\n";
|
||||
adium_beforeStatus.append("tell application \"Adium\"\n");
|
||||
adium_beforeStatus.append("set the status message of every account to \"");
|
||||
adium_beforeStatus.append( "tell application \"Adium\"\n" );
|
||||
adium_beforeStatus.append( "set the status message of every account to \"" );
|
||||
|
||||
adium_afterStatus.append("\"\nend tell\n");
|
||||
adium_afterStatus.append("end if\n");
|
||||
adium_afterStatus.append("on appIsRunning(appName)\n");
|
||||
adium_afterStatus.append("tell application \"System Events\" to (name of processes) contains appName\n");
|
||||
adium_afterStatus.append("end appIsRunning\n");
|
||||
adium_afterStatus.append( "\"\nend tell\n" );
|
||||
adium_afterStatus.append( "end if\n" );
|
||||
adium_afterStatus.append( "on appIsRunning(appName)\n" );
|
||||
adium_afterStatus.append( "tell application \"System Events\" to (name of processes) contains appName\n" );
|
||||
adium_afterStatus.append( "end appIsRunning\n" );
|
||||
|
||||
m_supportedPushTypes << InfoNowPlaying << InfoNowPaused << InfoNowResumed << InfoNowStopped;
|
||||
|
||||
m_active = TomahawkSettings::instance()->nowPlayingEnabled();
|
||||
|
||||
connect( TomahawkSettings::instance(), SIGNAL( changed() ),
|
||||
SLOT( settingsChanged() ), Qt::QueuedConnection );
|
||||
SLOT( settingsChanged() ), Qt::QueuedConnection );
|
||||
|
||||
m_pauseTimer = new QTimer( this );
|
||||
m_pauseTimer->setSingleShot( true );
|
||||
@@ -86,7 +86,9 @@ AdiumPlugin::~AdiumPlugin()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
if( m_active )
|
||||
setStatus( "" );
|
||||
{
|
||||
setStatus( "" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -111,25 +113,27 @@ AdiumPlugin::pushInfo( Tomahawk::InfoSystem::InfoPushData pushData )
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
if( !m_active )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch ( pushData.type )
|
||||
{
|
||||
case InfoNowPlaying:
|
||||
audioStarted( pushData.infoPair );
|
||||
break;
|
||||
audioStarted( pushData.infoPair );
|
||||
break;
|
||||
case InfoNowPaused:
|
||||
audioPaused();
|
||||
return;
|
||||
audioPaused();
|
||||
return;
|
||||
case InfoNowResumed:
|
||||
audioResumed( pushData.infoPair );
|
||||
break;
|
||||
audioResumed( pushData.infoPair );
|
||||
break;
|
||||
case InfoNowStopped:
|
||||
audioStopped();
|
||||
break;
|
||||
audioStopped();
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
// Stop the pause timer always, unless pausing of course
|
||||
@@ -142,20 +146,28 @@ void
|
||||
AdiumPlugin::audioStarted( const Tomahawk::InfoSystem::PushInfoPair pushInfoPair )
|
||||
{
|
||||
if ( !pushInfoPair.second.canConvert< QVariantMap >() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QVariantMap map = pushInfoPair.second.toMap();
|
||||
|
||||
if ( map.contains( "private" ) && map[ "private" ] == TomahawkSettings::FullyPrivate )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !map.contains( "trackinfo" ) || !map[ "trackinfo" ].canConvert< Tomahawk::InfoSystem::InfoStringHash >() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
InfoStringHash hash = map[ "trackinfo" ].value< Tomahawk::InfoSystem::InfoStringHash >();
|
||||
|
||||
if ( !hash.contains( "title" ) || !hash.contains( "artist" ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_currentTitle = hash["title"];
|
||||
m_currentArtist = hash["artist"];
|
||||
@@ -165,11 +177,13 @@ AdiumPlugin::audioStarted( const Tomahawk::InfoSystem::PushInfoPair pushInfoPair
|
||||
|
||||
QUrl shortUrl = m_currentLongUrl;
|
||||
if ( pushInfoPair.first.contains( "shortUrl" ) )
|
||||
{
|
||||
shortUrl = pushInfoPair.first[ "shortUrl" ].toUrl();
|
||||
}
|
||||
|
||||
QString nowPlaying = "";
|
||||
nowPlaying.append( m_currentArtist );
|
||||
nowPlaying.append(" - ");
|
||||
nowPlaying.append( " - " );
|
||||
nowPlaying.append( m_currentTitle );
|
||||
nowPlaying.replace( "\"", "\\\"" ); // Escape quotes, or Applescript gets confused
|
||||
|
||||
@@ -187,7 +201,7 @@ AdiumPlugin::audioStarted( const Tomahawk::InfoSystem::PushInfoPair pushInfoPair
|
||||
}
|
||||
|
||||
void
|
||||
AdiumPlugin::audioFinished( const QVariant &input )
|
||||
AdiumPlugin::audioFinished( const QVariant& input )
|
||||
{
|
||||
//qDebug() << Q_FUNC_INFO;
|
||||
}
|
||||
|
@@ -31,9 +31,11 @@
|
||||
|
||||
class QTimer;
|
||||
|
||||
namespace Tomahawk {
|
||||
namespace Tomahawk
|
||||
{
|
||||
|
||||
namespace InfoSystem {
|
||||
namespace InfoSystem
|
||||
{
|
||||
|
||||
class INFOPLUGINDLLEXPORT AdiumPlugin : public InfoPlugin
|
||||
{
|
||||
@@ -41,13 +43,13 @@ class INFOPLUGINDLLEXPORT AdiumPlugin : public InfoPlugin
|
||||
Q_OBJECT
|
||||
Q_INTERFACES( Tomahawk::InfoSystem::InfoPlugin )
|
||||
|
||||
public:
|
||||
public:
|
||||
AdiumPlugin();
|
||||
virtual ~AdiumPlugin();
|
||||
|
||||
protected slots:
|
||||
protected slots:
|
||||
virtual void init() {}
|
||||
|
||||
|
||||
virtual void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
{
|
||||
Q_UNUSED( requestData );
|
||||
@@ -55,20 +57,20 @@ protected slots:
|
||||
|
||||
virtual void pushInfo( Tomahawk::InfoSystem::InfoPushData pushData );
|
||||
|
||||
public slots:
|
||||
public slots:
|
||||
virtual void notInCacheSlot( const Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
{
|
||||
Q_UNUSED( criteria );
|
||||
Q_UNUSED( requestData );
|
||||
}
|
||||
|
||||
private slots:
|
||||
private slots:
|
||||
void clearStatus();
|
||||
void settingsChanged();
|
||||
|
||||
private:
|
||||
private:
|
||||
void audioStarted( const Tomahawk::InfoSystem::PushInfoPair pushInfoPair );
|
||||
void audioFinished( const QVariant &input );
|
||||
void audioFinished( const QVariant& input );
|
||||
void audioStopped();
|
||||
void audioPaused();
|
||||
void audioResumed( const Tomahawk::InfoSystem::PushInfoPair pushInfoPair );
|
||||
|
@@ -42,14 +42,14 @@ using namespace Tomahawk;
|
||||
using namespace TomahawkUtils;
|
||||
|
||||
Api_v1::Api_v1( QxtAbstractWebSessionManager* sm, QObject* parent )
|
||||
: QxtWebSlotService(sm, parent)
|
||||
: QxtWebSlotService( sm, parent )
|
||||
, m_api_v1_5( new Api_v1_5( this ) )
|
||||
{
|
||||
}
|
||||
|
||||
Api_v1::~Api_v1()
|
||||
{
|
||||
delete m_api_v1_5;
|
||||
delete m_api_v1_5;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -79,7 +79,9 @@ Api_v1::auth_1( QxtWebRequestEvent* event, QString arg )
|
||||
QString authPage = RESPATH "www/auth.html";
|
||||
QHash< QString, QString > args;
|
||||
if ( urlHasQueryItem( event->url, "receiverurl" ) )
|
||||
{
|
||||
args[ "url" ] = urlQueryItemValue( event->url, "receiverurl" ).toUtf8();
|
||||
}
|
||||
|
||||
args[ "formtoken" ] = formToken;
|
||||
args[ "website" ] = urlQueryItemValue( event->url, "website" ).toUtf8();
|
||||
@@ -105,13 +107,17 @@ Api_v1::auth_2( QxtWebRequestEvent* event, QString arg )
|
||||
QStringList pieces = params.split( '&' );
|
||||
QHash< QString, QString > queryItems;
|
||||
|
||||
foreach ( const QString& part, pieces )
|
||||
foreach ( const QString & part, pieces )
|
||||
{
|
||||
QStringList keyval = part.split( '=' );
|
||||
if ( keyval.size() == 2 )
|
||||
{
|
||||
queryItems.insert( keyval.first(), keyval.last() );
|
||||
}
|
||||
else
|
||||
{
|
||||
tDebug( LOGVERBOSE ) << "Failed parsing url parameters:" << part;
|
||||
}
|
||||
}
|
||||
|
||||
tDebug( LOGVERBOSE ) << "has query items:" << pieces;
|
||||
@@ -159,7 +165,7 @@ Api_v1::auth_2( QxtWebRequestEvent* event, QString arg )
|
||||
}
|
||||
|
||||
DatabaseCommand_AddClientAuth* dbcmd = new DatabaseCommand_AddClientAuth( authtoken, website, name, event->headers.key( "ua" ) );
|
||||
Database::instance()->enqueue( Tomahawk::dbcmd_ptr(dbcmd) );
|
||||
Database::instance()->enqueue( Tomahawk::dbcmd_ptr( dbcmd ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -174,20 +180,30 @@ Api_v1::api( QxtWebRequestEvent* event, const QString& version, const QString& m
|
||||
{
|
||||
tDebug( LOGVERBOSE ) << "HTTP" << event->url.toString();
|
||||
|
||||
if ( version.isEmpty() ) {
|
||||
// We dealing with API 1.0
|
||||
if ( version.isEmpty() )
|
||||
{
|
||||
// We dealing with API 1.0
|
||||
|
||||
const QUrl& url = event->url;
|
||||
if ( urlHasQueryItem( url, "method" ) )
|
||||
{
|
||||
const QString method = urlQueryItemValue( url, "method" );
|
||||
const QUrl& url = event->url;
|
||||
if ( urlHasQueryItem( url, "method" ) )
|
||||
{
|
||||
const QString method = urlQueryItemValue( url, "method" );
|
||||
|
||||
if ( method == "stat" ) return stat( event );
|
||||
if ( method == "resolve" ) return resolve( event );
|
||||
if ( method == "get_results" ) return get_results( event );
|
||||
}
|
||||
if ( method == "stat" )
|
||||
{
|
||||
return stat( event );
|
||||
}
|
||||
if ( method == "resolve" )
|
||||
{
|
||||
return resolve( event );
|
||||
}
|
||||
if ( method == "get_results" )
|
||||
{
|
||||
return get_results( event );
|
||||
}
|
||||
}
|
||||
|
||||
send404( event );
|
||||
send404( event );
|
||||
}
|
||||
else if ( version == "1.5" )
|
||||
{
|
||||
@@ -195,28 +211,28 @@ Api_v1::api( QxtWebRequestEvent* event, const QString& version, const QString& m
|
||||
{
|
||||
if ( !QMetaObject::invokeMethod( m_api_v1_5, method.toLatin1().constData(), Q_ARG( QxtWebRequestEvent*, event ), Q_ARG( QString, arg1 ), Q_ARG( QString, arg2 ), Q_ARG( QString, arg3 ) ) )
|
||||
{
|
||||
apiCallFailed(event, method);
|
||||
apiCallFailed( event, method );
|
||||
}
|
||||
}
|
||||
else if ( !arg2.isEmpty() )
|
||||
{
|
||||
if ( !QMetaObject::invokeMethod( m_api_v1_5, method.toLatin1().constData(), Q_ARG( QxtWebRequestEvent*, event ), Q_ARG( QString, arg1 ), Q_ARG( QString, arg2 ) ) )
|
||||
{
|
||||
apiCallFailed(event, method);
|
||||
apiCallFailed( event, method );
|
||||
}
|
||||
}
|
||||
else if ( !arg1.isEmpty() )
|
||||
{
|
||||
if ( !QMetaObject::invokeMethod( m_api_v1_5, method.toLatin1().constData(), Q_ARG( QxtWebRequestEvent*, event ), Q_ARG( QString, arg1 ) ) )
|
||||
{
|
||||
apiCallFailed(event, method);
|
||||
apiCallFailed( event, method );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !QMetaObject::invokeMethod( m_api_v1_5, method.toLatin1().constData(), Q_ARG( QxtWebRequestEvent*, event ) ) )
|
||||
{
|
||||
apiCallFailed(event, method);
|
||||
apiCallFailed( event, method );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -243,7 +259,7 @@ Api_v1::sid( QxtWebRequestEvent* event, QString unused )
|
||||
}
|
||||
|
||||
boost::function< void ( QSharedPointer< QIODevice >& ) > callback =
|
||||
boost::bind( &Api_v1::processSid, this, event, rp, _1 );
|
||||
boost::bind( &Api_v1::processSid, this, event, rp, _1 );
|
||||
Tomahawk::UrlHandler::getIODeviceForUrl( rp, rp->url(), callback );
|
||||
}
|
||||
|
||||
@@ -262,7 +278,9 @@ Api_v1::processSid( QxtWebRequestEvent* event, Tomahawk::result_ptr& rp, QShared
|
||||
e->streaming = iodev->isSequential();
|
||||
e->contentType = rp->mimetype().toLatin1();
|
||||
if ( rp->size() > 0 )
|
||||
{
|
||||
e->headers.insert( "Content-Length", QString::number( rp->size() ) );
|
||||
}
|
||||
|
||||
postEvent( e );
|
||||
}
|
||||
@@ -281,7 +299,7 @@ Api_v1::send404( QxtWebRequestEvent* event )
|
||||
void
|
||||
Api_v1::sendPlain404( QxtWebRequestEvent* event, const QString& message, const QString& statusmessage )
|
||||
{
|
||||
QxtWebPageEvent * e = new QxtWebPageEvent( event->sessionID, event->requestID, message.toUtf8() );
|
||||
QxtWebPageEvent* e = new QxtWebPageEvent( event->sessionID, event->requestID, message.toUtf8() );
|
||||
e->contentType = "text/plain";
|
||||
e->status = 404;
|
||||
e->statusMessage = statusmessage.toLatin1().constData();
|
||||
@@ -296,14 +314,16 @@ Api_v1::stat( QxtWebRequestEvent* event )
|
||||
m_storedEvent = event;
|
||||
|
||||
if ( !event->content.isNull() )
|
||||
{
|
||||
tDebug( LOGVERBOSE ) << "BODY:" << event->content->readAll();
|
||||
}
|
||||
|
||||
if ( urlHasQueryItem( event->url, "auth" ) )
|
||||
{
|
||||
// check for auth status
|
||||
DatabaseCommand_ClientAuthValid* dbcmd = new DatabaseCommand_ClientAuthValid( urlQueryItemValue( event->url, "auth" ) );
|
||||
connect( dbcmd, SIGNAL( authValid( QString, QString, bool ) ), this, SLOT( statResult( QString, QString, bool ) ) );
|
||||
Database::instance()->enqueue( Tomahawk::dbcmd_ptr(dbcmd) );
|
||||
Database::instance()->enqueue( Tomahawk::dbcmd_ptr( dbcmd ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -320,7 +340,9 @@ Api_v1::statResult( const QString& clientToken, const QString& name, bool valid
|
||||
|
||||
Q_ASSERT( m_storedEvent );
|
||||
if ( !m_storedEvent )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QVariantMap m;
|
||||
m.insert( "name", "playdar" );
|
||||
@@ -337,7 +359,7 @@ void
|
||||
Api_v1::resolve( QxtWebRequestEvent* event )
|
||||
{
|
||||
if ( !urlHasQueryItem( event->url, "artist" ) ||
|
||||
!urlHasQueryItem( event->url, "track" ) )
|
||||
!urlHasQueryItem( event->url, "track" ) )
|
||||
{
|
||||
tDebug( LOGVERBOSE ) << "Malformed HTTP resolve request";
|
||||
return send404( event );
|
||||
@@ -348,7 +370,7 @@ Api_v1::resolve( QxtWebRequestEvent* event )
|
||||
const QString album = urlQueryItemValue( event->url, "album" );
|
||||
|
||||
if ( artist.trimmed().isEmpty() ||
|
||||
track.trimmed().isEmpty() )
|
||||
track.trimmed().isEmpty() )
|
||||
{
|
||||
tDebug( LOGVERBOSE ) << "Malformed HTTP resolve request";
|
||||
return send404( event );
|
||||
@@ -356,9 +378,13 @@ Api_v1::resolve( QxtWebRequestEvent* event )
|
||||
|
||||
QString qid;
|
||||
if ( urlHasQueryItem( event->url, "qid" ) )
|
||||
{
|
||||
qid = urlQueryItemValue( event->url, "qid" );
|
||||
}
|
||||
else
|
||||
{
|
||||
qid = uuid();
|
||||
}
|
||||
|
||||
query_ptr qry = Query::get( artist, track, album, qid, false );
|
||||
if ( qry.isNull() )
|
||||
@@ -392,11 +418,17 @@ Api_v1::staticdata( QxtWebRequestEvent* event, const QString& file )
|
||||
QxtWebPageEvent* e = new QxtWebPageEvent( event->sessionID, event->requestID, data );
|
||||
|
||||
if ( file.endsWith( ".png" ) )
|
||||
{
|
||||
e->contentType = "image/png";
|
||||
}
|
||||
if ( file.endsWith( ".css" ) )
|
||||
{
|
||||
e->contentType = "text/css";
|
||||
}
|
||||
if ( file.endsWith( ".js" ) )
|
||||
{
|
||||
e->contentType = "application/javascript";
|
||||
}
|
||||
|
||||
postEvent( e );
|
||||
}
|
||||
@@ -441,10 +473,12 @@ Api_v1::get_results( QxtWebRequestEvent* event )
|
||||
r.insert( "query", qry->toVariant() );
|
||||
|
||||
QVariantList res;
|
||||
foreach( const result_ptr& rp, qry->results() )
|
||||
foreach( const result_ptr & rp, qry->results() )
|
||||
{
|
||||
if ( rp->isOnline() )
|
||||
{
|
||||
res << rp->toVariant();
|
||||
}
|
||||
}
|
||||
r.insert( "results", res );
|
||||
|
||||
@@ -462,7 +496,7 @@ Api_v1::sendJSON( const QVariantMap& m, QxtWebRequestEvent* event )
|
||||
if ( urlHasQueryItem( event->url, "jsonp" ) && !urlQueryItemValue( event->url, "jsonp" ).isEmpty() )
|
||||
{
|
||||
ctype = "text/javascript; charset=utf-8";
|
||||
body.prepend( QString("%1( ").arg( urlQueryItemValue( event->url, "jsonp" ) ).toLatin1() );
|
||||
body.prepend( QString( "%1( " ).arg( urlQueryItemValue( event->url, "jsonp" ) ).toLatin1() );
|
||||
body.append( " );" );
|
||||
}
|
||||
else
|
||||
@@ -470,7 +504,7 @@ Api_v1::sendJSON( const QVariantMap& m, QxtWebRequestEvent* event )
|
||||
ctype = "appplication/json; charset=utf-8";
|
||||
}
|
||||
|
||||
QxtWebPageEvent * e = new QxtWebPageEvent( event->sessionID, event->requestID, body );
|
||||
QxtWebPageEvent* e = new QxtWebPageEvent( event->sessionID, event->requestID, body );
|
||||
e->contentType = ctype;
|
||||
e->headers.insert( "Content-Length", QString::number( body.length() ) );
|
||||
e->headers.insert( "Access-Control-Allow-Origin", "*" );
|
||||
@@ -485,19 +519,23 @@ void
|
||||
Api_v1::sendWebpageWithArgs( QxtWebRequestEvent* event, const QString& filenameSource, const QHash< QString, QString >& args )
|
||||
{
|
||||
if ( !QFile::exists( filenameSource ) )
|
||||
{
|
||||
qWarning() << "Passed invalid file for html source:" << filenameSource;
|
||||
}
|
||||
|
||||
QFile f( filenameSource );
|
||||
f.open( QIODevice::ReadOnly );
|
||||
QByteArray html = f.readAll();
|
||||
|
||||
foreach( const QString& param, args.keys() )
|
||||
foreach( const QString & param, args.keys() )
|
||||
{
|
||||
html.replace( QString( "<%%1%>" ).arg( param.toUpper() ), args.value( param ).toUtf8() );
|
||||
}
|
||||
// workaround for receiverurl
|
||||
if ( !args.keys().contains( "URL" ) )
|
||||
{
|
||||
html.replace( QString( "<%URL%>" ).toLatin1(), QByteArray() );
|
||||
}
|
||||
|
||||
|
||||
QxtWebPageEvent* e = new QxtWebPageEvent( event->sessionID, event->requestID, html );
|
||||
@@ -522,7 +560,7 @@ Api_v1::apiCallFailed( QxtWebRequestEvent* event, const QString& method )
|
||||
void
|
||||
Api_v1::sendJsonOk( QxtWebRequestEvent* event )
|
||||
{
|
||||
QxtWebPageEvent * e = new QxtWebPageEvent( event->sessionID, event->requestID, "{ \"result\": \"ok\" }" );
|
||||
QxtWebPageEvent* e = new QxtWebPageEvent( event->sessionID, event->requestID, "{ \"result\": \"ok\" }" );
|
||||
e->headers.insert( "Access-Control-Allow-Origin", "*" );
|
||||
e->contentType = "application/json";
|
||||
postEvent( e );
|
||||
@@ -532,7 +570,7 @@ Api_v1::sendJsonOk( QxtWebRequestEvent* event )
|
||||
void
|
||||
Api_v1::sendJsonError( QxtWebRequestEvent* event, const QString& message )
|
||||
{
|
||||
QxtWebPageEvent * e = new QxtWebPageEvent( event->sessionID, event->requestID, QString( "{ \"result\": \"error\", \"error\": \"%1\" }" ).arg( message ).toUtf8().constData() );
|
||||
QxtWebPageEvent* e = new QxtWebPageEvent( event->sessionID, event->requestID, QString( "{ \"result\": \"error\", \"error\": \"%1\" }" ).arg( message ).toUtf8().constData() );
|
||||
e->headers.insert( "Access-Control-Allow-Origin", "*" );
|
||||
e->contentType = "application/json";
|
||||
e->status = 500;
|
||||
|
@@ -43,19 +43,19 @@ class Api_v1_5;
|
||||
|
||||
namespace Tomahawk
|
||||
{
|
||||
class Result;
|
||||
typedef QSharedPointer< Result > result_ptr;
|
||||
class Result;
|
||||
typedef QSharedPointer< Result > result_ptr;
|
||||
}
|
||||
|
||||
class TOMAHAWK_PLAYDARAPI_EXPORT Api_v1 : public QxtWebSlotService
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
public:
|
||||
Api_v1( QxtAbstractWebSessionManager* sm, QObject* parent = 0 );
|
||||
virtual ~Api_v1();
|
||||
|
||||
public slots:
|
||||
public slots:
|
||||
// authenticating uses /auth_1
|
||||
// we redirect to /auth_2 for the callback
|
||||
void auth_1( QxtWebRequestEvent* event, QString unused = QString() );
|
||||
@@ -63,11 +63,11 @@ public slots:
|
||||
|
||||
// all v1 api calls go to /api/
|
||||
void api( QxtWebRequestEvent* event,
|
||||
const QString& version = QString(),
|
||||
const QString& method = QString(),
|
||||
const QString& arg1 = QString(),
|
||||
const QString& arg2 = QString(),
|
||||
const QString& arg3 = QString() );
|
||||
const QString& version = QString(),
|
||||
const QString& method = QString(),
|
||||
const QString& arg1 = QString(),
|
||||
const QString& arg2 = QString(),
|
||||
const QString& arg3 = QString() );
|
||||
|
||||
// request for stream: /sid/<id>
|
||||
void sid( QxtWebRequestEvent* event, QString unused = QString() );
|
||||
@@ -88,11 +88,11 @@ public slots:
|
||||
|
||||
void index( QxtWebRequestEvent* event );
|
||||
|
||||
protected:
|
||||
protected:
|
||||
void apiCallFailed( QxtWebRequestEvent* event, const QString& method );
|
||||
void sendPlain404( QxtWebRequestEvent* event, const QString& message, const QString& statusmessage );
|
||||
|
||||
private:
|
||||
private:
|
||||
void processSid( QxtWebRequestEvent* event, Tomahawk::result_ptr&, QSharedPointer< QIODevice >& );
|
||||
|
||||
QxtWebRequestEvent* m_storedEvent;
|
||||
|
@@ -40,7 +40,7 @@ Api_v1_5::Api_v1_5( Api_v1* parent )
|
||||
void
|
||||
Api_v1_5::ping( QxtWebRequestEvent* event )
|
||||
{
|
||||
QxtWebPageEvent * e = new QxtWebPageEvent( event->sessionID, event->requestID, "pong" );
|
||||
QxtWebPageEvent* e = new QxtWebPageEvent( event->sessionID, event->requestID, "pong" );
|
||||
e->headers.insert( "Access-Control-Allow-Origin", "*" );
|
||||
e->contentType = "text/plain";
|
||||
m_service->postEvent( e );
|
||||
@@ -50,7 +50,7 @@ Api_v1_5::ping( QxtWebRequestEvent* event )
|
||||
void
|
||||
Api_v1_5::playback( QxtWebRequestEvent* event, const QString& command )
|
||||
{
|
||||
if ( command == "next")
|
||||
if ( command == "next" )
|
||||
{
|
||||
JSON_REPLY( QMetaObject::invokeMethod( AudioEngine::instance(), "next", Qt::QueuedConnection ) , "Skipping to the next track failed." );
|
||||
}
|
||||
@@ -110,7 +110,7 @@ Api_v1_5::playback( QxtWebRequestEvent* event, const QString& command )
|
||||
Q_ASSERT( ok );
|
||||
}
|
||||
|
||||
QxtWebPageEvent * e = new QxtWebPageEvent( event->sessionID, event->requestID, json );
|
||||
QxtWebPageEvent* e = new QxtWebPageEvent( event->sessionID, event->requestID, json );
|
||||
e->headers.insert( "Access-Control-Allow-Origin", "*" );
|
||||
e->contentType = "application/json";
|
||||
m_service->postEvent( e );
|
||||
@@ -118,7 +118,7 @@ Api_v1_5::playback( QxtWebRequestEvent* event, const QString& command )
|
||||
else if ( command == "volume" )
|
||||
{
|
||||
QByteArray json = QString( "{ \"result\": \"ok\", \"volume\": %1}" ).arg( AudioEngine::instance()->volume() ).toUtf8();
|
||||
QxtWebPageEvent * e = new QxtWebPageEvent( event->sessionID, event->requestID, json );
|
||||
QxtWebPageEvent* e = new QxtWebPageEvent( event->sessionID, event->requestID, json );
|
||||
e->headers.insert( "Access-Control-Allow-Origin", "*" );
|
||||
e->contentType = "application/json";
|
||||
m_service->postEvent( e );
|
||||
|
@@ -27,12 +27,12 @@ class QxtWebRequestEvent;
|
||||
class Api_v1_5 : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
public:
|
||||
Api_v1_5( Api_v1* parent = 0 );
|
||||
|
||||
signals:
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
public slots:
|
||||
/**
|
||||
* Simple test to check for API 1.5 support.
|
||||
*
|
||||
@@ -45,10 +45,10 @@ public slots:
|
||||
*/
|
||||
void playback( QxtWebRequestEvent* event, const QString& command );
|
||||
|
||||
protected:
|
||||
protected:
|
||||
void jsonReply( QxtWebRequestEvent* event, const char* funcInfo, const QString& errorMessage, bool isError );
|
||||
|
||||
private:
|
||||
private:
|
||||
Api_v1* m_service;
|
||||
};
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
*
|
||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2010-2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
*
|
||||
|
@@ -51,9 +51,13 @@ PlaydarApi::start()
|
||||
if ( d->session.isNull() || d->connector.isNull() )
|
||||
{
|
||||
if ( !d->session.isNull() )
|
||||
{
|
||||
delete d->session.data();
|
||||
}
|
||||
if ( !d->connector.isNull() )
|
||||
{
|
||||
delete d->connector.data();
|
||||
}
|
||||
tLog() << "Failed to start HTTPd, could not create object";
|
||||
return;
|
||||
}
|
||||
|
@@ -29,16 +29,16 @@ class PlaydarApiPrivate;
|
||||
class TOMAHAWK_PLAYDARAPI_EXPORT PlaydarApi : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit PlaydarApi( QHostAddress ha, qint16 port, QObject *parent = 0 );
|
||||
public:
|
||||
explicit PlaydarApi( QHostAddress ha, qint16 port, QObject* parent = 0 );
|
||||
virtual ~PlaydarApi();
|
||||
|
||||
void start();
|
||||
|
||||
protected:
|
||||
|
||||
protected:
|
||||
QScopedPointer<PlaydarApiPrivate> d_ptr;
|
||||
|
||||
private:
|
||||
private:
|
||||
Q_DECLARE_PRIVATE( PlaydarApi )
|
||||
};
|
||||
|
||||
|
@@ -25,7 +25,7 @@
|
||||
|
||||
class PlaydarApiPrivate
|
||||
{
|
||||
public:
|
||||
public:
|
||||
PlaydarApiPrivate( PlaydarApi* q )
|
||||
: q_ptr( q )
|
||||
{
|
||||
@@ -34,7 +34,7 @@ public:
|
||||
PlaydarApi* q_ptr;
|
||||
Q_DECLARE_PUBLIC( PlaydarApi )
|
||||
|
||||
private:
|
||||
private:
|
||||
QScopedPointer< Api_v1 > instance;
|
||||
QScopedPointer< QxtHttpServerConnector > connector;
|
||||
QScopedPointer< QxtHttpSessionManager > session;
|
||||
|
@@ -93,19 +93,27 @@ PlaylistDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option,
|
||||
QRect pixmapRect = option.rect.adjusted( 12, 12, -option.rect.width() + option.rect.height() - 12, -12 );
|
||||
QPixmap avatar = index.data( RecentlyPlayedPlaylistsModel::PlaylistRole ).value< Tomahawk::playlist_ptr >()->author()->avatar( TomahawkUtils::RoundedCorners, pixmapRect.size() );
|
||||
if ( avatar.isNull() )
|
||||
{
|
||||
avatar = TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultSourceAvatar, TomahawkUtils::RoundedCorners, pixmapRect.size() );
|
||||
}
|
||||
painter->drawPixmap( pixmapRect, avatar );
|
||||
|
||||
pixmapRect = QRect( option.rect.width() - option.fontMetrics.height() * 2.5 - 10, option.rect.top() + option.rect.height() / 4, option.fontMetrics.height() * 2.5, option.fontMetrics.height() * 2.5 );
|
||||
QPixmap icon;
|
||||
RecentlyPlayedPlaylistsModel::PlaylistTypes type = (RecentlyPlayedPlaylistsModel::PlaylistTypes)index.data( RecentlyPlayedPlaylistsModel::PlaylistTypeRole ).toInt();
|
||||
RecentlyPlayedPlaylistsModel::PlaylistTypes type = ( RecentlyPlayedPlaylistsModel::PlaylistTypes )index.data( RecentlyPlayedPlaylistsModel::PlaylistTypeRole ).toInt();
|
||||
|
||||
if ( type == RecentlyPlayedPlaylistsModel::StaticPlaylist )
|
||||
{
|
||||
icon = TomahawkUtils::defaultPixmap( TomahawkUtils::Playlist, TomahawkUtils::Original, pixmapRect.size() );
|
||||
}
|
||||
else if ( type == RecentlyPlayedPlaylistsModel::AutoPlaylist )
|
||||
{
|
||||
icon = TomahawkUtils::defaultPixmap( TomahawkUtils::AutomaticPlaylist, TomahawkUtils::Original, pixmapRect.size() );
|
||||
}
|
||||
else if ( type == RecentlyPlayedPlaylistsModel::Station )
|
||||
{
|
||||
icon = TomahawkUtils::defaultPixmap( TomahawkUtils::Station, TomahawkUtils::Original, pixmapRect.size() );
|
||||
}
|
||||
|
||||
painter->drawPixmap( pixmapRect, icon );
|
||||
|
||||
@@ -115,7 +123,7 @@ PlaylistDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option,
|
||||
painter->setFont( figFont );
|
||||
QString tracks = index.data( RecentlyPlayedPlaylistsModel::TrackCountRole ).toString();
|
||||
int width = painter->fontMetrics().width( tracks );
|
||||
// int bottomEdge = pixmapRect
|
||||
// int bottomEdge = pixmapRect
|
||||
// right edge 10px past right edge of pixmapRect
|
||||
// bottom edge flush with bottom of pixmap
|
||||
QRect rect( pixmapRect.right() - width, 0, width - 8, 0 );
|
||||
@@ -134,13 +142,15 @@ PlaylistDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option,
|
||||
painter->setFont( font );
|
||||
QString author = index.data( RecentlyPlayedPlaylistsModel::PlaylistRole ).value< Tomahawk::playlist_ptr >()->author()->friendlyName();
|
||||
if ( author.indexOf( '@' ) > 0 )
|
||||
{
|
||||
author = author.mid( 0, author.indexOf( '@' ) );
|
||||
}
|
||||
|
||||
/* const int w = painter->fontMetrics().width( author ) + 2;
|
||||
QRect avatarNameRect( opt.rect.width() - 10 - w, r.bottom(), w, opt.rect.bottom() - r.bottom() );
|
||||
painter->drawText( avatarNameRect, author, QTextOption( Qt::AlignCenter ) );
|
||||
/* const int w = painter->fontMetrics().width( author ) + 2;
|
||||
QRect avatarNameRect( opt.rect.width() - 10 - w, r.bottom(), w, opt.rect.bottom() - r.bottom() );
|
||||
painter->drawText( avatarNameRect, author, QTextOption( Qt::AlignCenter ) );
|
||||
|
||||
const int leftEdge = opt.rect.width() - qMin( avatarNameRect.left(), r.left() );*/
|
||||
const int leftEdge = opt.rect.width() - qMin( avatarNameRect.left(), r.left() );*/
|
||||
const int leftEdge = opt.rect.width() - pixmapRect.left();
|
||||
QString descText;
|
||||
if ( type == RecentlyPlayedPlaylistsModel::Station )
|
||||
|
@@ -32,12 +32,12 @@ namespace Widgets
|
||||
|
||||
class TOMAHAWK_WIDGETS_EXPORT PlaylistDelegate : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
public:
|
||||
PlaylistDelegate();
|
||||
|
||||
protected:
|
||||
protected:
|
||||
void paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const;
|
||||
QSize sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const;
|
||||
};
|
||||
|
@@ -51,8 +51,12 @@ void
|
||||
PlaylistWidget::verifySize()
|
||||
{
|
||||
if ( !model() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( model()->rowCount() > 0 )
|
||||
{
|
||||
setFixedHeight( model()->rowCount() * itemDelegate()->sizeHint( QStyleOptionViewItem(), model()->index( 0, 0 ) ).height() + frameWidth() * 2 );
|
||||
}
|
||||
}
|
||||
|
@@ -28,28 +28,31 @@
|
||||
|
||||
namespace Tomahawk
|
||||
{
|
||||
|
||||
|
||||
namespace Widgets
|
||||
{
|
||||
|
||||
class TOMAHAWK_WIDGETS_EXPORT PlaylistWidget : public QListView
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
public:
|
||||
PlaylistWidget( QWidget* parent = 0 );
|
||||
|
||||
OverlayWidget* overlay() const { return m_overlay; }
|
||||
OverlayWidget* overlay() const
|
||||
{
|
||||
return m_overlay;
|
||||
}
|
||||
|
||||
virtual void setModel( QAbstractItemModel* model );
|
||||
|
||||
signals:
|
||||
signals:
|
||||
void modelChanged();
|
||||
|
||||
private slots:
|
||||
private slots:
|
||||
void verifySize();
|
||||
|
||||
private:
|
||||
private:
|
||||
OverlayWidget* m_overlay;
|
||||
};
|
||||
|
||||
|
@@ -64,11 +64,11 @@ SocialPlaylistWidget::SocialPlaylistWidget ( QWidget* parent )
|
||||
TomahawkUtils::unmarginLayout( ui->verticalLayout_3->layout() );
|
||||
TomahawkUtils::unmarginLayout( ui->verticalLayout_4->layout() );
|
||||
|
||||
// ui->mostPlayedPlaylists->setItemDelegate( new PlaylistDelegate() );
|
||||
// ui->mostPlayedPlaylists->setModel( model );
|
||||
// ui->mostPlayedPlaylists->overlay()->resize( 380, 86 );
|
||||
// ui->mostPlayedPlaylists->setItemDelegate( new PlaylistDelegate() );
|
||||
// ui->mostPlayedPlaylists->setModel( model );
|
||||
// ui->mostPlayedPlaylists->overlay()->resize( 380, 86 );
|
||||
|
||||
// connect( model, SIGNAL( emptinessChanged( bool) ), this, SLOT( updatePlaylists() ) );
|
||||
// connect( model, SIGNAL( emptinessChanged( bool) ), this, SLOT( updatePlaylists() ) );
|
||||
|
||||
m_topForeignTracksModel = new PlaylistModel( ui->newTracksView );
|
||||
ui->newTracksView->setPlaylistModel( m_topForeignTracksModel );
|
||||
@@ -78,16 +78,16 @@ SocialPlaylistWidget::SocialPlaylistWidget ( QWidget* parent )
|
||||
m_popularNewAlbumsModel = new PlayableModel( ui->newAlbumsView );
|
||||
ui->newAlbumsView->setPlayableModel( m_popularNewAlbumsModel );
|
||||
// TODO run the genericselect command
|
||||
// m_recentAlbumsModel->addFilteredCollection( collection_ptr(), 20, DatabaseCommand_AllAlbums::ModificationTime );
|
||||
/*
|
||||
m_timer = new QTimer( this );
|
||||
connect( m_timer, SIGNAL( timeout() ), SLOT( checkQueries() ) );
|
||||
// m_recentAlbumsModel->addFilteredCollection( collection_ptr(), 20, DatabaseCommand_AllAlbums::ModificationTime );
|
||||
/*
|
||||
m_timer = new QTimer( this );
|
||||
connect( m_timer, SIGNAL( timeout() ), SLOT( checkQueries() ) );
|
||||
|
||||
connect( SourceList::instance(), SIGNAL( ready() ), SLOT( updateRecentTracks() ) );
|
||||
connect( SourceList::instance(), SIGNAL( sourceAdded( Tomahawk::source_ptr ) ), SLOT( onSourceAdded( Tomahawk::source_ptr ) ) );
|
||||
connect( ui->playlistWidget, SIGNAL( activated( QModelIndex ) ), SLOT( onPlaylistActivated( QModelIndex ) ) );
|
||||
connect( AudioEngine::instance() ,SIGNAL( playlistChanged( Tomahawk::playlistinterface_ptr ) ), this, SLOT( updatePlaylists() ), Qt::QueuedConnection );
|
||||
*/
|
||||
connect( SourceList::instance(), SIGNAL( ready() ), SLOT( updateRecentTracks() ) );
|
||||
connect( SourceList::instance(), SIGNAL( sourceAdded( Tomahawk::source_ptr ) ), SLOT( onSourceAdded( Tomahawk::source_ptr ) ) );
|
||||
connect( ui->playlistWidget, SIGNAL( activated( QModelIndex ) ), SLOT( onPlaylistActivated( QModelIndex ) ) );
|
||||
connect( AudioEngine::instance() ,SIGNAL( playlistChanged( Tomahawk::playlistinterface_ptr ) ), this, SLOT( updatePlaylists() ), Qt::QueuedConnection );
|
||||
*/
|
||||
fetchFromDB();
|
||||
}
|
||||
|
||||
@@ -105,9 +105,9 @@ SocialPlaylistWidget::fetchFromDB()
|
||||
connect( albumsCmd.data(), SIGNAL( albums( QList<Tomahawk::album_ptr> ) ), this, SLOT( popularAlbumsFetched( QList<Tomahawk::album_ptr> ) ) );
|
||||
Database::instance()->enqueue( Tomahawk::dbcmd_ptr( albumsCmd ) );
|
||||
|
||||
// QSharedPointer<DatabaseCommand_GenericSelect> plCmd = QSharedPointer<DatabaseCommand_GenericSelect>( new DatabaseCommand_GenericSelect( s_mostPlayedPlaylistsQuery, DatabaseCommand_GenericSelect::, 30, 0 ) );
|
||||
// connect( albumsCmd.data(), SIGNAL( albums( QList<Tomahawk::album_ptr> ) ), this, SLOT( popularAlbumsFetched( QList<Tomahawk::album_ptr> ) ) );
|
||||
// Database::instance()->enqueue( Tomahawk::dbcmd_ptr( albumsCmd ) );
|
||||
// QSharedPointer<DatabaseCommand_GenericSelect> plCmd = QSharedPointer<DatabaseCommand_GenericSelect>( new DatabaseCommand_GenericSelect( s_mostPlayedPlaylistsQuery, DatabaseCommand_GenericSelect::, 30, 0 ) );
|
||||
// connect( albumsCmd.data(), SIGNAL( albums( QList<Tomahawk::album_ptr> ) ), this, SLOT( popularAlbumsFetched( QList<Tomahawk::album_ptr> ) ) );
|
||||
// Database::instance()->enqueue( Tomahawk::dbcmd_ptr( albumsCmd ) );
|
||||
|
||||
QSharedPointer<DatabaseCommand_GenericSelect> trackCmd = QSharedPointer<DatabaseCommand_GenericSelect>( new DatabaseCommand_GenericSelect( s_topForeignTracksQuery, DatabaseCommand_GenericSelect::Track, 50, 0 ) );
|
||||
connect( trackCmd.data(), SIGNAL( tracks( QList<Tomahawk::query_ptr> ) ), this, SLOT( topForeignTracksFetched( QList<Tomahawk::query_ptr> ) ) );
|
||||
|
@@ -56,32 +56,57 @@ class TOMAHAWK_WIDGETS_EXPORT SocialPlaylistWidget : public QWidget, public Toma
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
public:
|
||||
SocialPlaylistWidget( QWidget* parent = 0 );
|
||||
~SocialPlaylistWidget();
|
||||
|
||||
virtual QWidget* widget() { return this; }
|
||||
virtual QWidget* widget()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
virtual Tomahawk::playlistinterface_ptr playlistInterface() const;
|
||||
|
||||
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 jumpToCurrentTrack() { return false; }
|
||||
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 jumpToCurrentTrack()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
signals:
|
||||
signals:
|
||||
void longDescriptionChanged( const QString& description );
|
||||
void descriptionChanged( const QString& description );
|
||||
void pixmapChanged( const QPixmap& pixmap );
|
||||
|
||||
private slots:
|
||||
private slots:
|
||||
void popularAlbumsFetched( QList<Tomahawk::album_ptr> );
|
||||
void topForeignTracksFetched( QList<Tomahawk::query_ptr> );
|
||||
|
||||
private:
|
||||
private:
|
||||
void fetchFromDB();
|
||||
|
||||
Ui_SocialPlaylistWidget *ui;
|
||||
Ui_SocialPlaylistWidget* ui;
|
||||
PlaylistModel* m_topForeignTracksModel;
|
||||
PlayableModel* m_popularNewAlbumsModel;
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
*
|
||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2010-2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
*
|
||||
|
@@ -32,7 +32,7 @@
|
||||
|
||||
// Forward Declarations breaking QSharedPointer
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 5, 0, 0 )
|
||||
#include "Query.h"
|
||||
#include "Query.h"
|
||||
#endif
|
||||
|
||||
|
||||
@@ -55,26 +55,26 @@ ActionCollection::~ActionCollection()
|
||||
{
|
||||
s_instance = 0;
|
||||
foreach( QString key, m_actionCollection.keys() )
|
||||
delete m_actionCollection[ key ];
|
||||
delete m_actionCollection[ key ];
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ActionCollection::initActions()
|
||||
{
|
||||
QAction *latchOn = new QAction( tr( "&Listen Along" ), this );
|
||||
QAction* latchOn = new QAction( tr( "&Listen Along" ), this );
|
||||
latchOn->setIcon( ImageRegistry::instance()->icon( RESPATH "images/headphones.svg" ) );
|
||||
m_actionCollection[ "latchOn" ] = latchOn;
|
||||
QAction *latchOff = new QAction( tr( "Stop &Listening Along" ), this );
|
||||
QAction* latchOff = new QAction( tr( "Stop &Listening Along" ), this );
|
||||
latchOff->setIcon( ImageRegistry::instance()->icon( RESPATH "images/headphones-off.svg" ) );
|
||||
m_actionCollection[ "latchOff" ] = latchOff;
|
||||
|
||||
QAction *realtimeFollowingAlong = new QAction( tr( "&Follow in real-time" ), this );
|
||||
QAction* realtimeFollowingAlong = new QAction( tr( "&Follow in real-time" ), this );
|
||||
realtimeFollowingAlong->setCheckable( true );
|
||||
m_actionCollection[ "realtimeFollowingAlong" ] = realtimeFollowingAlong;
|
||||
|
||||
bool isPublic = TomahawkSettings::instance()->privateListeningMode() == TomahawkSettings::PublicListening;
|
||||
QAction *privacyToggle = new QAction( ( isPublic ? tr( "&Listen Privately" ) : tr( "&Listen Publicly" ) ), this );
|
||||
QAction* privacyToggle = new QAction( ( isPublic ? tr( "&Listen Privately" ) : tr( "&Listen Publicly" ) ), this );
|
||||
privacyToggle->setIcon( ImageRegistry::instance()->icon( RESPATH "images/private-listening.svg" ) );
|
||||
privacyToggle->setIconVisibleInMenu( isPublic );
|
||||
m_actionCollection[ "togglePrivacy" ] = privacyToggle;
|
||||
@@ -102,7 +102,7 @@ ActionCollection::initActions()
|
||||
m_actionCollection[ "quit" ]->setMenuRole( QAction::QuitRole );
|
||||
|
||||
// connect actions to AudioEngine
|
||||
AudioEngine *ae = AudioEngine::instance();
|
||||
AudioEngine* ae = AudioEngine::instance();
|
||||
connect( m_actionCollection[ "playPause" ], SIGNAL( triggered() ), ae, SLOT( playPause() ), Qt::UniqueConnection );
|
||||
connect( m_actionCollection[ "stop" ], SIGNAL( triggered() ), ae, SLOT( stop() ), Qt::UniqueConnection );
|
||||
connect( m_actionCollection[ "previousTrack" ], SIGNAL( triggered() ), ae, SLOT( previous() ), Qt::UniqueConnection );
|
||||
@@ -138,7 +138,7 @@ ActionCollection::initActions()
|
||||
m_actionCollection[ "legalInfo" ]->setMenuRole( QAction::ApplicationSpecificRole );
|
||||
m_actionCollection[ "openLogfile" ] = new QAction( tr( "&View Logfile" ), this );
|
||||
m_actionCollection[ "openLogfile" ]->setMenuRole( QAction::ApplicationSpecificRole );
|
||||
#if defined( Q_OS_MAC ) && defined( HAVE_SPARKLE ) || defined( Q_OS_WIN )
|
||||
#if defined( Q_OS_MAC ) && defined( HAVE_SPARKLE ) || defined( Q_OS_WIN )
|
||||
m_actionCollection[ "checkForUpdates" ] = new QAction( tr( "Check For Updates..." ), this );
|
||||
m_actionCollection[ "checkForUpdates" ]->setMenuRole( QAction::ApplicationSpecificRole );
|
||||
#endif
|
||||
@@ -147,7 +147,7 @@ ActionCollection::initActions()
|
||||
|
||||
|
||||
QMenuBar*
|
||||
ActionCollection::createMenuBar( QWidget *parent )
|
||||
ActionCollection::createMenuBar( QWidget* parent )
|
||||
{
|
||||
QMenuBar* menuBar = new QMenuBar( parent );
|
||||
|
||||
@@ -212,7 +212,7 @@ ActionCollection::createMenuBar( QWidget *parent )
|
||||
|
||||
|
||||
QMenu*
|
||||
ActionCollection::createCompactMenu( QWidget *parent )
|
||||
ActionCollection::createCompactMenu( QWidget* parent )
|
||||
{
|
||||
QMenu* compactMenu = new QMenu( tr( "Main Menu" ), parent );
|
||||
|
||||
@@ -273,7 +273,9 @@ ActionCollection::addAction( ActionCollection::ActionDestination category, QActi
|
||||
m_categoryActions[ category ] = actions;
|
||||
|
||||
if ( notify )
|
||||
{
|
||||
m_actionNotifiers[ action ] = notify;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -321,11 +323,15 @@ ActionCollection::togglePrivateListeningMode()
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO;
|
||||
if ( TomahawkSettings::instance()->privateListeningMode() == TomahawkSettings::PublicListening )
|
||||
{
|
||||
TomahawkSettings::instance()->setPrivateListeningMode( TomahawkSettings::FullyPrivate );
|
||||
}
|
||||
else
|
||||
{
|
||||
TomahawkSettings::instance()->setPrivateListeningMode( TomahawkSettings::PublicListening );
|
||||
}
|
||||
|
||||
QAction *privacyToggle = m_actionCollection[ "togglePrivacy" ];
|
||||
QAction* privacyToggle = m_actionCollection[ "togglePrivacy" ];
|
||||
bool isPublic = TomahawkSettings::instance()->privateListeningMode() == TomahawkSettings::PublicListening;
|
||||
privacyToggle->setText( ( isPublic ? tr( "&Listen Privately" ) : tr( "&Listen Publicly" ) ) );
|
||||
privacyToggle->setIconVisibleInMenu( isPublic );
|
||||
|
@@ -30,16 +30,17 @@ class DLLEXPORT ActionCollection : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
public:
|
||||
// Categories for custom-registered actions
|
||||
enum ActionDestination {
|
||||
// Tracks, TODO
|
||||
enum ActionDestination
|
||||
{
|
||||
// Tracks, TODO
|
||||
LocalPlaylists = 0
|
||||
};
|
||||
|
||||
static ActionCollection* instance();
|
||||
|
||||
ActionCollection( QObject *parent );
|
||||
ActionCollection( QObject* parent );
|
||||
~ActionCollection();
|
||||
|
||||
void initActions();
|
||||
@@ -47,7 +48,7 @@ public:
|
||||
/**
|
||||
* This method returns a main menu bar, suitable for Windows, Mac and X11.
|
||||
*/
|
||||
QMenuBar *createMenuBar( QWidget *parent );
|
||||
QMenuBar* createMenuBar( QWidget* parent );
|
||||
|
||||
/**
|
||||
* Returns a QMenu with all the entries that would normally be in the main menu,
|
||||
@@ -55,7 +56,7 @@ public:
|
||||
* and fairly little sense on Unity and other X11 desktop configurations which pull
|
||||
* out the menu bar from the window.
|
||||
*/
|
||||
QMenu *createCompactMenu( QWidget *parent );
|
||||
QMenu* createCompactMenu( QWidget* parent );
|
||||
|
||||
QAction* getAction( const QString& name );
|
||||
QList< QAction* > getAction( ActionDestination category );
|
||||
@@ -87,13 +88,13 @@ public:
|
||||
void removeAction( QAction* action );
|
||||
void removeAction( QAction* action, ActionDestination category );
|
||||
|
||||
public slots:
|
||||
public slots:
|
||||
void togglePrivateListeningMode();
|
||||
|
||||
signals:
|
||||
signals:
|
||||
void privacyModeChanged();
|
||||
|
||||
private:
|
||||
private:
|
||||
static ActionCollection* s_instance;
|
||||
|
||||
QHash< QString, QAction* > m_actionCollection;
|
||||
|
@@ -63,7 +63,9 @@ album_ptr
|
||||
Album::get( const Tomahawk::artist_ptr& artist, const QString& name, bool autoCreate )
|
||||
{
|
||||
if ( !Database::instance() || !Database::instance()->impl() )
|
||||
{
|
||||
return album_ptr();
|
||||
}
|
||||
|
||||
QMutexLocker lock( &s_nameCacheMutex );
|
||||
const QString key = albumCacheKey( artist, name );
|
||||
@@ -71,7 +73,9 @@ Album::get( const Tomahawk::artist_ptr& artist, const QString& name, bool autoCr
|
||||
{
|
||||
album_wptr album = s_albumsByName.value( key );
|
||||
if ( album )
|
||||
{
|
||||
return album.toStrongRef();
|
||||
}
|
||||
}
|
||||
|
||||
album_ptr album = album_ptr( new Album( name, artist ), &Album::deleteLater );
|
||||
@@ -93,7 +97,9 @@ Album::get( unsigned int id, const QString& name, const Tomahawk::artist_ptr& ar
|
||||
s_idMutex.unlock();
|
||||
|
||||
if ( album )
|
||||
{
|
||||
return album;
|
||||
}
|
||||
}
|
||||
s_idMutex.unlock();
|
||||
|
||||
@@ -103,7 +109,9 @@ Album::get( unsigned int id, const QString& name, const Tomahawk::artist_ptr& ar
|
||||
{
|
||||
album_wptr album = s_albumsByName.value( key );
|
||||
if ( album )
|
||||
{
|
||||
return album;
|
||||
}
|
||||
}
|
||||
|
||||
album_ptr a = album_ptr( new Album( id, name, artist ), &Album::deleteLater );
|
||||
@@ -213,7 +221,9 @@ Album::id() const
|
||||
d->waitingForId = false;
|
||||
|
||||
if ( d->id > 0 )
|
||||
{
|
||||
s_albumsById.insert( d->id, d->ownRef.toStrongRef() );
|
||||
}
|
||||
|
||||
s_idMutex.unlock();
|
||||
}
|
||||
@@ -251,7 +261,9 @@ Album::cover( const QSize& size, bool forceLoad ) const
|
||||
if ( !d->coverLoaded && !d->coverLoading )
|
||||
{
|
||||
if ( !forceLoad )
|
||||
{
|
||||
return QPixmap();
|
||||
}
|
||||
|
||||
Tomahawk::InfoSystem::InfoStringHash trackInfo;
|
||||
trackInfo["artist"] = d->artist->name();
|
||||
@@ -264,12 +276,12 @@ Album::cover( const QSize& size, bool forceLoad ) const
|
||||
requestData.customData = QVariantMap();
|
||||
|
||||
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
|
||||
SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
|
||||
SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) );
|
||||
SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
|
||||
SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) );
|
||||
|
||||
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
|
||||
SIGNAL( finished( QString ) ),
|
||||
SLOT( infoSystemFinished( QString ) ) );
|
||||
SIGNAL( finished( QString ) ),
|
||||
SLOT( infoSystemFinished( QString ) ) );
|
||||
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData );
|
||||
|
||||
@@ -300,9 +312,13 @@ Album::cover( const QSize& size, bool forceLoad ) const
|
||||
}
|
||||
|
||||
if ( d->cover )
|
||||
{
|
||||
return *d->cover;
|
||||
}
|
||||
else
|
||||
{
|
||||
return QPixmap();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -318,7 +334,7 @@ Album::infoSystemInfo( const Tomahawk::InfoSystem::InfoRequestData& requestData,
|
||||
{
|
||||
Q_D( Album );
|
||||
if ( requestData.caller != infoid() ||
|
||||
requestData.type != Tomahawk::InfoSystem::InfoAlbumCoverArt )
|
||||
requestData.type != Tomahawk::InfoSystem::InfoAlbumCoverArt )
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -347,7 +363,9 @@ Album::infoSystemFinished( const QString& target )
|
||||
{
|
||||
Q_D( Album );
|
||||
if ( target != infoid() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
disconnect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
|
||||
this, SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) );
|
||||
@@ -370,7 +388,7 @@ Album::playlistInterface( ModelMode mode, const Tomahawk::collection_ptr& collec
|
||||
{
|
||||
pli = Tomahawk::playlistinterface_ptr( new Tomahawk::AlbumPlaylistInterface( this, mode, collection ) );
|
||||
connect( pli.data(), SIGNAL( tracksLoaded( Tomahawk::ModelMode, Tomahawk::collection_ptr ) ),
|
||||
SLOT( onTracksLoaded( Tomahawk::ModelMode, Tomahawk::collection_ptr ) ) );
|
||||
SLOT( onTracksLoaded( Tomahawk::ModelMode, Tomahawk::collection_ptr ) ) );
|
||||
|
||||
d->playlistInterface[ mode ][ collection ] = pli;
|
||||
}
|
||||
@@ -407,7 +425,9 @@ Album::infoid() const
|
||||
{
|
||||
Q_D( const Album );
|
||||
if ( d->uuid.isEmpty() )
|
||||
{
|
||||
d->uuid = uuid();
|
||||
}
|
||||
|
||||
return d->uuid;
|
||||
}
|
||||
|
@@ -27,7 +27,7 @@
|
||||
|
||||
// Forward Declarations breaking QSharedPointer
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 5, 0, 0 )
|
||||
#include "collection/Collection.h"
|
||||
#include "collection/Collection.h"
|
||||
#endif
|
||||
|
||||
#include "infosystem/InfoSystem.h"
|
||||
@@ -43,9 +43,9 @@ class IdThreadWorker;
|
||||
|
||||
class DLLEXPORT Album : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
public:
|
||||
static album_ptr get( const Tomahawk::artist_ptr& artist, const QString& name, bool autoCreate = false );
|
||||
static album_ptr get( unsigned int id, const QString& name, const Tomahawk::artist_ptr& artist );
|
||||
|
||||
@@ -69,24 +69,24 @@ public:
|
||||
|
||||
void loadId( bool autoCreate );
|
||||
|
||||
public slots:
|
||||
public slots:
|
||||
void deleteLater();
|
||||
|
||||
signals:
|
||||
signals:
|
||||
void tracksAdded( const QList<Tomahawk::query_ptr>& tracks, Tomahawk::ModelMode mode, const Tomahawk::collection_ptr& collection );
|
||||
void updated();
|
||||
void coverChanged();
|
||||
|
||||
protected:
|
||||
protected:
|
||||
QScopedPointer<AlbumPrivate> d_ptr;
|
||||
|
||||
private slots:
|
||||
private slots:
|
||||
void onTracksLoaded( Tomahawk::ModelMode mode, const Tomahawk::collection_ptr& collection );
|
||||
|
||||
void infoSystemInfo( const Tomahawk::InfoSystem::InfoRequestData& requestData, const QVariant& output );
|
||||
void infoSystemFinished( const QString& target );
|
||||
|
||||
private:
|
||||
private:
|
||||
Q_DECLARE_PRIVATE( Album )
|
||||
Q_DISABLE_COPY( Album )
|
||||
QString infoid() const;
|
||||
|
@@ -72,15 +72,21 @@ AlbumPlaylistInterface::siblingIndex( int itemsAway, qint64 rootIndex ) const
|
||||
{
|
||||
qint64 p = m_currentIndex;
|
||||
if ( rootIndex >= 0 )
|
||||
{
|
||||
p = rootIndex;
|
||||
}
|
||||
|
||||
p += itemsAway;
|
||||
|
||||
if ( p < 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( p >= m_queries.count() )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
@@ -100,13 +106,13 @@ AlbumPlaylistInterface::setCurrentTrack( unsigned int albumpos )
|
||||
Q_ASSERT( false );
|
||||
return false;
|
||||
|
||||
/* albumpos--;
|
||||
if ( ( int ) albumpos >= m_queries.count() )
|
||||
return false;
|
||||
/* albumpos--;
|
||||
if ( ( int ) albumpos >= m_queries.count() )
|
||||
return false;
|
||||
|
||||
m_currentTrack = albumpos;
|
||||
m_currentItem = m_queries.at( albumpos )->results().first();
|
||||
return true;*/
|
||||
m_currentTrack = albumpos;
|
||||
m_currentItem = m_queries.at( albumpos )->results().first();
|
||||
return true;*/
|
||||
}
|
||||
|
||||
|
||||
@@ -130,12 +136,12 @@ AlbumPlaylistInterface::tracks() const
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData );
|
||||
|
||||
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
|
||||
SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
|
||||
SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) );
|
||||
SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
|
||||
SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) );
|
||||
|
||||
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
|
||||
SIGNAL( finished( QString ) ),
|
||||
SLOT( infoSystemFinished( QString ) ) );
|
||||
SIGNAL( finished( QString ) ),
|
||||
SLOT( infoSystemFinished( QString ) ) );
|
||||
|
||||
const_cast< int& >( m_lastQueryTimestamp ) = QDateTime::currentMSecsSinceEpoch();
|
||||
}
|
||||
@@ -147,7 +153,7 @@ AlbumPlaylistInterface::tracks() const
|
||||
cmd->setAlbum( m_album->weakRef() );
|
||||
cmd->setSortOrder( DatabaseCommand_AllTracks::AlbumPosition );
|
||||
connect( cmd, SIGNAL( tracks( QList<Tomahawk::query_ptr>, QVariant ) ),
|
||||
SLOT( onTracksLoaded( QList<Tomahawk::query_ptr> ) ) );
|
||||
SLOT( onTracksLoaded( QList<Tomahawk::query_ptr> ) ) );
|
||||
Database::instance()->enqueue( Tomahawk::dbcmd_ptr( cmd ) );
|
||||
}
|
||||
else
|
||||
@@ -172,7 +178,9 @@ void
|
||||
AlbumPlaylistInterface::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output )
|
||||
{
|
||||
if ( requestData.caller != id() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch ( requestData.type )
|
||||
{
|
||||
@@ -193,12 +201,14 @@ AlbumPlaylistInterface::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData re
|
||||
// which should make this easier. --Teo 11/2011
|
||||
unsigned int trackNo = 1;
|
||||
|
||||
foreach ( const QString& trackName, tracks )
|
||||
foreach ( const QString & trackName, tracks )
|
||||
{
|
||||
track_ptr track = Track::get( inputInfo[ "artist" ], trackName, inputInfo[ "album" ], 0, QString(), trackNo++ );
|
||||
query_ptr query = Query::get( track );
|
||||
if ( query )
|
||||
{
|
||||
ql << query;
|
||||
}
|
||||
}
|
||||
Pipeline::instance()->resolve( ql );
|
||||
|
||||
@@ -227,7 +237,9 @@ void
|
||||
AlbumPlaylistInterface::infoSystemFinished( const QString& infoId )
|
||||
{
|
||||
if ( infoId != id() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_infoSystemLoaded = true;
|
||||
disconnect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
|
||||
@@ -243,7 +255,7 @@ AlbumPlaylistInterface::infoSystemFinished( const QString& infoId )
|
||||
cmd->setAlbum( m_album->weakRef() );
|
||||
cmd->setSortOrder( DatabaseCommand_AllTracks::AlbumPosition );
|
||||
connect( cmd, SIGNAL( tracks( QList<Tomahawk::query_ptr>, QVariant ) ),
|
||||
SLOT( onTracksLoaded( QList<Tomahawk::query_ptr> ) ) );
|
||||
SLOT( onTracksLoaded( QList<Tomahawk::query_ptr> ) ) );
|
||||
Database::instance()->enqueue( Tomahawk::dbcmd_ptr( cmd ) );
|
||||
}
|
||||
else
|
||||
@@ -274,7 +286,9 @@ AlbumPlaylistInterface::onTracksLoaded( const QList< query_ptr >& tracks )
|
||||
m_queries << filterTracks( tracks );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_queries << tracks;
|
||||
}
|
||||
|
||||
checkQueries();
|
||||
|
||||
@@ -287,10 +301,12 @@ qint64
|
||||
AlbumPlaylistInterface::indexOfResult( const Tomahawk::result_ptr& result ) const
|
||||
{
|
||||
int i = 0;
|
||||
foreach ( const Tomahawk::query_ptr& query, m_queries )
|
||||
foreach ( const Tomahawk::query_ptr & query, m_queries )
|
||||
{
|
||||
if ( query->numResults() && query->results().contains( result ) )
|
||||
{
|
||||
return i;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
@@ -303,10 +319,12 @@ qint64
|
||||
AlbumPlaylistInterface::indexOfQuery( const Tomahawk::query_ptr& query ) const
|
||||
{
|
||||
int i = 0;
|
||||
foreach ( const Tomahawk::query_ptr& q, m_queries )
|
||||
foreach ( const Tomahawk::query_ptr & q, m_queries )
|
||||
{
|
||||
if ( q->equals( query ) )
|
||||
{
|
||||
return i;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
@@ -332,7 +350,9 @@ AlbumPlaylistInterface::resultAt( qint64 index ) const
|
||||
{
|
||||
Tomahawk::query_ptr query = queryAt( index );
|
||||
if ( query && query->numResults() )
|
||||
{
|
||||
return query->results().first();
|
||||
}
|
||||
|
||||
return Tomahawk::result_ptr();
|
||||
}
|
||||
@@ -341,7 +361,7 @@ AlbumPlaylistInterface::resultAt( qint64 index ) const
|
||||
void
|
||||
AlbumPlaylistInterface::checkQueries()
|
||||
{
|
||||
foreach ( const Tomahawk::query_ptr& query, m_queries )
|
||||
foreach ( const Tomahawk::query_ptr & query, m_queries )
|
||||
{
|
||||
connect( query.data(), SIGNAL( playableStateChanged( bool ) ), SLOT( onItemsChanged() ), Qt::UniqueConnection );
|
||||
}
|
||||
|
@@ -34,15 +34,18 @@ namespace Tomahawk
|
||||
|
||||
class DLLEXPORT AlbumPlaylistInterface : public Tomahawk::PlaylistInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
public:
|
||||
AlbumPlaylistInterface( Tomahawk::Album* album, Tomahawk::ModelMode mode, const Tomahawk::collection_ptr& collection );
|
||||
virtual ~AlbumPlaylistInterface();
|
||||
|
||||
QList<Tomahawk::query_ptr> tracks() const;
|
||||
|
||||
virtual int trackCount() const { return m_queries.count(); }
|
||||
virtual int trackCount() const
|
||||
{
|
||||
return m_queries.count();
|
||||
}
|
||||
|
||||
virtual void setCurrentIndex( qint64 index );
|
||||
virtual qint64 siblingIndex( int itemsAway, qint64 rootIndex = -1 ) const;
|
||||
@@ -54,22 +57,28 @@ public:
|
||||
|
||||
virtual Tomahawk::result_ptr currentItem() const;
|
||||
|
||||
virtual PlaylistModes::RepeatMode repeatMode() const { return PlaylistModes::NoRepeat; }
|
||||
virtual bool shuffled() const { return false; }
|
||||
virtual PlaylistModes::RepeatMode repeatMode() const
|
||||
{
|
||||
return PlaylistModes::NoRepeat;
|
||||
}
|
||||
virtual bool shuffled() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void setRepeatMode( PlaylistModes::RepeatMode ) {}
|
||||
virtual void setShuffled( bool ) {}
|
||||
virtual bool setCurrentTrack( unsigned int albumpos );
|
||||
|
||||
signals:
|
||||
signals:
|
||||
void tracksLoaded( Tomahawk::ModelMode mode, const Tomahawk::collection_ptr& collection );
|
||||
|
||||
private slots:
|
||||
private slots:
|
||||
void onTracksLoaded( const QList< Tomahawk::query_ptr >& tracks );
|
||||
void infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output );
|
||||
void infoSystemFinished( const QString& infoId );
|
||||
|
||||
private:
|
||||
private:
|
||||
void checkQueries();
|
||||
|
||||
QList< Tomahawk::query_ptr > m_queries;
|
||||
|
@@ -29,7 +29,7 @@ namespace Tomahawk
|
||||
|
||||
class AlbumPrivate
|
||||
{
|
||||
public:
|
||||
public:
|
||||
AlbumPrivate( Album* q, unsigned int _id, const QString& _name, const Tomahawk::artist_ptr& _artist )
|
||||
: q_ptr( q )
|
||||
, waitingForId( false )
|
||||
@@ -58,7 +58,7 @@ public:
|
||||
Album* q_ptr;
|
||||
Q_DECLARE_PUBLIC( Album )
|
||||
|
||||
private:
|
||||
private:
|
||||
mutable bool waitingForId;
|
||||
mutable QFuture<unsigned int> idFuture;
|
||||
mutable unsigned int id;
|
||||
|
@@ -62,7 +62,9 @@ artist_ptr
|
||||
Artist::get( const QString& name, bool autoCreate )
|
||||
{
|
||||
if ( name.isEmpty() )
|
||||
{
|
||||
return artist_ptr();
|
||||
}
|
||||
|
||||
QMutexLocker lock( &s_nameCacheMutex );
|
||||
const QString key = name.toLower();
|
||||
@@ -70,11 +72,15 @@ Artist::get( const QString& name, bool autoCreate )
|
||||
{
|
||||
artist_wptr artist = s_artistsByName.value( key );
|
||||
if ( artist )
|
||||
{
|
||||
return artist.toStrongRef();
|
||||
}
|
||||
}
|
||||
|
||||
if ( !Database::instance() || !Database::instance()->impl() )
|
||||
{
|
||||
return artist_ptr();
|
||||
}
|
||||
|
||||
artist_ptr artist = artist_ptr( new Artist( name ), &Artist::deleteLater );
|
||||
artist->setWeakRef( artist.toWeakRef() );
|
||||
@@ -97,7 +103,9 @@ Artist::get( unsigned int id, const QString& name )
|
||||
s_idMutex.unlock();
|
||||
|
||||
if ( !artist.isNull() )
|
||||
{
|
||||
return artist;
|
||||
}
|
||||
}
|
||||
s_idMutex.unlock();
|
||||
|
||||
@@ -107,7 +115,9 @@ Artist::get( unsigned int id, const QString& name )
|
||||
{
|
||||
artist_wptr artist = s_artistsByName.value( key );
|
||||
if ( !artist.isNull() )
|
||||
{
|
||||
return artist;
|
||||
}
|
||||
}
|
||||
|
||||
artist_ptr a = artist_ptr( new Artist( id, name ), &Artist::deleteLater );
|
||||
@@ -217,7 +227,9 @@ Artist::albums( ModelMode mode, const Tomahawk::collection_ptr& collection ) con
|
||||
bool dbLoaded = m_albumsLoaded.value( DatabaseMode );
|
||||
const bool infoLoaded = m_albumsLoaded.value( InfoSystemMode );
|
||||
if ( !collection.isNull() )
|
||||
{
|
||||
dbLoaded = false;
|
||||
}
|
||||
|
||||
if ( ( mode == DatabaseMode || mode == Mixed ) && !dbLoaded )
|
||||
{
|
||||
@@ -227,7 +239,7 @@ Artist::albums( ModelMode mode, const Tomahawk::collection_ptr& collection ) con
|
||||
cmd->setData( QVariant( collection.isNull() ) );
|
||||
|
||||
connect( cmd, SIGNAL( albums( QList<Tomahawk::album_ptr>, QVariant ) ),
|
||||
SLOT( onAlbumsFound( QList<Tomahawk::album_ptr>, QVariant ) ) );
|
||||
SLOT( onAlbumsFound( QList<Tomahawk::album_ptr>, QVariant ) ) );
|
||||
|
||||
Database::instance()->enqueue( Tomahawk::dbcmd_ptr( cmd ) );
|
||||
}
|
||||
@@ -269,7 +281,9 @@ Artist::albums( ModelMode mode, const Tomahawk::collection_ptr& collection ) con
|
||||
}
|
||||
|
||||
if ( !collection.isNull() )
|
||||
{
|
||||
return QList<album_ptr>();
|
||||
}
|
||||
|
||||
switch ( mode )
|
||||
{
|
||||
@@ -300,12 +314,12 @@ Artist::similarArtists() const
|
||||
requestData.requestId = TomahawkUtils::infosystemRequestId();
|
||||
|
||||
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
|
||||
SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
|
||||
SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), Qt::UniqueConnection );
|
||||
SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
|
||||
SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), Qt::UniqueConnection );
|
||||
|
||||
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
|
||||
SIGNAL( finished( QString ) ),
|
||||
SLOT( infoSystemFinished( QString ) ), Qt::UniqueConnection );
|
||||
SIGNAL( finished( QString ) ),
|
||||
SLOT( infoSystemFinished( QString ) ), Qt::UniqueConnection );
|
||||
|
||||
m_infoJobs++;
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData );
|
||||
@@ -341,19 +355,21 @@ Artist::id() const
|
||||
|
||||
if ( waiting )
|
||||
{
|
||||
// qDebug() << Q_FUNC_INFO << "Asked for artist ID and NOT loaded yet" << m_name << m_idFuture.isFinished();
|
||||
// qDebug() << Q_FUNC_INFO << "Asked for artist ID and NOT loaded yet" << m_name << m_idFuture.isFinished();
|
||||
m_idFuture.waitForFinished();
|
||||
// qDebug() << "DONE WAITING:" << m_idFuture.resultCount() << m_idFuture.isResultReadyAt( 0 ) << m_idFuture.isCanceled() << m_idFuture.isFinished() << m_idFuture.isPaused() << m_idFuture.isRunning() << m_idFuture.isStarted();
|
||||
// qDebug() << "DONE WAITING:" << m_idFuture.resultCount() << m_idFuture.isResultReadyAt( 0 ) << m_idFuture.isCanceled() << m_idFuture.isFinished() << m_idFuture.isPaused() << m_idFuture.isRunning() << m_idFuture.isStarted();
|
||||
finalid = m_idFuture.result();
|
||||
|
||||
// qDebug() << Q_FUNC_INFO << "Got loaded artist:" << m_name << finalid;
|
||||
// qDebug() << Q_FUNC_INFO << "Got loaded artist:" << m_name << finalid;
|
||||
|
||||
s_idMutex.lockForWrite();
|
||||
m_id = finalid;
|
||||
m_waitingForFuture = false;
|
||||
|
||||
if ( m_id > 0 )
|
||||
{
|
||||
s_artistsById.insert( m_id, m_ownRef.toStrongRef() );
|
||||
}
|
||||
|
||||
s_idMutex.unlock();
|
||||
}
|
||||
@@ -377,12 +393,12 @@ Artist::biography() const
|
||||
requestData.customData = QVariantMap();
|
||||
|
||||
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
|
||||
SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
|
||||
SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), Qt::UniqueConnection );
|
||||
SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
|
||||
SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), Qt::UniqueConnection );
|
||||
|
||||
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
|
||||
SIGNAL( finished( QString ) ),
|
||||
SLOT( infoSystemFinished( QString ) ), Qt::UniqueConnection );
|
||||
SIGNAL( finished( QString ) ),
|
||||
SLOT( infoSystemFinished( QString ) ), Qt::UniqueConnection );
|
||||
|
||||
m_infoJobs++;
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData );
|
||||
@@ -399,13 +415,13 @@ Artist::loadStats()
|
||||
|
||||
{
|
||||
DatabaseCommand_TrackStats* cmd = new DatabaseCommand_TrackStats( a );
|
||||
Database::instance()->enqueue( Tomahawk::dbcmd_ptr(cmd) );
|
||||
Database::instance()->enqueue( Tomahawk::dbcmd_ptr( cmd ) );
|
||||
}
|
||||
|
||||
{
|
||||
DatabaseCommand_ArtistStats* cmd = new DatabaseCommand_ArtistStats( a );
|
||||
connect( cmd, SIGNAL( done( unsigned int, unsigned int, unsigned int ) ), SLOT( onArtistStatsLoaded( unsigned int, unsigned int, unsigned int ) ) );
|
||||
Database::instance()->enqueue( Tomahawk::dbcmd_ptr(cmd) );
|
||||
Database::instance()->enqueue( Tomahawk::dbcmd_ptr( cmd ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -415,7 +431,7 @@ Artist::playbackHistory( const Tomahawk::source_ptr& source ) const
|
||||
{
|
||||
QList< Tomahawk::PlaybackLog > history;
|
||||
|
||||
foreach ( const PlaybackLog& log, m_playbackHistory )
|
||||
foreach ( const PlaybackLog & log, m_playbackHistory )
|
||||
{
|
||||
if ( source.isNull() || log.source == source )
|
||||
{
|
||||
@@ -445,10 +461,12 @@ Artist::playbackCount( const source_ptr& source ) const
|
||||
QMutexLocker locker( &s_memberMutex );
|
||||
|
||||
unsigned int count = 0;
|
||||
foreach ( const PlaybackLog& log, m_playbackHistory )
|
||||
foreach ( const PlaybackLog & log, m_playbackHistory )
|
||||
{
|
||||
if ( source.isNull() || log.source == source )
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
@@ -486,7 +504,9 @@ void
|
||||
Artist::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output )
|
||||
{
|
||||
if ( requestData.caller != infoid() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QVariantMap returnedData = output.value< QVariantMap >();
|
||||
switch ( requestData.type )
|
||||
@@ -498,7 +518,7 @@ Artist::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVari
|
||||
inputInfo = requestData.input.value< InfoSystem::InfoStringHash >();
|
||||
|
||||
QList< album_ptr > albums;
|
||||
foreach ( const QString& albumName, albumNames )
|
||||
foreach ( const QString & albumName, albumNames )
|
||||
{
|
||||
Tomahawk::album_ptr album = Tomahawk::Album::get( m_ownRef.toStrongRef(), albumName, false );
|
||||
m_officialAlbums << album;
|
||||
@@ -507,7 +527,9 @@ Artist::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVari
|
||||
|
||||
m_albumsLoaded.insert( InfoSystemMode, true );
|
||||
if ( m_officialAlbums.count() )
|
||||
{
|
||||
emit albumsAdded( albums, InfoSystemMode );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -536,7 +558,7 @@ Artist::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVari
|
||||
case InfoSystem::InfoArtistSimilars:
|
||||
{
|
||||
const QStringList artists = returnedData["artists"].toStringList();
|
||||
foreach ( const QString& artist, artists )
|
||||
foreach ( const QString & artist, artists )
|
||||
{
|
||||
m_similarArtists << Artist::get( artist );
|
||||
}
|
||||
@@ -550,10 +572,12 @@ Artist::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVari
|
||||
case InfoSystem::InfoArtistBiography:
|
||||
{
|
||||
QVariantMap bmap = output.toMap();
|
||||
foreach ( const QString& source, bmap.keys() )
|
||||
foreach ( const QString & source, bmap.keys() )
|
||||
{
|
||||
if ( source == "last.fm" )
|
||||
{
|
||||
m_biography = bmap[ source ].toHash()[ "text" ].toString();
|
||||
}
|
||||
}
|
||||
|
||||
m_biographyLoaded = true;
|
||||
@@ -574,7 +598,9 @@ Artist::infoSystemFinished( QString target )
|
||||
Q_UNUSED( target );
|
||||
|
||||
if ( target != infoid() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( --m_infoJobs == 0 )
|
||||
{
|
||||
@@ -598,7 +624,9 @@ Artist::cover( const QSize& size, bool forceLoad ) const
|
||||
if ( !m_coverLoaded && !m_coverLoading )
|
||||
{
|
||||
if ( !forceLoad )
|
||||
{
|
||||
return QPixmap();
|
||||
}
|
||||
|
||||
Tomahawk::InfoSystem::InfoStringHash trackInfo;
|
||||
trackInfo["artist"] = name();
|
||||
@@ -610,12 +638,12 @@ Artist::cover( const QSize& size, bool forceLoad ) const
|
||||
requestData.customData = QVariantMap();
|
||||
|
||||
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
|
||||
SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
|
||||
SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), Qt::UniqueConnection );
|
||||
SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
|
||||
SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), Qt::UniqueConnection );
|
||||
|
||||
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
|
||||
SIGNAL( finished( QString ) ),
|
||||
SLOT( infoSystemFinished( QString ) ), Qt::UniqueConnection );
|
||||
SIGNAL( finished( QString ) ),
|
||||
SLOT( infoSystemFinished( QString ) ), Qt::UniqueConnection );
|
||||
|
||||
m_infoJobs++;
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData );
|
||||
@@ -647,9 +675,13 @@ Artist::cover( const QSize& size, bool forceLoad ) const
|
||||
}
|
||||
|
||||
if ( m_cover )
|
||||
{
|
||||
return *m_cover;
|
||||
}
|
||||
else
|
||||
{
|
||||
return QPixmap();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -663,7 +695,7 @@ Artist::playlistInterface( ModelMode mode, const Tomahawk::collection_ptr& colle
|
||||
{
|
||||
pli = Tomahawk::playlistinterface_ptr( new Tomahawk::ArtistPlaylistInterface( this, mode, collection ) );
|
||||
connect( pli.data(), SIGNAL( tracksLoaded( Tomahawk::ModelMode, Tomahawk::collection_ptr ) ),
|
||||
SLOT( onTracksLoaded( Tomahawk::ModelMode, Tomahawk::collection_ptr ) ) );
|
||||
SLOT( onTracksLoaded( Tomahawk::ModelMode, Tomahawk::collection_ptr ) ) );
|
||||
|
||||
m_playlistInterface[ mode ][ collection ] = pli;
|
||||
}
|
||||
@@ -683,7 +715,9 @@ QString
|
||||
Artist::infoid() const
|
||||
{
|
||||
if ( m_uuid.isEmpty() )
|
||||
{
|
||||
m_uuid = uuid();
|
||||
}
|
||||
|
||||
return m_uuid;
|
||||
}
|
||||
|
@@ -22,7 +22,7 @@
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#ifndef ENABLE_HEADLESS
|
||||
#include <QtGui/QPixmap>
|
||||
#include <QtGui/QPixmap>
|
||||
#endif
|
||||
|
||||
#include <QFuture>
|
||||
@@ -39,9 +39,9 @@ class IdThreadWorker;
|
||||
|
||||
class DLLEXPORT Artist : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
public:
|
||||
static artist_ptr get( const QString& name, bool autoCreate = false );
|
||||
static artist_ptr get( unsigned int id, const QString& name );
|
||||
|
||||
@@ -50,8 +50,14 @@ public:
|
||||
virtual ~Artist();
|
||||
|
||||
unsigned int id() const;
|
||||
QString name() const { return m_name; }
|
||||
QString sortname() const { return m_sortname; }
|
||||
QString name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
QString sortname() const
|
||||
{
|
||||
return m_sortname;
|
||||
}
|
||||
|
||||
QList<album_ptr> albums( ModelMode mode = Mixed, const Tomahawk::collection_ptr& collection = Tomahawk::collection_ptr() ) const;
|
||||
QList<artist_ptr> similarArtists() const;
|
||||
@@ -72,19 +78,28 @@ public:
|
||||
#ifndef ENABLE_HEADLESS
|
||||
QPixmap cover( const QSize& size, bool forceLoad = true ) const;
|
||||
#endif
|
||||
bool coverLoaded() const { return m_coverLoaded; }
|
||||
bool coverLoaded() const
|
||||
{
|
||||
return m_coverLoaded;
|
||||
}
|
||||
|
||||
Tomahawk::playlistinterface_ptr playlistInterface();
|
||||
|
||||
QWeakPointer< Tomahawk::Artist > weakRef() { return m_ownRef; }
|
||||
void setWeakRef( QWeakPointer< Tomahawk::Artist > weakRef ) { m_ownRef = weakRef; }
|
||||
QWeakPointer< Tomahawk::Artist > weakRef()
|
||||
{
|
||||
return m_ownRef;
|
||||
}
|
||||
void setWeakRef( QWeakPointer< Tomahawk::Artist > weakRef )
|
||||
{
|
||||
m_ownRef = weakRef;
|
||||
}
|
||||
|
||||
void loadId( bool autoCreate );
|
||||
|
||||
public slots:
|
||||
public slots:
|
||||
void deleteLater();
|
||||
|
||||
signals:
|
||||
signals:
|
||||
void tracksAdded( const QList<Tomahawk::query_ptr>& tracks, Tomahawk::ModelMode mode, const Tomahawk::collection_ptr& collection );
|
||||
void albumsAdded( const QList<Tomahawk::album_ptr>& albums, Tomahawk::ModelMode mode );
|
||||
|
||||
@@ -94,7 +109,7 @@ signals:
|
||||
void biographyLoaded();
|
||||
void statsLoaded();
|
||||
|
||||
private slots:
|
||||
private slots:
|
||||
void onArtistStatsLoaded( unsigned int plays, unsigned int chartPos, unsigned int chartCount );
|
||||
void onTracksLoaded( Tomahawk::ModelMode mode, const Tomahawk::collection_ptr& collection );
|
||||
void onAlbumsFound( const QList<Tomahawk::album_ptr>& albums, const QVariant& collectionIsNull = QVariant( false ) );
|
||||
@@ -102,7 +117,7 @@ private slots:
|
||||
void infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output );
|
||||
void infoSystemFinished( QString target );
|
||||
|
||||
private:
|
||||
private:
|
||||
Artist();
|
||||
QString infoid() const;
|
||||
|
||||
|
@@ -64,15 +64,21 @@ ArtistPlaylistInterface::siblingIndex( int itemsAway, qint64 rootIndex ) const
|
||||
{
|
||||
qint64 p = m_currentIndex;
|
||||
if ( rootIndex >= 0 )
|
||||
{
|
||||
p = rootIndex;
|
||||
}
|
||||
|
||||
p += itemsAway;
|
||||
|
||||
if ( p < 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( p >= m_queries.count() )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
@@ -104,12 +110,12 @@ ArtistPlaylistInterface::tracks() const
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData );
|
||||
|
||||
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
|
||||
SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
|
||||
SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) );
|
||||
SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
|
||||
SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) );
|
||||
|
||||
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
|
||||
SIGNAL( finished( QString ) ),
|
||||
SLOT( infoSystemFinished( QString ) ) );
|
||||
SIGNAL( finished( QString ) ),
|
||||
SLOT( infoSystemFinished( QString ) ) );
|
||||
}
|
||||
else if ( m_mode == DatabaseMode && !m_databaseLoaded )
|
||||
{
|
||||
@@ -118,7 +124,7 @@ ArtistPlaylistInterface::tracks() const
|
||||
cmd->setSortOrder( DatabaseCommand_AllTracks::AlbumPosition );
|
||||
|
||||
connect( cmd, SIGNAL( tracks( QList<Tomahawk::query_ptr>, QVariant ) ),
|
||||
SLOT( onTracksLoaded( QList<Tomahawk::query_ptr> ) ) );
|
||||
SLOT( onTracksLoaded( QList<Tomahawk::query_ptr> ) ) );
|
||||
|
||||
Database::instance()->enqueue( Tomahawk::dbcmd_ptr( cmd ) );
|
||||
}
|
||||
@@ -132,7 +138,9 @@ void
|
||||
ArtistPlaylistInterface::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output )
|
||||
{
|
||||
if ( requestData.caller != id() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch ( requestData.type )
|
||||
{
|
||||
@@ -153,12 +161,14 @@ ArtistPlaylistInterface::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData r
|
||||
// which should make this easier. --Teo 11/2011
|
||||
unsigned int trackNo = 1;
|
||||
|
||||
foreach ( const QString& trackName, tracks )
|
||||
foreach ( const QString & trackName, tracks )
|
||||
{
|
||||
track_ptr track = Track::get( inputInfo[ "artist" ], trackName, inputInfo[ "album" ], 0, QString(), trackNo++ );
|
||||
query_ptr query = Query::get( track );
|
||||
if ( query )
|
||||
{
|
||||
ql << query;
|
||||
}
|
||||
}
|
||||
|
||||
m_queries << ql;
|
||||
@@ -176,22 +186,26 @@ ArtistPlaylistInterface::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData r
|
||||
}
|
||||
|
||||
if ( !m_queries.isEmpty() )
|
||||
{
|
||||
infoSystemFinished( id() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ArtistPlaylistInterface::infoSystemFinished( const QString &infoId )
|
||||
ArtistPlaylistInterface::infoSystemFinished( const QString& infoId )
|
||||
{
|
||||
if ( infoId != id() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_infoSystemLoaded = true;
|
||||
|
||||
disconnect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
|
||||
this, SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) );
|
||||
disconnect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( finished( QString ) ),
|
||||
this, SLOT( infoSystemFinished( QString) ) );
|
||||
this, SLOT( infoSystemFinished( QString ) ) );
|
||||
|
||||
if ( m_queries.isEmpty() && m_mode == Mixed )
|
||||
{
|
||||
@@ -201,7 +215,7 @@ ArtistPlaylistInterface::infoSystemFinished( const QString &infoId )
|
||||
cmd->setSortOrder( DatabaseCommand_AllTracks::AlbumPosition );
|
||||
|
||||
connect( cmd, SIGNAL( tracks( QList<Tomahawk::query_ptr>, QVariant ) ),
|
||||
SLOT( onTracksLoaded( QList<Tomahawk::query_ptr> ) ) );
|
||||
SLOT( onTracksLoaded( QList<Tomahawk::query_ptr> ) ) );
|
||||
|
||||
Database::instance()->enqueue( Tomahawk::dbcmd_ptr( cmd ) );
|
||||
}
|
||||
@@ -222,7 +236,9 @@ ArtistPlaylistInterface::onTracksLoaded( const QList< query_ptr >& tracks )
|
||||
m_queries << filterTracks( tracks );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_queries << tracks;
|
||||
}
|
||||
|
||||
checkQueries();
|
||||
|
||||
@@ -235,10 +251,12 @@ qint64
|
||||
ArtistPlaylistInterface::indexOfResult( const Tomahawk::result_ptr& result ) const
|
||||
{
|
||||
int i = 0;
|
||||
foreach ( const Tomahawk::query_ptr& query, m_queries )
|
||||
foreach ( const Tomahawk::query_ptr & query, m_queries )
|
||||
{
|
||||
if ( query->numResults() && query->results().contains( result ) )
|
||||
{
|
||||
return i;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
@@ -251,10 +269,12 @@ qint64
|
||||
ArtistPlaylistInterface::indexOfQuery( const Tomahawk::query_ptr& query ) const
|
||||
{
|
||||
int i = 0;
|
||||
foreach ( const Tomahawk::query_ptr& q, m_queries )
|
||||
foreach ( const Tomahawk::query_ptr & q, m_queries )
|
||||
{
|
||||
if ( q->equals( query ) )
|
||||
{
|
||||
return i;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
@@ -280,7 +300,9 @@ ArtistPlaylistInterface::resultAt( qint64 index ) const
|
||||
{
|
||||
Tomahawk::query_ptr query = queryAt( index );
|
||||
if ( query && query->numResults() )
|
||||
{
|
||||
return query->results().first();
|
||||
}
|
||||
|
||||
return Tomahawk::result_ptr();
|
||||
}
|
||||
@@ -289,7 +311,7 @@ ArtistPlaylistInterface::resultAt( qint64 index ) const
|
||||
void
|
||||
ArtistPlaylistInterface::checkQueries()
|
||||
{
|
||||
foreach ( const Tomahawk::query_ptr& query, m_queries )
|
||||
foreach ( const Tomahawk::query_ptr & query, m_queries )
|
||||
{
|
||||
connect( query.data(), SIGNAL( playableStateChanged( bool ) ), SLOT( onItemsChanged() ), Qt::UniqueConnection );
|
||||
}
|
||||
|
@@ -33,15 +33,18 @@ namespace Tomahawk
|
||||
|
||||
class DLLEXPORT ArtistPlaylistInterface : public Tomahawk::PlaylistInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
public:
|
||||
ArtistPlaylistInterface( Tomahawk::Artist* artist, Tomahawk::ModelMode mode, const Tomahawk::collection_ptr& collection );
|
||||
virtual ~ArtistPlaylistInterface();
|
||||
|
||||
virtual QList<Tomahawk::query_ptr> tracks() const;
|
||||
|
||||
virtual int trackCount() const { return m_queries.count(); }
|
||||
virtual int trackCount() const
|
||||
{
|
||||
return m_queries.count();
|
||||
}
|
||||
|
||||
virtual void setCurrentIndex( qint64 index );
|
||||
virtual qint64 siblingIndex( int itemsAway, qint64 rootIndex = -1 ) const;
|
||||
@@ -52,21 +55,27 @@ public:
|
||||
|
||||
virtual Tomahawk::result_ptr currentItem() const;
|
||||
|
||||
virtual PlaylistModes::RepeatMode repeatMode() const { return PlaylistModes::NoRepeat; }
|
||||
virtual bool shuffled() const { return false; }
|
||||
virtual PlaylistModes::RepeatMode repeatMode() const
|
||||
{
|
||||
return PlaylistModes::NoRepeat;
|
||||
}
|
||||
virtual bool shuffled() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void setRepeatMode( PlaylistModes::RepeatMode ) {}
|
||||
virtual void setShuffled( bool ) {}
|
||||
|
||||
signals:
|
||||
signals:
|
||||
void tracksLoaded( Tomahawk::ModelMode mode, const Tomahawk::collection_ptr& collection );
|
||||
|
||||
private slots:
|
||||
private slots:
|
||||
void onTracksLoaded( const QList< Tomahawk::query_ptr >& tracks );
|
||||
void infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output );
|
||||
void infoSystemFinished( const QString& infoId );
|
||||
|
||||
private:
|
||||
private:
|
||||
Q_DISABLE_COPY( ArtistPlaylistInterface )
|
||||
|
||||
void checkQueries();
|
||||
|
@@ -52,7 +52,9 @@ bool
|
||||
resolverSort( const Attica::Content& first, const Attica::Content& second )
|
||||
{
|
||||
if ( !first.attribute( "typeid" ).isEmpty() && second.attribute( "typeid" ).isEmpty() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return first.downloads() > second.downloads();
|
||||
}
|
||||
@@ -66,14 +68,14 @@ AtticaManager::AtticaManager( QObject* parent )
|
||||
connect( &m_manager, SIGNAL( providerAdded( Attica::Provider ) ), this, SLOT( providerAdded( Attica::Provider ) ) );
|
||||
|
||||
// resolvers
|
||||
// m_manager.addProviderFile( QUrl( "http://bakery.tomahawk-player.org/resolvers/providers.xml" ) );
|
||||
// m_manager.addProviderFile( QUrl( "http://bakery.tomahawk-player.org/resolvers/providers.xml" ) );
|
||||
|
||||
const QString url = QString( "%1/resolvers/providers.xml?version=%2" ).arg( hostname() ).arg( TomahawkUtils::appFriendlyVersion() );
|
||||
QNetworkReply* reply = Tomahawk::Utils::nam()->get( QNetworkRequest( QUrl( url ) ) );
|
||||
NewClosure( reply, SIGNAL( finished() ), this, SLOT( providerFetched( QNetworkReply* ) ), reply );
|
||||
connect( reply, SIGNAL( error( QNetworkReply::NetworkError ) ), this, SLOT( providerError( QNetworkReply::NetworkError ) ) );
|
||||
|
||||
// m_manager.addProviderFile( QUrl( "http://lycophron/resolvers/providers.xml" ) );
|
||||
// m_manager.addProviderFile( QUrl( "http://lycophron/resolvers/providers.xml" ) );
|
||||
|
||||
qRegisterMetaType< Attica::Content >( "Attica::Content" );
|
||||
}
|
||||
@@ -84,10 +86,12 @@ AtticaManager::~AtticaManager()
|
||||
savePixmapsToCache();
|
||||
|
||||
|
||||
foreach( const QString& id, m_resolverStates.keys() )
|
||||
foreach( const QString & id, m_resolverStates.keys() )
|
||||
{
|
||||
if ( !m_resolverStates[ id ].pixmap )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
delete m_resolverStates[ id ].pixmap;
|
||||
}
|
||||
@@ -100,7 +104,9 @@ AtticaManager::fetchMissingIcons()
|
||||
foreach ( Content resolver, m_resolvers )
|
||||
{
|
||||
if ( !m_resolverStates.contains( resolver.id() ) )
|
||||
{
|
||||
m_resolverStates.insert( resolver.id(), Resolver() );
|
||||
}
|
||||
|
||||
if ( !m_resolverStates.value( resolver.id() ).pixmap && !resolver.icons().isEmpty() && !resolver.icons().first().url().isEmpty() )
|
||||
{
|
||||
@@ -124,11 +130,13 @@ AtticaManager::loadPixmapsFromCache()
|
||||
{
|
||||
QDir cacheDir = TomahawkUtils::appDataDir();
|
||||
if ( !cacheDir.cd( "atticacache" ) ) // doesn't exist, no cache
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "Loading resolvers from cache dir:" << cacheDir.absolutePath();
|
||||
qDebug() << "Currently we know about these resolvers:" << m_resolverStates.keys();
|
||||
foreach ( const QString& file, cacheDir.entryList( QStringList() << "*.png", QDir::Files | QDir::NoSymLinks ) )
|
||||
foreach ( const QString & file, cacheDir.entryList( QStringList() << "*.png", QDir::Files | QDir::NoSymLinks ) )
|
||||
{
|
||||
// load all the pixmaps
|
||||
QFileInfo info( file );
|
||||
@@ -157,10 +165,12 @@ AtticaManager::savePixmapsToCache()
|
||||
cacheDir.cd( "atticache" );
|
||||
}
|
||||
|
||||
foreach( const QString& id, m_resolverStates.keys() )
|
||||
foreach( const QString & id, m_resolverStates.keys() )
|
||||
{
|
||||
if ( !m_resolverStates[ id ].pixmap || !m_resolverStates[ id ].pixmapDirty )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const QString filename = cacheDir.absoluteFilePath( QString( "%1.png" ).arg( id ) );
|
||||
QFile f( filename );
|
||||
@@ -183,7 +193,9 @@ QPixmap
|
||||
AtticaManager::iconForResolver( const Content& resolver )
|
||||
{
|
||||
if ( !m_resolverStates[ resolver.id() ].pixmap )
|
||||
{
|
||||
return QPixmap();
|
||||
}
|
||||
|
||||
return *m_resolverStates.value( resolver.id() ).pixmap;
|
||||
}
|
||||
@@ -199,10 +211,12 @@ AtticaManager::resolvers() const
|
||||
Content
|
||||
AtticaManager::resolverForId( const QString& id ) const
|
||||
{
|
||||
foreach ( const Attica::Content& c, m_resolvers )
|
||||
foreach ( const Attica::Content & c, m_resolvers )
|
||||
{
|
||||
if ( c.id() == id )
|
||||
{
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
return Content();
|
||||
@@ -233,7 +247,9 @@ QString
|
||||
AtticaManager::pathFromId( const QString& resolverId ) const
|
||||
{
|
||||
if ( !m_resolverStates.contains( resolverId ) )
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
|
||||
return m_resolverStates.value( resolverId ).scriptPath;
|
||||
}
|
||||
@@ -257,7 +273,7 @@ AtticaManager::uploadRating( const Content& c )
|
||||
|
||||
TomahawkSettingsGui::instanceGui()->setAtticaResolverStates( m_resolverStates );
|
||||
|
||||
PostJob* job = m_resolverProvider.voteForContent( c.id(), (uint)c.rating() );
|
||||
PostJob* job = m_resolverProvider.voteForContent( c.id(), ( uint )c.rating() );
|
||||
connect( job, SIGNAL( finished( Attica::BaseJob* ) ), job, SLOT( deleteLater() ) );
|
||||
|
||||
job->start();
|
||||
@@ -274,28 +290,28 @@ AtticaManager::userHasRated( const Content& c ) const
|
||||
|
||||
|
||||
bool
|
||||
AtticaManager::hasCustomAccountForAttica( const QString &id ) const
|
||||
AtticaManager::hasCustomAccountForAttica( const QString& id ) const
|
||||
{
|
||||
return m_customAccounts.keys().contains( id );
|
||||
}
|
||||
|
||||
|
||||
Tomahawk::Accounts::Account*
|
||||
AtticaManager::customAccountForAttica( const QString &id ) const
|
||||
AtticaManager::customAccountForAttica( const QString& id ) const
|
||||
{
|
||||
return m_customAccounts.value( id );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AtticaManager::registerCustomAccount( const QString &atticaId, Tomahawk::Accounts::Account *account )
|
||||
AtticaManager::registerCustomAccount( const QString& atticaId, Tomahawk::Accounts::Account* account )
|
||||
{
|
||||
m_customAccounts.insert( atticaId, account );
|
||||
}
|
||||
|
||||
|
||||
AtticaManager::Resolver
|
||||
AtticaManager::resolverData(const QString &atticaId) const
|
||||
AtticaManager::resolverData( const QString& atticaId ) const
|
||||
{
|
||||
return m_resolverStates.value( atticaId );
|
||||
}
|
||||
@@ -316,7 +332,9 @@ AtticaManager::providerFetched( QNetworkReply* reply )
|
||||
{
|
||||
Q_ASSERT( reply );
|
||||
if ( !reply )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_manager.addProviderFromXml( reply->readAll() );
|
||||
}
|
||||
@@ -345,14 +363,18 @@ AtticaManager::categoriesReturned( BaseJob* j )
|
||||
ListJob< Category >* job = static_cast< ListJob< Category >* >( j );
|
||||
|
||||
Category::List categories = job->itemList();
|
||||
foreach ( const Category& category, categories )
|
||||
foreach ( const Category & category, categories )
|
||||
{
|
||||
ListJob< Content >* job = m_resolverProvider.searchContents( Category::List() << category, QString(), Provider::Downloads, 0, 50 );
|
||||
|
||||
if ( category.name() == "Resolver" )
|
||||
{
|
||||
connect( job, SIGNAL( finished( Attica::BaseJob* ) ), this, SLOT( resolversList( Attica::BaseJob* ) ) );
|
||||
}
|
||||
else if ( category.name() == "BinaryResolver" )
|
||||
{
|
||||
connect( job, SIGNAL( finished( Attica::BaseJob* ) ), this, SLOT( binaryResolversList( Attica::BaseJob* ) ) );
|
||||
}
|
||||
|
||||
job->start();
|
||||
}
|
||||
@@ -367,13 +389,15 @@ AtticaManager::resolversList( BaseJob* j )
|
||||
m_resolvers.append( job->itemList() );
|
||||
|
||||
// Sanity check. if any resolvers are installed that don't exist on the hd, remove them.
|
||||
foreach ( const QString& rId, m_resolverStates.keys() )
|
||||
foreach ( const QString & rId, m_resolverStates.keys() )
|
||||
{
|
||||
if ( m_resolverStates[ rId ].state == Installed ||
|
||||
m_resolverStates[ rId ].state == NeedsUpgrade )
|
||||
m_resolverStates[ rId ].state == NeedsUpgrade )
|
||||
{
|
||||
if ( m_resolverStates[ rId ].binary )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Guess location on disk
|
||||
QDir dir( QString( "%1/atticaresolvers/%2" ).arg( TomahawkUtils::appDataDir().absolutePath() ).arg( rId ) );
|
||||
@@ -425,7 +449,7 @@ AtticaManager::binaryResolversList( BaseJob* j )
|
||||
platform = QString();
|
||||
#endif
|
||||
|
||||
foreach ( const Content& c, binaryResolvers )
|
||||
foreach ( const Content & c, binaryResolvers )
|
||||
{
|
||||
if ( !c.attribute( "typeid" ).isEmpty() && c.attribute( "typeid" ) == platform )
|
||||
{
|
||||
@@ -439,7 +463,8 @@ AtticaManager::binaryResolversList( BaseJob* j )
|
||||
m_resolverStates.insert( c.id(), r );
|
||||
}
|
||||
else if ( m_resolverStates[ c.id() ].binary != true )
|
||||
{ // HACK workaround... why is this not set in the first place sometimes? Migration issue?
|
||||
{
|
||||
// HACK workaround... why is this not set in the first place sometimes? Migration issue?
|
||||
m_resolverStates[ c.id() ].binary = true;
|
||||
}
|
||||
|
||||
@@ -486,7 +511,7 @@ AtticaManager::syncServerData()
|
||||
// look for any newer. m_resolvers has list from server, and m_resolverStates will contain any locally installed ones
|
||||
// also update ratings
|
||||
tLog() << "Syncing server data!";
|
||||
foreach ( const QString& id, m_resolverStates.keys() )
|
||||
foreach ( const QString & id, m_resolverStates.keys() )
|
||||
{
|
||||
Resolver r = m_resolverStates[ id ];
|
||||
for ( int i = 0; i < m_resolvers.size(); i++ )
|
||||
@@ -494,7 +519,9 @@ AtticaManager::syncServerData()
|
||||
Attica::Content upstream = m_resolvers[ i ];
|
||||
// same resolver
|
||||
if ( id != upstream.id() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Update our rating with the server's idea of rating if we haven't rated it
|
||||
if ( m_resolverStates[ id ].userRating != -1 )
|
||||
@@ -506,7 +533,7 @@ AtticaManager::syncServerData()
|
||||
// DO we need to upgrade?
|
||||
tDebug( LOGVERBOSE ) << "Upgrade check for" << upstream.id() << "local is" << r.version << "upstream is" << upstream.version() << "and state is: " << r.state;
|
||||
if ( ( r.state == Installed || r.state == NeedsUpgrade ) &&
|
||||
!upstream.version().isEmpty() )
|
||||
!upstream.version().isEmpty() )
|
||||
{
|
||||
if ( TomahawkUtils::newerVersion( r.version, upstream.version() ) )
|
||||
{
|
||||
@@ -541,13 +568,15 @@ void AtticaManager::doInstallResolver( const Content& resolver, bool autoCreate,
|
||||
emit startedInstalling( resolver.id() );
|
||||
|
||||
if ( m_resolverStates[ resolver.id() ].state != Upgrading )
|
||||
{
|
||||
m_resolverStates[ resolver.id() ].state = Installing;
|
||||
}
|
||||
|
||||
m_resolverStates[ resolver.id() ].scriptPath = resolver.attribute( "mainscript" );
|
||||
m_resolverStates[ resolver.id() ].version = resolver.version();
|
||||
emit resolverStateChanged( resolver.id() );
|
||||
|
||||
// ItemJob< DownloadItem >* job = m_resolverProvider.downloadLink( resolver.id() );
|
||||
// ItemJob< DownloadItem >* job = m_resolverProvider.downloadLink( resolver.id() );
|
||||
QUrl url( QString( "%1/resolvers/v1/content/download/%2/1" ).arg( hostname() ).arg( resolver.id() ) );
|
||||
|
||||
TomahawkUtils::urlAddQueryItem( url, "tomahawkversion", TomahawkUtils::appFriendlyVersion() );
|
||||
@@ -556,7 +585,7 @@ void AtticaManager::doInstallResolver( const Content& resolver, bool autoCreate,
|
||||
r->setProperty( "resolverId", resolver.id() );
|
||||
r->setProperty( "createAccount", autoCreate );
|
||||
r->setProperty( "handler", QVariant::fromValue< QObject* >( handler ) );
|
||||
r->setProperty( "binarySignature", resolver.attribute("signature"));
|
||||
r->setProperty( "binarySignature", resolver.attribute( "signature" ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -568,7 +597,9 @@ AtticaManager::upgradeResolver( const Content& resolver )
|
||||
Q_ASSERT( m_resolverStates[ resolver.id() ].state == NeedsUpgrade );
|
||||
|
||||
if ( !m_resolverStates.contains( resolver.id() ) || m_resolverStates[ resolver.id() ].state != NeedsUpgrade )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_resolverStates[ resolver.id() ].state = Upgrading;
|
||||
emit resolverStateChanged( resolver.id() );
|
||||
@@ -579,45 +610,47 @@ AtticaManager::upgradeResolver( const Content& resolver )
|
||||
|
||||
|
||||
void
|
||||
AtticaManager::resolverDownloadFinished ( QNetworkReply *j )
|
||||
AtticaManager::resolverDownloadFinished ( QNetworkReply* j )
|
||||
{
|
||||
Q_ASSERT( j );
|
||||
if ( !j )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( j->error() == QNetworkReply::NoError )
|
||||
{
|
||||
QDomDocument doc;
|
||||
doc.setContent( j );
|
||||
|
||||
const QDomNodeList nodes = doc.documentElement().elementsByTagName( "downloadlink" );
|
||||
if ( nodes.length() < 1 )
|
||||
{
|
||||
tLog() << "Found no download link for resolver:" << doc.toString();
|
||||
return;
|
||||
}
|
||||
const QDomNodeList nodes = doc.documentElement().elementsByTagName( "downloadlink" );
|
||||
if ( nodes.length() < 1 )
|
||||
{
|
||||
tLog() << "Found no download link for resolver:" << doc.toString();
|
||||
return;
|
||||
}
|
||||
|
||||
QUrl url( nodes.item( 0 ).toElement().text() );
|
||||
// download the resolver itself :)
|
||||
tDebug() << "Downloading resolver from url:" << url.toString();
|
||||
QUrl url( nodes.item( 0 ).toElement().text() );
|
||||
// download the resolver itself :)
|
||||
tDebug() << "Downloading resolver from url:" << url.toString();
|
||||
|
||||
const QDomNodeList signatures = doc.documentElement().elementsByTagName( "signature" );
|
||||
const QDomNodeList signatures = doc.documentElement().elementsByTagName( "signature" );
|
||||
|
||||
// Use the original signature provided
|
||||
QString signature = j->property( "binarySignature" ).toString();
|
||||
if ( signatures.size() > 0 )
|
||||
{
|
||||
// Use the original signature provided
|
||||
QString signature = j->property( "binarySignature" ).toString();
|
||||
if ( signatures.size() > 0 )
|
||||
{
|
||||
// THis download has an overriding signature. Take that one instead
|
||||
const QString sig = signatures.item( 0 ).toElement().text();
|
||||
tLog() << "Found overridden signature in binary download:" << sig;
|
||||
signature = sig;
|
||||
}
|
||||
QNetworkReply* reply = Tomahawk::Utils::nam()->get( QNetworkRequest( url ) );
|
||||
connect( reply, SIGNAL( finished() ), this, SLOT( payloadFetched() ) );
|
||||
reply->setProperty( "resolverId", j->property( "resolverId" ) );
|
||||
reply->setProperty( "createAccount", j->property( "createAccount" ) );
|
||||
reply->setProperty( "handler", j->property( "handler" ) );
|
||||
reply->setProperty( "binarySignature", signature );
|
||||
const QString sig = signatures.item( 0 ).toElement().text();
|
||||
tLog() << "Found overridden signature in binary download:" << sig;
|
||||
signature = sig;
|
||||
}
|
||||
QNetworkReply* reply = Tomahawk::Utils::nam()->get( QNetworkRequest( url ) );
|
||||
connect( reply, SIGNAL( finished() ), this, SLOT( payloadFetched() ) );
|
||||
reply->setProperty( "resolverId", j->property( "resolverId" ) );
|
||||
reply->setProperty( "createAccount", j->property( "createAccount" ) );
|
||||
reply->setProperty( "handler", j->property( "handler" ) );
|
||||
reply->setProperty( "binarySignature", signature );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -654,7 +687,9 @@ AtticaManager::payloadFetched()
|
||||
// Must have a signature for binary resolvers...
|
||||
Q_ASSERT( !signature.isEmpty() );
|
||||
if ( signature.isEmpty() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( !TomahawkUtils::verifyFile( f->fileName(), signature ) )
|
||||
{
|
||||
qWarning() << "FILE SIGNATURE FAILED FOR BINARY RESOLVER! WARNING! :" << f->fileName() << signature;
|
||||
@@ -723,7 +758,7 @@ void
|
||||
AtticaManager::uninstallResolver( const QString& pathToResolver )
|
||||
{
|
||||
// when is this used? find and fix
|
||||
Q_ASSERT(false);
|
||||
Q_ASSERT( false );
|
||||
|
||||
// User manually removed a resolver not through attica dialog, simple remove
|
||||
QRegExp r( ".*([^/]*)/contents/code/main.js" );
|
||||
@@ -732,7 +767,7 @@ AtticaManager::uninstallResolver( const QString& pathToResolver )
|
||||
tDebug() << "Got resolver ID to remove:" << atticaId;
|
||||
if ( !atticaId.isEmpty() ) // this is an attica-installed resolver, mark as uninstalled
|
||||
{
|
||||
foreach ( const Content& resolver, m_resolvers )
|
||||
foreach ( const Content & resolver, m_resolvers )
|
||||
{
|
||||
if ( resolver.id() == atticaId ) // this is the one
|
||||
{
|
||||
@@ -773,21 +808,29 @@ AtticaManager::doResolverRemove( const QString& id ) const
|
||||
// uninstalling is easy... just delete it! :)
|
||||
QDir resolverDir = TomahawkUtils::appDataDir();
|
||||
if ( !resolverDir.cd( QString( "atticaresolvers/%1" ).arg( id ) ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( id.isEmpty() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// sanity check
|
||||
if ( !resolverDir.absolutePath().contains( "atticaresolvers" ) ||
|
||||
!resolverDir.absolutePath().contains( id ) )
|
||||
!resolverDir.absolutePath().contains( id ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TomahawkUtils::removeDirectory( resolverDir.absolutePath() );
|
||||
|
||||
QDir cacheDir = TomahawkUtils::appDataDir();
|
||||
if ( !cacheDir.cd( "atticacache" ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const bool removed = cacheDir.remove( id + ".png" );
|
||||
tDebug() << "Tried to remove cached image, succeeded?" << removed << cacheDir.filePath( id );
|
||||
|
@@ -31,8 +31,10 @@
|
||||
#include <attica/providermanager.h>
|
||||
#include <attica/content.h>
|
||||
|
||||
namespace Tomahawk {
|
||||
namespace Accounts {
|
||||
namespace Tomahawk
|
||||
{
|
||||
namespace Accounts
|
||||
{
|
||||
class AtticaResolverAccount;
|
||||
}
|
||||
}
|
||||
@@ -42,8 +44,9 @@ class BinaryInstallerHelper;
|
||||
class DLLEXPORT AtticaManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum ResolverState {
|
||||
public:
|
||||
enum ResolverState
|
||||
{
|
||||
Uninstalled = 0,
|
||||
Installing,
|
||||
Installed,
|
||||
@@ -52,7 +55,8 @@ public:
|
||||
Failed
|
||||
};
|
||||
|
||||
struct Resolver {
|
||||
struct Resolver
|
||||
{
|
||||
QString version, scriptPath;
|
||||
int userRating; // 0-100
|
||||
ResolverState state;
|
||||
@@ -74,7 +78,9 @@ public:
|
||||
static AtticaManager* instance()
|
||||
{
|
||||
if ( !s_instance )
|
||||
{
|
||||
s_instance = new AtticaManager();
|
||||
}
|
||||
|
||||
return s_instance;
|
||||
}
|
||||
@@ -107,13 +113,13 @@ public:
|
||||
|
||||
AtticaManager::Resolver resolverData( const QString& atticaId ) const;
|
||||
|
||||
public slots:
|
||||
public slots:
|
||||
void installResolver( const Attica::Content& resolver, bool autoCreateAccount = true );
|
||||
void installResolverWithHandler( const Attica::Content& resolver, Tomahawk::Accounts::AtticaResolverAccount* handler );
|
||||
|
||||
void upgradeResolver( const Attica::Content& resolver );
|
||||
|
||||
signals:
|
||||
signals:
|
||||
void resolversLoaded( const Attica::Content::List& resolvers );
|
||||
|
||||
void resolverStateChanged( const QString& resolverId );
|
||||
@@ -125,7 +131,7 @@ signals:
|
||||
|
||||
void startedInstalling( const QString& resolverId );
|
||||
|
||||
private slots:
|
||||
private slots:
|
||||
void providerFetched( QNetworkReply* reply );
|
||||
void providerError( QNetworkReply::NetworkError );
|
||||
void providerAdded( const Attica::Provider& );
|
||||
@@ -141,7 +147,7 @@ private slots:
|
||||
|
||||
void syncServerData();
|
||||
|
||||
private:
|
||||
private:
|
||||
void doResolverRemove( const QString& id ) const;
|
||||
void doInstallResolver( const Attica::Content& resolver, bool autoCreate, Tomahawk::Accounts::AtticaResolverAccount* handler );
|
||||
void fetchMissingIcons();
|
||||
@@ -164,12 +170,12 @@ private:
|
||||
class DLLEXPORT CustomAtticaAccount : public Tomahawk::Accounts::Account
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
public:
|
||||
virtual ~CustomAtticaAccount() {}
|
||||
|
||||
virtual Attica::Content atticaContent() const = 0;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
// No, you can't.
|
||||
CustomAtticaAccount( const QString& id ) : Tomahawk::Accounts::Account( id ) {}
|
||||
};
|
||||
|
@@ -70,7 +70,7 @@ ContextMenu::clear()
|
||||
unsigned int
|
||||
ContextMenu::itemCount() const
|
||||
{
|
||||
return m_queries.count() + m_artists.count() + m_albums.count();
|
||||
return m_queries.count() + m_artists.count() + m_albums.count();
|
||||
}
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ ContextMenu::addToPlaylist( int playlistIdx )
|
||||
void
|
||||
ContextMenu::sendToSource( int sourceIdx )
|
||||
{
|
||||
const Tomahawk::source_ptr &src = m_sources.at( sourceIdx );
|
||||
const Tomahawk::source_ptr& src = m_sources.at( sourceIdx );
|
||||
foreach ( Tomahawk::query_ptr query, m_queries )
|
||||
{
|
||||
query->queryTrack()->share( src );
|
||||
@@ -111,17 +111,23 @@ void
|
||||
ContextMenu::setQueries( const QList<Tomahawk::query_ptr>& queries )
|
||||
{
|
||||
if ( queries.isEmpty() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QMenu::clear();
|
||||
m_queries.clear();
|
||||
m_queries << queries;
|
||||
|
||||
if ( m_supportedActions & ActionPlay && itemCount() == 1 )
|
||||
{
|
||||
m_sigmap->setMapping( addAction( tr( "&Play" ) ), ActionPlay );
|
||||
}
|
||||
|
||||
if ( m_supportedActions & ActionQueue )
|
||||
{
|
||||
m_sigmap->setMapping( addAction( tr( "Add to &Queue" ) ), ActionQueue );
|
||||
}
|
||||
|
||||
if ( m_supportedActions & ActionPlaylist )
|
||||
{
|
||||
@@ -130,7 +136,9 @@ ContextMenu::setQueries( const QList<Tomahawk::query_ptr>& queries )
|
||||
// Sort the playlist
|
||||
qSort( m_playlists.begin(), m_playlists.end(), playlistsLessThan );
|
||||
if ( m_playlists_sigmap != 0 )
|
||||
{
|
||||
m_playlists_sigmap->deleteLater();
|
||||
}
|
||||
m_playlists_sigmap = new QSignalMapper( this );
|
||||
|
||||
// Build the menu listing all available playlists
|
||||
@@ -138,7 +146,7 @@ ContextMenu::setQueries( const QList<Tomahawk::query_ptr>& queries )
|
||||
for ( int i = 0; i < m_playlists.length(); ++i )
|
||||
{
|
||||
QAction* action = new QAction( m_playlists.at( i )->title() , this );
|
||||
playlistMenu->addAction(action);
|
||||
playlistMenu->addAction( action );
|
||||
m_playlists_sigmap->setMapping( action, i );
|
||||
connect( action, SIGNAL( triggered() ), m_playlists_sigmap, SLOT( map() ) );
|
||||
}
|
||||
@@ -152,7 +160,9 @@ ContextMenu::setQueries( const QList<Tomahawk::query_ptr>& queries )
|
||||
qSort( m_sources.begin(), m_sources.end(), sourcesLessThan );
|
||||
|
||||
if ( m_sources_sigmap != 0 )
|
||||
{
|
||||
m_sources_sigmap->deleteLater();
|
||||
}
|
||||
m_sources_sigmap = new QSignalMapper( this );
|
||||
|
||||
QMenu* sourcesMenu = addMenu( tr( "Send to &Friend" ) );
|
||||
@@ -169,9 +179,13 @@ ContextMenu::setQueries( const QList<Tomahawk::query_ptr>& queries )
|
||||
if ( m_supportedActions & ActionStopAfter && itemCount() == 1 )
|
||||
{
|
||||
if ( AudioEngine::instance()->stopAfterTrack() == queries.first() )
|
||||
{
|
||||
m_sigmap->setMapping( addAction( tr( "Continue Playback after this &Track" ) ), ActionStopAfter );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_sigmap->setMapping( addAction( tr( "Stop Playback after this &Track" ) ), ActionStopAfter );
|
||||
}
|
||||
}
|
||||
|
||||
addSeparator();
|
||||
@@ -207,17 +221,21 @@ ContextMenu::setQueries( const QList<Tomahawk::query_ptr>& queries )
|
||||
addSeparator();
|
||||
|
||||
if ( m_supportedActions & ActionCopyLink && itemCount() == 1 )
|
||||
{
|
||||
m_sigmap->setMapping( addAction( tr( "&Copy Track Link" ) ), ActionCopyLink );
|
||||
}
|
||||
|
||||
if ( m_supportedActions & ActionEditMetadata && itemCount() == 1 )
|
||||
{
|
||||
m_sigmap->setMapping( addAction( tr( "Properties..." ) ), ActionEditMetadata );
|
||||
}
|
||||
|
||||
addSeparator();
|
||||
|
||||
if ( m_supportedActions & ActionMarkListened )
|
||||
{
|
||||
bool thereAreUnlistenedTracks = false;
|
||||
foreach ( const Tomahawk::query_ptr& query, m_queries )
|
||||
foreach ( const Tomahawk::query_ptr & query, m_queries )
|
||||
{
|
||||
if ( !query->queryTrack()->isListened() )
|
||||
{
|
||||
@@ -227,13 +245,17 @@ ContextMenu::setQueries( const QList<Tomahawk::query_ptr>& queries )
|
||||
}
|
||||
|
||||
if ( thereAreUnlistenedTracks )
|
||||
{
|
||||
m_sigmap->setMapping( addAction( tr( "Mark as &Listened" ) ), ActionMarkListened );
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_supportedActions & ActionDelete )
|
||||
{
|
||||
m_sigmap->setMapping( addAction( queries.count() > 1 ? tr( "&Remove Items" ) : tr( "&Remove Item" ) ), ActionDelete );
|
||||
}
|
||||
|
||||
foreach ( QAction* action, actions() )
|
||||
foreach ( QAction * action, actions() )
|
||||
{
|
||||
connect( action, SIGNAL( triggered() ), m_sigmap, SLOT( map() ) );
|
||||
}
|
||||
@@ -244,7 +266,9 @@ void
|
||||
ContextMenu::setQuery( const Tomahawk::query_ptr& query )
|
||||
{
|
||||
if ( query.isNull() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QList<query_ptr> queries;
|
||||
queries << query;
|
||||
@@ -256,14 +280,18 @@ void
|
||||
ContextMenu::setAlbums( const QList<Tomahawk::album_ptr>& albums )
|
||||
{
|
||||
if ( albums.isEmpty() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QMenu::clear();
|
||||
m_albums.clear();
|
||||
m_albums << albums;
|
||||
|
||||
if ( m_supportedActions & ActionQueue )
|
||||
{
|
||||
m_sigmap->setMapping( addAction( tr( "Add to &Queue" ) ), ActionQueue );
|
||||
}
|
||||
|
||||
addSeparator();
|
||||
|
||||
@@ -282,9 +310,11 @@ ContextMenu::setAlbums( const QList<Tomahawk::album_ptr>& albums )
|
||||
addSeparator();
|
||||
|
||||
if ( m_supportedActions & ActionCopyLink && itemCount() == 1 )
|
||||
{
|
||||
m_sigmap->setMapping( addAction( tr( "Copy Album &Link" ) ), ActionCopyLink );
|
||||
}
|
||||
|
||||
foreach ( QAction* action, actions() )
|
||||
foreach ( QAction * action, actions() )
|
||||
{
|
||||
connect( action, SIGNAL( triggered() ), m_sigmap, SLOT( map() ) );
|
||||
}
|
||||
@@ -304,17 +334,21 @@ void
|
||||
ContextMenu::setArtists( const QList<Tomahawk::artist_ptr>& artists )
|
||||
{
|
||||
if ( artists.isEmpty() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QMenu::clear();
|
||||
m_artists.clear();
|
||||
m_artists << artists;
|
||||
|
||||
/* if ( m_supportedActions & ActionPlay && itemCount() == 1 )
|
||||
m_sigmap->setMapping( addAction( tr( "Show &Artist Page" ) ), ActionPlay );*/
|
||||
/* if ( m_supportedActions & ActionPlay && itemCount() == 1 )
|
||||
m_sigmap->setMapping( addAction( tr( "Show &Artist Page" ) ), ActionPlay );*/
|
||||
|
||||
if ( m_supportedActions & ActionQueue )
|
||||
{
|
||||
m_sigmap->setMapping( addAction( tr( "Add to &Queue" ) ), ActionQueue );
|
||||
}
|
||||
|
||||
addSeparator();
|
||||
|
||||
@@ -330,9 +364,11 @@ ContextMenu::setArtists( const QList<Tomahawk::artist_ptr>& artists )
|
||||
addSeparator();
|
||||
|
||||
if ( m_supportedActions & ActionCopyLink && itemCount() == 1 )
|
||||
{
|
||||
m_sigmap->setMapping( addAction( tr( "Copy Artist &Link" ) ), ActionCopyLink );
|
||||
}
|
||||
|
||||
foreach ( QAction* action, actions() )
|
||||
foreach ( QAction * action, actions() )
|
||||
{
|
||||
connect( action, SIGNAL( triggered() ), m_sigmap, SLOT( map() ) );
|
||||
}
|
||||
@@ -364,7 +400,7 @@ ContextMenu::onTriggered( int action )
|
||||
case ActionTrackPage:
|
||||
case ActionArtistPage:
|
||||
case ActionAlbumPage:
|
||||
openPage( (MenuActions)action );
|
||||
openPage( ( MenuActions )action );
|
||||
break;
|
||||
|
||||
case ActionLove:
|
||||
@@ -373,17 +409,21 @@ ContextMenu::onTriggered( int action )
|
||||
|
||||
case ActionStopAfter:
|
||||
if ( m_queries.first()->equals( AudioEngine::instance()->stopAfterTrack() ) )
|
||||
{
|
||||
AudioEngine::instance()->setStopAfterTrack( query_ptr() );
|
||||
}
|
||||
else
|
||||
{
|
||||
AudioEngine::instance()->setStopAfterTrack( m_queries.first() );
|
||||
}
|
||||
break;
|
||||
|
||||
case ActionEditMetadata:
|
||||
{
|
||||
MetadataEditor* d = new MetadataEditor( m_queries.first(), m_interface, this );
|
||||
d->show();
|
||||
}
|
||||
break;
|
||||
{
|
||||
MetadataEditor* d = new MetadataEditor( m_queries.first(), m_interface, this );
|
||||
d->show();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
emit triggered( action );
|
||||
@@ -397,15 +437,15 @@ ContextMenu::onTriggered( int action )
|
||||
void
|
||||
ContextMenu::addToQueue()
|
||||
{
|
||||
foreach ( const query_ptr& query, m_queries )
|
||||
foreach ( const query_ptr & query, m_queries )
|
||||
{
|
||||
ViewManager::instance()->queue()->model()->appendQuery( query );
|
||||
}
|
||||
foreach ( const artist_ptr& artist, m_artists )
|
||||
foreach ( const artist_ptr & artist, m_artists )
|
||||
{
|
||||
ViewManager::instance()->queue()->model()->appendArtist( artist );
|
||||
}
|
||||
foreach ( const album_ptr& album, m_albums )
|
||||
foreach ( const album_ptr & album, m_albums )
|
||||
{
|
||||
ViewManager::instance()->queue()->model()->appendAlbum( album );
|
||||
}
|
||||
@@ -475,7 +515,9 @@ void
|
||||
ContextMenu::onSocialActionsLoaded()
|
||||
{
|
||||
if ( m_queries.isEmpty() || m_queries.first().isNull() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_loveAction && m_queries.first()->track()->loved() )
|
||||
{
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user