diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index e37c1fa33..f45615699 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -189,6 +189,7 @@ IF(GLOOX_FOUND)
SET( tomahawkHeaders ${tomahawkHeaders} xmppbot/xmppbot.h )
SET( tomahawkSources ${tomahawkSources} xmppbot/xmppbot.cpp )
ENDIF(GLOOX_FOUND)
+ADD_SUBDIRECTORY( accounts )
ADD_SUBDIRECTORY( sip )
IF(QCA2_FOUND)
diff --git a/src/accounts/CMakeLists.txt b/src/accounts/CMakeLists.txt
new file mode 100644
index 000000000..37e10994b
--- /dev/null
+++ b/src/accounts/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory( twitter )
diff --git a/src/accounts/twitter/CMakeLists.txt b/src/accounts/twitter/CMakeLists.txt
new file mode 100644
index 000000000..80587ad75
--- /dev/null
+++ b/src/accounts/twitter/CMakeLists.txt
@@ -0,0 +1,54 @@
+project( tomahawk )
+
+include( ${QT_USE_FILE} )
+add_definitions( ${QT_DEFINITIONS} )
+add_definitions( -DQT_PLUGIN )
+add_definitions( -DQT_SHARED )
+add_definitions( -DDLLEXPORT_PRO )
+
+set( twitterAccountSources
+ twitteraccount.cpp
+ twitterconfigwidget.cpp
+ tomahawkoauthtwitter.cpp
+)
+
+set( twitterAccountHeaders
+ twitteraccount.h
+ twitterconfigwidget.h
+ tomahawkoauthtwitter.h
+)
+
+set( twitterAccountUI
+ twitterconfigwidget.ui
+)
+
+include_directories( . ${CMAKE_CURRENT_BINARY_DIR} ..
+ ${QT_INCLUDE_DIR}
+ ${QTWEETLIB_INCLUDE_DIR}
+)
+
+qt4_add_resources( RC_SRCS "resources.qrc" )
+qt4_wrap_cpp( twitterAccountMoc ${twitterAccountHeaders} )
+qt4_wrap_ui( twitterAccountUI_H ${twitterAccountUI} )
+add_library( tomahawk_account_twitter SHARED ${twitterAccountUI_H} ${twitterAccountSources} ${twitterAccountMoc} ${RC_SRCS} )
+
+IF( WIN32 )
+SET( OS_SPECIFIC_LINK_LIBRARIES
+ ${OS_SPECIFIC_LINK_LIBRARIES}
+ "winmm.dll"
+ "iphlpapi.a"
+)
+ENDIF( WIN32 )
+
+target_link_libraries( tomahawk_account_twitter
+ ${TOMAHAWK_LIBRARIES}
+ ${QTWEETLIB_LIBRARIES}
+ ${QT_LIBRARIES}
+ ${OS_SPECIFIC_LINK_LIBRARIES}
+)
+
+IF( APPLE )
+# SET( CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} "-undefined dynamic_lookup" )
+ENDIF( APPLE )
+
+install( TARGETS tomahawk_account_twitter DESTINATION lib${LIB_SUFFIX} )
diff --git a/src/accounts/twitter/resources.qrc b/src/accounts/twitter/resources.qrc
new file mode 100644
index 000000000..fc7df302f
--- /dev/null
+++ b/src/accounts/twitter/resources.qrc
@@ -0,0 +1,5 @@
+
+
+twitter-icon.png
+
+
diff --git a/src/accounts/twitter/tomahawkoauthtwitter.cpp b/src/accounts/twitter/tomahawkoauthtwitter.cpp
new file mode 100644
index 000000000..35cd98a9e
--- /dev/null
+++ b/src/accounts/twitter/tomahawkoauthtwitter.cpp
@@ -0,0 +1,32 @@
+#include "tomahawkoauthtwitter.h"
+
+#include
+
+#include "utils/logger.h"
+
+
+TomahawkOAuthTwitter::TomahawkOAuthTwitter( QNetworkAccessManager *nam, QObject* parent )
+ : OAuthTwitter( QByteArray::fromBase64( "QzR2NFdmYTIxcmZJRGNrNEhNUjNB" ), QByteArray::fromBase64( "elhTalU2Ympydmc2VVZNSlg0SnVmcUh5amozaWV4dFkxNFNSOXVCRUFv" ), parent )
+{
+ setNetworkAccessManager( nam );
+}
+
+
+int
+TomahawkOAuthTwitter::authorizationWidget()
+{
+ bool ok;
+ int i = QInputDialog::getInt(0, tr( "Twitter PIN" ), tr( "After authenticating on Twitter's web site,\nenter the displayed PIN number here:" ), 0, 0, 2147483647, 1, &ok);
+ if (ok)
+ return i;
+
+ return 0;
+}
+
+void
+TomahawkOAuthTwitter::error()
+{
+ qDebug() << Q_FUNC_INFO;
+ setOAuthToken( QString().toLatin1() );
+ setOAuthTokenSecret( QString().toLatin1() );
+}
diff --git a/src/accounts/twitter/tomahawkoauthtwitter.h b/src/accounts/twitter/tomahawkoauthtwitter.h
new file mode 100644
index 000000000..72cd3329c
--- /dev/null
+++ b/src/accounts/twitter/tomahawkoauthtwitter.h
@@ -0,0 +1,25 @@
+#ifndef TOMAHAWKOAUTHTWITTERACCOUNT
+#define TOMAHAWKOAUTHTWITTERACCOUNT
+
+#include "dllmacro.h"
+
+#include
+#include
+
+class DLLEXPORT TomahawkOAuthTwitter : public OAuthTwitter
+{
+ Q_OBJECT
+
+public:
+ TomahawkOAuthTwitter( QNetworkAccessManager *nam, QObject *parent = 0 );
+
+ ~TomahawkOAuthTwitter() {}
+
+protected:
+ virtual int authorizationWidget();
+
+private slots:
+ void error();
+};
+
+#endif
diff --git a/src/accounts/twitter/twitter-icon.png b/src/accounts/twitter/twitter-icon.png
new file mode 100644
index 000000000..aab1fca87
Binary files /dev/null and b/src/accounts/twitter/twitter-icon.png differ
diff --git a/src/accounts/twitter/twitteraccount.cpp b/src/accounts/twitter/twitteraccount.cpp
new file mode 100644
index 000000000..f283da14c
--- /dev/null
+++ b/src/accounts/twitter/twitteraccount.cpp
@@ -0,0 +1,77 @@
+/* === This file is part of Tomahawk Player - ===
+ *
+ * Copyright 2010-2011, Christian Muehlhaeuser
+ *
+ * Tomahawk is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Tomahawk is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Tomahawk. If not, see .
+ */
+
+#include "twitteraccount.h"
+
+#include "twitterconfigwidget.h"
+
+#include
+
+namespace Tomahawk
+{
+
+namespace Accounts
+{
+
+Account*
+TwitterAccountFactory::createAccount( const QString& accountId )
+{
+ return new TwitterAccount( accountId.isEmpty() ? Tomahawk::Accounts::generateId( factoryId() ) : accountId );
+}
+
+
+TwitterAccount::TwitterAccount( const QString &accountId )
+ : Account( accountId )
+ , m_isAuthenticated( false )
+{
+ loadFromConfig( accountId );
+
+ setAccountServiceName( "Twitter" );
+ QSet< AccountType > types;
+ types << InfoType;
+ setTypes( types );
+
+ m_configWidget = QWeakPointer< TwitterConfigWidget >( new TwitterConfigWidget( this, 0 ) );
+ connect( m_configWidget.data(), SIGNAL( twitterAuthed( bool ) ), SLOT( configDialogAuthedSignalSlot( bool ) ) );
+}
+
+
+TwitterAccount::~TwitterAccount()
+{
+
+}
+
+
+void
+TwitterAccount::configDialogAuthedSignalSlot( bool authed )
+{
+ m_isAuthenticated = authed;
+ if ( !credentials()[ "username" ].toString().isEmpty() )
+ setAccountFriendlyName( QString( "@%1" ).arg( credentials()[ "username" ].toString() ) );
+ syncConfig();
+ emit configurationChanged();
+}
+
+
+}
+
+}
+
+#ifndef GOOGLE_WRAPPER
+Q_EXPORT_PLUGIN2( Tomahawk::Accounts::AccountFactory, Tomahawk::Accounts::TwitterAccountFactory )
+#endif
\ No newline at end of file
diff --git a/src/accounts/twitter/twitteraccount.h b/src/accounts/twitter/twitteraccount.h
new file mode 100644
index 000000000..af51cee17
--- /dev/null
+++ b/src/accounts/twitter/twitteraccount.h
@@ -0,0 +1,87 @@
+/* === This file is part of Tomahawk Player - ===
+ *
+ * Copyright 2010-2011, Christian Muehlhaeuser
+ *
+ * Tomahawk is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Tomahawk is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Tomahawk. If not, see .
+ */
+
+#ifndef TWITTERACCOUNT_H
+#define TWITTERACCOUNT_H
+
+#include "dllmacro.h"
+
+#include "twitterconfigwidget.h"
+#include "tomahawkoauthtwitter.h"
+
+#include "accounts/account.h"
+
+#define MYNAME "ACCOUNTTWITTER"
+
+namespace Tomahawk
+{
+
+namespace Accounts
+{
+
+class DLLEXPORT TwitterAccountFactory : public AccountFactory
+{
+ Q_OBJECT
+ Q_INTERFACES( Tomahawk::Accounts::AccountFactory )
+
+public:
+ TwitterAccountFactory() {}
+ virtual ~TwitterAccountFactory() {}
+
+ QString prettyName() const { return "Twitter"; }
+ QString factoryId() const { return "twitteraccount"; }
+ QIcon icon() const { return QIcon( ":/twitter-icon.png" ); }
+ Account* createAccount( const QString& pluginId = QString() );
+};
+
+class DLLEXPORT TwitterAccount : public Account
+{
+ Q_OBJECT
+
+public:
+ TwitterAccount( const QString &accountId );
+ virtual ~TwitterAccount();
+
+ QIcon icon() const { return QIcon( ":/twitter-icon.png" ); }
+
+ bool canSelfAuthenticate() { return false; }
+ bool authenticate() { return false; }
+ bool isAuthenticated() { return m_isAuthenticated; }
+
+ Tomahawk::InfoSystem::InfoPlugin* infoPlugin() { return 0; }
+ SipPlugin* sipPlugin() { return 0; }
+
+ QWidget* configurationWidget() { return m_configWidget.data(); }
+ QWidget* aclWidget() { return 0; }
+
+private slots:
+ void configDialogAuthedSignalSlot( bool authed );
+
+private:
+ bool m_isAuthenticated;
+ QWeakPointer< TwitterConfigWidget > m_configWidget;
+
+ // for settings access
+ friend class TwitterConfigWidget;
+};
+
+};
+
+};
+
+#endif
diff --git a/src/accounts/twitter/twitterconfigwidget.cpp b/src/accounts/twitter/twitterconfigwidget.cpp
new file mode 100644
index 000000000..f308bd74f
--- /dev/null
+++ b/src/accounts/twitter/twitterconfigwidget.cpp
@@ -0,0 +1,294 @@
+/* === This file is part of Tomahawk Player - ===
+ *
+ * Copyright 2010-2011, Christian Muehlhaeuser
+ *
+ * Tomahawk is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Tomahawk is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Tomahawk. If not, see .
+ */
+
+#include "twitterconfigwidget.h"
+#include "twitteraccount.h"
+#include "ui_twitterconfigwidget.h"
+
+#include "tomahawksettings.h"
+#include "utils/tomahawkutils.h"
+#include "database/database.h"
+
+#include "tomahawkoauthtwitter.h"
+#include
+#include
+#include
+
+#include
+
+#include "utils/logger.h"
+
+namespace Tomahawk
+{
+
+namespace Accounts
+{
+
+TwitterConfigWidget::TwitterConfigWidget( TwitterAccount* account, QWidget *parent ) :
+ QWidget( parent ),
+ ui( new Ui::TwitterConfigWidget ),
+ m_account( account )
+{
+ ui->setupUi( this );
+
+ connect( ui->twitterAuthenticateButton, SIGNAL( pressed() ),
+ this, SLOT( authDeauthTwitter() ) );
+ connect( ui->twitterTweetGotTomahawkButton, SIGNAL( pressed() ),
+ this, SLOT( startPostGotTomahawkStatus() ) );
+ connect( ui->twitterTweetComboBox, SIGNAL( currentIndexChanged( int ) ),
+ this, SLOT( tweetComboBoxIndexChanged( int ) ) );
+
+ ui->twitterTweetComboBox->setCurrentIndex( 0 );
+ ui->twitterTweetGotTomahawkButton->setText( tr( "Tweet!" ) );
+
+ QVariantHash credentials = m_account->credentials();
+
+ if ( credentials[ "oauthtoken" ].toString().isEmpty() ||
+ credentials[ "oauthtokensecret" ].toString().isEmpty() ||
+ credentials[ "username" ].toString().isEmpty() )
+ {
+ ui->twitterStatusLabel->setText( tr( "Status: No saved credentials" ) );
+ ui->twitterAuthenticateButton->setText( tr( "Authenticate" ) );
+ ui->twitterSyncGroupBox->setVisible( false );
+
+ emit twitterAuthed( false );
+ }
+ else
+ {
+ ui->twitterStatusLabel->setText( tr( "Status: Credentials saved for %1" ).arg( m_account->credentials()[ "username" ].toString() ) );
+ ui->twitterAuthenticateButton->setText( tr( "De-authenticate" ) );
+ ui->twitterSyncGroupBox->setVisible( true );
+ ui->twitterUserTweetLineEdit->setVisible( false );
+
+ emit twitterAuthed( true );
+ }
+
+}
+
+TwitterConfigWidget::~TwitterConfigWidget()
+{
+ delete ui;
+}
+
+void
+TwitterConfigWidget::authDeauthTwitter()
+{
+ if ( 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 );
+ twitAuth->authorizePin();
+
+ QVariantHash credentials = m_account->credentials();
+ credentials[ "oauthtoken" ] = twitAuth->oauthToken();
+ credentials[ "oauthtokensecret" ] = twitAuth->oauthTokenSecret();
+ m_account->setCredentials( credentials );
+
+ 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 )
+{
+ 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.") );
+ emit twitterAuthed( false );
+ return;
+ }
+
+ QVariantHash credentials = m_account->credentials();
+ credentials[ "username" ] = user.screenName();
+ m_account->setCredentials( credentials );
+
+ QVariantHash configuration = m_account->configuration();
+ configuration[ "sipcachedfriendssinceid" ] = 0;
+ configuration[ "sipcachedmentionssinceid" ] = 0;
+ m_account->setConfiguration( configuration );
+
+ ui->twitterStatusLabel->setText( tr( "Status: Credentials saved for %1" ).arg( user.screenName() ) );
+ ui->twitterAuthenticateButton->setText( tr( "De-authenticate" ) );
+ ui->twitterSyncGroupBox->setVisible( true );
+ ui->twitterTweetComboBox->setCurrentIndex( 0 );
+ ui->twitterUserTweetLineEdit->setVisible( false );
+ ui->twitterTweetGotTomahawkButton->setText( tr( "Tweet!" ) );
+
+ emit twitterAuthed( true );
+ emit sizeHintChanged();
+}
+
+void
+TwitterConfigWidget::authenticateVerifyError( QTweetNetBase::ErrorCode code, const QString &errorMsg )
+{
+ qDebug() << Q_FUNC_INFO;
+ qDebug() << "Error validating credentials, error code is " << code << ", error message is " << errorMsg;
+ ui->twitterStatusLabel->setText(tr("Status: Error validating credentials"));
+ emit twitterAuthed( false );
+ return;
+}
+
+void
+TwitterConfigWidget::deauthenticateTwitter()
+{
+ qDebug() << Q_FUNC_INFO;
+ QVariantHash credentials = m_account->credentials();
+ credentials[ "oauthtoken" ] = QString();
+ credentials[ "oauthtokensecret" ] = QString();
+ credentials[ "username" ] = QString();
+ m_account->setCredentials( credentials );
+
+ ui->twitterStatusLabel->setText(tr("Status: No saved credentials"));
+ ui->twitterAuthenticateButton->setText( tr( "Authenticate" ) );
+ ui->twitterSyncGroupBox->setVisible( false );
+
+ emit twitterAuthed( false );
+ emit sizeHintChanged();
+}
+
+void
+TwitterConfigWidget::tweetComboBoxIndexChanged( int index )
+{
+ Q_UNUSED( index );
+ if ( ui->twitterTweetComboBox->currentText() == tr( "Global Tweet" ) ) //FIXME: use data!
+ ui->twitterUserTweetLineEdit->setVisible( false );
+ else
+ ui->twitterUserTweetLineEdit->setVisible( true );
+
+ if ( ui->twitterTweetComboBox->currentText() == tr( "Direct Message" ) ) //FIXME: use data!
+ ui->twitterTweetGotTomahawkButton->setText( tr( "Send Message!" ) );
+ else if ( ui->twitterTweetComboBox->currentText() == tr( "@Mention" ) )
+ ui->twitterTweetGotTomahawkButton->setText( tr( "Send Mention!" ) );
+ else
+ ui->twitterTweetGotTomahawkButton->setText( tr( "Tweet!" ) );
+}
+
+void
+TwitterConfigWidget::startPostGotTomahawkStatus()
+{
+ qDebug() << Q_FUNC_INFO;
+ m_postGTtype = ui->twitterTweetComboBox->currentText();
+
+ if ( m_postGTtype != "Global Tweet" && ( ui->twitterUserTweetLineEdit->text().isEmpty() || ui->twitterUserTweetLineEdit->text() == "@" ) )
+ {
+ QMessageBox::critical( this, tr("Tweetin' Error"), tr("You must enter a user name for this type of tweet.") );
+ return;
+ }
+
+ qDebug() << "Posting Got Tomahawk status";
+ QVariantHash credentials = m_account->credentials();
+
+ if ( credentials[ "oauthtoken" ].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.") );
+ emit twitterAuthed( false );
+ return;
+ }
+ 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 &) ) );
+ credVerifier->verify();
+}
+
+void
+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.") );
+ emit twitterAuthed( false );
+ return;
+ }
+ 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 &) ) );
+ QString uuid = QUuid::createUuid();
+ QString message = QString( "Got Tomahawk? {" ) + Database::instance()->dbid() + QString( "} (" ) + uuid.mid( 1, 8 ) + QString( ")" ) + QString( " http://gettomahawk.com" );
+ if ( m_postGTtype == "@Mention" )
+ {
+ QString user = 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 &) ) );
+ QString uuid = QUuid::createUuid();
+ QString message = QString( "Got Tomahawk? {" ) + Database::instance()->dbid() + QString( "} (" ) + uuid.mid( 1, 8 ) + QString( ")" ) + QString( " http://gettomahawk.com" );
+ QString user = ui->twitterUserTweetLineEdit->text();
+ if ( user.startsWith( "@" ) )
+ user.remove( 0, 1 );
+ statUpdate->post( user, message );
+ }
+}
+
+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!") );
+ else
+ 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!") );
+ else
+ QMessageBox::information( this, tr("Tweeted!"), tr("Your message has been posted!") );
+}
+
+void
+TwitterConfigWidget::postGotTomahawkStatusUpdateError( QTweetNetBase::ErrorCode code, const QString& errorMsg )
+{
+ 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!") );
+}
+
+}
+
+}
\ No newline at end of file
diff --git a/src/accounts/twitter/twitterconfigwidget.h b/src/accounts/twitter/twitterconfigwidget.h
new file mode 100644
index 000000000..df0b60748
--- /dev/null
+++ b/src/accounts/twitter/twitterconfigwidget.h
@@ -0,0 +1,84 @@
+/* === This file is part of Tomahawk Player - ===
+ *
+ * Copyright 2010-2011, Christian Muehlhaeuser
+ *
+ * Tomahawk is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Tomahawk is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Tomahawk. If not, see .
+ */
+
+#ifndef TWITTERACCOUNTCONFIGWIDGET_H
+#define TWITTERACCOUNTCONFIGWIDGET_H
+
+#include "dllmacro.h"
+
+#include
+#include
+#include
+#include
+
+#include
+
+class TwitterAccount;
+
+namespace Ui
+{
+ class TwitterConfigWidget;
+}
+
+namespace Tomahawk
+{
+
+namespace Accounts
+{
+
+class TwitterAccount;
+
+
+class DLLEXPORT TwitterConfigWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit TwitterConfigWidget( TwitterAccount* account = 0, QWidget *parent = 0 );
+ virtual ~TwitterConfigWidget();
+
+signals:
+ void twitterAuthed( bool authed );
+
+ void sizeHintChanged();
+
+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 tweetComboBoxIndexChanged( int index );
+
+private:
+ void authenticateTwitter();
+ void deauthenticateTwitter();
+
+ Ui::TwitterConfigWidget *ui;
+ TwitterAccount *m_account;
+ QString m_postGTtype;
+};
+
+}
+
+}
+
+#endif // TWITTERCONFIGWIDGET_H
diff --git a/src/accounts/twitter/twitterconfigwidget.ui b/src/accounts/twitter/twitterconfigwidget.ui
new file mode 100644
index 000000000..f60dbb5f8
--- /dev/null
+++ b/src/accounts/twitter/twitterconfigwidget.ui
@@ -0,0 +1,381 @@
+
+
+ TwitterConfigWidget
+
+
+
+ 0
+ 0
+ 580
+ 390
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 580
+ 390
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 0
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+
+
+ :/twitter-icon.png
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 11
+ 75
+ true
+
+
+
+ Configure this Twitter account
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Expanding
+
+
+
+ 40
+ 0
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ The Twitter plugin allows you to discover and play music from your Twitter friends running Tomahawk and post messages to your account.
+
+
+ true
+
+
+
+ -
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ Status: No saved credentials
+
+
+ Qt::AutoText
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Authenticate with Twitter
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Twitter Connections
+
+
+
-
+
+
+
+If you only want to post tweets, you're done.
+
+If you want to connect Tomahawk to your friends using Twitter, select the type of tweet and press the button below to send a sync message. You must both be following each other as Direct Messages are used. Then be (very) patient -- it can take several minutes!
+
+You can re-send a sync message at any time simply by sending another tweet using the button.
+
+
+ true
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Expanding
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
+ QLayout::SetFixedSize
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ Select the kind of tweet you would like, then press the button to post it:
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Fixed
+
+
+
+ 20
+ 10
+
+
+
+
+ -
+
+
-
+
+
+
+ 0
+ 0
+
+
+
-
+
+ Global Tweet
+
+
+ -
+
+ @Mention
+
+
+ -
+
+ Direct Message
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Fixed
+
+
+
+ 10
+ 20
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 250
+ 0
+
+
+
+ e.g. @tomahawk
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Fixed
+
+
+
+ 10
+ 20
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Send Message
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt
index 8e3a940d7..e9ed1083b 100644
--- a/src/libtomahawk/CMakeLists.txt
+++ b/src/libtomahawk/CMakeLists.txt
@@ -253,6 +253,7 @@ set( libHeaders
album.h
playlist.h
+ accounts/account.h
accounts/accountmanager.h
sip/SipPlugin.h
diff --git a/src/libtomahawk/accounts/account.h b/src/libtomahawk/accounts/account.h
index f6349e72b..8b2d680df 100644
--- a/src/libtomahawk/accounts/account.h
+++ b/src/libtomahawk/accounts/account.h
@@ -29,7 +29,7 @@
#include "dllmacro.h"
#include "infosystem/infosystem.h"
#include "sip/SipPlugin.h"
-#include
+#include "tomahawksettings.h"
namespace Tomahawk
{
@@ -37,54 +37,128 @@ namespace Tomahawk
namespace Accounts
{
-typedef QMap< QString, bool > ACLMap;
-
enum AccountType { InfoType, SipType };
+inline QString generateId( const QString &factoryId )
+{
+ QString uniq = QUuid::createUuid().toString().mid( 1, 8 );
+ return factoryId + "_" + uniq;
+}
+
class DLLEXPORT Account : public QObject
{
-
Q_OBJECT
public:
- explicit Account()
+ explicit Account( const QString &accountId )
: QObject()
+ , m_autoConnect( false )
+ , m_accountId( accountId ) {}
+ virtual ~Account() {}
+
+ virtual QString accountServiceName() const { return m_accountServiceName; } // e.g. "Twitter", "Last.fm"
+ virtual QString accountFriendlyName() const { return m_accountFriendlyName; } // e.g. screen name on the service, JID, etc.
+ virtual bool autoConnect() const { return m_autoConnect; }
+ virtual QString accountId() const { return m_accountId; }
+
+ virtual QVariantHash configuration() const { return m_configuration; }
+ virtual QWidget* configurationWidget() = 0;
+
+ virtual QVariantHash credentials() { return m_credentials; }
+
+ virtual QVariantMap acl() const { return m_acl; }
+ virtual QWidget* aclWidget() = 0;
+
+ virtual QIcon icon() const = 0;
+
+ virtual bool authenticate() = 0; //if none needed, just return true
+ virtual bool isAuthenticated() = 0;
+
+ virtual Tomahawk::InfoSystem::InfoPlugin* infoPlugin() = 0;
+ virtual SipPlugin* sipPlugin() = 0;
+
+ virtual QSet< AccountType > types() const
+ {
+ QSet< AccountType > set;
+ foreach ( QString type, m_types )
{
- m_autoConnect = false;
+ if ( type == "InfoType" )
+ set << InfoType;
+ else if ( type == "SipType" )
+ set << SipType;
}
- virtual ~Account();
+ return set;
+ }
- QString accountServiceName() const; // e.g. "Twitter", "Last.fm"
- void setAccountServiceName( const QString &serviceName );
+signals:
+ void configurationChanged();
- QString accountFriendlyName() const; // e.g. screen name on the service, JID, etc.
- void setAccountFriendlyName( const QString &friendlyName );
+protected:
+ virtual void setAccountServiceName( const QString &serviceName ) { m_accountServiceName = serviceName; }
+ virtual void setAccountFriendlyName( const QString &friendlyName ) { m_accountFriendlyName = friendlyName; }
+ virtual void setAutoConnect( bool autoConnect ) { m_autoConnect = autoConnect; }
+ virtual void setAccountId( const QString &accountId ) { m_accountId = accountId; }
+ virtual void setCredentials( const QVariantHash &credentialHash ) { m_credentials = credentialHash; }
+
+ virtual void setConfiguration( const QVariantHash &configuration ) { m_configuration = configuration; }
+
+ virtual void setAcl( const QVariantMap &acl ) { m_acl = acl; }
- bool autoConnect() const { return m_autoConnect; }
- void setAutoConnect( bool autoConnect ) { m_autoConnect = autoConnect; }
+ virtual void setTypes( const QSet< AccountType > types )
+ {
+ m_types = QStringList();
+ foreach ( AccountType type, types )
+ {
+ switch( type )
+ {
+ case InfoType:
+ m_types << "InfoType";
+ case SipType:
+ m_types << "SipType";
+ }
+ }
+ syncConfig();
+ }
+
+ virtual void loadFromConfig( const QString &accountId )
+ {
+ m_accountId = accountId;
+ TomahawkSettings* s = TomahawkSettings::instance();
+ s->beginGroup( "accounts/" + m_accountId );
+ m_accountFriendlyName = s->value( "accountFriendlyName", QString() ).toString();
+ m_autoConnect = s->value( "autoConnect", false ).toBool();
+ m_credentials = s->value( "credentials", QVariantHash() ).toHash();
+ m_configuration = s->value( "configuration", QVariantHash() ).toHash();
+ m_acl = s->value( "acl", QVariantMap() ).toMap();
+ m_types = s->value( "types", QStringList() ).toStringList();
+ s->endGroup();
+ s->sync();
+ }
- QHash< QString, QString > credentials() { return m_credentials; }
- void setCredentials( const QHash< QString, QString > &credentialMap );
+ virtual void syncConfig()
+ {
+ TomahawkSettings* s = TomahawkSettings::instance();
+ s->beginGroup( "accounts/" + m_accountId );
+ s->setValue( "accountFriendlyName", m_accountFriendlyName );
+ s->setValue( "autoConnect", m_autoConnect );
+ s->setValue( "credentials", m_credentials );
+ s->setValue( "configuration", m_configuration );
+ s->setValue( "acl", m_acl );
+ s->setValue( "types", m_types );
+ s->endGroup();
+ s->sync();
- QIcon icon() const;
+ emit configurationChanged();
+ }
- QVariantMap configuration() const;
- void setConfiguration( const QVariantMap &configuration );
- QWidget* configurationWidget();
-
- ACLMap acl() const;
- void setAcl( const ACLMap &acl );
- QWidget* aclWidget();
-
- QSet< AccountType > types() const;
- void setTypes( const QSet< AccountType > types );
-
- Tomahawk::InfoSystem::InfoPlugin* infoPlugin();
- SipPlugin* sipPlugin();
-
-private:
+ QString m_accountServiceName;
+ QString m_accountFriendlyName;
bool m_autoConnect;
- QHash< QString, QString > m_credentials;
+ QString m_accountId;
+ QVariantHash m_credentials;
+ QVariantHash m_configuration;
+ QVariantMap m_acl;
+ QStringList m_types;
};
class DLLEXPORT AccountFactory : public QObject
@@ -103,13 +177,6 @@ public:
virtual bool isUnique() const { return false; }
virtual Account* createAccount( const QString& pluginId = QString() ) = 0;
-
-protected:
- QString generateId()
- {
- QString uniq = QUuid::createUuid().toString().mid( 1, 8 );
- return factoryId() + "_" + uniq;
- }
};
};
diff --git a/src/libtomahawk/accounts/accountmanager.cpp b/src/libtomahawk/accounts/accountmanager.cpp
index 90e60bd04..385403908 100644
--- a/src/libtomahawk/accounts/accountmanager.cpp
+++ b/src/libtomahawk/accounts/accountmanager.cpp
@@ -31,9 +31,20 @@ namespace Accounts
{
-AccountManager::AccountManager()
- : QObject()
+AccountManager* AccountManager::s_instance = 0;
+
+
+AccountManager*
+AccountManager::instance()
{
+ return s_instance;
+}
+
+
+AccountManager::AccountManager( QObject *parent )
+ : QObject( parent )
+{
+ s_instance = this;
loadPluginFactories( findPluginFactories() );
}
@@ -70,7 +81,7 @@ AccountManager::findPluginFactories()
pluginDirs << appDir << libDir << lib64Dir << QDir( qApp->applicationDirPath() );
foreach ( const QDir& pluginDir, pluginDirs )
{
- qDebug() << "Checking directory for plugins:" << pluginDir;
+ tDebug() << Q_FUNC_INFO << "Checking directory for plugins:" << pluginDir;
foreach ( QString fileName, pluginDir.entryList( QStringList() << "*tomahawk_account_*.so" << "*tomahawk_account_*.dylib" << "*tomahawk_account_*.dll", QDir::Files ) )
{
if ( fileName.startsWith( "libtomahawk_account" ) )
@@ -94,7 +105,7 @@ AccountManager::loadPluginFactories( const QStringList& paths )
if ( !QLibrary::isLibrary( fileName ) )
continue;
- qDebug() << "Trying to load plugin:" << fileName;
+ tDebug() << Q_FUNC_INFO << "Trying to load plugin:" << fileName;
loadPluginFactory( fileName );
}
}
@@ -114,17 +125,17 @@ AccountManager::loadPluginFactory( const QString& path )
QObject* plugin = loader.instance();
if ( !plugin )
{
- qDebug() << "Error loading plugin:" << loader.errorString();
+ tDebug() << Q_FUNC_INFO << "Error loading plugin:" << loader.errorString();
}
AccountFactory* accountfactory = qobject_cast( plugin );
if ( accountfactory )
{
- qDebug() << "Loaded plugin factory:" << loader.fileName() << accountfactory->factoryId() << accountfactory->prettyName();
+ tDebug() << Q_FUNC_INFO << "Loaded plugin factory:" << loader.fileName() << accountfactory->factoryId() << accountfactory->prettyName();
m_accountFactories[ accountfactory->factoryId() ] = accountfactory;
} else
{
- qDebug() << "Loaded invalid plugin.." << loader.fileName();
+ tDebug() << Q_FUNC_INFO << "Loaded invalid plugin.." << loader.fileName();
}
}
@@ -162,9 +173,11 @@ AccountManager::loadPlugin( const QString& pluginId )
void
AccountManager::addAccountPlugin( Account* account )
{
- m_accounts << account;
+ m_accounts.append( account );
- //FIXME:
+ foreach( AccountType type, account->types() )
+ m_accountsByAccountType[ type ].append( account );
+ //TODO:
//emit pluginAdded( account );
}
diff --git a/src/libtomahawk/accounts/accountmanager.h b/src/libtomahawk/accounts/accountmanager.h
index 640dae794..9cb4d5ee7 100644
--- a/src/libtomahawk/accounts/accountmanager.h
+++ b/src/libtomahawk/accounts/accountmanager.h
@@ -38,7 +38,9 @@ class DLLEXPORT AccountManager : public QObject
Q_OBJECT
public:
- explicit AccountManager();
+ static AccountManager* instance();
+
+ explicit AccountManager( QObject *parent );
virtual ~AccountManager();
QStringList findPluginFactories();
@@ -50,12 +52,15 @@ public:
Account* loadPlugin( const QString &pluginId );
QString factoryFromId( const QString& pluginId ) const;
- //QSet< Account > getAccounts( Tomahawk::Accounts::AccountType type );
+ QList< Account* > getAccounts() { return m_accounts; };
+ QList< Account* > getAccounts( Tomahawk::Accounts::AccountType type ) { return m_accountsByAccountType[ type ]; }
private:
- QSet< Account* > m_accounts;
+ QList< Account* > m_accounts;
+ QHash< AccountType, QList< Account* > > m_accountsByAccountType;
QHash< QString, AccountFactory* > m_accountFactories;
-
+
+ static AccountManager* s_instance;
};
};
diff --git a/src/sip/twitter/twittersip.cpp b/src/sip/twitter/twittersip.cpp
index 8d77d34dd..c349bf62c 100644
--- a/src/sip/twitter/twittersip.cpp
+++ b/src/sip/twitter/twittersip.cpp
@@ -86,9 +86,6 @@ TwitterPlugin::TwitterPlugin( const QString& pluginId )
m_connectTimer.setInterval( 180000 );
m_connectTimer.setSingleShot( false );
connect( &m_connectTimer, SIGNAL( timeout() ), SLOT( connectTimerFired() ) );
-
- m_configWidget = QWeakPointer< TwitterConfigWidget >( new TwitterConfigWidget( this, 0 ) );
- connect( m_configWidget.data(), SIGNAL( twitterAuthed( bool ) ), SLOT( configDialogAuthedSignalSlot( bool ) ) );
}
diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp
index 83ac51699..60f535ad4 100644
--- a/src/tomahawkapp.cpp
+++ b/src/tomahawkapp.cpp
@@ -35,6 +35,7 @@
#include "album.h"
#include "collection.h"
#include "infosystem/infosystem.h"
+#include "accounts/accountmanager.h"
#include "database/database.h"
#include "database/databasecollection.h"
#include "database/databasecommand_collectionstats.h"
@@ -212,6 +213,10 @@ TomahawkApp::init()
connect( m_shortcutHandler.data(), SIGNAL( mute() ), m_audioEngine.data(), SLOT( mute() ) );
}
+ tDebug() << "Init AccountManager.";
+ m_accountManager = QWeakPointer< Tomahawk::Accounts::AccountManager >( new Tomahawk::Accounts::AccountManager( this ) );
+ Tomahawk::Accounts::AccountManager::instance()->loadFromConfig();
+
tDebug() << "Init InfoSystem.";
m_infoSystem = QWeakPointer( new Tomahawk::InfoSystem::InfoSystem( this ) );
@@ -499,6 +504,12 @@ TomahawkApp::initServent()
void
TomahawkApp::initSIP()
{
+ foreach ( Tomahawk::Accounts::Account* account, Tomahawk::Accounts::AccountManager::instance()->getAccounts() )
+ {
+ if ( account->configurationWidget() )
+ account->configurationWidget()->show();
+ }
+
//FIXME: jabber autoconnect is really more, now that there is sip -- should be renamed and/or split out of jabber-specific settings
if ( !arguments().contains( "--nosip" ) )
{
diff --git a/src/tomahawkapp.h b/src/tomahawkapp.h
index 0b3a0b1a8..528127825 100644
--- a/src/tomahawkapp.h
+++ b/src/tomahawkapp.h
@@ -53,6 +53,11 @@ namespace Tomahawk
{
class InfoSystem;
}
+
+ namespace Accounts
+ {
+ class AccountManager;
+ }
}
#ifdef LIBLASTFM_FOUND
@@ -119,6 +124,7 @@ private:
QWeakPointer m_infoSystem;
QWeakPointer m_xmppBot;
QWeakPointer m_shortcutHandler;
+ QWeakPointer< Tomahawk::Accounts::AccountManager > m_accountManager;
bool m_scrubFriendlyName;
#ifdef LIBLASTFM_FOUND
@@ -139,3 +145,7 @@ Q_DECLARE_METATYPE( QPersistentModelIndex );
#endif // TOMAHAWKAPP_H
+
+struct A;
+
+struct A;