From c7f6144bfe05e077dd95d3b3c484dbc54e39f2b1 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Sat, 24 Sep 2011 13:29:43 -0400 Subject: [PATCH 001/104] First commit towards new accounts system. Shouldn't work, but compiles. --- src/libtomahawk/CMakeLists.txt | 6 + src/libtomahawk/accounts/account.h | 79 ++++++-- src/libtomahawk/accounts/accountmanager.cpp | 174 ++++++++++++++++++ src/libtomahawk/accounts/accountmanager.h | 65 +++++++ src/libtomahawk/sip/SipHandler.cpp | 12 +- src/libtomahawk/sip/SipHandler.h | 6 +- src/libtomahawk/sip/SipPlugin.h | 2 +- src/libtomahawk/tomahawksettings.cpp | 32 ++++ src/libtomahawk/tomahawksettings.h | 12 +- src/sip/jabber/jabber.cpp | 5 +- src/sip/jabber/jabber.h | 2 +- src/sip/twitter/CMakeLists.txt | 4 +- src/sip/twitter/twitterconfigwidget.cpp | 4 +- .../twitter/{twitter.cpp => twittersip.cpp} | 7 +- src/sip/twitter/{twitter.h => twittersip.h} | 2 +- src/sip/zeroconf/zeroconf.cpp | 22 ++- src/sip/zeroconf/zeroconf.h | 7 +- src/tomahawkapp.cpp | 2 +- 18 files changed, 395 insertions(+), 48 deletions(-) create mode 100644 src/libtomahawk/accounts/accountmanager.cpp create mode 100644 src/libtomahawk/accounts/accountmanager.h rename src/sip/twitter/{twitter.cpp => twittersip.cpp} (99%) rename src/sip/twitter/{twitter.h => twittersip.h} (99%) diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index dd34dde69..8e3a940d7 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -34,6 +34,8 @@ set( libSources dropjob.cpp playlistinterface.cpp + accounts/accountmanager.cpp + sip/SipPlugin.cpp sip/SipHandler.cpp sip/SipModel.cpp @@ -251,6 +253,8 @@ set( libHeaders album.h playlist.h + accounts/accountmanager.h + sip/SipPlugin.h sip/SipHandler.h sip/SipModel.h @@ -443,6 +447,8 @@ set( libHeaders set( libHeaders_NoMOC viewpage.h + accounts/account.h + infosystem/infoplugins/unix/imageconverter.h playlist/dynamic/GeneratorInterface.h diff --git a/src/libtomahawk/accounts/account.h b/src/libtomahawk/accounts/account.h index f1219d80c..f6349e72b 100644 --- a/src/libtomahawk/accounts/account.h +++ b/src/libtomahawk/accounts/account.h @@ -22,53 +22,100 @@ #include #include #include +#include +#include #include "typedefs.h" #include "dllmacro.h" #include "infosystem/infosystem.h" #include "sip/SipPlugin.h" +#include namespace Tomahawk { -class DLLEXPORT Account +namespace Accounts { - typedef QMap< QString, bool > ACLMap; +typedef QMap< QString, bool > ACLMap; + +enum AccountType { InfoType, SipType }; + +class DLLEXPORT Account : public QObject +{ + + Q_OBJECT public: - enum AccountTypes { InfoType, SipType }; - - explicit Account(); + explicit Account() + : QObject() + { + m_autoConnect = false; + } virtual ~Account(); - QString accountServiceName(); // e.g. "Twitter", "Last.fm" + QString accountServiceName() const; // e.g. "Twitter", "Last.fm" void setAccountServiceName( const QString &serviceName ); - QString accountFriendlyName(); // e.g. screen name on the service, JID, etc. + QString accountFriendlyName() const; // e.g. screen name on the service, JID, etc. void setAccountFriendlyName( const QString &friendlyName ); - bool autoConnect(); - void setAutoConnect( bool autoConnect ); + bool autoConnect() const { return m_autoConnect; } + void setAutoConnect( bool autoConnect ) { m_autoConnect = autoConnect; } - QStringMap credentials(); - void setCredentials( const QStringMap &credentialMap ); + QHash< QString, QString > credentials() { return m_credentials; } + void setCredentials( const QHash< QString, QString > &credentialMap ); + + QIcon icon() const; - QVariantMap configuration(); + QVariantMap configuration() const; void setConfiguration( const QVariantMap &configuration ); QWidget* configurationWidget(); - ACLMap acl(); + ACLMap acl() const; void setAcl( const ACLMap &acl ); QWidget* aclWidget(); - QSet< AccountTypes > types(); - void setTypes( const QSet< AccountTypes > types ); + QSet< AccountType > types() const; + void setTypes( const QSet< AccountType > types ); Tomahawk::InfoSystem::InfoPlugin* infoPlugin(); SipPlugin* sipPlugin(); + +private: + bool m_autoConnect; + QHash< QString, QString > m_credentials; +}; + +class DLLEXPORT AccountFactory : public QObject +{ + Q_OBJECT +public: + AccountFactory() {} + virtual ~AccountFactory() {} + + // display name for plugin + virtual QString prettyName() const = 0; + // internal name + virtual QString factoryId() const = 0; + // if the user can create multiple + virtual QIcon icon() const { return QIcon(); } + 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; + } }; }; -#endif // ACCOUNT_H +}; + +Q_DECLARE_INTERFACE( Tomahawk::Accounts::AccountFactory, "tomahawk.AccountFactory/1.0" ) + +#endif \ No newline at end of file diff --git a/src/libtomahawk/accounts/accountmanager.cpp b/src/libtomahawk/accounts/accountmanager.cpp new file mode 100644 index 000000000..90e60bd04 --- /dev/null +++ b/src/libtomahawk/accounts/accountmanager.cpp @@ -0,0 +1,174 @@ +/* === 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 "accountmanager.h" +#include "config.h" + +#include +#include +#include +#include + +namespace Tomahawk +{ + +namespace Accounts +{ + + +AccountManager::AccountManager() + : QObject() +{ + loadPluginFactories( findPluginFactories() ); +} + + +AccountManager::~AccountManager() +{ + +} + + +QStringList +AccountManager::findPluginFactories() +{ + QStringList paths; + QList< QDir > pluginDirs; + + QDir appDir( qApp->applicationDirPath() ); + #ifdef Q_WS_MAC + if ( appDir.dirName() == "MacOS" ) + { + // Development convenience-hack + appDir.cdUp(); + appDir.cdUp(); + appDir.cdUp(); + } + #endif + + QDir libDir( CMAKE_INSTALL_PREFIX "/lib" ); + + QDir lib64Dir( appDir ); + lib64Dir.cdUp(); + lib64Dir.cd( "lib64" ); + + pluginDirs << appDir << libDir << lib64Dir << QDir( qApp->applicationDirPath() ); + foreach ( const QDir& pluginDir, pluginDirs ) + { + qDebug() << "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" ) ) + { + const QString path = pluginDir.absoluteFilePath( fileName ); + if ( !paths.contains( path ) ) + paths << path; + } + } + } + + return paths; +} + + +void +AccountManager::loadPluginFactories( const QStringList& paths ) +{ + foreach ( QString fileName, paths ) + { + if ( !QLibrary::isLibrary( fileName ) ) + continue; + + qDebug() << "Trying to load plugin:" << fileName; + loadPluginFactory( fileName ); + } +} + + +QString +AccountManager::factoryFromId( const QString& pluginId ) const +{ + return pluginId.split( "_" ).first(); +} + + +void +AccountManager::loadPluginFactory( const QString& path ) +{ + QPluginLoader loader( path ); + QObject* plugin = loader.instance(); + if ( !plugin ) + { + qDebug() << "Error loading plugin:" << loader.errorString(); + } + + AccountFactory* accountfactory = qobject_cast( plugin ); + if ( accountfactory ) + { + qDebug() << "Loaded plugin factory:" << loader.fileName() << accountfactory->factoryId() << accountfactory->prettyName(); + m_accountFactories[ accountfactory->factoryId() ] = accountfactory; + } else + { + qDebug() << "Loaded invalid plugin.." << loader.fileName(); + } +} + + +void +AccountManager::loadFromConfig() +{ + QStringList pluginIds = TomahawkSettings::instance()->accountPlugins(); + foreach( const QString& pluginId, pluginIds ) + { + QString pluginFactory = factoryFromId( pluginId ); + if( m_accountFactories.contains( pluginFactory ) ) + { + Account* a = loadPlugin( pluginId ); + addAccountPlugin( a ); + } + } +} + + + +Account* +AccountManager::loadPlugin( const QString& pluginId ) +{ + QString factoryName = factoryFromId( pluginId ); + + Q_ASSERT( m_accountFactories.contains( factoryName ) ); + + Account* account = m_accountFactories[ factoryName ]->createAccount( pluginId ); + + // caller responsible for calling pluginAdded() and hookupPlugin + return account; +} + +void +AccountManager::addAccountPlugin( Account* account ) +{ + m_accounts << account; + + //FIXME: + //emit pluginAdded( account ); +} + + +}; + +}; diff --git a/src/libtomahawk/accounts/accountmanager.h b/src/libtomahawk/accounts/accountmanager.h new file mode 100644 index 000000000..640dae794 --- /dev/null +++ b/src/libtomahawk/accounts/accountmanager.h @@ -0,0 +1,65 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Christian Muehlhaeuser + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#ifndef ACCOUNTMANAGER_H +#define ACCOUNTMANAGER_H + +#include + +#include "typedefs.h" +#include "dllmacro.h" +#include "infosystem/infosystem.h" +#include "sip/SipPlugin.h" +#include "account.h" + +namespace Tomahawk +{ + +namespace Accounts +{ + +class DLLEXPORT AccountManager : public QObject +{ + Q_OBJECT + +public: + explicit AccountManager(); + virtual ~AccountManager(); + + QStringList findPluginFactories(); + void loadPluginFactories( const QStringList &paths ); + + void loadFromConfig(); + void loadPluginFactory( const QString &path ); + void addAccountPlugin( Account* account ); + Account* loadPlugin( const QString &pluginId ); + QString factoryFromId( const QString& pluginId ) const; + + //QSet< Account > getAccounts( Tomahawk::Accounts::AccountType type ); + +private: + QSet< Account* > m_accounts; + QHash< QString, AccountFactory* > m_accountFactories; + +}; + +}; + +}; + +#endif \ No newline at end of file diff --git a/src/libtomahawk/sip/SipHandler.cpp b/src/libtomahawk/sip/SipHandler.cpp index 8b418b9f0..6364a97c7 100644 --- a/src/libtomahawk/sip/SipHandler.cpp +++ b/src/libtomahawk/sip/SipHandler.cpp @@ -266,14 +266,14 @@ SipHandler::checkSettings() void -SipHandler::addSipPlugin( SipPlugin* p, bool enabled, bool startup ) +SipHandler::addSipPlugin( SipPlugin* p, bool enabled ) { m_allPlugins << p; hookUpPlugin( p ); if ( enabled ) { - p->connectPlugin( startup ); + p->connectPlugin(); m_enabledPlugins << p; } @@ -308,7 +308,7 @@ SipHandler::hasPluginType( const QString& factoryId ) const void -SipHandler::loadFromConfig( bool startup ) +SipHandler::loadFromConfig() { QStringList pluginIds = TomahawkSettings::instance()->sipPlugins(); QStringList enabled = TomahawkSettings::instance()->enabledSipPlugins(); @@ -318,7 +318,7 @@ SipHandler::loadFromConfig( bool startup ) if( m_pluginFactories.contains( pluginFactory ) ) { SipPlugin* p = loadPlugin( pluginId ); - addSipPlugin( p, enabled.contains( pluginId ), startup ); + addSipPlugin( p, enabled.contains( pluginId ) ); } } m_connected = true; @@ -371,7 +371,7 @@ SipHandler::enablePlugin( SipPlugin* p ) void -SipHandler::connectPlugin( bool startup, const QString &pluginId ) +SipHandler::connectPlugin( const QString &pluginId ) { #ifndef TOMAHAWK_HEADLESS if ( !TomahawkSettings::instance()->acceptedLegalWarning() ) @@ -394,7 +394,7 @@ SipHandler::connectPlugin( bool startup, const QString &pluginId ) { Q_ASSERT( m_enabledPlugins.contains( sip ) ); // make sure the plugin we're connecting is enabled. should always be the case //each sip should refreshProxy() or take care of that function in some other way during connection - sip->connectPlugin( startup ); + sip->connectPlugin(); } } } diff --git a/src/libtomahawk/sip/SipHandler.h b/src/libtomahawk/sip/SipHandler.h index 8eed7f3a2..c7a6e9999 100644 --- a/src/libtomahawk/sip/SipHandler.h +++ b/src/libtomahawk/sip/SipHandler.h @@ -41,9 +41,9 @@ public: QList< SipPlugin* > allPlugins() const; QList< SipPlugin* > enabledPlugins() const; QList< SipPlugin* > connectedPlugins() const; - void loadFromConfig( bool startup = false ); + void loadFromConfig(); - void addSipPlugin( SipPlugin* p, bool enable = true, bool connectImmediately = true ); + void addSipPlugin( SipPlugin* p, bool enable = true ); void removeSipPlugin( SipPlugin* p ); bool hasPluginType( const QString& factoryId ) const; @@ -60,7 +60,7 @@ public slots: void enablePlugin( SipPlugin* p ); void disablePlugin( SipPlugin* p ); - void connectPlugin( bool startup = false, const QString &pluginId = QString() ); + void connectPlugin( const QString &pluginId = QString() ); void disconnectPlugin( const QString &pluginId = QString() ); void connectAll(); void disconnectAll(); diff --git a/src/libtomahawk/sip/SipPlugin.h b/src/libtomahawk/sip/SipPlugin.h index 1830a9ea5..2797c3d0a 100644 --- a/src/libtomahawk/sip/SipPlugin.h +++ b/src/libtomahawk/sip/SipPlugin.h @@ -82,7 +82,7 @@ public: virtual const QStringList peersOnline() const; public slots: - virtual bool connectPlugin( bool startup = false ) = 0; + virtual bool connectPlugin() = 0; virtual void disconnectPlugin() = 0; virtual void checkSettings() = 0; diff --git a/src/libtomahawk/tomahawksettings.cpp b/src/libtomahawk/tomahawksettings.cpp index 1aa88bcbb..ad3239ba7 100644 --- a/src/libtomahawk/tomahawksettings.cpp +++ b/src/libtomahawk/tomahawksettings.cpp @@ -650,6 +650,38 @@ TomahawkSettings::removeSipPlugin( const QString& pluginId ) } +QStringList +TomahawkSettings::accountPlugins() const +{ + return value( "accounts/allplugins", QStringList() ).toStringList(); +} + + +void +TomahawkSettings::setAccountPlugins( const QStringList& plugins ) +{ + setValue( "accounts/allplugins", plugins ); +} + + +void +TomahawkSettings::addAccountPlugin( const QString& pluginId ) +{ + QStringList list = accountPlugins(); + list << pluginId; + setAccountPlugins( list ); +} + + +void +TomahawkSettings::removeAccountPlugin( const QString& pluginId ) +{ + QStringList list = accountPlugins(); + list.removeAll( pluginId ); + setAccountPlugins( list ); +} + + TomahawkSettings::ExternalAddressMode TomahawkSettings::externalAddressMode() const { diff --git a/src/libtomahawk/tomahawksettings.h b/src/libtomahawk/tomahawksettings.h index 9f518b21a..d644b1210 100644 --- a/src/libtomahawk/tomahawksettings.h +++ b/src/libtomahawk/tomahawksettings.h @@ -97,9 +97,6 @@ public: void setSipPlugins( const QStringList& plugins ); QStringList sipPlugins() const; - void setBookmarkPlaylist( const QString& guid ); - QString bookmarkPlaylist() const; - // just the enabled sip plugins. void setEnabledSipPlugins( const QStringList& list ); QStringList enabledSipPlugins() const; @@ -109,6 +106,15 @@ public: void addSipPlugin( const QString& pluginId, bool enable = true ); void removeSipPlugin( const QString& pluginId ); + void setAccountPlugins( const QStringList& plugins ); + QStringList accountPlugins() const; + void addAccountPlugin( const QString& pluginId ); + void removeAccountPlugin( const QString& pluginId ); + + + void setBookmarkPlaylist( const QString& guid ); + QString bookmarkPlaylist() const; + /// Network settings enum ExternalAddressMode { Lan, Upnp }; ExternalAddressMode externalAddressMode() const; diff --git a/src/sip/jabber/jabber.cpp b/src/sip/jabber/jabber.cpp index 91c0a6371..bedcb7392 100644 --- a/src/sip/jabber/jabber.cpp +++ b/src/sip/jabber/jabber.cpp @@ -193,9 +193,8 @@ JabberPlugin::icon() const bool -JabberPlugin::connectPlugin( bool startup ) +JabberPlugin::connectPlugin() { - Q_UNUSED( startup ); qDebug() << Q_FUNC_INFO; if(m_client->isConnected()) @@ -527,7 +526,7 @@ JabberPlugin::checkSettings() setupClientHelper(); qDebug() << Q_FUNC_INFO << "Updated settings"; - connectPlugin( false ); + connectPlugin(); } } diff --git a/src/sip/jabber/jabber.h b/src/sip/jabber/jabber.h index cc10e5322..c2b7d4585 100644 --- a/src/sip/jabber/jabber.h +++ b/src/sip/jabber/jabber.h @@ -88,7 +88,7 @@ signals: void jidChanged( const QString& ); public slots: - virtual bool connectPlugin( bool startup ); + virtual bool connectPlugin(); void disconnectPlugin(); void checkSettings(); void sendMsg( const QString& to, const QString& msg ); diff --git a/src/sip/twitter/CMakeLists.txt b/src/sip/twitter/CMakeLists.txt index f5f0e7fd4..32eb308f1 100644 --- a/src/sip/twitter/CMakeLists.txt +++ b/src/sip/twitter/CMakeLists.txt @@ -7,13 +7,13 @@ add_definitions( -DQT_SHARED ) add_definitions( -DSIPDLLEXPORT_PRO ) set( twitterSources - twitter.cpp + twittersip.cpp twitterconfigwidget.cpp tomahawkoauthtwitter.cpp ) set( twitterHeaders - twitter.h + twittersip.h twitterconfigwidget.h tomahawkoauthtwitter.h ) diff --git a/src/sip/twitter/twitterconfigwidget.cpp b/src/sip/twitter/twitterconfigwidget.cpp index 535dcc8d1..357bc038f 100644 --- a/src/sip/twitter/twitterconfigwidget.cpp +++ b/src/sip/twitter/twitterconfigwidget.cpp @@ -17,7 +17,7 @@ */ #include "twitterconfigwidget.h" -#include "twitter.h" +#include "twittersip.h" #include "ui_twitterconfigwidget.h" #include "tomahawksettings.h" @@ -123,7 +123,7 @@ TwitterConfigWidget::authenticateVerifyReply( const QTweetUser &user ) ui->twitterUserTweetLineEdit->setVisible( false ); ui->twitterTweetGotTomahawkButton->setText( tr( "Tweet!" ) ); - m_plugin->connectPlugin( false ); + m_plugin->connectPlugin(); emit twitterAuthed( true ); emit sizeHintChanged(); diff --git a/src/sip/twitter/twitter.cpp b/src/sip/twitter/twittersip.cpp similarity index 99% rename from src/sip/twitter/twitter.cpp rename to src/sip/twitter/twittersip.cpp index 7b916fe6b..8d77d34dd 100644 --- a/src/sip/twitter/twitter.cpp +++ b/src/sip/twitter/twittersip.cpp @@ -16,7 +16,7 @@ * along with Tomahawk. If not, see . */ -#include "twitter.h" +#include "twittersip.h" #include "twitterconfigwidget.h" @@ -158,9 +158,8 @@ QWidget* TwitterPlugin::configWidget() } bool -TwitterPlugin::connectPlugin( bool startup ) +TwitterPlugin::connectPlugin() { - Q_UNUSED( startup ); qDebug() << Q_FUNC_INFO; m_cachedPeers = twitterCachedPeers(); @@ -810,7 +809,7 @@ TwitterPlugin::checkSettings() if ( m_state == Disconnected ) return; disconnectPlugin(); - connectPlugin( false ); + connectPlugin(); } diff --git a/src/sip/twitter/twitter.h b/src/sip/twitter/twittersip.h similarity index 99% rename from src/sip/twitter/twitter.h rename to src/sip/twitter/twittersip.h index 3ca0688ca..40a8e3b73 100644 --- a/src/sip/twitter/twitter.h +++ b/src/sip/twitter/twittersip.h @@ -73,7 +73,7 @@ public: virtual QWidget* configWidget(); public slots: - virtual bool connectPlugin( bool startup ); + virtual bool connectPlugin(); void disconnectPlugin(); void checkSettings(); void refreshProxy(); diff --git a/src/sip/zeroconf/zeroconf.cpp b/src/sip/zeroconf/zeroconf.cpp index 80c0ffccd..59fd33de9 100644 --- a/src/sip/zeroconf/zeroconf.cpp +++ b/src/sip/zeroconf/zeroconf.cpp @@ -20,6 +20,8 @@ #include +#include + #include "tomahawksettings.h" #include "utils/logger.h" @@ -39,6 +41,9 @@ ZeroconfPlugin::ZeroconfPlugin ( const QString& pluginId ) , m_cachedNodes() { qDebug() << Q_FUNC_INFO; + m_advertisementTimer.setInterval( 60000 ); + m_advertisementTimer.setSingleShot( false ); + connect( &m_advertisementTimer, SIGNAL( timeout() ), this, SLOT( advertise() ) ); } ZeroconfPlugin::~ZeroconfPlugin() {} @@ -75,16 +80,14 @@ ZeroconfFactory::icon() const bool -ZeroconfPlugin::connectPlugin( bool startup ) +ZeroconfPlugin::connectPlugin() { - Q_UNUSED( startup ); - 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 ) ) ); - m_zeroconf->advertise(); + advertise(); m_state = Connected; foreach( const QStringList& nodeSet, m_cachedNodes ) @@ -93,12 +96,16 @@ ZeroconfPlugin::connectPlugin( bool startup ) Servent::instance()->connectToPeer( nodeSet[0], nodeSet[1].toInt(), "whitelist", nodeSet[2], nodeSet[3] ); } m_cachedNodes.clear(); + + m_advertisementTimer.start(); + return true; } void ZeroconfPlugin::disconnectPlugin() { + m_advertisementTimer.stop(); m_state = Disconnected; delete m_zeroconf; @@ -112,6 +119,13 @@ ZeroconfPlugin::icon() const } +void +ZeroconfPlugin::advertise() +{ + m_zeroconf->advertise(); +} + + void ZeroconfPlugin::lanHostFound( const QString& host, int port, const QString& name, const QString& nodeid ) { diff --git a/src/sip/zeroconf/zeroconf.h b/src/sip/zeroconf/zeroconf.h index 5c1870ef6..a1e9460e9 100644 --- a/src/sip/zeroconf/zeroconf.h +++ b/src/sip/zeroconf/zeroconf.h @@ -24,6 +24,8 @@ #include "../sipdllmacro.h" +#include + #define MYNAME "Local Network" class SIPDLLEXPORT ZeroconfFactory : public SipPluginFactory @@ -62,9 +64,11 @@ public: virtual void checkSettings() {} public slots: - virtual bool connectPlugin( bool startup ); + virtual bool connectPlugin(); void disconnectPlugin(); + void advertise(); + void sendMsg( const QString& , const QString& ) {} void broadcastMsg( const QString & ) {} void addContact( const QString &, const QString& ) {} @@ -76,6 +80,7 @@ private: TomahawkZeroconf* m_zeroconf; ConnectionState m_state; QVector m_cachedNodes; + QTimer m_advertisementTimer; }; #endif diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index 2b89bda95..83ac51699 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -508,7 +508,7 @@ TomahawkApp::initSIP() tDebug( LOGINFO ) << "Connecting SIP classes"; //SipHandler::instance()->refreshProxy(); - SipHandler::instance()->loadFromConfig( true ); + SipHandler::instance()->loadFromConfig(); } } From 88350b6a6c4ce2facc9f007eb4d08a800a7e199a Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Sat, 24 Sep 2011 17:38:24 -0400 Subject: [PATCH 002/104] More account work; most of the pure-account side of a twitter account, but not yet tested --- src/CMakeLists.txt | 1 + src/accounts/CMakeLists.txt | 1 + src/accounts/twitter/CMakeLists.txt | 54 +++ src/accounts/twitter/resources.qrc | 5 + src/accounts/twitter/tomahawkoauthtwitter.cpp | 32 ++ src/accounts/twitter/tomahawkoauthtwitter.h | 25 ++ src/accounts/twitter/twitter-icon.png | Bin 0 -> 2970 bytes src/accounts/twitter/twitteraccount.cpp | 77 ++++ src/accounts/twitter/twitteraccount.h | 87 ++++ src/accounts/twitter/twitterconfigwidget.cpp | 294 ++++++++++++++ src/accounts/twitter/twitterconfigwidget.h | 84 ++++ src/accounts/twitter/twitterconfigwidget.ui | 381 ++++++++++++++++++ src/libtomahawk/CMakeLists.txt | 1 + src/libtomahawk/accounts/account.h | 145 +++++-- src/libtomahawk/accounts/accountmanager.cpp | 31 +- src/libtomahawk/accounts/accountmanager.h | 13 +- src/sip/twitter/twittersip.cpp | 3 - src/tomahawkapp.cpp | 11 + src/tomahawkapp.h | 10 + 19 files changed, 1200 insertions(+), 55 deletions(-) create mode 100644 src/accounts/CMakeLists.txt create mode 100644 src/accounts/twitter/CMakeLists.txt create mode 100644 src/accounts/twitter/resources.qrc create mode 100644 src/accounts/twitter/tomahawkoauthtwitter.cpp create mode 100644 src/accounts/twitter/tomahawkoauthtwitter.h create mode 100644 src/accounts/twitter/twitter-icon.png create mode 100644 src/accounts/twitter/twitteraccount.cpp create mode 100644 src/accounts/twitter/twitteraccount.h create mode 100644 src/accounts/twitter/twitterconfigwidget.cpp create mode 100644 src/accounts/twitter/twitterconfigwidget.h create mode 100644 src/accounts/twitter/twitterconfigwidget.ui 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 0000000000000000000000000000000000000000..aab1fca8755c0cc5b051bde0d373d5c8bf825c3f GIT binary patch literal 2970 zcmV;L3uW|)P)|0rI6xS8K-7`J=rd>h^jSUiD2nZ)}Y*z&fmBZp6WXI(=KSnqp6Q?THhf}Gt zVQ?vb);s6j<=xj$0AI=%Tew`l{LRxBtMO2eYEC$s7kR8NuHDneXLfJ3er^bO z^VG%NcxWWRDy3l7Yt>*hXrZXU0D@c&CW9{N^LD2Q!B7Y$rkvn#y20i4g3lkECgjvJ zjayGII|8~+UZ9a~BGqeE=F0LSs3J3CP>Y!S|gH9y_J*o_eafxo|xjg`*6AlQ4BSb`7QwBsxBH+Zk7mRplLEtT`Doadj zsw+XER5HL*Vi5eHXiof9Dd(U-Con<+em{I_9fUiBV|FB>9dEbqec};E&Ix$q-R{lg zizS6d^M;yLpwsDK${k`Fi9{hE!t+RkR?buuMYz#>2gW8HlfEqq?d1r53y!>tz}r&?PkFq$SOvv;0pzk6&!KP> z#$7?Mj{DfWAQv)>eI$3FK1Z+h)QybWDMRc{+X8;~_W4$=M%lLYflc5Ja%q95G*wrv zn*lyshzN^SWN9;JmVhK^g(zJ7*Hv(P{B6%Ywe3*K1pM~xbDQNdndPDT*Mp$a!N8<1 zt&#uwy#@x}fkCpP#{-u}W8^(ts(|KN4Hz+K5eXmOcIM0yNLCiAAm|g}gO6_F-wW3r zc&gz_N-ls|t#jS#m7vw>;j>XMMAJxfW;FY0@QNv4^D0?WF%1A zn?s(Q5ip1YcTcGv2+Oq|E6p0W%t@uQFTDQNxfcvtb=}Gp<;?6U+7kh(YOz6x1yCIM zMDWu>*XSMzwN2;U=_>V|Fc22PMA#N3faccs)tbQ@jLqkxF^fo91zGHs(`G-POy8rn z>ApW*B@BdR?dnwwTT&PJ%^%P0G3m7?qrm`u<9=jO`V^1MeIdDS56+xFy0Kuvc0nA% zF=r5N*}NIWiebAS-OU7qjWGV;>4vU(EdcShR92K=zK>u{9+hNvsfaU}T0^ps6*#$h zu*SeLi&R%2EQE=$5ypA5z_0&su39O``?fx~3C6|P15#w?rb2csdut?VyN62@i@qx{ zYmhZu>T#kuOY4_T$wRS@gNy&T3jSco{KM}ySnqa$C^Q;$YT$SQ{l*8mmSirnP}W#o zriN?%Zb^TS3bzu23JBxaq>EOpj^5=0Xz=v~CIfi<6!@h7WLpxmMwwB_sBeUgFcQ`| zK@huc)@d~?*hH78yiF-lP_-2&13)?{ZEEH8TBoaVCD0>K$!fW%Zm%xzEhrZTLS<0 z9tXJnk&NR9vx51i!ZZGn#gWWZ0tlQIIR1kbV>Z?w6EV)23L`HTyVD6ufy>G~AeEV3 z${o+r4`CyWgmu1JpwH#Pj}X%yJfv`Eq0ubvQ7x?j> zZ&^d(h-GYI3QJF3a*m~M1|%B`gsjAY#9ClQfkJY>2oqr=jD&Um^#FkO!C@O-jG(!2 zl2%{_kN|Q6k|SI6S*-=ggr)R}un;D~Mi>`d5__p>dzZ%-wA)5UkukaCVDryg&KWB> z`hYR(wLrQ`SO^ngBaBJc1hIYFz>p2NND$M8G{$Wh2WZwt^7K7wMgq<5GOYyy@me4q zB@BdxFh%EC6P!c9%X_yUMW!tM1A}0|)Wb<+{c@iOw@1A*Bv2re5)%?@fq_YXT796t z69&RUml1AE=G+U?2{9KSQw_XK8+oIcBTMj-ucl47I5GUb;UZZNNsi}bw8jCZ- zZ+TUPN~UE7MM`84@P0J=tNmhHi?jxOw;X%i+uI8+kFOKKr~h$uS`PjG{f~7TRb5TZ z8hoX|J~S+6(KGNt1pg_B9-pQ4d)v1pYtN_f&U%-}Yw1BY!vS~9w6a#7WbcRiM17+^ z_OOxnvb_O|flE0zwH`lvLXh!I)vKz&SWv{=AsAjBb+dp)4w=1UY67fx`so`&=b?Q& zva>}dQ4StI`vT8FdueeYlvS*RFvK=NF6AaED!lk;7;M7>FgiX-eQ7zoZ^zM8-;wt0 ziilY&ktoz^T);4}t1?C#JcPkrD9v161NR9^StrciZF= z<&|S+TQPvN=yV!WX;}qm^akbr~RGtKOjSQCg&2aMW=!RhkY5k>ov{W}gx zB~!Az(s8yL15g{sL6b_UfTE&e79V(-oRL8q%FsXLXy@ePq>*rl`T4}eIQaauLJXZ8 zaBWALcjR}g>}>f-#~CBSq_3_`a-KJ9bz0CHaN>hjAt;n=Juj4Iz@*h1+W!{}_(60z z!G$C47Tri_giIZQL;FvgcRI4+PFaH{`Fe!gDC0P@Uay17>eY;dRE>dx8-X9R z-U63Pgm5(4hnHv(=XQ2QqLI$Q0gO{vm-8Gf z2%p`$+9)xqc+rb_Ewh9H37dku*-q?nnbtT zJ~1{N`}Qzv{OKCqqc+r*p83BafaI44c3q)SofsPh52iIfVWo-A=^EXmHqhq6X`9cst^5X07?Sa_;|FH$j*Pef@Ybp9Mhk(DH z>!y`rU0k&^F-thA6I2yfWr8Z=O79TjDvSRvi@V&ka{uo4vE{0-RjEEsNC-4t49Ab5 z_<1mXPRBrk`s3=0t2aSC2}+v_=|iRXXhXgKu9{;hS8@=z1-_J}mH!Gb01k === + * + * 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; From abd7edab365a4fa2b611c29c93d45d0464831de6 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Sat, 24 Sep 2011 17:53:58 -0400 Subject: [PATCH 003/104] twitter account showing a config dialog --- src/libtomahawk/accounts/account.h | 2 ++ src/libtomahawk/accounts/accountmanager.cpp | 13 +++++++++++-- src/tomahawkapp.cpp | 1 + 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/libtomahawk/accounts/account.h b/src/libtomahawk/accounts/account.h index 8b2d680df..970b6614b 100644 --- a/src/libtomahawk/accounts/account.h +++ b/src/libtomahawk/accounts/account.h @@ -113,8 +113,10 @@ protected: { case InfoType: m_types << "InfoType"; + break; case SipType: m_types << "SipType"; + break; } } syncConfig(); diff --git a/src/libtomahawk/accounts/accountmanager.cpp b/src/libtomahawk/accounts/accountmanager.cpp index 385403908..3cca9b797 100644 --- a/src/libtomahawk/accounts/accountmanager.cpp +++ b/src/libtomahawk/accounts/accountmanager.cpp @@ -144,13 +144,21 @@ void AccountManager::loadFromConfig() { QStringList pluginIds = TomahawkSettings::instance()->accountPlugins(); + + //FIXME: this is just for debugging + if ( pluginIds.isEmpty() ) + { + Account* account = m_accountFactories[ "twitteraccount" ]->createAccount(); + addAccountPlugin( account ); + } + foreach( const QString& pluginId, pluginIds ) { QString pluginFactory = factoryFromId( pluginId ); if( m_accountFactories.contains( pluginFactory ) ) { - Account* a = loadPlugin( pluginId ); - addAccountPlugin( a ); + Account* account = loadPlugin( pluginId ); + addAccountPlugin( account ); } } } @@ -173,6 +181,7 @@ AccountManager::loadPlugin( const QString& pluginId ) void AccountManager::addAccountPlugin( Account* account ) { + tDebug() << Q_FUNC_INFO << "adding account plugin"; m_accounts.append( account ); foreach( AccountType type, account->types() ) diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index 60f535ad4..1d002f435 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -506,6 +506,7 @@ TomahawkApp::initSIP() { foreach ( Tomahawk::Accounts::Account* account, Tomahawk::Accounts::AccountManager::instance()->getAccounts() ) { + tDebug() << Q_FUNC_INFO << "testing account with name " << account->accountServiceName(); if ( account->configurationWidget() ) account->configurationWidget()->show(); } From c3064d8249a96bb23f6aa3354ad57a3ab7c99286 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Tue, 4 Oct 2011 19:34:44 -0400 Subject: [PATCH 004/104] More twitter changeover to accounts work, mostly on sip -- does not compile, does not work yet --- src/accounts/twitter/twitteraccount.cpp | 14 + src/accounts/twitter/twitteraccount.h | 4 +- src/libtomahawk/accounts/account.h | 29 +- src/libtomahawk/sip/SipHandler.cpp | 220 +---------- src/libtomahawk/sip/SipHandler.h | 3 +- src/libtomahawk/sip/SipPlugin.cpp | 37 +- src/libtomahawk/sip/SipPlugin.h | 39 +- src/sip/CMakeLists.txt | 8 +- src/sip/twitter/twittersip.cpp | 495 +++++------------------- src/sip/twitter/twittersip.h | 50 +-- src/tomahawkapp.cpp | 3 +- 11 files changed, 186 insertions(+), 716 deletions(-) diff --git a/src/accounts/twitter/twitteraccount.cpp b/src/accounts/twitter/twitteraccount.cpp index f283da14c..9cf146c85 100644 --- a/src/accounts/twitter/twitteraccount.cpp +++ b/src/accounts/twitter/twitteraccount.cpp @@ -20,6 +20,8 @@ #include "twitterconfigwidget.h" +#include "sip/SipPlugin.h" + #include namespace Tomahawk @@ -68,6 +70,18 @@ TwitterAccount::configDialogAuthedSignalSlot( bool authed ) } +SipPlugin* +TwitterAccount::sipPlugin() +{ + if ( m_twitterSipPlugin.isNull() ) + { + m_twitterSipPlugin = QWeakPointer< TwitterSipPlugin >( new TwitterSipPlugin( this ) ); + return m_twitterSipPlugin.data(); + } + return m_twitterSipPlugin.data(); +} + + } } diff --git a/src/accounts/twitter/twitteraccount.h b/src/accounts/twitter/twitteraccount.h index af51cee17..1530c9e2b 100644 --- a/src/accounts/twitter/twitteraccount.h +++ b/src/accounts/twitter/twitteraccount.h @@ -24,6 +24,7 @@ #include "twitterconfigwidget.h" #include "tomahawkoauthtwitter.h" +#include "sip/twitter/twittersip.h" #include "accounts/account.h" #define MYNAME "ACCOUNTTWITTER" @@ -64,7 +65,7 @@ public: bool isAuthenticated() { return m_isAuthenticated; } Tomahawk::InfoSystem::InfoPlugin* infoPlugin() { return 0; } - SipPlugin* sipPlugin() { return 0; } + SipPlugin* sipPlugin(); QWidget* configurationWidget() { return m_configWidget.data(); } QWidget* aclWidget() { return 0; } @@ -75,6 +76,7 @@ private slots: private: bool m_isAuthenticated; QWeakPointer< TwitterConfigWidget > m_configWidget; + QWeakPointer< TwitterSipPlugin > m_twitterSipPlugin; // for settings access friend class TwitterConfigWidget; diff --git a/src/libtomahawk/accounts/account.h b/src/libtomahawk/accounts/account.h index 970b6614b..7cf3c1761 100644 --- a/src/libtomahawk/accounts/account.h +++ b/src/libtomahawk/accounts/account.h @@ -27,13 +27,18 @@ #include "typedefs.h" #include "dllmacro.h" -#include "infosystem/infosystem.h" -#include "sip/SipPlugin.h" #include "tomahawksettings.h" +class SipPlugin; + namespace Tomahawk { +namespace InfoSystem +{ + class InfoPlugin; +} + namespace Accounts { @@ -52,12 +57,14 @@ class DLLEXPORT Account : public QObject public: explicit Account( const QString &accountId ) : QObject() + , m_enabled( false ) , 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 enabled() const { return m_enabled; } virtual bool autoConnect() const { return m_autoConnect; } virtual QString accountId() const { return m_accountId; } @@ -90,12 +97,9 @@ public: return set; } -signals: - void configurationChanged(); - -protected: virtual void setAccountServiceName( const QString &serviceName ) { m_accountServiceName = serviceName; } virtual void setAccountFriendlyName( const QString &friendlyName ) { m_accountFriendlyName = friendlyName; } + virtual void setEnabled( bool enabled ) { m_enabled = enabled; } 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; } @@ -103,7 +107,7 @@ protected: virtual void setConfiguration( const QVariantHash &configuration ) { m_configuration = configuration; } virtual void setAcl( const QVariantMap &acl ) { m_acl = acl; } - + virtual void setTypes( const QSet< AccountType > types ) { m_types = QStringList(); @@ -128,6 +132,7 @@ protected: TomahawkSettings* s = TomahawkSettings::instance(); s->beginGroup( "accounts/" + m_accountId ); m_accountFriendlyName = s->value( "accountFriendlyName", QString() ).toString(); + m_enabled = s->value( "enabled", false ).toBool(); m_autoConnect = s->value( "autoConnect", false ).toBool(); m_credentials = s->value( "credentials", QVariantHash() ).toHash(); m_configuration = s->value( "configuration", QVariantHash() ).toHash(); @@ -136,12 +141,13 @@ protected: s->endGroup(); s->sync(); } - + virtual void syncConfig() { TomahawkSettings* s = TomahawkSettings::instance(); s->beginGroup( "accounts/" + m_accountId ); s->setValue( "accountFriendlyName", m_accountFriendlyName ); + s->setValue( "enabled", m_enabled ); s->setValue( "autoConnect", m_autoConnect ); s->setValue( "credentials", m_credentials ); s->setValue( "configuration", m_configuration ); @@ -152,15 +158,20 @@ protected: emit configurationChanged(); } - + QString m_accountServiceName; QString m_accountFriendlyName; + bool m_enabled; bool m_autoConnect; QString m_accountId; QVariantHash m_credentials; QVariantHash m_configuration; QVariantMap m_acl; QStringList m_types; + +signals: + void configurationChanged(); + }; class DLLEXPORT AccountFactory : public QObject diff --git a/src/libtomahawk/sip/SipHandler.cpp b/src/libtomahawk/sip/SipHandler.cpp index 6364a97c7..2fb7fbab2 100644 --- a/src/libtomahawk/sip/SipHandler.cpp +++ b/src/libtomahawk/sip/SipHandler.cpp @@ -32,6 +32,7 @@ #include "sourcelist.h" #include "tomahawksettings.h" #include "utils/logger.h" +#include "accounts/accountmanager.h" #include "config.h" @@ -54,8 +55,6 @@ SipHandler::SipHandler( QObject* parent ) { s_instance = this; - loadPluginFactories( findPluginFactories() ); - connect( TomahawkSettings::instance(), SIGNAL( changed() ), SLOT( onSettingsChanged() ) ); } @@ -87,13 +86,13 @@ SipHandler::avatar( const QString& name ) const const SipInfo -SipHandler::sipInfo(const QString& peerId) const +SipHandler::sipInfo( const QString& peerId ) const { return m_peersSipInfos.value( peerId ); } const QString -SipHandler::versionString(const QString& peerId) const +SipHandler::versionString( const QString& peerId ) const { return m_peersSoftwareVersions.value( peerId ); } @@ -106,103 +105,6 @@ SipHandler::onSettingsChanged() } -QStringList -SipHandler::findPluginFactories() -{ - QStringList paths; - QList< QDir > pluginDirs; - - QDir appDir( qApp->applicationDirPath() ); - #ifdef Q_WS_MAC - if ( appDir.dirName() == "MacOS" ) - { - // Development convenience-hack - appDir.cdUp(); - appDir.cdUp(); - appDir.cdUp(); - } - #endif - - QDir libDir( CMAKE_INSTALL_PREFIX "/lib" ); - - QDir lib64Dir( appDir ); - lib64Dir.cdUp(); - lib64Dir.cd( "lib64" ); - - pluginDirs << appDir << libDir << lib64Dir << QDir( qApp->applicationDirPath() ); - foreach ( const QDir& pluginDir, pluginDirs ) - { - qDebug() << "Checking directory for plugins:" << pluginDir; - foreach ( QString fileName, pluginDir.entryList( QStringList() << "*tomahawk_sip*.so" << "*tomahawk_sip*.dylib" << "*tomahawk_sip*.dll", QDir::Files ) ) - { - if ( fileName.startsWith( "libtomahawk_sip" ) ) - { - const QString path = pluginDir.absoluteFilePath( fileName ); - if ( !paths.contains( path ) ) - paths << path; - } - } - } - - return paths; -} - - -void -SipHandler::loadPluginFactories( const QStringList& paths ) -{ - foreach ( QString fileName, paths ) - { - if ( !QLibrary::isLibrary( fileName ) ) - continue; - - qDebug() << "Trying to load plugin:" << fileName; - loadPluginFactory( fileName ); - } -} - - -SipPlugin* -SipHandler::createPlugin( const QString& factoryId ) -{ - Q_ASSERT( m_pluginFactories.contains( factoryId ) ); - - SipPlugin* sip = m_pluginFactories[ factoryId ]->createPlugin(); - hookUpPlugin( sip ); - - emit pluginAdded( sip ); - return sip; -} - - -SipPlugin* -SipHandler::loadPlugin( const QString& pluginId ) -{ - QString factoryName = factoryFromId( pluginId ); - - Q_ASSERT( m_pluginFactories.contains( factoryName ) ); - - SipPlugin* sip = m_pluginFactories[ factoryName ]->createPlugin( pluginId ); - - // caller responsible for calling pluginAdded() and hookupPlugin - return sip; -} - - -void -SipHandler::removePlugin( SipPlugin* p ) -{ - p->disconnectPlugin(); - - m_allPlugins.removeAll( p ); - m_enabledPlugins.removeAll( p ); - - TomahawkSettings::instance()->removeSipPlugin( p->pluginId() ); - - emit pluginRemoved( p ); -} - - void SipHandler::hookUpPlugin( SipPlugin* sip ) { @@ -217,28 +119,8 @@ SipHandler::hookUpPlugin( SipPlugin* sip ) QObject::connect( sip, SIGNAL( avatarReceived( QString, QPixmap ) ), SLOT( onAvatarReceived( QString, QPixmap ) ) ); QObject::connect( sip, SIGNAL( avatarReceived( QPixmap ) ), SLOT( onAvatarReceived( QPixmap ) ) ); -} - -void -SipHandler::loadPluginFactory( const QString& path ) -{ - QPluginLoader loader( path ); - QObject* plugin = loader.instance(); - if ( !plugin ) - { - qDebug() << "Error loading plugin:" << loader.errorString(); - } - - SipPluginFactory* sipfactory = qobject_cast(plugin); - if ( sipfactory ) - { - qDebug() << "Loaded plugin factory:" << loader.fileName() << sipfactory->factoryId() << sipfactory->prettyName(); - m_pluginFactories[ sipfactory->factoryId() ] = sipfactory; - } else - { - qDebug() << "Loaded invalid plugin.." << loader.fileName(); - } + QObject::connect( sip->account(), SIGNAL( configurationChanged() ), sip, SLOT( configurationChanged() ) ); } @@ -266,16 +148,12 @@ SipHandler::checkSettings() void -SipHandler::addSipPlugin( SipPlugin* p, bool enabled ) +SipHandler::addSipPlugin( SipPlugin* p ) { m_allPlugins << p; hookUpPlugin( p ); - if ( enabled ) - { - p->connectPlugin(); - m_enabledPlugins << p; - } + p->connectPlugin(); emit pluginAdded( p ); } @@ -285,41 +163,21 @@ void SipHandler::removeSipPlugin( SipPlugin* p ) { p->disconnectPlugin(); - p->deletePlugin(); emit pluginRemoved( p ); - // emit first so sipmodel can find the indexOf - TomahawkSettings::instance()->removeSipPlugin( p->pluginId() ); m_allPlugins.removeAll( p ); - m_enabledPlugins.removeAll( p ); -} - - -bool -SipHandler::hasPluginType( const QString& factoryId ) const -{ - foreach( SipPlugin* p, m_allPlugins ) { - if( factoryFromId( p->pluginId() ) == factoryId ) - return true; - } - return false; } void -SipHandler::loadFromConfig() +SipHandler::loadFromAccountManager() { - QStringList pluginIds = TomahawkSettings::instance()->sipPlugins(); - QStringList enabled = TomahawkSettings::instance()->enabledSipPlugins(); - foreach( const QString& pluginId, pluginIds ) + QList< Tomahawk::Accounts::Account* > accountList = Tomahawk::Accounts::AccountManager::instance()->getAccounts( Tomahawk::Accounts::SipType ); + foreach( const Tomahawk::Accounts::Account* account, accountList ) { - QString pluginFactory = factoryFromId( pluginId ); - if( m_pluginFactories.contains( pluginFactory ) ) - { - SipPlugin* p = loadPlugin( pluginId ); - addSipPlugin( p, enabled.contains( pluginId ) ); - } + SipPlugin* p = account->sipPlugin(); + addSipPlugin( p ); } m_connected = true; } @@ -328,7 +186,7 @@ SipHandler::loadFromConfig() void SipHandler::connectAll() { - foreach( SipPlugin* sip, m_enabledPlugins ) + foreach( SipPlugin* sip, m_allPlugins ) { sip->connectPlugin(); } @@ -347,29 +205,6 @@ SipHandler::disconnectAll() } -void -SipHandler::disablePlugin( SipPlugin* p ) -{ - Q_ASSERT( m_enabledPlugins.contains( p ) ); - - TomahawkSettings::instance()->disableSipPlugin( p->pluginId() ); - p->disconnectPlugin(); - - m_enabledPlugins.removeAll( p ); -} - - -void -SipHandler::enablePlugin( SipPlugin* p ) -{ - Q_ASSERT( !m_enabledPlugins.contains( p ) ); - p->connectPlugin(); - - TomahawkSettings::instance()->enableSipPlugin( p->pluginId() ); - m_enabledPlugins << p; -} - - void SipHandler::connectPlugin( const QString &pluginId ) { @@ -392,7 +227,7 @@ SipHandler::connectPlugin( const QString &pluginId ) { if ( sip->pluginId() == pluginId ) { - Q_ASSERT( m_enabledPlugins.contains( sip ) ); // make sure the plugin we're connecting is enabled. should always be the case + Q_ASSERT( m_allPlugins.contains( sip ) ); // make sure the plugin we're connecting is enabled. should always be the case //each sip should refreshProxy() or take care of that function in some other way during connection sip->connectPlugin(); } @@ -418,13 +253,6 @@ SipHandler::allPlugins() const } -QList< SipPlugin* > -SipHandler::enabledPlugins() const -{ - return m_enabledPlugins; -} - - QList< SipPlugin* > SipHandler::connectedPlugins() const { @@ -432,13 +260,6 @@ SipHandler::connectedPlugins() const } -QList< SipPluginFactory* > -SipHandler::pluginFactories() const -{ - return m_pluginFactories.values(); -} - - void SipHandler::toggleConnect() { @@ -644,18 +465,3 @@ SipHandler::onAvatarReceived( const QPixmap& avatar ) // qDebug() << Q_FUNC_INFO << "Set own avatar on MyCollection"; SourceList::instance()->getLocal()->setAvatar( avatar ); } - - -QString -SipHandler::factoryFromId( const QString& pluginId ) const -{ - return pluginId.split( "_" ).first(); -} - - -SipPluginFactory* -SipHandler::factoryFromPlugin( SipPlugin* p ) const -{ - QString factoryId = factoryFromId( p->pluginId() ); - return m_pluginFactories.value( factoryId, 0 ); -} diff --git a/src/libtomahawk/sip/SipHandler.h b/src/libtomahawk/sip/SipHandler.h index c7a6e9999..5df67357a 100644 --- a/src/libtomahawk/sip/SipHandler.h +++ b/src/libtomahawk/sip/SipHandler.h @@ -39,9 +39,8 @@ public: QList< SipPluginFactory* > pluginFactories() const; QList< SipPlugin* > allPlugins() const; - QList< SipPlugin* > enabledPlugins() const; QList< SipPlugin* > connectedPlugins() const; - void loadFromConfig(); + void loadFromAccountManager(); void addSipPlugin( SipPlugin* p, bool enable = true ); void removeSipPlugin( SipPlugin* p ); diff --git a/src/libtomahawk/sip/SipPlugin.cpp b/src/libtomahawk/sip/SipPlugin.cpp index a79557661..b10216bf7 100644 --- a/src/libtomahawk/sip/SipPlugin.cpp +++ b/src/libtomahawk/sip/SipPlugin.cpp @@ -19,24 +19,15 @@ #include "sip/SipPlugin.h" -#include - #include "utils/logger.h" -QString -SipPluginFactory::generateId() -{ - QString uniq = QUuid::createUuid().toString().mid( 1, 8 ); - return factoryId() + "_" + uniq; -} - SipPlugin::SipPlugin() : QObject() {} SipPlugin::~SipPlugin() {} -SipPlugin::SipPlugin( const QString& pluginId, QObject* parent ) +SipPlugin::SipPlugin( Tomahawk::Accounts::Account *account, QObject* parent ) : QObject( parent ) - , m_pluginId( pluginId ) + , m_account( account ) { connect( this, SIGNAL( error( int, QString ) ), this, SLOT( onError( int,QString ) ) ); connect( this, SIGNAL( stateChanged( SipPlugin::ConnectionState ) ), this, SLOT( onStateChange( SipPlugin::ConnectionState ) ) ); @@ -48,7 +39,21 @@ SipPlugin::SipPlugin( const QString& pluginId, QObject* parent ) QString SipPlugin::pluginId() const { - return m_pluginId; + return m_account->accountId(); +} + + +const QString +SipPlugin::friendlyName() const +{ + return m_account->accountFriendlyName(); +} + + +const QString +SipPlugin::serviceName() const +{ + return m_account->accountServiceName(); } @@ -59,10 +64,10 @@ SipPlugin::menu() } -QWidget* -SipPlugin::configWidget() +Tomahawk::Accounts::Account* +SipPlugin::account() const { - return 0; + return m_account; } @@ -76,7 +81,7 @@ SipPlugin::errorMessage() const QIcon SipPlugin::icon() const { - return QIcon(); + return m_account->icon(); } diff --git a/src/libtomahawk/sip/SipPlugin.h b/src/libtomahawk/sip/SipPlugin.h index 2797c3d0a..bb51dabc0 100644 --- a/src/libtomahawk/sip/SipPlugin.h +++ b/src/libtomahawk/sip/SipPlugin.h @@ -27,31 +27,12 @@ #include #include +#include "accounts/account.h" + #include "dllmacro.h" class SipPlugin; -class DLLEXPORT SipPluginFactory : public QObject -{ - Q_OBJECT -public: - SipPluginFactory() {} - virtual ~SipPluginFactory() {} - - // display name for plugin - virtual QString prettyName() const = 0; - // internal name - virtual QString factoryId() const = 0; - // if the user can create multiple - virtual QIcon icon() const { return QIcon(); } - virtual bool isUnique() const { return false; } - - virtual SipPlugin* createPlugin( const QString& pluginId = QString() ) = 0; - -protected: - QString generateId(); -}; - class DLLEXPORT SipPlugin : public QObject { Q_OBJECT @@ -61,23 +42,20 @@ public: enum ConnectionState { Disconnected, Connecting, Connected, Disconnecting }; SipPlugin(); - explicit SipPlugin( const QString& pluginId, QObject* parent = 0 ); + explicit SipPlugin( Tomahawk::Accounts::Account *account, QObject* parent = 0 ); virtual ~SipPlugin(); // plugin id is "pluginfactoryname_someuniqueid". get it from SipPluginFactory::generateId QString pluginId() const; virtual bool isValid() const = 0; - virtual const QString name() const = 0; - virtual const QString friendlyName() const = 0; - virtual const QString accountName() const = 0; + virtual const QString friendlyName() const; + virtual const QString serviceName() const; virtual ConnectionState connectionState() const = 0; virtual QString errorMessage() const; virtual QMenu* menu(); - virtual QWidget* configWidget(); - virtual void saveConfig() {} // called when the widget has been edited virtual QIcon icon() const; - + virtual Tomahawk::Accounts::Account* account() const; // peer infos virtual const QStringList peersOnline() const; @@ -85,6 +63,7 @@ public slots: virtual bool connectPlugin() = 0; virtual void disconnectPlugin() = 0; virtual void checkSettings() = 0; + virtual void configurationChanged() = 0; virtual void addContact( const QString &jid, const QString& msg = QString() ) = 0; virtual void sendMsg( const QString& to, const QString& msg ) = 0; @@ -124,11 +103,9 @@ private slots: void onPeerOffline( const QString &peerId ); private: - QString m_pluginId; + Tomahawk::Accounts::Account *m_account; QString m_cachedError; QStringList m_peersOnline; }; -Q_DECLARE_INTERFACE( SipPluginFactory, "tomahawk.SipFactory/1.0" ) - #endif diff --git a/src/sip/CMakeLists.txt b/src/sip/CMakeLists.txt index c8668998c..054db9928 100644 --- a/src/sip/CMakeLists.txt +++ b/src/sip/CMakeLists.txt @@ -1,9 +1,9 @@ -IF( LIBJREEN_FOUND ) - ADD_SUBDIRECTORY( jabber ) -ENDIF( LIBJREEN_FOUND ) +#IF( LIBJREEN_FOUND ) +# ADD_SUBDIRECTORY( jabber ) +#ENDIF( LIBJREEN_FOUND ) IF( QTWEETLIB_FOUND ) ADD_SUBDIRECTORY( twitter ) ENDIF( QTWEETLIB_FOUND ) -ADD_SUBDIRECTORY( zeroconf ) +#ADD_SUBDIRECTORY( zeroconf ) diff --git a/src/sip/twitter/twittersip.cpp b/src/sip/twitter/twittersip.cpp index c349bf62c..06318b5bd 100644 --- a/src/sip/twitter/twittersip.cpp +++ b/src/sip/twitter/twittersip.cpp @@ -42,21 +42,10 @@ static QString s_gotTomahawkRegex = QString( "^(@[a-zA-Z0-9]+ )?(Got Tomahawk\\?) (\\{[a-fA-F0-9\\-]+\\}) (.*)$" ); - -SipPlugin* -TwitterFactory::createPlugin( const QString& pluginId ) -{ - return new TwitterPlugin( pluginId.isEmpty() ? generateId() : pluginId ); -} - -QIcon TwitterFactory::icon() const -{ - return QIcon( ":/twitter-icon.png" ); -} - - -TwitterPlugin::TwitterPlugin( const QString& pluginId ) - : SipPlugin( pluginId ) +TwitterSipPlugin::TwitterSipPlugin( Tomahawk::Accounts::Account* account ) + : SipPlugin( account ) + , m_configuration( account->configuration() ) + , m_credentials( account->credentials() ) , m_isAuthed( false ) , m_checkTimer( this ) , m_connectTimer( this ) @@ -70,10 +59,12 @@ TwitterPlugin::TwitterPlugin( const QString& pluginId ) { qDebug() << Q_FUNC_INFO; - if ( Database::instance()->dbid() != twitterSavedDbid() ) - setTwitterCachedPeers( QVariantHash() ); - - setTwitterSavedDbid( Database::instance()->dbid() ); + if ( Database::instance()->dbid() != m_configuration[ "savedDbid" ].toString() ) + { + m_configuration[ "cachedPeers" ] = QVariantHash(); + m_configuration[ "savedDbid" ] = Database::instance()->dbid(); + syncConfig(); + } m_checkTimer.setInterval( 180000 ); m_checkTimer.setSingleShot( false ); @@ -89,92 +80,44 @@ TwitterPlugin::TwitterPlugin( const QString& pluginId ) } -void -TwitterPlugin::configDialogAuthedSignalSlot( bool authed ) -{ - - if ( !authed ) - { - if( m_isAuthed ) { - m_state = Disconnected; - emit stateChanged( m_state ); - } - - setTwitterScreenName( QString() ); - setTwitterOAuthToken( QString() ); - setTwitterOAuthTokenSecret( QString() ); - } - - m_isAuthed = authed; -} - bool -TwitterPlugin::isValid() const +TwitterSipPlugin::isValid() const { - return m_isAuthed; -} - -const QString -TwitterPlugin::name() const -{ - return QString( MYNAME ); -} - -const QString -TwitterPlugin::friendlyName() const -{ - return tr("Twitter"); -} - -const QString -TwitterPlugin::accountName() const -{ - if( twitterScreenName().isEmpty() ) - return friendlyName(); - else - return twitterScreenName(); -} - -QIcon -TwitterPlugin::icon() const -{ - return QIcon( ":/twitter-icon.png" ); + return m_account->enabled() && m_isAuthed; } SipPlugin::ConnectionState -TwitterPlugin::connectionState() const +TwitterSipPlugin::connectionState() const { return m_state; } -QWidget* TwitterPlugin::configWidget() -{ - return m_configWidget.data(); -} - bool -TwitterPlugin::connectPlugin() +TwitterSipPlugin::connectPlugin() { qDebug() << Q_FUNC_INFO; - m_cachedPeers = twitterCachedPeers(); + if ( !m_account->enabled() ) + return; + + m_cachedPeers = m_configuration[ "cachedPeers" ].toHash(); QStringList peerList = m_cachedPeers.keys(); qStableSort( peerList.begin(), peerList.end() ); registerOffers( peerList ); - if ( twitterOAuthToken().isEmpty() || twitterOAuthTokenSecret().isEmpty() ) + if ( m_credentials[ "oauthToken" ].toString().isEmpty() || m_credentials[ "oauthTokenSecret" ].toString().isEmpty() ) { - qDebug() << "TwitterPlugin has empty Twitter credentials; not connecting"; + qDebug() << "TwitterSipPlugin has empty Twitter credentials; not connecting"; return m_cachedPeers.isEmpty(); } if ( refreshTwitterAuth() ) { QTweetAccountVerifyCredentials *credVerifier = new QTweetAccountVerifyCredentials( m_twitterAuth.data(), this ); - connect( credVerifier, SIGNAL( parsedUser(const QTweetUser &) ), SLOT( connectAuthVerifyReply(const QTweetUser &) ) ); + connect( credVerifier, SIGNAL( parsedUser( const QTweetUser & ) ), SLOT( connectAuthVerifyReply( const QTweetUser & ) ) ); credVerifier->verify(); m_state = Connecting; @@ -185,7 +128,7 @@ TwitterPlugin::connectPlugin() } bool -TwitterPlugin::refreshTwitterAuth() +TwitterSipPlugin::refreshTwitterAuth() { qDebug() << Q_FUNC_INFO << " begin"; if( !m_twitterAuth.isNull() ) @@ -198,14 +141,14 @@ TwitterPlugin::refreshTwitterAuth() if( m_twitterAuth.isNull() ) return false; - m_twitterAuth.data()->setOAuthToken( twitterOAuthToken().toLatin1() ); - m_twitterAuth.data()->setOAuthTokenSecret( twitterOAuthTokenSecret().toLatin1() ); + m_twitterAuth.data()->setOAuthToken( m_credentials[ "oauthToken" ].toString().toLatin1() ); + m_twitterAuth.data()->setOAuthTokenSecret( m_credentials[ "oauthTokenSecret" ].toString().toLatin1() ); return true; } void -TwitterPlugin::disconnectPlugin() +TwitterSipPlugin::disconnectPlugin() { qDebug() << Q_FUNC_INFO; m_checkTimer.stop(); @@ -224,6 +167,7 @@ TwitterPlugin::disconnectPlugin() if( !m_twitterAuth.isNull() ) delete m_twitterAuth.data(); + m_configuration[ "cachedPeers" ] = m_cachedPeers; syncConfig(); m_cachedPeers.empty(); m_state = Disconnected; @@ -231,11 +175,11 @@ TwitterPlugin::disconnectPlugin() } void -TwitterPlugin::connectAuthVerifyReply( const QTweetUser &user ) +TwitterSipPlugin::connectAuthVerifyReply( const QTweetUser &user ) { if ( user.id() == 0 ) { - qDebug() << "TwitterPlugin could not authenticate to Twitter"; + qDebug() << "TwitterSipPlugin could not authenticate to Twitter"; m_isAuthed = false; m_state = Disconnected; m_connectTimer.stop(); @@ -245,11 +189,12 @@ TwitterPlugin::connectAuthVerifyReply( const QTweetUser &user ) } else { - qDebug() << "TwitterPlugin successfully authenticated to Twitter as user " << user.screenName(); + qDebug() << "TwitterSipPlugin successfully authenticated to Twitter as user " << user.screenName(); m_isAuthed = true; if ( !m_twitterAuth.isNull() ) { - setTwitterScreenName( user.screenName() ); + m_configuration[ "screenName" ] = user.screenName; + syncConfig(); m_friendsTimeline = QWeakPointer( new QTweetFriendsTimeline( m_twitterAuth.data(), this ) ); m_mentions = QWeakPointer( new QTweetMentions( m_twitterAuth.data(), this ) ); m_directMessages = QWeakPointer( new QTweetDirectMessages( m_twitterAuth.data(), this ) ); @@ -279,7 +224,7 @@ TwitterPlugin::connectAuthVerifyReply( const QTweetUser &user ) } else { - qDebug() << "TwitterPlugin auth pointer was null!"; + qDebug() << "TwitterSipPlugin auth pointer was null!"; m_isAuthed = false; m_state = Disconnected; m_connectTimer.stop(); @@ -291,30 +236,25 @@ TwitterPlugin::connectAuthVerifyReply( const QTweetUser &user ) } } -void -TwitterPlugin::deletePlugin() -{ - TomahawkSettings::instance()->remove( pluginId() ); -} void -TwitterPlugin::checkTimerFired() +TwitterSipPlugin::checkTimerFired() { if ( !isValid() || m_twitterAuth.isNull() ) return; if ( m_cachedFriendsSinceId == 0 ) - m_cachedFriendsSinceId = twitterCachedFriendsSinceId(); + m_cachedFriendsSinceId = m_configuration[ "cachedFriendsSinceId" ].toLongLong(); - qDebug() << "TwitterPlugin looking at friends timeline since id " << m_cachedFriendsSinceId; + 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 = twitterCachedMentionsSinceId(); + m_cachedMentionsSinceId = m_configuration[ "cachedMentionsSinceId" ].toLongLong(); - qDebug() << "TwitterPlugin looking at mentions timeline since id " << m_cachedMentionsSinceId; + qDebug() << "TwitterSipPlugin looking at mentions timeline since id " << m_cachedMentionsSinceId; if ( !m_mentions.isNull() ) m_mentions.data()->fetch( m_cachedMentionsSinceId, 0, 800 ); @@ -322,7 +262,7 @@ TwitterPlugin::checkTimerFired() void -TwitterPlugin::registerOffers( const QStringList &peerList ) +TwitterSipPlugin::registerOffers( const QStringList &peerList ) { foreach( QString screenName, peerList ) { @@ -331,6 +271,7 @@ TwitterPlugin::registerOffers( const QStringList &peerList ) if ( peerData.contains( "onod" ) && peerData["onod"] != Database::instance()->dbid() ) { m_cachedPeers.remove( screenName ); + m_configuration[ "cachedPeers" ] = m_cachedPeers; syncConfig(); } @@ -338,6 +279,7 @@ TwitterPlugin::registerOffers( const QStringList &peerList ) { peerData["lastseen"] = QDateTime::currentMSecsSinceEpoch(); m_cachedPeers[screenName] = peerData; + m_configuration[ "cachedPeers" ] = m_cachedPeers; syncConfig(); qDebug() << Q_FUNC_INFO << " already connected"; continue; @@ -346,6 +288,7 @@ TwitterPlugin::registerOffers( const QStringList &peerList ) { qDebug() << Q_FUNC_INFO << " aging peer " << screenName << " out of cache"; m_cachedPeers.remove( screenName ); + m_configuration[ "cachedPeers" ] = m_cachedPeers; syncConfig(); m_cachedAvatars.remove( screenName ); continue; @@ -353,7 +296,7 @@ TwitterPlugin::registerOffers( const QStringList &peerList ) if ( !peerData.contains( "host" ) || !peerData.contains( "port" ) || !peerData.contains( "pkey" ) ) { - qDebug() << "TwitterPlugin does not have host, port and/or pkey values for " << screenName << " (this is usually *not* a bug or problem but a normal part of the process)"; + qDebug() << "TwitterSipPlugin does not have host, port and/or pkey values for " << screenName << " (this is usually *not* a bug or problem but a normal part of the process)"; continue; } @@ -363,7 +306,7 @@ TwitterPlugin::registerOffers( const QStringList &peerList ) void -TwitterPlugin::connectTimerFired() +TwitterSipPlugin::connectTimerFired() { qDebug() << Q_FUNC_INFO << " beginning"; if ( !isValid() || m_cachedPeers.isEmpty() || m_twitterAuth.isNull() ) @@ -378,21 +321,21 @@ TwitterPlugin::connectTimerFired() } qDebug() << Q_FUNC_INFO << " continuing"; - QString myScreenName = twitterScreenName(); + QString myScreenName = m_configuration[ "screenName" ].toString(); QStringList peerList = m_cachedPeers.keys(); qStableSort( peerList.begin(), peerList.end() ); registerOffers( peerList ); } void -TwitterPlugin::parseGotTomahawk( const QRegExp ®ex, const QString &screenName, const QString &text ) +TwitterSipPlugin::parseGotTomahawk( const QRegExp ®ex, const QString &screenName, const QString &text ) { - QString myScreenName = twitterScreenName(); - qDebug() << "TwitterPlugin found an exact matching Got Tomahawk? mention or direct message from user " << screenName << ", now parsing"; + QString myScreenName = m_configuration[ "screenName" ].toString(); + qDebug() << "TwitterSipPlugin found an exact matching Got Tomahawk? mention or direct message from user " << screenName << ", now parsing"; regex.exactMatch( text ); if ( text.startsWith( '@' ) && regex.captureCount() >= 2 && regex.cap( 1 ) != QString( '@' + myScreenName ) ) { - qDebug() << "TwitterPlugin skipping mention because it's directed @someone that isn't us"; + qDebug() << "TwitterSipPlugin skipping mention because it's directed @someone that isn't us"; return; } @@ -408,11 +351,11 @@ TwitterPlugin::parseGotTomahawk( const QRegExp ®ex, const QString &screenName } if ( node.isEmpty() ) { - qDebug() << "TwitterPlugin could not parse node out of the tweet"; + qDebug() << "TwitterSipPlugin could not parse node out of the tweet"; return; } else - qDebug() << "TwitterPlugin parsed node " << node << " out of the tweet"; + qDebug() << "TwitterSipPlugin parsed node " << node << " out of the tweet"; if ( node == Database::instance()->dbid() ) { @@ -434,7 +377,7 @@ TwitterPlugin::parseGotTomahawk( const QRegExp ®ex, const QString &screenName } void -TwitterPlugin::friendsTimelineStatuses( const QList< QTweetStatus > &statuses ) +TwitterSipPlugin::friendsTimelineStatuses( const QList< QTweetStatus > &statuses ) { qDebug() << Q_FUNC_INFO; QRegExp regex( s_gotTomahawkRegex, Qt::CaseSensitive, QRegExp::RegExp2 ); @@ -459,15 +402,16 @@ TwitterPlugin::friendsTimelineStatuses( const QList< QTweetStatus > &statuses ) if ( status.id() > m_cachedFriendsSinceId ) m_cachedFriendsSinceId = status.id(); - qDebug() << "TwitterPlugin checking mention from " << status.user().screenName() << " with content " << status.text(); + qDebug() << "TwitterSipPlugin checking mention from " << status.user().screenName() << " with content " << status.text(); parseGotTomahawk( regex, status.user().screenName(), status.text() ); } - setTwitterCachedFriendsSinceId( m_cachedFriendsSinceId ); + m_configuration[ "cachedFriendsSinceId" ] = m_cachedFriendsSinceId; + syncConfig(); } void -TwitterPlugin::mentionsStatuses( const QList< QTweetStatus > &statuses ) +TwitterSipPlugin::mentionsStatuses( const QList< QTweetStatus > &statuses ) { qDebug() << Q_FUNC_INFO; QRegExp regex( s_gotTomahawkRegex, Qt::CaseSensitive, QRegExp::RegExp2 ); @@ -492,35 +436,36 @@ TwitterPlugin::mentionsStatuses( const QList< QTweetStatus > &statuses ) if ( status.id() > m_cachedMentionsSinceId ) m_cachedMentionsSinceId = status.id(); - qDebug() << "TwitterPlugin checking mention from " << status.user().screenName() << " with content " << status.text(); + qDebug() << "TwitterSipPlugin checking mention from " << status.user().screenName() << " with content " << status.text(); parseGotTomahawk( regex, status.user().screenName(), status.text() ); } - setTwitterCachedMentionsSinceId( m_cachedMentionsSinceId ); + m_configuration[ "cachedMentionsSinceId" ] = m_cachedMentionsSinceId; + syncConfig(); } void -TwitterPlugin::pollDirectMessages() +TwitterSipPlugin::pollDirectMessages() { if ( !isValid() ) return; if ( m_cachedDirectMessagesSinceId == 0 ) - m_cachedDirectMessagesSinceId = twitterCachedDirectMessagesSinceId(); + m_cachedDirectMessagesSinceId = m_configuration[ "cachedDirectMentionsSinceId" ].toLongLong(); - qDebug() << "TwitterPlugin looking for direct messages since id " << m_cachedDirectMessagesSinceId; + qDebug() << "TwitterSipPlugin looking for direct messages since id " << m_cachedDirectMessagesSinceId; if ( !m_directMessages.isNull() ) m_directMessages.data()->fetch( m_cachedDirectMessagesSinceId, 0, 800 ); } void -TwitterPlugin::directMessages( const QList< QTweetDMStatus > &messages ) +TwitterSipPlugin::directMessages( const QList< QTweetDMStatus > &messages ) { qDebug() << Q_FUNC_INFO; QRegExp regex( s_gotTomahawkRegex, Qt::CaseSensitive, QRegExp::RegExp2 ); - QString myScreenName = twitterScreenName(); + QString myScreenName = m_configuration[ "screenName" ].toString(); QHash< QString, QTweetDMStatus > latestHash; foreach ( QTweetDMStatus status, messages ) @@ -550,7 +495,7 @@ TwitterPlugin::directMessages( const QList< QTweetDMStatus > &messages ) foreach( QTweetDMStatus status, latestHash.values() ) { - qDebug() << "TwitterPlugin checking direct message from " << status.senderScreenName() << " with content " << status.text(); + qDebug() << "TwitterSipPlugin checking direct message from " << status.senderScreenName() << " with content " << status.text(); if ( status.id() > m_cachedDirectMessagesSinceId ) m_cachedDirectMessagesSinceId = status.id(); @@ -559,7 +504,7 @@ TwitterPlugin::directMessages( const QList< QTweetDMStatus > &messages ) else { QStringList splitList = status.text().split(':'); - qDebug() << "TwitterPlugin found " << splitList.length() << " parts to the message; the parts are:"; + qDebug() << "TwitterSipPlugin found " << splitList.length() << " parts to the message; the parts are:"; foreach( QString part, splitList ) qDebug() << part; //validity is checked above @@ -573,7 +518,7 @@ TwitterPlugin::directMessages( const QList< QTweetDMStatus > &messages ) qDebug() << "Old-style node info found, ignoring"; continue; } - qDebug() << "TwitterPlugin found a peerstart message from " << status.senderScreenName() << " with host " << host << " and port " << port << " and pkey " << pkey << " and node " << splitNode[0] << " destined for node " << splitNode[1]; + qDebug() << "TwitterSipPlugin found a peerstart message from " << status.senderScreenName() << " with host " << host << " and port " << port << " and pkey " << pkey << " and node " << splitNode[0] << " destined for node " << splitNode[1]; QVariantHash peerData = ( m_cachedPeers.contains( status.senderScreenName() ) ) ? @@ -590,18 +535,19 @@ TwitterPlugin::directMessages( const QList< QTweetDMStatus > &messages ) if ( Database::instance()->dbid().startsWith( splitNode[1] ) ) { - qDebug() << "TwitterPlugin found message destined for this node; destroying it"; + qDebug() << "TwitterSipPlugin found message destined for this node; destroying it"; if ( !m_directMessageDestroy.isNull() ) m_directMessageDestroy.data()->destroyMessage( status.id() ); } } } - setTwitterCachedDirectMessagesSinceId( m_cachedDirectMessagesSinceId ); + m_configuration[ "cachedDirectMessagesSinceId" ] = m_cachedDirectMessagesSinceId; + syncConfig(); } void -TwitterPlugin::registerOffer( const QString &screenName, const QVariantHash &peerData ) +TwitterSipPlugin::registerOffer( const QString &screenName, const QVariantHash &peerData ) { qDebug() << Q_FUNC_INFO; @@ -656,26 +602,27 @@ TwitterPlugin::registerOffer( const QString &screenName, const QVariantHash &pee if( needToAddToCache && _peerData.contains( "node" ) ) { - qDebug() << "TwitterPlugin registering offer to " << friendlyName << " with node " << _peerData["node"].toString() << " and offeredkey " << _peerData["okey"].toString(); + qDebug() << "TwitterSipPlugin registering offer to " << friendlyName << " with node " << _peerData["node"].toString() << " and offeredkey " << _peerData["okey"].toString(); m_keyCache << Servent::instance()->createConnectionKey( friendlyName, _peerData["node"].toString(), _peerData["okey"].toString(), false ); } if( needToSend && _peerData.contains( "node") ) { - qDebug() << "TwitterPlugin needs to send and has 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() << "TwitterPlugin did not send offer because external address is " << Servent::instance()->externalAddress() << " and external port is " << Servent::instance()->externalPort(); + qDebug() << "TwitterSipPlugin did not send offer because external address is " << Servent::instance()->externalAddress() << " and external port is " << Servent::instance()->externalPort(); } if ( peersChanged ) { _peerData["lastseen"] = QString::number( QDateTime::currentMSecsSinceEpoch() ); m_cachedPeers[screenName] = QVariant::fromValue< QVariantHash >( _peerData ); + m_configuration[ "cachedPeers" ] = m_cachedPeers; syncConfig(); } @@ -685,7 +632,7 @@ TwitterPlugin::registerOffer( const QString &screenName, const QVariantHash &pee } void -TwitterPlugin::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() ) @@ -693,26 +640,26 @@ TwitterPlugin::sendOffer( const QString &screenName, const QVariantHash &peerDat .arg( Database::instance()->dbid() ) .arg( peerData["node"].toString().left( 8 ) ) .arg( peerData["okey"].toString() ); - qDebug() << "TwitterPlugin sending message to " << screenName << ": " << offerString; + qDebug() << "TwitterSipPlugin sending message to " << screenName << ": " << offerString; if( !m_directMessageNew.isNull() ) m_directMessageNew.data()->post( screenName, offerString ); } void -TwitterPlugin::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() ) { - qDebug() << "TwitterPlugin could not find host and/or port and/or pkey and/or node for peer " << screenName; + 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() ) { - qDebug() << "TwitterPlugin asked to make connection to our own host and port, ignoring " << screenName; + qDebug() << "TwitterSipPlugin asked to make connection to our own host and port, ignoring " << screenName; return; } @@ -726,31 +673,31 @@ TwitterPlugin::makeConnection( const QString &screenName, const QVariantHash &pe } void -TwitterPlugin::directMessagePosted( const QTweetDMStatus& message ) +TwitterSipPlugin::directMessagePosted( const QTweetDMStatus& message ) { qDebug() << Q_FUNC_INFO; - qDebug() << "TwitterPlugin sent message to " << message.recipientScreenName() << " containing: " << message.text(); + qDebug() << "TwitterSipPlugin sent message to " << message.recipientScreenName() << " containing: " << message.text(); } void -TwitterPlugin::directMessagePostError( QTweetNetBase::ErrorCode errorCode, const QString &message ) +TwitterSipPlugin::directMessagePostError( QTweetNetBase::ErrorCode errorCode, const QString &message ) { Q_UNUSED( errorCode ); Q_UNUSED( message ); qDebug() << Q_FUNC_INFO; - qDebug() << "TwitterPlugin received an error posting direct message: " << m_directMessageNew.data()->lastErrorMessage(); + qDebug() << "TwitterSipPlugin received an error posting direct message: " << m_directMessageNew.data()->lastErrorMessage(); } void -TwitterPlugin::directMessageDestroyed( const QTweetDMStatus& message ) +TwitterSipPlugin::directMessageDestroyed( const QTweetDMStatus& message ) { qDebug() << Q_FUNC_INFO; - qDebug() << "TwitterPlugin destroyed message " << message.text(); + qDebug() << "TwitterSipPlugin destroyed message " << message.text(); } void -TwitterPlugin::fetchAvatar( const QString& screenName ) +TwitterSipPlugin::fetchAvatar( const QString& screenName ) { qDebug() << Q_FUNC_INFO; if ( m_twitterAuth.isNull() ) @@ -761,7 +708,7 @@ TwitterPlugin::fetchAvatar( const QString& screenName ) } void -TwitterPlugin::avatarUserDataSlot( const QTweetUser &user ) +TwitterSipPlugin::avatarUserDataSlot( const QTweetUser &user ) { qDebug() << Q_FUNC_INFO; if ( user.profileImageUrl().isEmpty() || m_twitterAuth.isNull() ) @@ -774,14 +721,14 @@ TwitterPlugin::avatarUserDataSlot( const QTweetUser &user ) } void -TwitterPlugin::refreshProxy() +TwitterSipPlugin::refreshProxy() { if ( !m_twitterAuth.isNull() ) m_twitterAuth.data()->setNetworkAccessManager( TomahawkUtils::nam() ); } void -TwitterPlugin::profilePicReply() +TwitterSipPlugin::profilePicReply() { qDebug() << Q_FUNC_INFO; QNetworkReply *reply = qobject_cast< QNetworkReply* >( sender() ); @@ -801,267 +748,9 @@ TwitterPlugin::profilePicReply() } void -TwitterPlugin::checkSettings() +TwitterSipPlugin::configurationChanged() { - if ( m_state == Disconnected ) - return; - disconnectPlugin(); + if ( m_state != Disconnected ) + disconnectPlugin(); connectPlugin(); } - - -void -TwitterPlugin::setTwitterSavedDbid( const QString& dbid ) -{ - TomahawkSettings::instance()->setValue( pluginId() + "/saveddbid", dbid ); -} - - -QString -TwitterPlugin::twitterSavedDbid() const -{ - return TomahawkSettings::instance()->value( pluginId() + "/saveddbid", QString() ).toString(); -} - - -QString -TwitterPlugin::twitterScreenName() const -{ - TomahawkSettings* s = TomahawkSettings::instance(); - s->beginGroup( pluginId() ); - QStringList keys = s->childKeys(); - if ( keys.contains( "ScreenName", Qt::CaseSensitive ) ) - { - s->setValue( "screenname_tmp", - s->value( "ScreenName" ).toString() ); - s->remove( "ScreenName" ); - - s->sync(); - } - keys = s->childKeys(); - if ( keys.contains( "screenname_tmp", Qt::CaseSensitive ) ) - { - s->setValue( "screenname", - s->value( "screenname_tmp" ).toString() ); - s->remove( "screenname_tmp" ); - - s->sync(); - } - s->endGroup(); - - return s->value( pluginId() + "/screenname" ).toString(); -} - -void -TwitterPlugin::setTwitterScreenName( const QString& screenName ) -{ - TomahawkSettings::instance()->setValue( pluginId() + "/screenname", screenName ); -} - -QString -TwitterPlugin::twitterOAuthToken() const -{ - TomahawkSettings* s = TomahawkSettings::instance(); - s->beginGroup( pluginId() ); - QStringList keys = s->childKeys(); - if ( keys.contains( "OAuthToken", Qt::CaseSensitive ) ) - { - s->setValue( "oauthtoken_tmp", - s->value( "OAuthToken" ).toString() ); - s->remove( "OAuthToken" ); - - s->sync(); - - } - keys = s->childKeys(); - if ( keys.contains( "oauthtoken_tmp", Qt::CaseSensitive ) ) - { - s->setValue( "oauthtoken", - s->value( "oauthtoken_tmp" ).toString() ); - s->remove( "oauthtoken_tmp" ); - - s->sync(); - } - s->endGroup(); - - return s->value( pluginId() + "/oauthtoken" ).toString(); -} - -void -TwitterPlugin::setTwitterOAuthToken( const QString& oauthtoken ) -{ - TomahawkSettings::instance()->setValue( pluginId() + "/oauthtoken", oauthtoken ); -} - -QString -TwitterPlugin::twitterOAuthTokenSecret() const -{ - TomahawkSettings* s = TomahawkSettings::instance(); - s->beginGroup( pluginId() ); - QStringList keys = s->childKeys(); - if ( keys.contains( "OAuthTokenSecret", Qt::CaseSensitive ) ) - { - s->setValue( "oauthtokensecret_tmp", - s->value( "OAuthTokenSecret" ).toString() ); - s->remove( "OAuthTokenSecret" ); - - s->sync(); - } - keys = s->childKeys(); - if ( keys.contains( "oauthtokensecret_tmp", Qt::CaseSensitive ) ) - { - s->setValue( "oauthtokensecret", - s->value( "oauthtokensecret_tmp" ).toString() ); - s->remove( "oauthtokensecret_tmp" ); - - s->sync(); - } - s->endGroup(); - - return s->value( pluginId() + "/oauthtokensecret" ).toString(); -} - -void -TwitterPlugin::setTwitterOAuthTokenSecret( const QString& oauthtokensecret ) -{ - TomahawkSettings::instance()->setValue( pluginId() + "/oauthtokensecret", oauthtokensecret ); -} - -qint64 -TwitterPlugin::twitterCachedFriendsSinceId() const -{ - TomahawkSettings* s = TomahawkSettings::instance(); - s->beginGroup( pluginId() ); - QStringList keys = s->childKeys(); - if ( keys.contains( "CachedFriendsSinceID", Qt::CaseSensitive ) ) - { - s->setValue( "cachedfriendssinceid_tmp", - s->value( "CachedFriendsSinceID" ).toLongLong() ); - s->remove( "CachedFriendsSinceID" ); - - s->sync(); - } - keys = s->childKeys(); - if ( keys.contains( "cachedfriendssinceid_tmp", Qt::CaseSensitive ) ) - { - s->setValue( "cachedfriendssinceid", - s->value( "cachedfriendssinceid_tmp" ).toLongLong() ); - s->remove( "cachedfriendssinceid_tmp" ); - - s->sync(); - } - s->endGroup(); - - return s->value( pluginId() + "/cachedfriendssinceid", 0 ).toLongLong(); -} - -void -TwitterPlugin::setTwitterCachedFriendsSinceId( qint64 cachedId ) -{ - TomahawkSettings::instance()->setValue( pluginId() + "/cachedfriendssinceid", cachedId ); -} - -qint64 -TwitterPlugin::twitterCachedMentionsSinceId() const -{ - TomahawkSettings* s = TomahawkSettings::instance(); - s->beginGroup( pluginId() ); - QStringList keys = s->childKeys(); - if ( keys.contains( "CachedMentionsSinceID", Qt::CaseSensitive ) ) - { - s->setValue( "cachedmentionssinceid_tmp", - s->value( "CachedMentionsSinceID" ).toLongLong() ); - s->remove( "CachedMentionsSinceID" ); - - s->sync(); - } - keys = s->childKeys(); - if ( keys.contains( "cachedmentionssinceid_tmp", Qt::CaseSensitive ) ) - { - s->setValue( "cachedmentionssinceid", - s->value( "cachedmentionssinceid_tmp" ).toLongLong() ); - s->remove( "cachedmentionssinceid_tmp" ); - - s->sync(); - } - s->endGroup(); - - return s->value( pluginId() + "/cachedmentionssinceid", 0 ).toLongLong(); -} - -void -TwitterPlugin::setTwitterCachedMentionsSinceId( qint64 cachedId ) -{ - TomahawkSettings::instance()->setValue( pluginId() + "/cachedmentionssinceid", cachedId ); -} - -qint64 -TwitterPlugin::twitterCachedDirectMessagesSinceId() const -{ - TomahawkSettings* s = TomahawkSettings::instance(); - s->beginGroup( pluginId() ); - QStringList keys = s->childKeys(); - if ( keys.contains( "CachedDirectMessagesSinceID", Qt::CaseSensitive ) ) - { - s->setValue( "cacheddirectmessagessinceid_tmp", - s->value( "CachedDirectMessagesSinceID" ).toLongLong() ); - s->remove( "CachedDirectMessagesSinceID" ); - - s->sync(); - } - keys = s->childKeys(); - if ( keys.contains( "cacheddirectmessagessinceid_tmp", Qt::CaseSensitive ) ) - { - s->setValue( "cacheddirectmessagessinceid", - s->value( "cacheddirectmessagessinceid_tmp" ).toLongLong() ); - s->remove( "cacheddirectmessagessinceid_tmp" ); - - s->sync(); - } - s->endGroup(); - - return s->value( pluginId() + "/cacheddirectmessagessinceid", 0 ).toLongLong(); -} - -void -TwitterPlugin::setTwitterCachedDirectMessagesSinceId( qint64 cachedId ) -{ - TomahawkSettings::instance()->setValue( pluginId() + "/cacheddirectmessagessinceid", cachedId ); -} - -QVariantHash -TwitterPlugin::twitterCachedPeers() const -{ - TomahawkSettings* s = TomahawkSettings::instance(); - s->beginGroup( pluginId() ); - QStringList keys = s->childKeys(); - if ( keys.contains( "CachedPeers", Qt::CaseSensitive ) ) - { - s->setValue( "cachedpeers_tmp", - s->value( "CachedPeers" ).toHash() ); - s->remove( "CachedPeers" ); - - s->sync(); - } - keys = s->childKeys(); - if ( keys.contains( "cachedpeers_tmp", Qt::CaseSensitive ) ) - { - s->setValue( "cachedpeers", - s->value( "cachedpeers_tmp" ).toHash() ); - s->remove( "cachedpeers_tmp" ); - - s->sync(); - } - s->endGroup(); - - return s->value( pluginId() + "/cachedpeers", QVariantHash() ).toHash(); -} - -void -TwitterPlugin::setTwitterCachedPeers( const QVariantHash &cachedPeers ) -{ - TomahawkSettings::instance()->setValue( pluginId() + "/cachedpeers", cachedPeers ); - TomahawkSettings::instance()->sync(); -} - -Q_EXPORT_PLUGIN2( sipfactory, TwitterFactory ) diff --git a/src/sip/twitter/twittersip.h b/src/sip/twitter/twittersip.h index 40a8e3b73..2674d1eb5 100644 --- a/src/sip/twitter/twittersip.h +++ b/src/sip/twitter/twittersip.h @@ -19,8 +19,6 @@ #ifndef TWITTER_H #define TWITTER_H -#include "twitterconfigwidget.h" - #include #include #include @@ -36,48 +34,28 @@ #include "../sipdllmacro.h" #include "sip/SipPlugin.h" +#include "accounts/account.h" #include "tomahawkoauthtwitter.h" #define MYNAME "SIPTWITTER" -class SIPDLLEXPORT TwitterFactory : public SipPluginFactory -{ - Q_OBJECT - Q_INTERFACES( SipPluginFactory ) - -public: - TwitterFactory() {} - virtual ~TwitterFactory() {} - - virtual QString prettyName() const { return "Twitter"; } - virtual QString factoryId() const { return "siptwitter"; } - virtual QIcon icon() const; - virtual SipPlugin* createPlugin( const QString& pluginId = QString() ); -}; - -class SIPDLLEXPORT TwitterPlugin : public SipPlugin +class SIPDLLEXPORT TwitterSipPlugin : public SipPlugin { Q_OBJECT public: - TwitterPlugin( const QString& pluginId ); + TwitterSipPlugin( Tomahawk::Accounts::Account *account ); - virtual ~TwitterPlugin() {} + virtual ~TwitterSipPlugin() {} virtual bool isValid() const; - virtual const QString name() const; - virtual const QString accountName() const; - virtual const QString friendlyName() const; virtual ConnectionState connectionState() const; - virtual QIcon icon() const; - virtual QWidget* configWidget(); public slots: virtual bool connectPlugin(); void disconnectPlugin(); - void checkSettings(); void refreshProxy(); - void deletePlugin(); + void configurationChanged(); void sendMsg( const QString& to, const QString& msg ) { @@ -97,7 +75,6 @@ public slots: } private slots: - void configDialogAuthedSignalSlot( bool authed ); void connectAuthVerifyReply( const QTweetUser &user ); void checkTimerFired(); void connectTimerFired(); @@ -117,26 +94,14 @@ private slots: void profilePicReply(); private: - inline void syncConfig() { setTwitterCachedPeers( m_cachedPeers ); } + inline void syncConfig() { m_account->setCredentials( m_credentials ); m_account->setConfiguration( m_configuration ); m_account->syncConfig(); } bool refreshTwitterAuth(); void parseGotTomahawk( const QRegExp ®ex, const QString &screenName, const QString &text ); // handle per-plugin config - QString twitterSavedDbid() const; - void setTwitterSavedDbid( const QString& dbid ); - QString twitterScreenName() const; - void setTwitterScreenName( const QString& screenName ); QString twitterOAuthToken() const; void setTwitterOAuthToken( const QString& oauthtoken ); QString twitterOAuthTokenSecret() const; void setTwitterOAuthTokenSecret( const QString& oauthtokensecret ); - qint64 twitterCachedFriendsSinceId() const; - void setTwitterCachedFriendsSinceId( qint64 sinceid ); - qint64 twitterCachedMentionsSinceId() const; - void setTwitterCachedMentionsSinceId( qint64 sinceid ); - qint64 twitterCachedDirectMessagesSinceId() const; - void setTwitterCachedDirectMessagesSinceId( qint64 sinceid ); - QVariantHash twitterCachedPeers() const; - void setTwitterCachedPeers( const QVariantHash &cachedPeers ); QWeakPointer< TomahawkOAuthTwitter > m_twitterAuth; QWeakPointer< QTweetFriendsTimeline > m_friendsTimeline; @@ -145,6 +110,9 @@ private: QWeakPointer< QTweetDirectMessageNew > m_directMessageNew; QWeakPointer< QTweetDirectMessageDestroy > m_directMessageDestroy; + QVariantHash m_configuration; + QVariantHash m_credentials; + bool m_isAuthed; QTimer m_checkTimer; QTimer m_connectTimer; diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index 80c18ac32..3563a71b7 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -523,8 +523,7 @@ TomahawkApp::initSIP() #endif tDebug( LOGINFO ) << "Connecting SIP classes"; - //SipHandler::instance()->refreshProxy(); - SipHandler::instance()->loadFromConfig(); + SipHandler::instance()->loadFromAccountManager(); } } From f548d36586a9adf44775519c1daefb57b8cbb93a Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Sat, 22 Oct 2011 13:26:00 -0400 Subject: [PATCH 005/104] Further work towards compilation --- src/libtomahawk/accounts/account.h | 1 + src/libtomahawk/sip/SipHandler.cpp | 6 +++--- src/libtomahawk/sip/SipHandler.h | 15 +-------------- src/libtomahawk/sip/SipModel.cpp | 18 ++++++++++-------- src/libtomahawk/sip/SipModel.h | 4 ---- 5 files changed, 15 insertions(+), 29 deletions(-) diff --git a/src/libtomahawk/accounts/account.h b/src/libtomahawk/accounts/account.h index 7cf3c1761..719ae1444 100644 --- a/src/libtomahawk/accounts/account.h +++ b/src/libtomahawk/accounts/account.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/src/libtomahawk/sip/SipHandler.cpp b/src/libtomahawk/sip/SipHandler.cpp index 2fb7fbab2..c63ffcfe2 100644 --- a/src/libtomahawk/sip/SipHandler.cpp +++ b/src/libtomahawk/sip/SipHandler.cpp @@ -174,7 +174,7 @@ void SipHandler::loadFromAccountManager() { QList< Tomahawk::Accounts::Account* > accountList = Tomahawk::Accounts::AccountManager::instance()->getAccounts( Tomahawk::Accounts::SipType ); - foreach( const Tomahawk::Accounts::Account* account, accountList ) + foreach( Tomahawk::Accounts::Account* account, accountList ) { SipPlugin* p = account->sipPlugin(); addSipPlugin( p ); @@ -240,7 +240,7 @@ SipHandler::disconnectPlugin( const QString &pluginName ) { foreach( SipPlugin* sip, m_connectedPlugins ) { - if ( sip->name() == pluginName ) + if ( sip->account()->accountId() == pluginName ) sip->disconnectPlugin(); } } @@ -387,7 +387,7 @@ SipHandler::onError( int code, const QString& msg ) SipPlugin* sip = qobject_cast< SipPlugin* >( sender() ); Q_ASSERT( sip ); - qWarning() << "Failed to connect to SIP:" << sip->accountName() << code << msg; + qWarning() << "Failed to connect to SIP:" << sip->account()->accountFriendlyName() << code << msg; if ( code == SipPlugin::AuthError ) { diff --git a/src/libtomahawk/sip/SipHandler.h b/src/libtomahawk/sip/SipHandler.h index 5df67357a..19cee9c60 100644 --- a/src/libtomahawk/sip/SipHandler.h +++ b/src/libtomahawk/sip/SipHandler.h @@ -37,16 +37,14 @@ public: SipHandler( QObject* parent ); ~SipHandler(); - QList< SipPluginFactory* > pluginFactories() const; QList< SipPlugin* > allPlugins() const; QList< SipPlugin* > connectedPlugins() const; void loadFromAccountManager(); - void addSipPlugin( SipPlugin* p, bool enable = true ); + void addSipPlugin( SipPlugin* p ); void removeSipPlugin( SipPlugin* p ); bool hasPluginType( const QString& factoryId ) const; - SipPluginFactory* factoryFromPlugin( SipPlugin* p ) const; const QPixmap avatar( const QString& name ) const; //TODO: implement a proper SipInfo class and maybe attach it to the source @@ -56,9 +54,6 @@ public: public slots: void checkSettings(); - void enablePlugin( SipPlugin* p ); - void disablePlugin( SipPlugin* p ); - void connectPlugin( const QString &pluginId = QString() ); void disconnectPlugin( const QString &pluginId = QString() ); void connectAll(); @@ -68,13 +63,6 @@ public slots: void refreshProxy(); - // create a new plugin of the given name. the name is the value returned in SipPluginFactory::pluginName - // be default sip plugins are NOt connected when created - SipPlugin* createPlugin( const QString& factoryName ); - // load a plugin with the given id - SipPlugin* loadPlugin( const QString& pluginId ); - void removePlugin( SipPlugin* p ); - signals: void connected( SipPlugin* ); void disconnected( SipPlugin* ); @@ -113,7 +101,6 @@ private: void loadPluginFactory( const QString& path ); QString factoryFromId( const QString& pluginId ) const; - QHash< QString, SipPluginFactory* > m_pluginFactories; QList< SipPlugin* > m_allPlugins; QList< SipPlugin* > m_enabledPlugins; QList< SipPlugin* > m_connectedPlugins; diff --git a/src/libtomahawk/sip/SipModel.cpp b/src/libtomahawk/sip/SipModel.cpp index 863769cbb..093d81c88 100644 --- a/src/libtomahawk/sip/SipModel.cpp +++ b/src/libtomahawk/sip/SipModel.cpp @@ -70,11 +70,11 @@ SipModel::data( const QModelIndex& index, int role ) const { case Qt::DisplayRole: case SipModel::PluginName: - return p->accountName(); + return p->account()->accountServiceName(); case SipModel::ConnectionStateRole: return p->connectionState(); case SipModel::HasConfig: - return ( p->configWidget() != 0 ); + return ( p->account()->configurationWidget() != 0 ); case SipModel::FactoryRole: return false; case Qt::DecorationRole: @@ -82,12 +82,14 @@ SipModel::data( const QModelIndex& index, int role ) const case SipModel::SipPluginData: return QVariant::fromValue< QObject* >( p ); case Qt::CheckStateRole: - return SipHandler::instance()->enabledPlugins().contains( p ) ? Qt::Checked : Qt::Unchecked; + return p->account()->enabled() ? Qt::Checked : Qt::Unchecked; default: return QVariant(); } } + /* + * m_factories never actually populated yet, so just disable if( index.parent().isValid() ) { // this is a factory type SipPluginFactory* p = m_factories.at( index.row() ); switch( role ) @@ -104,7 +106,7 @@ SipModel::data( const QModelIndex& index, int role ) const return QVariant(); } } - + */ return QVariant(); } @@ -119,10 +121,10 @@ SipModel::setData( const QModelIndex& index, const QVariant& value, int role ) QList< SipPlugin* > plugins = SipHandler::instance()->allPlugins(); SipPlugin* p = plugins[ index.row() ]; - if( state == Qt::Checked && !SipHandler::instance()->enabledPlugins().contains( p ) ) { - SipHandler::instance()->enablePlugin( p ); + if( state == Qt::Checked && !p->account()->enabled() ) { + p->account()->setEnabled( true ); } else if( state == Qt::Unchecked ) { - SipHandler::instance()->disablePlugin( p ); + p->account()->setEnabled( false ); } dataChanged( index, index ); @@ -169,7 +171,7 @@ SipModel::rowCount( const QModelIndex& parent ) const return SipHandler::instance()->allPlugins().size() /* TODO inline factories disabled + 1*/; if( parent.isValid() && !parent.parent().isValid() ) { // top level item if( parent.row() == SipHandler::instance()->allPlugins().count() ) {// last row, this is the factory - return m_factories.count(); + //return m_factories.count(); } } diff --git a/src/libtomahawk/sip/SipModel.h b/src/libtomahawk/sip/SipModel.h index 18e15cf0b..7f4901032 100644 --- a/src/libtomahawk/sip/SipModel.h +++ b/src/libtomahawk/sip/SipModel.h @@ -25,7 +25,6 @@ #include #include -class SipPluginFactory; class SipPlugin; class DLLEXPORT SipModel : public QAbstractItemModel @@ -59,9 +58,6 @@ private slots: void pluginAdded( SipPlugin* p ); void pluginRemoved( SipPlugin* p ); void pluginStateChanged( SipPlugin* p ); - -private: - QList< SipPluginFactory* > m_factories; }; #endif // SIPMODEL_H From 8f24acd00881a4264d98cadb9a53ab9747ffb7cd Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Sat, 22 Oct 2011 13:59:05 -0400 Subject: [PATCH 006/104] More account updates --- src/libtomahawk/sip/SipPlugin.h | 4 +- src/sip/twitter/CMakeLists.txt | 11 +- src/sip/twitter/tomahawkoauthtwitter.cpp | 32 -- src/sip/twitter/tomahawkoauthtwitter.h | 25 -- src/sip/twitter/twitterconfigwidget.cpp | 270 ---------------- src/sip/twitter/twitterconfigwidget.h | 69 ---- src/sip/twitter/twitterconfigwidget.ui | 381 ----------------------- src/sip/twitter/twittersip.cpp | 2 - src/sip/twitter/twittersip.h | 9 +- 9 files changed, 5 insertions(+), 798 deletions(-) delete mode 100644 src/sip/twitter/tomahawkoauthtwitter.cpp delete mode 100644 src/sip/twitter/tomahawkoauthtwitter.h delete mode 100644 src/sip/twitter/twitterconfigwidget.cpp delete mode 100644 src/sip/twitter/twitterconfigwidget.h delete mode 100644 src/sip/twitter/twitterconfigwidget.ui diff --git a/src/libtomahawk/sip/SipPlugin.h b/src/libtomahawk/sip/SipPlugin.h index bb51dabc0..65ebe8209 100644 --- a/src/libtomahawk/sip/SipPlugin.h +++ b/src/libtomahawk/sip/SipPlugin.h @@ -102,8 +102,10 @@ private slots: void onPeerOnline( const QString &peerId ); void onPeerOffline( const QString &peerId ); -private: +protected: Tomahawk::Accounts::Account *m_account; + +private: QString m_cachedError; QStringList m_peersOnline; }; diff --git a/src/sip/twitter/CMakeLists.txt b/src/sip/twitter/CMakeLists.txt index 32eb308f1..cac93c6b7 100644 --- a/src/sip/twitter/CMakeLists.txt +++ b/src/sip/twitter/CMakeLists.txt @@ -8,18 +8,10 @@ add_definitions( -DSIPDLLEXPORT_PRO ) set( twitterSources twittersip.cpp - twitterconfigwidget.cpp - tomahawkoauthtwitter.cpp ) set( twitterHeaders twittersip.h - twitterconfigwidget.h - tomahawkoauthtwitter.h -) - -set( twitterUI - twitterconfigwidget.ui ) include_directories( . ${CMAKE_CURRENT_BINARY_DIR} .. @@ -29,8 +21,7 @@ include_directories( . ${CMAKE_CURRENT_BINARY_DIR} .. qt4_add_resources( RC_SRCS "resources.qrc" ) qt4_wrap_cpp( twitterMoc ${twitterHeaders} ) -qt4_wrap_ui( twitterUI_H ${twitterUI} ) -add_library( tomahawk_siptwitter SHARED ${twitterUI_H} ${twitterSources} ${twitterMoc} ${RC_SRCS} ) +add_library( tomahawk_siptwitter SHARED ${twitterSources} ${twitterMoc} ${RC_SRCS} ) IF( WIN32 ) SET( OS_SPECIFIC_LINK_LIBRARIES diff --git a/src/sip/twitter/tomahawkoauthtwitter.cpp b/src/sip/twitter/tomahawkoauthtwitter.cpp deleted file mode 100644 index 35cd98a9e..000000000 --- a/src/sip/twitter/tomahawkoauthtwitter.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#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/sip/twitter/tomahawkoauthtwitter.h b/src/sip/twitter/tomahawkoauthtwitter.h deleted file mode 100644 index 6b1a75465..000000000 --- a/src/sip/twitter/tomahawkoauthtwitter.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef TOMAHAWKOAUTHTWITTER -#define TOMAHAWKOAUTHTWITTER - -#include "../sipdllmacro.h" - -#include -#include - -class SIPDLLEXPORT 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/sip/twitter/twitterconfigwidget.cpp b/src/sip/twitter/twitterconfigwidget.cpp deleted file mode 100644 index 357bc038f..000000000 --- a/src/sip/twitter/twitterconfigwidget.cpp +++ /dev/null @@ -1,270 +0,0 @@ -/* === 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 "twittersip.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" - - -TwitterConfigWidget::TwitterConfigWidget( TwitterPlugin* plugin, QWidget *parent ) : - QWidget( parent ), - ui( new Ui::TwitterConfigWidget ), - m_plugin( plugin ) -{ - 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!" ) ); - - if ( m_plugin->twitterOAuthToken().isEmpty() || m_plugin->twitterOAuthTokenSecret().isEmpty() || m_plugin->twitterScreenName().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_plugin->twitterScreenName() ) ); - 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(); - - m_plugin->setTwitterOAuthToken( twitAuth->oauthToken() ); - m_plugin->setTwitterOAuthTokenSecret( twitAuth->oauthTokenSecret() ); - - 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; - } - - m_plugin->setTwitterScreenName( user.screenName() ); - m_plugin->setTwitterCachedFriendsSinceId( 0 ); - m_plugin->setTwitterCachedMentionsSinceId( 0 ); - - ui->twitterStatusLabel->setText( tr( "Status: Credentials saved for %1" ).arg( m_plugin->twitterScreenName() ) ); - ui->twitterAuthenticateButton->setText( tr( "De-authenticate" ) ); - ui->twitterSyncGroupBox->setVisible( true ); - ui->twitterTweetComboBox->setCurrentIndex( 0 ); - ui->twitterUserTweetLineEdit->setVisible( false ); - ui->twitterTweetGotTomahawkButton->setText( tr( "Tweet!" ) ); - - m_plugin->connectPlugin(); - - 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; - m_plugin->setTwitterOAuthToken( QString() ); - m_plugin->setTwitterOAuthTokenSecret( QString() ); - m_plugin->setTwitterScreenName( QString() ); - - 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"; - if ( m_plugin->twitterOAuthToken().isEmpty() || m_plugin->twitterOAuthTokenSecret().isEmpty() || m_plugin->twitterScreenName().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( m_plugin->twitterOAuthToken().toLatin1() ); - twitAuth->setOAuthTokenSecret( m_plugin->twitterOAuthTokenSecret().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; - } - m_plugin->setTwitterScreenName( user.screenName() ); - TomahawkOAuthTwitter *twitAuth = new TomahawkOAuthTwitter( TomahawkUtils::nam(), this ); - twitAuth->setOAuthToken( m_plugin->twitterOAuthToken().toLatin1() ); - twitAuth->setOAuthTokenSecret( m_plugin->twitterOAuthTokenSecret().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!") ); -} diff --git a/src/sip/twitter/twitterconfigwidget.h b/src/sip/twitter/twitterconfigwidget.h deleted file mode 100644 index d06c08737..000000000 --- a/src/sip/twitter/twitterconfigwidget.h +++ /dev/null @@ -1,69 +0,0 @@ -/* === 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 TWITTERCONFIGWIDGET_H -#define TWITTERCONFIGWIDGET_H - -#include "sip/SipPlugin.h" - -#include -#include -#include -#include - -#include - -class TwitterPlugin; - -namespace Ui { - class TwitterConfigWidget; -} - -class TwitterConfigWidget : public QWidget -{ - Q_OBJECT - -public: - explicit TwitterConfigWidget( TwitterPlugin* plugin = 0, QWidget *parent = 0 ); - ~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; - TwitterPlugin *m_plugin; - QString m_postGTtype; -}; - -#endif // TWITTERCONFIGWIDGET_H diff --git a/src/sip/twitter/twitterconfigwidget.ui b/src/sip/twitter/twitterconfigwidget.ui deleted file mode 100644 index f60dbb5f8..000000000 --- a/src/sip/twitter/twitterconfigwidget.ui +++ /dev/null @@ -1,381 +0,0 @@ - - - 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/sip/twitter/twittersip.cpp b/src/sip/twitter/twittersip.cpp index 06318b5bd..0a316f41b 100644 --- a/src/sip/twitter/twittersip.cpp +++ b/src/sip/twitter/twittersip.cpp @@ -18,8 +18,6 @@ #include "twittersip.h" -#include "twitterconfigwidget.h" - #include #include #include diff --git a/src/sip/twitter/twittersip.h b/src/sip/twitter/twittersip.h index 2674d1eb5..b3f314d29 100644 --- a/src/sip/twitter/twittersip.h +++ b/src/sip/twitter/twittersip.h @@ -35,9 +35,7 @@ #include "../sipdllmacro.h" #include "sip/SipPlugin.h" #include "accounts/account.h" -#include "tomahawkoauthtwitter.h" - -#define MYNAME "SIPTWITTER" +#include "accounts/twitter/tomahawkoauthtwitter.h" class SIPDLLEXPORT TwitterSipPlugin : public SipPlugin { @@ -124,11 +122,6 @@ private: QHash< QString, QPixmap > m_cachedAvatars; QSet m_keyCache; ConnectionState m_state; - - QWeakPointer m_configWidget; - - // for settings access - friend class TwitterConfigWidget; }; #endif From 709a25ce975ef84fcb41910b45851b09db80dfed Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Sat, 22 Oct 2011 14:45:40 -0400 Subject: [PATCH 007/104] More compilation fixes, though settings dialog needs serious reworking. Can't figure out why it isn't linking atm --- src/accounts/twitter/CMakeLists.txt | 23 ++++++++++++++++++++--- src/diagnosticsdialog.cpp | 4 ++-- src/settingsdialog.cpp | 10 +++++----- src/settingsdialog.h | 14 ++++++++------ src/sip/twitter/CMakeLists.txt | 2 ++ src/sip/twitter/twittersip.cpp | 13 ++++++++++--- src/sip/twitter/twittersip.h | 9 +++------ 7 files changed, 50 insertions(+), 25 deletions(-) diff --git a/src/accounts/twitter/CMakeLists.txt b/src/accounts/twitter/CMakeLists.txt index 80587ad75..007ee0f6a 100644 --- a/src/accounts/twitter/CMakeLists.txt +++ b/src/accounts/twitter/CMakeLists.txt @@ -9,27 +9,35 @@ add_definitions( -DDLLEXPORT_PRO ) set( twitterAccountSources twitteraccount.cpp twitterconfigwidget.cpp - tomahawkoauthtwitter.cpp ) set( twitterAccountHeaders twitteraccount.h twitterconfigwidget.h - tomahawkoauthtwitter.h ) set( twitterAccountUI twitterconfigwidget.ui ) +set( tomahawkOAuthTwitterSources + tomahawkoauthtwitter.cpp +) + +set( tomahawkOAuthTwitterHeaders + tomahawkoauthtwitter.h +) + include_directories( . ${CMAKE_CURRENT_BINARY_DIR} .. ${QT_INCLUDE_DIR} ${QTWEETLIB_INCLUDE_DIR} ) -qt4_add_resources( RC_SRCS "resources.qrc" ) +qt4_wrap_cpp( tomahawkOAuthTwitterMoc ${tomahawkOAuthTwitterSources} ) +add_library( tomahawk_oauth_twitter SHARED ${tomahawkOAuthTwitterSources} ${tomahawkOAuthTwitterMoc} ) qt4_wrap_cpp( twitterAccountMoc ${twitterAccountHeaders} ) qt4_wrap_ui( twitterAccountUI_H ${twitterAccountUI} ) +qt4_add_resources( RC_SRCS "resources.qrc" ) add_library( tomahawk_account_twitter SHARED ${twitterAccountUI_H} ${twitterAccountSources} ${twitterAccountMoc} ${RC_SRCS} ) IF( WIN32 ) @@ -40,7 +48,15 @@ SET( OS_SPECIFIC_LINK_LIBRARIES ) ENDIF( WIN32 ) +target_link_libraries( tomahawk_oauth_twitter + ${TOMAHAWK_LIBRARIES} + ${QTWEETLIB_LIBRARIES} + ${QT_LIBRARIES} + ${OS_SPECIFIC_LINK_LIBRARIES} +) + target_link_libraries( tomahawk_account_twitter + tomahawk_oauth_twitter ${TOMAHAWK_LIBRARIES} ${QTWEETLIB_LIBRARIES} ${QT_LIBRARIES} @@ -51,4 +67,5 @@ IF( APPLE ) # SET( CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} "-undefined dynamic_lookup" ) ENDIF( APPLE ) +install( TARGETS tomahawk_oauth_twitter DESTINATION lib${LIB_SUFFIX} ) install( TARGETS tomahawk_account_twitter DESTINATION lib${LIB_SUFFIX} ) diff --git a/src/diagnosticsdialog.cpp b/src/diagnosticsdialog.cpp index 565032f8c..3d0f8e631 100644 --- a/src/diagnosticsdialog.cpp +++ b/src/diagnosticsdialog.cpp @@ -115,9 +115,9 @@ void DiagnosticsDialog::updateLogView() } log.append( QString(" %2 (%1): %3 (%4)\n") - .arg(sip->name()) + .arg(sip->account()->accountServiceName()) .arg(sip->friendlyName()) - .arg(sip->accountName()) + .arg(sip->account()->accountFriendlyName()) .arg(stateString) ); diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index 307e6d569..ef56af80f 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -128,7 +128,7 @@ SettingsDialog::SettingsDialog( QWidget *parent ) connect( Servent::instance(), SIGNAL( ready() ), this, SLOT( serventReady() ) ); } - setupSipButtons(); + //setupSipButtons(); ui->staticHostName->setText( s->externalHostname() ); ui->staticPort->setValue( s->externalPort() ); @@ -309,7 +309,7 @@ SettingsDialog::createIcons() connect( ui->listWidget, SIGNAL( currentItemChanged( QListWidgetItem*, QListWidgetItem* ) ), SLOT( changePage( QListWidgetItem*, QListWidgetItem* ) ) ); } - +/* void SettingsDialog::setupSipButtons() { @@ -329,7 +329,7 @@ SettingsDialog::setupSipButtons() connect( ui->removeSipButton, SIGNAL( clicked( bool ) ), this, SLOT( sipPluginDeleted( bool ) ) ); } - +*/ void SettingsDialog::changePage( QListWidgetItem* current, QListWidgetItem* previous ) @@ -599,7 +599,7 @@ SettingsDialog::resolverConfigClosed( int value ) } } - +/* void SettingsDialog::sipItemClicked( const QModelIndex& item ) { @@ -814,7 +814,7 @@ SettingsDialog::sipPluginDeleted( bool ) } } } - +*/ ProxyDialog::ProxyDialog( QWidget *parent ) : QDialog( parent ) diff --git a/src/settingsdialog.h b/src/settingsdialog.h index 834ef3880..ef2d53eee 100644 --- a/src/settingsdialog.h +++ b/src/settingsdialog.h @@ -89,6 +89,7 @@ private slots: #endif void openResolverConfig( const QString& ); + /* void sipItemClicked ( const QModelIndex& ); void openSipConfig( SipPlugin* ); void factoryActionTriggered ( bool ); @@ -96,21 +97,22 @@ private slots: void sipContextMenuRequest( const QPoint& ); void sipPluginDeleted( bool ); void sipPluginRowDeleted( bool ); - - void updateScanOptionsView(); - + */ // dialog slots void resolverConfigClosed( int value ); + /* void sipConfigClosed( int value ); void sipCreateConfigClosed( int value ); - + */ + void updateScanOptionsView(); + void changePage( QListWidgetItem*, QListWidgetItem* ); void serventReady(); private: void createIcons(); - void setupSipButtons(); - void handleSipPluginAdded( SipPlugin* p, bool added ); + //void setupSipButtons(); + //void handleSipPluginAdded( SipPlugin* p, bool added ); Ui_StackedSettingsDialog* ui; diff --git a/src/sip/twitter/CMakeLists.txt b/src/sip/twitter/CMakeLists.txt index cac93c6b7..97ee49188 100644 --- a/src/sip/twitter/CMakeLists.txt +++ b/src/sip/twitter/CMakeLists.txt @@ -32,6 +32,8 @@ SET( OS_SPECIFIC_LINK_LIBRARIES ENDIF( WIN32 ) target_link_libraries( tomahawk_siptwitter + tomahawk_oauth_twitter + tomahawk_account_twitter ${TOMAHAWK_LIBRARIES} ${QTWEETLIB_LIBRARIES} ${QT_LIBRARIES} diff --git a/src/sip/twitter/twittersip.cpp b/src/sip/twitter/twittersip.cpp index 0a316f41b..7dcd1b2af 100644 --- a/src/sip/twitter/twittersip.cpp +++ b/src/sip/twitter/twittersip.cpp @@ -37,6 +37,7 @@ #include #include "utils/logger.h" +#include "accounts/twitter/tomahawkoauthtwitter.h" static QString s_gotTomahawkRegex = QString( "^(@[a-zA-Z0-9]+ )?(Got Tomahawk\\?) (\\{[a-fA-F0-9\\-]+\\}) (.*)$" ); @@ -92,13 +93,19 @@ TwitterSipPlugin::connectionState() const } +void TwitterSipPlugin::checkSettings() +{ + //TODO/FIXME: check status and enable/disable? +} + + bool TwitterSipPlugin::connectPlugin() { qDebug() << Q_FUNC_INFO; if ( !m_account->enabled() ) - return; + return false; m_cachedPeers = m_configuration[ "cachedPeers" ].toHash(); QStringList peerList = m_cachedPeers.keys(); @@ -134,7 +141,7 @@ TwitterSipPlugin::refreshTwitterAuth() Q_ASSERT( TomahawkUtils::nam() != 0 ); qDebug() << Q_FUNC_INFO << " with nam " << TomahawkUtils::nam(); - m_twitterAuth = QWeakPointer( new TomahawkOAuthTwitter( TomahawkUtils::nam(), this ) ); + m_twitterAuth = QWeakPointer< TomahawkOAuthTwitter >( new TomahawkOAuthTwitter( TomahawkUtils::nam(), this ) ); if( m_twitterAuth.isNull() ) return false; @@ -191,7 +198,7 @@ TwitterSipPlugin::connectAuthVerifyReply( const QTweetUser &user ) m_isAuthed = true; if ( !m_twitterAuth.isNull() ) { - m_configuration[ "screenName" ] = user.screenName; + m_configuration[ "screenName" ] = user.screenName(); syncConfig(); m_friendsTimeline = QWeakPointer( new QTweetFriendsTimeline( m_twitterAuth.data(), this ) ); m_mentions = QWeakPointer( new QTweetMentions( m_twitterAuth.data(), this ) ); diff --git a/src/sip/twitter/twittersip.h b/src/sip/twitter/twittersip.h index b3f314d29..65b7ef9f0 100644 --- a/src/sip/twitter/twittersip.h +++ b/src/sip/twitter/twittersip.h @@ -72,6 +72,8 @@ public slots: Q_UNUSED( msg ); } + void checkSettings(); + private slots: void connectAuthVerifyReply( const QTweetUser &user ); void checkTimerFired(); @@ -90,16 +92,11 @@ private slots: void fetchAvatar( const QString &screenName ); void avatarUserDataSlot( const QTweetUser &user ); void profilePicReply(); - + private: inline void syncConfig() { m_account->setCredentials( m_credentials ); m_account->setConfiguration( m_configuration ); m_account->syncConfig(); } bool refreshTwitterAuth(); void parseGotTomahawk( const QRegExp ®ex, const QString &screenName, const QString &text ); - // handle per-plugin config - QString twitterOAuthToken() const; - void setTwitterOAuthToken( const QString& oauthtoken ); - QString twitterOAuthTokenSecret() const; - void setTwitterOAuthTokenSecret( const QString& oauthtokensecret ); QWeakPointer< TomahawkOAuthTwitter > m_twitterAuth; QWeakPointer< QTweetFriendsTimeline > m_friendsTimeline; From 13cfda6e1ee207ab0ad3f4d8495c386ed6be08af Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Sat, 5 Nov 2011 12:22:57 -0400 Subject: [PATCH 008/104] Account properly saves itself now and can reload a saved account --- src/accounts/twitter/CMakeLists.txt | 3 +- src/accounts/twitter/twitteraccount.cpp | 2 +- src/accounts/twitter/twitteraccount.h | 2 +- src/libtomahawk/CMakeLists.txt | 1 + src/libtomahawk/accounts/account.cpp | 64 +++++++++++++++++++++ src/libtomahawk/accounts/account.h | 4 +- src/libtomahawk/accounts/accountmanager.cpp | 25 ++++---- src/libtomahawk/accounts/accountmanager.h | 4 +- src/libtomahawk/tomahawksettings.cpp | 24 ++++---- src/libtomahawk/tomahawksettings.h | 8 +-- src/sip/twitter/CMakeLists.txt | 1 - src/tomahawkapp.cpp | 1 + 12 files changed, 103 insertions(+), 36 deletions(-) create mode 100644 src/libtomahawk/accounts/account.cpp diff --git a/src/accounts/twitter/CMakeLists.txt b/src/accounts/twitter/CMakeLists.txt index 007ee0f6a..804707edd 100644 --- a/src/accounts/twitter/CMakeLists.txt +++ b/src/accounts/twitter/CMakeLists.txt @@ -33,7 +33,7 @@ include_directories( . ${CMAKE_CURRENT_BINARY_DIR} .. ${QTWEETLIB_INCLUDE_DIR} ) -qt4_wrap_cpp( tomahawkOAuthTwitterMoc ${tomahawkOAuthTwitterSources} ) +qt4_wrap_cpp( tomahawkOAuthTwitterMoc ${tomahawkOAuthTwitterHeaders} ) add_library( tomahawk_oauth_twitter SHARED ${tomahawkOAuthTwitterSources} ${tomahawkOAuthTwitterMoc} ) qt4_wrap_cpp( twitterAccountMoc ${twitterAccountHeaders} ) qt4_wrap_ui( twitterAccountUI_H ${twitterAccountUI} ) @@ -57,6 +57,7 @@ target_link_libraries( tomahawk_oauth_twitter target_link_libraries( tomahawk_account_twitter tomahawk_oauth_twitter + tomahawk_siptwitter ${TOMAHAWK_LIBRARIES} ${QTWEETLIB_LIBRARIES} ${QT_LIBRARIES} diff --git a/src/accounts/twitter/twitteraccount.cpp b/src/accounts/twitter/twitteraccount.cpp index 9cf146c85..264db1039 100644 --- a/src/accounts/twitter/twitteraccount.cpp +++ b/src/accounts/twitter/twitteraccount.cpp @@ -45,7 +45,7 @@ TwitterAccount::TwitterAccount( const QString &accountId ) setAccountServiceName( "Twitter" ); QSet< AccountType > types; - types << InfoType; + types << InfoType << SipType; setTypes( types ); m_configWidget = QWeakPointer< TwitterConfigWidget >( new TwitterConfigWidget( this, 0 ) ); diff --git a/src/accounts/twitter/twitteraccount.h b/src/accounts/twitter/twitteraccount.h index 1530c9e2b..a305cd7e5 100644 --- a/src/accounts/twitter/twitteraccount.h +++ b/src/accounts/twitter/twitteraccount.h @@ -62,7 +62,7 @@ public: bool canSelfAuthenticate() { return false; } bool authenticate() { return false; } - bool isAuthenticated() { return m_isAuthenticated; } + bool isAuthenticated() const { return m_isAuthenticated; } Tomahawk::InfoSystem::InfoPlugin* infoPlugin() { return 0; } SipPlugin* sipPlugin(); diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index 77d798ff0..3f935039a 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -38,6 +38,7 @@ set( libSources EchonestCatalogSynchronizer.cpp accounts/accountmanager.cpp + accounts/account.cpp sip/SipPlugin.cpp sip/SipHandler.cpp diff --git a/src/libtomahawk/accounts/account.cpp b/src/libtomahawk/accounts/account.cpp new file mode 100644 index 000000000..3a0e53b9e --- /dev/null +++ b/src/libtomahawk/accounts/account.cpp @@ -0,0 +1,64 @@ +/* === 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 "account.h" + +namespace Tomahawk +{ + +namespace Accounts +{ + +QWidget* +Account::configurationWidget() +{ + return 0; +} + + +QWidget* +Account::aclWidget() +{ + return 0; +} + + +QIcon +Account::icon() const +{ + return QIcon(); +} + + +bool +Account::authenticate() +{ + return false; +} + + +bool +Account::isAuthenticated() const +{ + return false; +} + + +} + +} \ No newline at end of file diff --git a/src/libtomahawk/accounts/account.h b/src/libtomahawk/accounts/account.h index 719ae1444..bc2046c04 100644 --- a/src/libtomahawk/accounts/account.h +++ b/src/libtomahawk/accounts/account.h @@ -80,7 +80,7 @@ public: virtual QIcon icon() const = 0; virtual bool authenticate() = 0; //if none needed, just return true - virtual bool isAuthenticated() = 0; + virtual bool isAuthenticated() const = 0; virtual Tomahawk::InfoSystem::InfoPlugin* infoPlugin() = 0; virtual SipPlugin* sipPlugin() = 0; @@ -190,7 +190,7 @@ public: virtual QIcon icon() const { return QIcon(); } virtual bool isUnique() const { return false; } - virtual Account* createAccount( const QString& pluginId = QString() ) = 0; + virtual Account* createAccount( const QString& accountId = QString() ) = 0; }; }; diff --git a/src/libtomahawk/accounts/accountmanager.cpp b/src/libtomahawk/accounts/accountmanager.cpp index 3cca9b797..b340ec4ab 100644 --- a/src/libtomahawk/accounts/accountmanager.cpp +++ b/src/libtomahawk/accounts/accountmanager.cpp @@ -112,9 +112,9 @@ AccountManager::loadPluginFactories( const QStringList& paths ) QString -AccountManager::factoryFromId( const QString& pluginId ) const +AccountManager::factoryFromId( const QString& accountId ) const { - return pluginId.split( "_" ).first(); + return accountId.split( "_" ).first(); } @@ -143,21 +143,22 @@ AccountManager::loadPluginFactory( const QString& path ) void AccountManager::loadFromConfig() { - QStringList pluginIds = TomahawkSettings::instance()->accountPlugins(); + QStringList accountIds = TomahawkSettings::instance()->accounts(); //FIXME: this is just for debugging - if ( pluginIds.isEmpty() ) + if ( accountIds.isEmpty() ) { Account* account = m_accountFactories[ "twitteraccount" ]->createAccount(); addAccountPlugin( account ); + TomahawkSettings::instance()->addAccount( account->accountId() ); } - - foreach( const QString& pluginId, pluginIds ) + + foreach( const QString& accountId, accountIds ) { - QString pluginFactory = factoryFromId( pluginId ); + QString pluginFactory = factoryFromId( accountId ); if( m_accountFactories.contains( pluginFactory ) ) { - Account* account = loadPlugin( pluginId ); + Account* account = loadPlugin( accountId ); addAccountPlugin( account ); } } @@ -166,13 +167,13 @@ AccountManager::loadFromConfig() Account* -AccountManager::loadPlugin( const QString& pluginId ) +AccountManager::loadPlugin( const QString& accountId ) { - QString factoryName = factoryFromId( pluginId ); + QString factoryName = factoryFromId( accountId ); Q_ASSERT( m_accountFactories.contains( factoryName ) ); - Account* account = m_accountFactories[ factoryName ]->createAccount( pluginId ); + Account* account = m_accountFactories[ factoryName ]->createAccount( accountId ); // caller responsible for calling pluginAdded() and hookupPlugin return account; @@ -186,7 +187,7 @@ AccountManager::addAccountPlugin( Account* account ) foreach( AccountType type, account->types() ) m_accountsByAccountType[ type ].append( account ); - //TODO: + //TODO:? //emit pluginAdded( account ); } diff --git a/src/libtomahawk/accounts/accountmanager.h b/src/libtomahawk/accounts/accountmanager.h index 9cb4d5ee7..8020c5759 100644 --- a/src/libtomahawk/accounts/accountmanager.h +++ b/src/libtomahawk/accounts/accountmanager.h @@ -49,8 +49,8 @@ public: void loadFromConfig(); void loadPluginFactory( const QString &path ); void addAccountPlugin( Account* account ); - Account* loadPlugin( const QString &pluginId ); - QString factoryFromId( const QString& pluginId ) const; + Account* loadPlugin( const QString &accountId ); + QString factoryFromId( const QString& accountId ) const; QList< Account* > getAccounts() { return m_accounts; }; QList< Account* > getAccounts( Tomahawk::Accounts::AccountType type ) { return m_accountsByAccountType[ type ]; } diff --git a/src/libtomahawk/tomahawksettings.cpp b/src/libtomahawk/tomahawksettings.cpp index 8eeb7e615..412a19704 100644 --- a/src/libtomahawk/tomahawksettings.cpp +++ b/src/libtomahawk/tomahawksettings.cpp @@ -693,34 +693,34 @@ TomahawkSettings::removeSipPlugin( const QString& pluginId ) QStringList -TomahawkSettings::accountPlugins() const +TomahawkSettings::accounts() const { - return value( "accounts/allplugins", QStringList() ).toStringList(); + return value( "accounts/allaccounts", QStringList() ).toStringList(); } void -TomahawkSettings::setAccountPlugins( const QStringList& plugins ) +TomahawkSettings::setAccounts( const QStringList& accountIds ) { - setValue( "accounts/allplugins", plugins ); + setValue( "accounts/allaccounts", accountIds ); } void -TomahawkSettings::addAccountPlugin( const QString& pluginId ) +TomahawkSettings::addAccount( const QString& accountId ) { - QStringList list = accountPlugins(); - list << pluginId; - setAccountPlugins( list ); + QStringList list = accounts(); + list << accountId; + setAccounts( list ); } void -TomahawkSettings::removeAccountPlugin( const QString& pluginId ) +TomahawkSettings::removeAccount( const QString& accountId ) { - QStringList list = accountPlugins(); - list.removeAll( pluginId ); - setAccountPlugins( list ); + QStringList list = accounts(); + list.removeAll( accountId ); + setAccounts( list ); } diff --git a/src/libtomahawk/tomahawksettings.h b/src/libtomahawk/tomahawksettings.h index 384c5a3cf..198f4c981 100644 --- a/src/libtomahawk/tomahawksettings.h +++ b/src/libtomahawk/tomahawksettings.h @@ -106,10 +106,10 @@ public: void addSipPlugin( const QString& pluginId, bool enable = true ); void removeSipPlugin( const QString& pluginId ); - void setAccountPlugins( const QStringList& plugins ); - QStringList accountPlugins() const; - void addAccountPlugin( const QString& pluginId ); - void removeAccountPlugin( const QString& pluginId ); + void setAccounts( const QStringList& accountIds ); + QStringList accounts() const; + void addAccount( const QString& accountId ); + void removeAccount( const QString& accountId ); void setBookmarkPlaylist( const QString& guid ); diff --git a/src/sip/twitter/CMakeLists.txt b/src/sip/twitter/CMakeLists.txt index 97ee49188..6f3256ba7 100644 --- a/src/sip/twitter/CMakeLists.txt +++ b/src/sip/twitter/CMakeLists.txt @@ -33,7 +33,6 @@ ENDIF( WIN32 ) target_link_libraries( tomahawk_siptwitter tomahawk_oauth_twitter - tomahawk_account_twitter ${TOMAHAWK_LIBRARIES} ${QTWEETLIB_LIBRARIES} ${QT_LIBRARIES} diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index 69126417a..3afccf765 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -510,6 +510,7 @@ TomahawkApp::initServent() void TomahawkApp::initSIP() { + tDebug() << Q_FUNC_INFO; foreach ( Tomahawk::Accounts::Account* account, Tomahawk::Accounts::AccountManager::instance()->getAccounts() ) { tDebug() << Q_FUNC_INFO << "testing account with name " << account->accountServiceName(); From 9db0b5ed4046c771ee19539fa76b900538f216ce Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Sat, 5 Nov 2011 13:36:58 -0400 Subject: [PATCH 009/104] Twitter actually saves auth and connects --- src/accounts/twitter/twitteraccount.cpp | 1 + src/libtomahawk/accounts/account.h | 10 ++-- src/libtomahawk/sip/SipHandler.cpp | 2 + src/sip/twitter/twittersip.cpp | 71 +++++++++++++------------ src/tomahawkapp.cpp | 4 +- 5 files changed, 48 insertions(+), 40 deletions(-) diff --git a/src/accounts/twitter/twitteraccount.cpp b/src/accounts/twitter/twitteraccount.cpp index 264db1039..ba76bb92b 100644 --- a/src/accounts/twitter/twitteraccount.cpp +++ b/src/accounts/twitter/twitteraccount.cpp @@ -62,6 +62,7 @@ TwitterAccount::~TwitterAccount() void TwitterAccount::configDialogAuthedSignalSlot( bool authed ) { + tDebug() << Q_FUNC_INFO; m_isAuthenticated = authed; if ( !credentials()[ "username" ].toString().isEmpty() ) setAccountFriendlyName( QString( "@%1" ).arg( credentials()[ "username" ].toString() ) ); diff --git a/src/libtomahawk/accounts/account.h b/src/libtomahawk/accounts/account.h index bc2046c04..0c8ca4d24 100644 --- a/src/libtomahawk/accounts/account.h +++ b/src/libtomahawk/accounts/account.h @@ -132,9 +132,9 @@ public: m_accountId = accountId; TomahawkSettings* s = TomahawkSettings::instance(); s->beginGroup( "accounts/" + m_accountId ); - m_accountFriendlyName = s->value( "accountFriendlyName", QString() ).toString(); + m_accountFriendlyName = s->value( "accountfriendlyname", QString() ).toString(); m_enabled = s->value( "enabled", false ).toBool(); - m_autoConnect = s->value( "autoConnect", false ).toBool(); + 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(); @@ -147,17 +147,15 @@ public: { TomahawkSettings* s = TomahawkSettings::instance(); s->beginGroup( "accounts/" + m_accountId ); - s->setValue( "accountFriendlyName", m_accountFriendlyName ); + s->setValue( "accountfriendlyname", m_accountFriendlyName ); s->setValue( "enabled", m_enabled ); - s->setValue( "autoConnect", m_autoConnect ); + 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(); - - emit configurationChanged(); } QString m_accountServiceName; diff --git a/src/libtomahawk/sip/SipHandler.cpp b/src/libtomahawk/sip/SipHandler.cpp index c63ffcfe2..5c9c4d496 100644 --- a/src/libtomahawk/sip/SipHandler.cpp +++ b/src/libtomahawk/sip/SipHandler.cpp @@ -173,9 +173,11 @@ SipHandler::removeSipPlugin( SipPlugin* p ) void SipHandler::loadFromAccountManager() { + tDebug() << Q_FUNC_INFO; QList< Tomahawk::Accounts::Account* > accountList = Tomahawk::Accounts::AccountManager::instance()->getAccounts( Tomahawk::Accounts::SipType ); foreach( Tomahawk::Accounts::Account* account, accountList ) { + tDebug() << Q_FUNC_INFO << "adding plugin " << account->accountId(); SipPlugin* p = account->sipPlugin(); addSipPlugin( p ); } diff --git a/src/sip/twitter/twittersip.cpp b/src/sip/twitter/twittersip.cpp index 7dcd1b2af..666277116 100644 --- a/src/sip/twitter/twittersip.cpp +++ b/src/sip/twitter/twittersip.cpp @@ -58,10 +58,10 @@ TwitterSipPlugin::TwitterSipPlugin( Tomahawk::Accounts::Account* account ) { qDebug() << Q_FUNC_INFO; - if ( Database::instance()->dbid() != m_configuration[ "savedDbid" ].toString() ) + if ( Database::instance()->dbid() != m_configuration[ "saveddbid" ].toString() ) { - m_configuration[ "cachedPeers" ] = QVariantHash(); - m_configuration[ "savedDbid" ] = Database::instance()->dbid(); + m_configuration[ "cachedpeers" ] = QVariantHash(); + m_configuration[ "saveddbid" ] = Database::instance()->dbid(); syncConfig(); } @@ -102,18 +102,22 @@ void TwitterSipPlugin::checkSettings() bool TwitterSipPlugin::connectPlugin() { - qDebug() << Q_FUNC_INFO; - + tDebug() << Q_FUNC_INFO; if ( !m_account->enabled() ) + { + tDebug() << Q_FUNC_INFO << "account isn't enabled"; return false; + } - m_cachedPeers = m_configuration[ "cachedPeers" ].toHash(); + m_cachedPeers = m_configuration[ "cachedpeers" ].toHash(); QStringList peerList = m_cachedPeers.keys(); qStableSort( peerList.begin(), peerList.end() ); registerOffers( peerList ); + + tDebug() << Q_FUNC_INFO << "credentials: " << m_credentials.keys(); - if ( m_credentials[ "oauthToken" ].toString().isEmpty() || m_credentials[ "oauthTokenSecret" ].toString().isEmpty() ) + if ( m_credentials[ "oauthtoken" ].toString().isEmpty() || m_credentials[ "oauthtokensecret" ].toString().isEmpty() ) { qDebug() << "TwitterSipPlugin has empty Twitter credentials; not connecting"; return m_cachedPeers.isEmpty(); @@ -146,8 +150,8 @@ TwitterSipPlugin::refreshTwitterAuth() if( m_twitterAuth.isNull() ) return false; - m_twitterAuth.data()->setOAuthToken( m_credentials[ "oauthToken" ].toString().toLatin1() ); - m_twitterAuth.data()->setOAuthTokenSecret( m_credentials[ "oauthTokenSecret" ].toString().toLatin1() ); + m_twitterAuth.data()->setOAuthToken( m_credentials[ "oauthtoken" ].toString().toLatin1() ); + m_twitterAuth.data()->setOAuthTokenSecret( m_credentials[ "oauthtokensecret" ].toString().toLatin1() ); return true; } @@ -155,7 +159,7 @@ TwitterSipPlugin::refreshTwitterAuth() void TwitterSipPlugin::disconnectPlugin() { - qDebug() << Q_FUNC_INFO; + tDebug() << Q_FUNC_INFO; m_checkTimer.stop(); m_connectTimer.stop(); m_dmPollTimer.stop(); @@ -172,7 +176,7 @@ TwitterSipPlugin::disconnectPlugin() if( !m_twitterAuth.isNull() ) delete m_twitterAuth.data(); - m_configuration[ "cachedPeers" ] = m_cachedPeers; + m_configuration[ "cachedpeers" ] = m_cachedPeers; syncConfig(); m_cachedPeers.empty(); m_state = Disconnected; @@ -198,7 +202,7 @@ TwitterSipPlugin::connectAuthVerifyReply( const QTweetUser &user ) m_isAuthed = true; if ( !m_twitterAuth.isNull() ) { - m_configuration[ "screenName" ] = user.screenName(); + m_configuration[ "screenname" ] = user.screenName(); syncConfig(); m_friendsTimeline = QWeakPointer( new QTweetFriendsTimeline( m_twitterAuth.data(), this ) ); m_mentions = QWeakPointer( new QTweetMentions( m_twitterAuth.data(), this ) ); @@ -249,7 +253,7 @@ TwitterSipPlugin::checkTimerFired() return; if ( m_cachedFriendsSinceId == 0 ) - m_cachedFriendsSinceId = m_configuration[ "cachedFriendsSinceId" ].toLongLong(); + m_cachedFriendsSinceId = m_configuration[ "cachedfriendssinceid" ].toLongLong(); qDebug() << "TwitterSipPlugin looking at friends timeline since id " << m_cachedFriendsSinceId; @@ -257,7 +261,7 @@ TwitterSipPlugin::checkTimerFired() m_friendsTimeline.data()->fetch( m_cachedFriendsSinceId, 0, 800 ); if ( m_cachedMentionsSinceId == 0 ) - m_cachedMentionsSinceId = m_configuration[ "cachedMentionsSinceId" ].toLongLong(); + m_cachedMentionsSinceId = m_configuration[ "cachedmentionssinceid" ].toLongLong(); qDebug() << "TwitterSipPlugin looking at mentions timeline since id " << m_cachedMentionsSinceId; @@ -276,7 +280,7 @@ TwitterSipPlugin::registerOffers( const QStringList &peerList ) if ( peerData.contains( "onod" ) && peerData["onod"] != Database::instance()->dbid() ) { m_cachedPeers.remove( screenName ); - m_configuration[ "cachedPeers" ] = m_cachedPeers; + m_configuration[ "cachedpeers" ] = m_cachedPeers; syncConfig(); } @@ -284,7 +288,7 @@ TwitterSipPlugin::registerOffers( const QStringList &peerList ) { peerData["lastseen"] = QDateTime::currentMSecsSinceEpoch(); m_cachedPeers[screenName] = peerData; - m_configuration[ "cachedPeers" ] = m_cachedPeers; + m_configuration[ "cachedpeers" ] = m_cachedPeers; syncConfig(); qDebug() << Q_FUNC_INFO << " already connected"; continue; @@ -293,7 +297,7 @@ TwitterSipPlugin::registerOffers( const QStringList &peerList ) { qDebug() << Q_FUNC_INFO << " aging peer " << screenName << " out of cache"; m_cachedPeers.remove( screenName ); - m_configuration[ "cachedPeers" ] = m_cachedPeers; + m_configuration[ "cachedpeers" ] = m_cachedPeers; syncConfig(); m_cachedAvatars.remove( screenName ); continue; @@ -313,20 +317,20 @@ TwitterSipPlugin::registerOffers( const QStringList &peerList ) void TwitterSipPlugin::connectTimerFired() { - qDebug() << Q_FUNC_INFO << " beginning"; + tDebug() << Q_FUNC_INFO << " beginning"; if ( !isValid() || m_cachedPeers.isEmpty() || m_twitterAuth.isNull() ) { if ( !isValid() ) - qDebug() << Q_FUNC_INFO << " is not valid"; + tDebug() << Q_FUNC_INFO << " is not valid"; if ( m_cachedPeers.isEmpty() ) - qDebug() << Q_FUNC_INFO << " has empty cached peers"; + tDebug() << Q_FUNC_INFO << " has empty cached peers"; if ( m_twitterAuth.isNull() ) - qDebug() << Q_FUNC_INFO << " has null twitterAuth"; + tDebug() << Q_FUNC_INFO << " has null twitterAuth"; return; } - qDebug() << Q_FUNC_INFO << " continuing"; - QString myScreenName = m_configuration[ "screenName" ].toString(); + tDebug() << Q_FUNC_INFO << " continuing"; + QString myScreenName = m_configuration[ "screenname" ].toString(); QStringList peerList = m_cachedPeers.keys(); qStableSort( peerList.begin(), peerList.end() ); registerOffers( peerList ); @@ -335,7 +339,7 @@ TwitterSipPlugin::connectTimerFired() void TwitterSipPlugin::parseGotTomahawk( const QRegExp ®ex, const QString &screenName, const QString &text ) { - QString myScreenName = m_configuration[ "screenName" ].toString(); + QString myScreenName = m_configuration[ "screenname" ].toString(); qDebug() << "TwitterSipPlugin found an exact matching Got Tomahawk? mention or direct message from user " << screenName << ", now parsing"; regex.exactMatch( text ); if ( text.startsWith( '@' ) && regex.captureCount() >= 2 && regex.cap( 1 ) != QString( '@' + myScreenName ) ) @@ -411,7 +415,7 @@ TwitterSipPlugin::friendsTimelineStatuses( const QList< QTweetStatus > &statuses parseGotTomahawk( regex, status.user().screenName(), status.text() ); } - m_configuration[ "cachedFriendsSinceId" ] = m_cachedFriendsSinceId; + m_configuration[ "cachedfriendssinceid" ] = m_cachedFriendsSinceId; syncConfig(); } @@ -445,7 +449,7 @@ TwitterSipPlugin::mentionsStatuses( const QList< QTweetStatus > &statuses ) parseGotTomahawk( regex, status.user().screenName(), status.text() ); } - m_configuration[ "cachedMentionsSinceId" ] = m_cachedMentionsSinceId; + m_configuration[ "cachedmentionssinceid" ] = m_cachedMentionsSinceId; syncConfig(); } @@ -456,7 +460,7 @@ TwitterSipPlugin::pollDirectMessages() return; if ( m_cachedDirectMessagesSinceId == 0 ) - m_cachedDirectMessagesSinceId = m_configuration[ "cachedDirectMentionsSinceId" ].toLongLong(); + m_cachedDirectMessagesSinceId = m_configuration[ "cacheddirectmentionssinceid" ].toLongLong(); qDebug() << "TwitterSipPlugin looking for direct messages since id " << m_cachedDirectMessagesSinceId; @@ -470,7 +474,7 @@ TwitterSipPlugin::directMessages( const QList< QTweetDMStatus > &messages ) qDebug() << Q_FUNC_INFO; QRegExp regex( s_gotTomahawkRegex, Qt::CaseSensitive, QRegExp::RegExp2 ); - QString myScreenName = m_configuration[ "screenName" ].toString(); + QString myScreenName = m_configuration[ "screenname" ].toString(); QHash< QString, QTweetDMStatus > latestHash; foreach ( QTweetDMStatus status, messages ) @@ -547,7 +551,7 @@ TwitterSipPlugin::directMessages( const QList< QTweetDMStatus > &messages ) } } - m_configuration[ "cachedDirectMessagesSinceId" ] = m_cachedDirectMessagesSinceId; + m_configuration[ "cacheddirectmessagessinceid" ] = m_cachedDirectMessagesSinceId; syncConfig(); } @@ -627,7 +631,7 @@ TwitterSipPlugin::registerOffer( const QString &screenName, const QVariantHash & { _peerData["lastseen"] = QString::number( QDateTime::currentMSecsSinceEpoch() ); m_cachedPeers[screenName] = QVariant::fromValue< QVariantHash >( _peerData ); - m_configuration[ "cachedPeers" ] = m_cachedPeers; + m_configuration[ "cachedpeers" ] = m_cachedPeers; syncConfig(); } @@ -715,7 +719,7 @@ TwitterSipPlugin::fetchAvatar( const QString& screenName ) void TwitterSipPlugin::avatarUserDataSlot( const QTweetUser &user ) { - qDebug() << Q_FUNC_INFO; + tDebug() << Q_FUNC_INFO; if ( user.profileImageUrl().isEmpty() || m_twitterAuth.isNull() ) return; @@ -735,11 +739,11 @@ TwitterSipPlugin::refreshProxy() void TwitterSipPlugin::profilePicReply() { - qDebug() << Q_FUNC_INFO; + tDebug() << Q_FUNC_INFO; QNetworkReply *reply = qobject_cast< QNetworkReply* >( sender() ); if ( !reply || reply->error() != QNetworkReply::NoError || !reply->property( "screenname" ).isValid() ) { - qDebug() << Q_FUNC_INFO << " reply not valid or came back with error"; + tDebug() << Q_FUNC_INFO << " reply not valid or came back with error"; return; } QString screenName = reply->property( "screenname" ).toString(); @@ -755,6 +759,7 @@ TwitterSipPlugin::profilePicReply() void TwitterSipPlugin::configurationChanged() { + tDebug() << Q_FUNC_INFO; if ( m_state != Disconnected ) disconnectPlugin(); connectPlugin(); diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index 3afccf765..922d1e2ed 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -514,8 +514,10 @@ TomahawkApp::initSIP() foreach ( Tomahawk::Accounts::Account* account, Tomahawk::Accounts::AccountManager::instance()->getAccounts() ) { tDebug() << Q_FUNC_INFO << "testing account with name " << account->accountServiceName(); - if ( account->configurationWidget() ) + if ( account->configurationWidget() && account->configuration().isEmpty() ) account->configurationWidget()->show(); + if ( !account->enabled() ) + account->setEnabled( true ); } //FIXME: jabber autoconnect is really more, now that there is sip -- should be renamed and/or split out of jabber-specific settings From 1736f4caaab92ee6f74a074c5b2380f9158054cf Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Sat, 5 Nov 2011 15:51:31 -0400 Subject: [PATCH 010/104] Rename tomahawksipmessage to tomahawkxmppmessage -- after all it's quite xmpp specific --- src/libtomahawk/accounts/account.h | 1 - src/sip/jabber/CMakeLists.txt | 4 +-- src/sip/jabber/googlewrapper/CMakeLists.txt | 4 +-- src/sip/jabber/jabber.cpp | 14 +++++----- ...sipmessage.cpp => tomahawkxmppmessage.cpp} | 24 ++++++++--------- ...hawksipmessage.h => tomahawkxmppmessage.h} | 16 ++++++------ ...ory.cpp => tomahawkxmppmessagefactory.cpp} | 26 +++++++++---------- ...factory.h => tomahawkxmppmessagefactory.h} | 8 +++--- 8 files changed, 48 insertions(+), 49 deletions(-) rename src/sip/jabber/{tomahawksipmessage.cpp => tomahawkxmppmessage.cpp} (66%) rename src/sip/jabber/{tomahawksipmessage.h => tomahawkxmppmessage.h} (76%) rename src/sip/jabber/{tomahawksipmessagefactory.cpp => tomahawkxmppmessagefactory.cpp} (80%) rename src/sip/jabber/{tomahawksipmessagefactory.h => tomahawkxmppmessagefactory.h} (88%) diff --git a/src/libtomahawk/accounts/account.h b/src/libtomahawk/accounts/account.h index 0c8ca4d24..d4c0a7f7d 100644 --- a/src/libtomahawk/accounts/account.h +++ b/src/libtomahawk/accounts/account.h @@ -140,7 +140,6 @@ public: m_acl = s->value( "acl", QVariantMap() ).toMap(); m_types = s->value( "types", QStringList() ).toStringList(); s->endGroup(); - s->sync(); } virtual void syncConfig() diff --git a/src/sip/jabber/CMakeLists.txt b/src/sip/jabber/CMakeLists.txt index 98815219c..111272ff6 100644 --- a/src/sip/jabber/CMakeLists.txt +++ b/src/sip/jabber/CMakeLists.txt @@ -8,8 +8,8 @@ add_definitions( -DSIPDLLEXPORT_PRO ) set( jabberSources jabber.cpp - tomahawksipmessage.cpp - tomahawksipmessagefactory.cpp + tomahawkxmppmessage.cpp + tomahawkxmppmessagefactory.cpp avatarmanager.cpp xmlconsole.cpp ) diff --git a/src/sip/jabber/googlewrapper/CMakeLists.txt b/src/sip/jabber/googlewrapper/CMakeLists.txt index 6f9e310c7..8a3e47957 100644 --- a/src/sip/jabber/googlewrapper/CMakeLists.txt +++ b/src/sip/jabber/googlewrapper/CMakeLists.txt @@ -9,8 +9,8 @@ set( googleHeaders set( googleSources ../jabber.cpp - ../tomahawksipmessage.cpp - ../tomahawksipmessagefactory.cpp + ../tomahawkxmppmessage.cpp + ../tomahawkxmppmessagefactory.cpp ../avatarmanager.cpp ../xmlconsole.cpp googlewrapper.cpp ) diff --git a/src/sip/jabber/jabber.cpp b/src/sip/jabber/jabber.cpp index c9a4b8e97..e173c40ae 100644 --- a/src/sip/jabber/jabber.cpp +++ b/src/sip/jabber/jabber.cpp @@ -25,8 +25,8 @@ #include "config.h" #include "tomahawksettings.h" -#include "tomahawksipmessage.h" -#include "tomahawksipmessagefactory.h" +#include "tomahawkxmppmessage.h" +#include "tomahawkxmppmessagefactory.h" #include #include @@ -96,7 +96,7 @@ JabberPlugin::JabberPlugin( const QString& pluginId ) m_client = new Jreen::Client( jid, m_currentPassword ); setupClientHelper(); - m_client->registerPayload(new TomahawkSipMessageFactory); + m_client->registerPayload(new TomahawkXMPPMessageFactory); m_currentResource = QString::fromAscii( "tomahawk%1" ).arg( QString::number( qrand() % 10000 ) ); m_client->setResource( m_currentResource ); @@ -402,10 +402,10 @@ JabberPlugin::sendMsg(const QString& to, const QString& msg) QVariantMap m = v.toMap(); /*******************************************************/ - TomahawkSipMessage *sipMessage; + TomahawkXMPPMessage *sipMessage; if(m["visible"].toBool()) { - sipMessage = new TomahawkSipMessage(m["ip"].toString(), + sipMessage = new TomahawkXMPPMessage(m["ip"].toString(), m["port"].toInt(), m["uniqname"].toString(), m["key"].toString() @@ -413,7 +413,7 @@ JabberPlugin::sendMsg(const QString& to, const QString& msg) } else { - sipMessage = new TomahawkSipMessage(); + sipMessage = new TomahawkXMPPMessage(); } qDebug() << "Send sip messsage to " << to; @@ -802,7 +802,7 @@ void JabberPlugin::onNewIq(const Jreen::IQ& iq) }*/ else { - TomahawkSipMessage::Ptr sipMessage = iq.payload(); + TomahawkXMPPMessage::Ptr sipMessage = iq.payload(); if(sipMessage) { iq.accept(); diff --git a/src/sip/jabber/tomahawksipmessage.cpp b/src/sip/jabber/tomahawkxmppmessage.cpp similarity index 66% rename from src/sip/jabber/tomahawksipmessage.cpp rename to src/sip/jabber/tomahawkxmppmessage.cpp index 68ecfea79..f8d5110c9 100644 --- a/src/sip/jabber/tomahawksipmessage.cpp +++ b/src/sip/jabber/tomahawkxmppmessage.cpp @@ -16,12 +16,12 @@ * along with Tomahawk. If not, see . */ -#include "tomahawksipmessage.h" +#include "tomahawkxmppmessage.h" #include "utils/logger.h" -class TomahawkSipMessagePrivate +class TomahawkXMPPMessagePrivate { public: QString ip; @@ -31,9 +31,9 @@ public: bool visible; }; -TomahawkSipMessage::TomahawkSipMessage(const QString &ip, unsigned int port, const QString &uniqname, const QString &key) : d_ptr(new TomahawkSipMessagePrivate) +TomahawkXMPPMessage::TomahawkXMPPMessage(const QString &ip, unsigned int port, const QString &uniqname, const QString &key) : d_ptr(new TomahawkXMPPMessagePrivate) { - Q_D(TomahawkSipMessage); + Q_D(TomahawkXMPPMessage); d->ip = ip; d->port = port; d->uniqname = uniqname; @@ -41,39 +41,39 @@ TomahawkSipMessage::TomahawkSipMessage(const QString &ip, unsigned int port, con d->visible = true; } -TomahawkSipMessage::TomahawkSipMessage() : d_ptr(new TomahawkSipMessagePrivate) +TomahawkXMPPMessage::TomahawkXMPPMessage() : d_ptr(new TomahawkXMPPMessagePrivate) { - Q_D(TomahawkSipMessage); + Q_D(TomahawkXMPPMessage); d->visible = false; d->port = -1; } -TomahawkSipMessage::~TomahawkSipMessage() +TomahawkXMPPMessage::~TomahawkXMPPMessage() { } -const QString TomahawkSipMessage::ip() const +const QString TomahawkXMPPMessage::ip() const { return d_func()->ip; } -unsigned int TomahawkSipMessage::port() const +unsigned int TomahawkXMPPMessage::port() const { return d_func()->port; } -const QString TomahawkSipMessage::uniqname() const +const QString TomahawkXMPPMessage::uniqname() const { return d_func()->uniqname; } -const QString TomahawkSipMessage::key() const +const QString TomahawkXMPPMessage::key() const { return d_func()->key; } -bool TomahawkSipMessage::visible() const +bool TomahawkXMPPMessage::visible() const { return d_func()->visible; } diff --git a/src/sip/jabber/tomahawksipmessage.h b/src/sip/jabber/tomahawkxmppmessage.h similarity index 76% rename from src/sip/jabber/tomahawksipmessage.h rename to src/sip/jabber/tomahawkxmppmessage.h index 0dbdb0ad0..d3edeed65 100644 --- a/src/sip/jabber/tomahawksipmessage.h +++ b/src/sip/jabber/tomahawkxmppmessage.h @@ -25,18 +25,18 @@ #include "../sipdllmacro.h" -class TomahawkSipMessagePrivate; -class SIPDLLEXPORT TomahawkSipMessage : public Jreen::Payload +class TomahawkXMPPMessagePrivate; +class SIPDLLEXPORT TomahawkXMPPMessage : public Jreen::Payload { - J_PAYLOAD(TomahawkSipMessage) - Q_DECLARE_PRIVATE(TomahawkSipMessage) + J_PAYLOAD(TomahawkXMPPMessage) + Q_DECLARE_PRIVATE(TomahawkXMPPMessage) public: // sets visible to true - TomahawkSipMessage(const QString &ip, unsigned int port, const QString &uniqname, const QString &key); + TomahawkXMPPMessage(const QString &ip, unsigned int port, const QString &uniqname, const QString &key); // sets visible to false as we dont have any extra information - TomahawkSipMessage(); - ~TomahawkSipMessage(); + TomahawkXMPPMessage(); + ~TomahawkXMPPMessage(); const QString ip() const; unsigned int port() const; @@ -44,7 +44,7 @@ class SIPDLLEXPORT TomahawkSipMessage : public Jreen::Payload const QString key() const; bool visible() const; private: - QScopedPointer d_ptr; + QScopedPointer d_ptr; }; #endif // ENTITYTIME_H diff --git a/src/sip/jabber/tomahawksipmessagefactory.cpp b/src/sip/jabber/tomahawkxmppmessagefactory.cpp similarity index 80% rename from src/sip/jabber/tomahawksipmessagefactory.cpp rename to src/sip/jabber/tomahawkxmppmessagefactory.cpp index a45cc27f2..785146b6b 100644 --- a/src/sip/jabber/tomahawksipmessagefactory.cpp +++ b/src/sip/jabber/tomahawkxmppmessagefactory.cpp @@ -16,7 +16,7 @@ * along with Tomahawk. If not, see . */ -#include "tomahawksipmessagefactory.h" +#include "tomahawkxmppmessagefactory.h" #include #include @@ -26,29 +26,29 @@ using namespace Jreen; -TomahawkSipMessageFactory::TomahawkSipMessageFactory() +TomahawkXMPPMessageFactory::TomahawkXMPPMessageFactory() { m_depth = 0; m_state = AtNowhere; } -TomahawkSipMessageFactory::~TomahawkSipMessageFactory() +TomahawkXMPPMessageFactory::~TomahawkXMPPMessageFactory() { } -QStringList TomahawkSipMessageFactory::features() const +QStringList TomahawkXMPPMessageFactory::features() const { return QStringList(TOMAHAWK_SIP_MESSAGE_NS); } -bool TomahawkSipMessageFactory::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; } -void TomahawkSipMessageFactory::handleStartElement(const QStringRef &name, const QStringRef &uri, +void TomahawkXMPPMessageFactory::handleStartElement(const QStringRef &name, const QStringRef &uri, const QXmlStreamAttributes &attributes) { m_depth++; @@ -83,7 +83,7 @@ void TomahawkSipMessageFactory::handleStartElement(const QStringRef &name, const Q_UNUSED(attributes); } -void TomahawkSipMessageFactory::handleEndElement(const QStringRef &name, const QStringRef &uri) +void TomahawkXMPPMessageFactory::handleEndElement(const QStringRef &name, const QStringRef &uri) { if (m_depth == 3) m_state = AtNowhere; @@ -92,7 +92,7 @@ void TomahawkSipMessageFactory::handleEndElement(const QStringRef &name, const Q m_depth--; } -void TomahawkSipMessageFactory::handleCharacterData(const QStringRef &text) +void TomahawkXMPPMessageFactory::handleCharacterData(const QStringRef &text) { /*if (m_state == AtUtc) { //m_utc = Util::fromStamp(text.toString()); @@ -105,9 +105,9 @@ void TomahawkSipMessageFactory::handleCharacterData(const QStringRef &text) Q_UNUSED(text); } -void TomahawkSipMessageFactory::serialize(Payload *extension, QXmlStreamWriter *writer) +void TomahawkXMPPMessageFactory::serialize(Payload *extension, QXmlStreamWriter *writer) { - TomahawkSipMessage *sipMessage = se_cast(extension); + TomahawkXMPPMessage *sipMessage = se_cast(extension); writer->writeStartElement(QLatin1String("tomahawk")); writer->writeDefaultNamespace(TOMAHAWK_SIP_MESSAGE_NS); @@ -137,10 +137,10 @@ void TomahawkSipMessageFactory::serialize(Payload *extension, QXmlStreamWriter * writer->writeEndElement(); } -Payload::Ptr TomahawkSipMessageFactory::createPayload() +Payload::Ptr TomahawkXMPPMessageFactory::createPayload() { if(m_visible) - return Payload::Ptr(new TomahawkSipMessage(m_ip, m_port, m_uniqname, m_key)); + return Payload::Ptr(new TomahawkXMPPMessage(m_ip, m_port, m_uniqname, m_key)); else - return Payload::Ptr(new TomahawkSipMessage()); + return Payload::Ptr(new TomahawkXMPPMessage()); } diff --git a/src/sip/jabber/tomahawksipmessagefactory.h b/src/sip/jabber/tomahawkxmppmessagefactory.h similarity index 88% rename from src/sip/jabber/tomahawksipmessagefactory.h rename to src/sip/jabber/tomahawkxmppmessagefactory.h index a9e7a0db0..d96db5988 100644 --- a/src/sip/jabber/tomahawksipmessagefactory.h +++ b/src/sip/jabber/tomahawkxmppmessagefactory.h @@ -19,17 +19,17 @@ #ifndef ENTITYTIMEFACTORY_P_H #define ENTITYTIMEFACTORY_P_H -#include "tomahawksipmessage.h" +#include "tomahawkxmppmessage.h" #include #include "../sipdllmacro.h" -class SIPDLLEXPORT TomahawkSipMessageFactory : public Jreen::PayloadFactory +class SIPDLLEXPORT TomahawkXMPPMessageFactory : public Jreen::PayloadFactory { public: - TomahawkSipMessageFactory(); - virtual ~TomahawkSipMessageFactory(); + 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); From d50e41f4d2ce53ce55dd6e8f8ecd336581f7d497 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Sat, 5 Nov 2011 16:42:07 -0400 Subject: [PATCH 011/104] XMPP via Accounts compiles. NFC if it works, but this is a big step... (Also, GoogleWrapper not ported yet) --- src/accounts/CMakeLists.txt | 1 + src/accounts/twitter/twitteraccount.cpp | 4 +- src/accounts/twitter/twitterconfigwidget.cpp | 76 +++--- src/accounts/twitter/twitterconfigwidget.h | 4 +- src/accounts/xmpp/CMakeLists.txt | 53 ++++ .../jabber => accounts/xmpp}/resources.qrc | 2 +- .../xmpp/xmpp-icon.png} | Bin src/accounts/xmpp/xmppaccount.cpp | 75 ++++++ src/accounts/xmpp/xmppaccount.h | 88 +++++++ src/accounts/xmpp/xmppconfigwidget.cpp | 89 +++++++ src/accounts/xmpp/xmppconfigwidget.h | 63 +++++ .../xmpp/xmppconfigwidget.ui} | 38 +-- src/libtomahawk/accounts/account.h | 37 +-- src/libtomahawk/sip/SipPlugin.cpp | 6 - src/libtomahawk/sip/SipPlugin.h | 3 - src/sip/CMakeLists.txt | 6 +- src/sip/twitter/twittersip.cpp | 2 +- src/sip/{jabber => xmpp}/CMakeLists.txt | 24 +- src/sip/{jabber => xmpp}/avatarmanager.cpp | 0 src/sip/{jabber => xmpp}/avatarmanager.h | 0 .../googlewrapper/CMakeLists.txt | 0 .../googlewrapper/gmail-logo.png | Bin .../googlewrapper/googlewrapper.cpp | 0 .../googlewrapper/googlewrapper.h | 0 .../googlewrapper/resources.qrc | 0 .../{jabber => xmpp}/tomahawkxmppmessage.cpp | 22 +- .../{jabber => xmpp}/tomahawkxmppmessage.h | 16 +- .../tomahawkxmppmessagefactory.cpp | 24 +- .../tomahawkxmppmessagefactory.h | 6 +- src/sip/{jabber => xmpp}/xmlconsole.cpp | 0 src/sip/{jabber => xmpp}/xmlconsole.h | 0 src/sip/{jabber => xmpp}/xmlconsole.ui | 0 .../{jabber/jabber.cpp => xmpp/xmppsip.cpp} | 245 ++++++------------ src/sip/{jabber/jabber.h => xmpp/xmppsip.h} | 43 +-- 34 files changed, 588 insertions(+), 339 deletions(-) create mode 100644 src/accounts/xmpp/CMakeLists.txt rename src/{sip/jabber => accounts/xmpp}/resources.qrc (69%) rename src/{sip/jabber/jabber-icon.png => accounts/xmpp/xmpp-icon.png} (100%) create mode 100644 src/accounts/xmpp/xmppaccount.cpp create mode 100644 src/accounts/xmpp/xmppaccount.h create mode 100644 src/accounts/xmpp/xmppconfigwidget.cpp create mode 100644 src/accounts/xmpp/xmppconfigwidget.h rename src/{sip/jabber/configwidget.ui => accounts/xmpp/xmppconfigwidget.ui} (89%) rename src/sip/{jabber => xmpp}/CMakeLists.txt (64%) rename src/sip/{jabber => xmpp}/avatarmanager.cpp (100%) rename src/sip/{jabber => xmpp}/avatarmanager.h (100%) rename src/sip/{jabber => xmpp}/googlewrapper/CMakeLists.txt (100%) rename src/sip/{jabber => xmpp}/googlewrapper/gmail-logo.png (100%) rename src/sip/{jabber => xmpp}/googlewrapper/googlewrapper.cpp (100%) rename src/sip/{jabber => xmpp}/googlewrapper/googlewrapper.h (100%) rename src/sip/{jabber => xmpp}/googlewrapper/resources.qrc (100%) rename src/sip/{jabber => xmpp}/tomahawkxmppmessage.cpp (71%) rename src/sip/{jabber => xmpp}/tomahawkxmppmessage.h (79%) rename src/sip/{jabber => xmpp}/tomahawkxmppmessagefactory.cpp (85%) rename src/sip/{jabber => xmpp}/tomahawkxmppmessagefactory.h (90%) rename src/sip/{jabber => xmpp}/xmlconsole.cpp (100%) rename src/sip/{jabber => xmpp}/xmlconsole.h (100%) rename src/sip/{jabber => xmpp}/xmlconsole.ui (100%) rename src/sip/{jabber/jabber.cpp => xmpp/xmppsip.cpp} (79%) rename src/sip/{jabber/jabber.h => xmpp/xmppsip.h} (77%) diff --git a/src/accounts/CMakeLists.txt b/src/accounts/CMakeLists.txt index 37e10994b..a001ab0b5 100644 --- a/src/accounts/CMakeLists.txt +++ b/src/accounts/CMakeLists.txt @@ -1 +1,2 @@ +add_subdirectory( xmpp ) add_subdirectory( twitter ) diff --git a/src/accounts/twitter/twitteraccount.cpp b/src/accounts/twitter/twitteraccount.cpp index ba76bb92b..277a5cbd7 100644 --- a/src/accounts/twitter/twitteraccount.cpp +++ b/src/accounts/twitter/twitteraccount.cpp @@ -87,6 +87,4 @@ TwitterAccount::sipPlugin() } -#ifndef GOOGLE_WRAPPER -Q_EXPORT_PLUGIN2( Tomahawk::Accounts::AccountFactory, Tomahawk::Accounts::TwitterAccountFactory ) -#endif \ No newline at end of file +Q_EXPORT_PLUGIN2( Tomahawk::Accounts::AccountFactory, Tomahawk::Accounts::TwitterAccountFactory ) \ No newline at end of file diff --git a/src/accounts/twitter/twitterconfigwidget.cpp b/src/accounts/twitter/twitterconfigwidget.cpp index f308bd74f..efb8fc8ab 100644 --- a/src/accounts/twitter/twitterconfigwidget.cpp +++ b/src/accounts/twitter/twitterconfigwidget.cpp @@ -41,20 +41,20 @@ namespace Accounts TwitterConfigWidget::TwitterConfigWidget( TwitterAccount* account, QWidget *parent ) : QWidget( parent ), - ui( new Ui::TwitterConfigWidget ), + m_ui( new Ui::TwitterConfigWidget ), m_account( account ) { - ui->setupUi( this ); + m_ui->setupUi( this ); - connect( ui->twitterAuthenticateButton, SIGNAL( pressed() ), + connect( m_ui->twitterAuthenticateButton, SIGNAL( pressed() ), this, SLOT( authDeauthTwitter() ) ); - connect( ui->twitterTweetGotTomahawkButton, SIGNAL( pressed() ), + connect( m_ui->twitterTweetGotTomahawkButton, SIGNAL( pressed() ), this, SLOT( startPostGotTomahawkStatus() ) ); - connect( ui->twitterTweetComboBox, SIGNAL( currentIndexChanged( int ) ), + connect( m_ui->twitterTweetComboBox, SIGNAL( currentIndexChanged( int ) ), this, SLOT( tweetComboBoxIndexChanged( int ) ) ); - ui->twitterTweetComboBox->setCurrentIndex( 0 ); - ui->twitterTweetGotTomahawkButton->setText( tr( "Tweet!" ) ); + m_ui->twitterTweetComboBox->setCurrentIndex( 0 ); + m_ui->twitterTweetGotTomahawkButton->setText( tr( "Tweet!" ) ); QVariantHash credentials = m_account->credentials(); @@ -62,18 +62,18 @@ TwitterConfigWidget::TwitterConfigWidget( TwitterAccount* account, QWidget *pare 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 ); + m_ui->twitterStatusLabel->setText( tr( "Status: No saved credentials" ) ); + m_ui->twitterAuthenticateButton->setText( tr( "Authenticate" ) ); + m_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 ); + m_ui->twitterStatusLabel->setText( tr( "Status: Credentials saved for %1" ).arg( m_account->credentials()[ "username" ].toString() ) ); + m_ui->twitterAuthenticateButton->setText( tr( "De-authenticate" ) ); + m_ui->twitterSyncGroupBox->setVisible( true ); + m_ui->twitterUserTweetLineEdit->setVisible( false ); emit twitterAuthed( true ); } @@ -82,13 +82,13 @@ TwitterConfigWidget::TwitterConfigWidget( TwitterAccount* account, QWidget *pare TwitterConfigWidget::~TwitterConfigWidget() { - delete ui; + delete m_ui; } void TwitterConfigWidget::authDeauthTwitter() { - if ( ui->twitterAuthenticateButton->text() == tr( "Authenticate" ) ) //FIXME: don't rely on UI strings here! + if ( m_ui->twitterAuthenticateButton->text() == tr( "Authenticate" ) ) //FIXME: don't rely on UI strings here! authenticateTwitter(); else deauthenticateTwitter(); @@ -132,12 +132,12 @@ TwitterConfigWidget::authenticateVerifyReply( const QTweetUser &user ) 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!" ) ); + m_ui->twitterStatusLabel->setText( tr( "Status: Credentials saved for %1" ).arg( user.screenName() ) ); + m_ui->twitterAuthenticateButton->setText( tr( "De-authenticate" ) ); + m_ui->twitterSyncGroupBox->setVisible( true ); + m_ui->twitterTweetComboBox->setCurrentIndex( 0 ); + m_ui->twitterUserTweetLineEdit->setVisible( false ); + m_ui->twitterTweetGotTomahawkButton->setText( tr( "Tweet!" ) ); emit twitterAuthed( true ); emit sizeHintChanged(); @@ -148,7 +148,7 @@ TwitterConfigWidget::authenticateVerifyError( QTweetNetBase::ErrorCode code, con { qDebug() << Q_FUNC_INFO; qDebug() << "Error validating credentials, error code is " << code << ", error message is " << errorMsg; - ui->twitterStatusLabel->setText(tr("Status: Error validating credentials")); + m_ui->twitterStatusLabel->setText(tr("Status: Error validating credentials")); emit twitterAuthed( false ); return; } @@ -163,9 +163,9 @@ TwitterConfigWidget::deauthenticateTwitter() credentials[ "username" ] = QString(); m_account->setCredentials( credentials ); - ui->twitterStatusLabel->setText(tr("Status: No saved credentials")); - ui->twitterAuthenticateButton->setText( tr( "Authenticate" ) ); - ui->twitterSyncGroupBox->setVisible( false ); + m_ui->twitterStatusLabel->setText(tr("Status: No saved credentials")); + m_ui->twitterAuthenticateButton->setText( tr( "Authenticate" ) ); + m_ui->twitterSyncGroupBox->setVisible( false ); emit twitterAuthed( false ); emit sizeHintChanged(); @@ -175,26 +175,26 @@ void TwitterConfigWidget::tweetComboBoxIndexChanged( int index ) { Q_UNUSED( index ); - if ( ui->twitterTweetComboBox->currentText() == tr( "Global Tweet" ) ) //FIXME: use data! - ui->twitterUserTweetLineEdit->setVisible( false ); + if ( m_ui->twitterTweetComboBox->currentText() == tr( "Global Tweet" ) ) //FIXME: use data! + m_ui->twitterUserTweetLineEdit->setVisible( false ); else - ui->twitterUserTweetLineEdit->setVisible( true ); + m_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!" ) ); + 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 - ui->twitterTweetGotTomahawkButton->setText( tr( "Tweet!" ) ); + m_ui->twitterTweetGotTomahawkButton->setText( tr( "Tweet!" ) ); } void TwitterConfigWidget::startPostGotTomahawkStatus() { qDebug() << Q_FUNC_INFO; - m_postGTtype = ui->twitterTweetComboBox->currentText(); + m_postGTtype = m_ui->twitterTweetComboBox->currentText(); - if ( m_postGTtype != "Global Tweet" && ( ui->twitterUserTweetLineEdit->text().isEmpty() || ui->twitterUserTweetLineEdit->text() == "@" ) ) + 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.") ); return; @@ -242,7 +242,7 @@ TwitterConfigWidget::postGotTomahawkStatusAuthVerifyReply( const QTweetUser &use 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(); + QString user = m_ui->twitterUserTweetLineEdit->text(); if ( user.startsWith( "@" ) ) user.remove( 0, 1 ); message = QString( "@" ) + user + QString( " " ) + message; @@ -256,7 +256,7 @@ TwitterConfigWidget::postGotTomahawkStatusAuthVerifyReply( const QTweetUser &use 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(); + QString user = m_ui->twitterUserTweetLineEdit->text(); if ( user.startsWith( "@" ) ) user.remove( 0, 1 ); statUpdate->post( user, message ); diff --git a/src/accounts/twitter/twitterconfigwidget.h b/src/accounts/twitter/twitterconfigwidget.h index df0b60748..7d223fe95 100644 --- a/src/accounts/twitter/twitterconfigwidget.h +++ b/src/accounts/twitter/twitterconfigwidget.h @@ -28,8 +28,6 @@ #include -class TwitterAccount; - namespace Ui { class TwitterConfigWidget; @@ -72,7 +70,7 @@ private: void authenticateTwitter(); void deauthenticateTwitter(); - Ui::TwitterConfigWidget *ui; + Ui::TwitterConfigWidget *m_ui; TwitterAccount *m_account; QString m_postGTtype; }; diff --git a/src/accounts/xmpp/CMakeLists.txt b/src/accounts/xmpp/CMakeLists.txt new file mode 100644 index 000000000..5ead4733b --- /dev/null +++ b/src/accounts/xmpp/CMakeLists.txt @@ -0,0 +1,53 @@ +project( tomahawk ) + +include( ${QT_USE_FILE} ) +add_definitions( ${QT_DEFINITIONS} ) +add_definitions( -DQT_PLUGIN ) +add_definitions( -DQT_SHARED ) +add_definitions( -DDLLEXPORT_PRO ) + +set( xmppAccountSources + xmppaccount.cpp + xmppconfigwidget.cpp +) + +set( xmppAccountHeaders + xmppaccount.h + xmppconfigwidget.h +) + +set( xmppAccountUI + xmppconfigwidget.ui +) + +include_directories( . ${CMAKE_CURRENT_BINARY_DIR} .. + ${QT_INCLUDE_DIR} + ${LIBJREEN_INCLUDE_DIR} +) + +qt4_wrap_cpp( xmppAccountMoc ${xmppAccountHeaders} ) +qt4_wrap_ui( xmppAccountUI_H ${xmppAccountUI} ) +qt4_add_resources( RC_SRCS "resources.qrc" ) +add_library( tomahawk_account_xmpp SHARED ${xmppAccountUI_H} ${xmppAccountSources} ${xmppAccountMoc} ${RC_SRCS} ) + +IF( WIN32 ) +SET( OS_SPECIFIC_LINK_LIBRARIES + ${OS_SPECIFIC_LINK_LIBRARIES} + "winmm.dll" + "iphlpapi.a" +) +ENDIF( WIN32 ) + +target_link_libraries( tomahawk_account_xmpp + tomahawk_sipxmpp + ${TOMAHAWK_LIBRARIES} + ${JREEN_LIBRARY} + ${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_xmpp DESTINATION lib${LIB_SUFFIX} ) diff --git a/src/sip/jabber/resources.qrc b/src/accounts/xmpp/resources.qrc similarity index 69% rename from src/sip/jabber/resources.qrc rename to src/accounts/xmpp/resources.qrc index 9700ac51f..7240db9d3 100644 --- a/src/sip/jabber/resources.qrc +++ b/src/accounts/xmpp/resources.qrc @@ -1,5 +1,5 @@ -jabber-icon.png +xmpp-icon.png diff --git a/src/sip/jabber/jabber-icon.png b/src/accounts/xmpp/xmpp-icon.png similarity index 100% rename from src/sip/jabber/jabber-icon.png rename to src/accounts/xmpp/xmpp-icon.png diff --git a/src/accounts/xmpp/xmppaccount.cpp b/src/accounts/xmpp/xmppaccount.cpp new file mode 100644 index 000000000..298a46036 --- /dev/null +++ b/src/accounts/xmpp/xmppaccount.cpp @@ -0,0 +1,75 @@ +/* === 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 "xmppaccount.h" +#include "xmppconfigwidget.h" +#include "sip/SipPlugin.h" + +#include + +namespace Tomahawk +{ + +namespace Accounts +{ + +Account* +XmppAccountFactory::createAccount( const QString& accountId ) +{ + return new XmppAccount( accountId.isEmpty() ? Tomahawk::Accounts::generateId( factoryId() ) : accountId ); +} + + +XmppAccount::XmppAccount( const QString &accountId ) + : Account( accountId ) + , m_isAuthenticated( false ) +{ + loadFromConfig( accountId ); + + setAccountServiceName( "XMPP (Jabber)" ); + QSet< AccountType > types; + types << SipType; + setTypes( types ); + + m_configWidget = QWeakPointer< XmppConfigWidget >( new XmppConfigWidget( this, 0 ) ); +} + + +XmppAccount::~XmppAccount() +{ + +} + + +SipPlugin* +XmppAccount::sipPlugin() +{ + if ( m_xmppSipPlugin.isNull() ) + { + m_xmppSipPlugin = QWeakPointer< XmppSipPlugin >( new XmppSipPlugin( this ) ); + return m_xmppSipPlugin.data(); + } + return m_xmppSipPlugin.data(); +} + + +} + +} + +Q_EXPORT_PLUGIN2( Tomahawk::Accounts::AccountFactory, Tomahawk::Accounts::XmppAccountFactory ) diff --git a/src/accounts/xmpp/xmppaccount.h b/src/accounts/xmpp/xmppaccount.h new file mode 100644 index 000000000..10b1a556e --- /dev/null +++ b/src/accounts/xmpp/xmppaccount.h @@ -0,0 +1,88 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Dominik Schmidt + * 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 XMPPACCOUNT_H +#define XMPPACCOUNT_H + +#include "dllmacro.h" + +#include "sip/xmpp/xmppsip.h" +#include "accounts/account.h" + +#define MYNAME "ACCOUNTJABBER" + +class Ui_XmppConfigWidget; + +namespace Tomahawk +{ + +namespace Accounts +{ + +class DLLEXPORT XmppAccountFactory : public AccountFactory +{ + Q_OBJECT + Q_INTERFACES( Tomahawk::Accounts::AccountFactory ) + +public: + XmppAccountFactory() {} + virtual ~XmppAccountFactory() {} + + QString prettyName() const { return "XMPP (Jabber)"; } + QString factoryId() const { return "xmppaccount"; } + QIcon icon() const { return QIcon( ":/xmpp-icon.png" ); } + Account* createAccount( const QString& pluginId = QString() ); +}; + +class DLLEXPORT XmppAccount : public Account +{ + Q_OBJECT + +public: + XmppAccount( const QString &accountId ); + virtual ~XmppAccount(); + + QIcon icon() const { return QIcon( ":/xmpp-icon.png" ); } + + bool canSelfAuthenticate() { return false; } + bool authenticate() { return false; } + bool isAuthenticated() const { return m_isAuthenticated; } + + Tomahawk::InfoSystem::InfoPlugin* infoPlugin() { return 0; } + SipPlugin* sipPlugin(); + + QWidget* configurationWidget() { return m_configWidget.data(); } + QWidget* aclWidget() { return 0; } + +private: + Ui_XmppConfigWidget* m_ui; // so the google wrapper can change the config dialog a bit + bool m_isAuthenticated; + QWeakPointer< QWidget > m_configWidget; + QWeakPointer< XmppSipPlugin > m_xmppSipPlugin; + + + // for settings access + friend class XmppConfigWidget; +}; + +}; + +}; + +#endif diff --git a/src/accounts/xmpp/xmppconfigwidget.cpp b/src/accounts/xmpp/xmppconfigwidget.cpp new file mode 100644 index 000000000..19f7b7735 --- /dev/null +++ b/src/accounts/xmpp/xmppconfigwidget.cpp @@ -0,0 +1,89 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Christian Muehlhaeuser + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#include "xmppaccount.h" +#include "xmppconfigwidget.h" +#include "ui_xmppconfigwidget.h" + +#include + +#include +#include + +namespace Tomahawk +{ + +namespace Accounts +{ + +XmppConfigWidget::XmppConfigWidget( XmppAccount* account, QWidget *parent ) : + QWidget( parent ), + m_ui( new Ui::XmppConfigWidget ), + m_account( account ) +{ + m_ui->setupUi( this ); + + m_ui->xmppUsername->setText( account->credentials().contains( "username" ) ? account->credentials()[ "username" ].toString() : QString() ); + 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->jidExistsLabel->hide(); + + connect( m_ui->xmppUsername, SIGNAL( textChanged( QString ) ), SLOT( onCheckJidExists( QString ) ) ); +} + + +XmppConfigWidget::~XmppConfigWidget() +{ + delete m_ui; +} + + +void +XmppConfigWidget::onCheckJidExists( QString jid ) +{ + QList< Tomahawk::Accounts::Account* > accounts = Tomahawk::Accounts::AccountManager::instance()->getAccounts( Tomahawk::Accounts::SipType ); + 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("@"); + 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() ) + { + m_ui->jidExistsLabel->show(); + // the already jid exists + emit dataError( true ); + return; + } + } + m_ui->jidExistsLabel->hide(); + emit dataError( false ); +} + + +} + +} diff --git a/src/accounts/xmpp/xmppconfigwidget.h b/src/accounts/xmpp/xmppconfigwidget.h new file mode 100644 index 000000000..89a1827ca --- /dev/null +++ b/src/accounts/xmpp/xmppconfigwidget.h @@ -0,0 +1,63 @@ +/* === 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 JABBERACCOUNTCONFIGWIDGET_H +#define JABBERACCOUNTCONFIGWIDGET_H + +#include "dllmacro.h" + +#include + +namespace Ui +{ + class XmppConfigWidget; +} + +namespace Tomahawk +{ + +namespace Accounts +{ + +class XmppAccount; + + +class DLLEXPORT XmppConfigWidget : public QWidget +{ + Q_OBJECT + +public: + explicit XmppConfigWidget( XmppAccount* account = 0, QWidget *parent = 0 ); + virtual ~XmppConfigWidget(); + +signals: + void dataError( bool exists ); + +private slots: + void onCheckJidExists( QString jid ); + +private: + Ui::XmppConfigWidget *m_ui; + XmppAccount *m_account; +}; + +} + +} + +#endif // TWITTERCONFIGWIDGET_H diff --git a/src/sip/jabber/configwidget.ui b/src/accounts/xmpp/xmppconfigwidget.ui similarity index 89% rename from src/sip/jabber/configwidget.ui rename to src/accounts/xmpp/xmppconfigwidget.ui index cd5fd72b1..99876aa6a 100644 --- a/src/sip/jabber/configwidget.ui +++ b/src/accounts/xmpp/xmppconfigwidget.ui @@ -1,7 +1,7 @@ - JabberConfig - + XmppConfigWidget + 0 @@ -11,7 +11,7 @@ - Jabber Configuration + Xmpp Configuration @@ -35,7 +35,7 @@ - :/jabber-icon.png + :/xmpp-icon.png @@ -49,7 +49,7 @@ - Configure this Jabber account + Configure this Xmpp account @@ -84,9 +84,9 @@ - + - Enter your Jabber login to connect with your friends using Tomahawk! + Enter your Xmpp login to connect with your friends using Tomahawk! @@ -128,15 +128,15 @@ - Jabber ID: + Xmpp ID: - jabberUsername + xmppUsername - + 0 @@ -160,12 +160,12 @@ Password: - jabberPassword + xmppPassword - + 0 @@ -196,7 +196,7 @@ - + true @@ -207,13 +207,13 @@ - Advanced Jabber Settings + Advanced Xmpp Settings - + 0 @@ -233,12 +233,12 @@ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - jabberServer + xmppServer - + 0 @@ -248,7 +248,7 @@ - + Port: @@ -258,7 +258,7 @@ - + 0 diff --git a/src/libtomahawk/accounts/account.h b/src/libtomahawk/accounts/account.h index d4c0a7f7d..050c88725 100644 --- a/src/libtomahawk/accounts/account.h +++ b/src/libtomahawk/accounts/account.h @@ -63,18 +63,18 @@ public: , 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 enabled() const { return m_enabled; } - virtual bool autoConnect() const { return m_autoConnect; } - virtual QString accountId() const { return m_accountId; } + virtual QString accountServiceName() const { QMutexLocker locker( &m_mutex ); return m_accountServiceName; } // e.g. "Twitter", "Last.fm" + virtual QString accountFriendlyName() const { QMutexLocker locker( &m_mutex ); return m_accountFriendlyName; } // e.g. screen name on the service, JID, etc. + virtual bool enabled() const { QMutexLocker locker( &m_mutex ); return m_enabled; } + virtual bool autoConnect() const { QMutexLocker locker( &m_mutex ); return m_autoConnect; } + virtual QString accountId() const { QMutexLocker locker( &m_mutex ); return m_accountId; } - virtual QVariantHash configuration() const { return m_configuration; } + virtual QVariantHash configuration() const { QMutexLocker locker( &m_mutex ); return m_configuration; } virtual QWidget* configurationWidget() = 0; - virtual QVariantHash credentials() { return m_credentials; } + virtual QVariantHash credentials() { QMutexLocker locker( &m_mutex ); return m_credentials; } - virtual QVariantMap acl() const { return m_acl; } + virtual QVariantMap acl() const { QMutexLocker locker( &m_mutex ); return m_acl; } virtual QWidget* aclWidget() = 0; virtual QIcon icon() const = 0; @@ -87,6 +87,7 @@ public: virtual QSet< AccountType > types() const { + QMutexLocker locker( &m_mutex ); QSet< AccountType > set; foreach ( QString type, m_types ) { @@ -98,19 +99,20 @@ public: return set; } - virtual void setAccountServiceName( const QString &serviceName ) { m_accountServiceName = serviceName; } - virtual void setAccountFriendlyName( const QString &friendlyName ) { m_accountFriendlyName = friendlyName; } - virtual void setEnabled( bool enabled ) { m_enabled = enabled; } - 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 setAccountServiceName( const QString &serviceName ) { QMutexLocker locker( &m_mutex ); m_accountServiceName = serviceName; } + virtual void setAccountFriendlyName( const QString &friendlyName ) { QMutexLocker locker( &m_mutex ); m_accountFriendlyName = friendlyName; } + virtual void setEnabled( bool enabled ) { QMutexLocker locker( &m_mutex ); m_enabled = enabled; } + virtual void setAutoConnect( bool autoConnect ) { QMutexLocker locker( &m_mutex ); m_autoConnect = autoConnect; } + virtual void setAccountId( const QString &accountId ) { QMutexLocker locker( &m_mutex ); m_accountId = accountId; } + virtual void setCredentials( const QVariantHash &credentialHash ) { QMutexLocker locker( &m_mutex ); m_credentials = credentialHash; } - virtual void setConfiguration( const QVariantHash &configuration ) { m_configuration = configuration; } + virtual void setConfiguration( const QVariantHash &configuration ) { QMutexLocker locker( &m_mutex ); m_configuration = configuration; } - virtual void setAcl( const QVariantMap &acl ) { m_acl = acl; } + virtual void setAcl( const QVariantMap &acl ) { QMutexLocker locker( &m_mutex ); m_acl = acl; } virtual void setTypes( const QSet< AccountType > types ) { + QMutexLocker locker( &m_mutex ); m_types = QStringList(); foreach ( AccountType type, types ) { @@ -129,6 +131,7 @@ public: virtual void loadFromConfig( const QString &accountId ) { + QMutexLocker locker( &m_mutex ); m_accountId = accountId; TomahawkSettings* s = TomahawkSettings::instance(); s->beginGroup( "accounts/" + m_accountId ); @@ -144,6 +147,7 @@ public: virtual void syncConfig() { + QMutexLocker locker( &m_mutex ); TomahawkSettings* s = TomahawkSettings::instance(); s->beginGroup( "accounts/" + m_accountId ); s->setValue( "accountfriendlyname", m_accountFriendlyName ); @@ -166,6 +170,7 @@ public: QVariantHash m_configuration; QVariantMap m_acl; QStringList m_types; + mutable QMutex m_mutex; signals: void configurationChanged(); diff --git a/src/libtomahawk/sip/SipPlugin.cpp b/src/libtomahawk/sip/SipPlugin.cpp index b10216bf7..54301cfaa 100644 --- a/src/libtomahawk/sip/SipPlugin.cpp +++ b/src/libtomahawk/sip/SipPlugin.cpp @@ -130,9 +130,3 @@ SipPlugin::onPeerOffline( const QString& peerId ) { m_peersOnline.removeAll( peerId ); } - - -void -SipPlugin::deletePlugin() -{ -} diff --git a/src/libtomahawk/sip/SipPlugin.h b/src/libtomahawk/sip/SipPlugin.h index 65ebe8209..26d2d42b5 100644 --- a/src/libtomahawk/sip/SipPlugin.h +++ b/src/libtomahawk/sip/SipPlugin.h @@ -70,9 +70,6 @@ public slots: virtual void refreshProxy(); - // so plugins can clean up after themselves - virtual void deletePlugin(); - signals: void error( int, const QString& ); void stateChanged( SipPlugin::ConnectionState state ); diff --git a/src/sip/CMakeLists.txt b/src/sip/CMakeLists.txt index 054db9928..a85c4010a 100644 --- a/src/sip/CMakeLists.txt +++ b/src/sip/CMakeLists.txt @@ -1,6 +1,6 @@ -#IF( LIBJREEN_FOUND ) -# ADD_SUBDIRECTORY( jabber ) -#ENDIF( LIBJREEN_FOUND ) +IF( LIBJREEN_FOUND ) + ADD_SUBDIRECTORY( xmpp ) +ENDIF( LIBJREEN_FOUND ) IF( QTWEETLIB_FOUND ) ADD_SUBDIRECTORY( twitter ) diff --git a/src/sip/twitter/twittersip.cpp b/src/sip/twitter/twittersip.cpp index 666277116..4314f466d 100644 --- a/src/sip/twitter/twittersip.cpp +++ b/src/sip/twitter/twittersip.cpp @@ -95,7 +95,7 @@ TwitterSipPlugin::connectionState() const void TwitterSipPlugin::checkSettings() { - //TODO/FIXME: check status and enable/disable? + configurationChanged(); } diff --git a/src/sip/jabber/CMakeLists.txt b/src/sip/xmpp/CMakeLists.txt similarity index 64% rename from src/sip/jabber/CMakeLists.txt rename to src/sip/xmpp/CMakeLists.txt index 111272ff6..c1ad08f4b 100644 --- a/src/sip/jabber/CMakeLists.txt +++ b/src/sip/xmpp/CMakeLists.txt @@ -6,22 +6,21 @@ add_definitions( -DQT_PLUGIN ) add_definitions( -DQT_SHARED ) add_definitions( -DSIPDLLEXPORT_PRO ) -set( jabberSources - jabber.cpp +set( xmppSipSources + xmppsip.cpp tomahawkxmppmessage.cpp tomahawkxmppmessagefactory.cpp avatarmanager.cpp xmlconsole.cpp ) -set( jabberHeaders - jabber.h +set( xmppSipHeaders + xmppsip.h avatarmanager.h xmlconsole.h ) -set( jabberUI - configwidget.ui +set( xmppSipUI xmlconsole.ui ) @@ -30,10 +29,9 @@ include_directories( . ${CMAKE_CURRENT_BINARY_DIR} .. ${LIBJREEN_INCLUDE_DIR} ) -qt4_add_resources( RC_SRCS "resources.qrc" ) -qt4_wrap_ui( jabberUI_H ${jabberUI} ) -qt4_wrap_cpp( jabberMoc ${jabberHeaders} ) -add_library( tomahawk_sipjabber SHARED ${jabberSources} ${jabberMoc} ${jabberUI_H} ${RC_SRCS} ) +qt4_wrap_ui( xmppSipUI_H ${xmppSipUI} ) +qt4_wrap_cpp( xmppSipMoc ${xmppSipHeaders} ) +add_library( tomahawk_sipxmpp SHARED ${xmppSipSources} ${xmppSipMoc} ${xmppSipUI_H} ${RC_SRCS} ) IF( WIN32 ) SET( OS_SPECIFIC_LINK_LIBRARIES @@ -44,7 +42,7 @@ SET( OS_SPECIFIC_LINK_LIBRARIES ) ENDIF( WIN32 ) -target_link_libraries( tomahawk_sipjabber +target_link_libraries( tomahawk_sipxmpp ${QT_LIBRARIES} ${LIBJREEN_LIBRARY} ${OS_SPECIFIC_LINK_LIBRARIES} @@ -55,7 +53,7 @@ IF( APPLE ) # SET( CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} "-undefined dynamic_lookup" ) ENDIF( APPLE ) -install( TARGETS tomahawk_sipjabber DESTINATION lib${LIB_SUFFIX} ) +install( TARGETS tomahawk_sipxmpp DESTINATION lib${LIB_SUFFIX} ) -add_subdirectory(googlewrapper) +#add_subdirectory(googlewrapper) diff --git a/src/sip/jabber/avatarmanager.cpp b/src/sip/xmpp/avatarmanager.cpp similarity index 100% rename from src/sip/jabber/avatarmanager.cpp rename to src/sip/xmpp/avatarmanager.cpp diff --git a/src/sip/jabber/avatarmanager.h b/src/sip/xmpp/avatarmanager.h similarity index 100% rename from src/sip/jabber/avatarmanager.h rename to src/sip/xmpp/avatarmanager.h diff --git a/src/sip/jabber/googlewrapper/CMakeLists.txt b/src/sip/xmpp/googlewrapper/CMakeLists.txt similarity index 100% rename from src/sip/jabber/googlewrapper/CMakeLists.txt rename to src/sip/xmpp/googlewrapper/CMakeLists.txt diff --git a/src/sip/jabber/googlewrapper/gmail-logo.png b/src/sip/xmpp/googlewrapper/gmail-logo.png similarity index 100% rename from src/sip/jabber/googlewrapper/gmail-logo.png rename to src/sip/xmpp/googlewrapper/gmail-logo.png diff --git a/src/sip/jabber/googlewrapper/googlewrapper.cpp b/src/sip/xmpp/googlewrapper/googlewrapper.cpp similarity index 100% rename from src/sip/jabber/googlewrapper/googlewrapper.cpp rename to src/sip/xmpp/googlewrapper/googlewrapper.cpp diff --git a/src/sip/jabber/googlewrapper/googlewrapper.h b/src/sip/xmpp/googlewrapper/googlewrapper.h similarity index 100% rename from src/sip/jabber/googlewrapper/googlewrapper.h rename to src/sip/xmpp/googlewrapper/googlewrapper.h diff --git a/src/sip/jabber/googlewrapper/resources.qrc b/src/sip/xmpp/googlewrapper/resources.qrc similarity index 100% rename from src/sip/jabber/googlewrapper/resources.qrc rename to src/sip/xmpp/googlewrapper/resources.qrc diff --git a/src/sip/jabber/tomahawkxmppmessage.cpp b/src/sip/xmpp/tomahawkxmppmessage.cpp similarity index 71% rename from src/sip/jabber/tomahawkxmppmessage.cpp rename to src/sip/xmpp/tomahawkxmppmessage.cpp index f8d5110c9..1b0cf0804 100644 --- a/src/sip/jabber/tomahawkxmppmessage.cpp +++ b/src/sip/xmpp/tomahawkxmppmessage.cpp @@ -21,7 +21,7 @@ #include "utils/logger.h" -class TomahawkXMPPMessagePrivate +class TomahawkXmppMessagePrivate { public: QString ip; @@ -31,9 +31,9 @@ public: bool visible; }; -TomahawkXMPPMessage::TomahawkXMPPMessage(const QString &ip, unsigned int port, const QString &uniqname, const QString &key) : d_ptr(new TomahawkXMPPMessagePrivate) +TomahawkXmppMessage::TomahawkXmppMessage(const QString &ip, unsigned int port, const QString &uniqname, const QString &key) : d_ptr(new TomahawkXmppMessagePrivate) { - Q_D(TomahawkXMPPMessage); + Q_D(TomahawkXmppMessage); d->ip = ip; d->port = port; d->uniqname = uniqname; @@ -41,39 +41,39 @@ TomahawkXMPPMessage::TomahawkXMPPMessage(const QString &ip, unsigned int port, c d->visible = true; } -TomahawkXMPPMessage::TomahawkXMPPMessage() : d_ptr(new TomahawkXMPPMessagePrivate) +TomahawkXmppMessage::TomahawkXmppMessage() : d_ptr(new TomahawkXmppMessagePrivate) { - Q_D(TomahawkXMPPMessage); + Q_D(TomahawkXmppMessage); d->visible = false; d->port = -1; } -TomahawkXMPPMessage::~TomahawkXMPPMessage() +TomahawkXmppMessage::~TomahawkXmppMessage() { } -const QString TomahawkXMPPMessage::ip() const +const QString TomahawkXmppMessage::ip() const { return d_func()->ip; } -unsigned int TomahawkXMPPMessage::port() const +unsigned int TomahawkXmppMessage::port() const { return d_func()->port; } -const QString TomahawkXMPPMessage::uniqname() const +const QString TomahawkXmppMessage::uniqname() const { return d_func()->uniqname; } -const QString TomahawkXMPPMessage::key() const +const QString TomahawkXmppMessage::key() const { return d_func()->key; } -bool TomahawkXMPPMessage::visible() const +bool TomahawkXmppMessage::visible() const { return d_func()->visible; } diff --git a/src/sip/jabber/tomahawkxmppmessage.h b/src/sip/xmpp/tomahawkxmppmessage.h similarity index 79% rename from src/sip/jabber/tomahawkxmppmessage.h rename to src/sip/xmpp/tomahawkxmppmessage.h index d3edeed65..5d6e0b14f 100644 --- a/src/sip/jabber/tomahawkxmppmessage.h +++ b/src/sip/xmpp/tomahawkxmppmessage.h @@ -25,18 +25,18 @@ #include "../sipdllmacro.h" -class TomahawkXMPPMessagePrivate; -class SIPDLLEXPORT TomahawkXMPPMessage : public Jreen::Payload +class TomahawkXmppMessagePrivate; +class SIPDLLEXPORT TomahawkXmppMessage : public Jreen::Payload { - J_PAYLOAD(TomahawkXMPPMessage) - Q_DECLARE_PRIVATE(TomahawkXMPPMessage) + J_PAYLOAD(TomahawkXmppMessage) + Q_DECLARE_PRIVATE(TomahawkXmppMessage) public: // sets visible to true - TomahawkXMPPMessage(const QString &ip, unsigned int port, const QString &uniqname, const QString &key); + TomahawkXmppMessage(const QString &ip, unsigned int port, const QString &uniqname, const QString &key); // sets visible to false as we dont have any extra information - TomahawkXMPPMessage(); - ~TomahawkXMPPMessage(); + TomahawkXmppMessage(); + ~TomahawkXmppMessage(); const QString ip() const; unsigned int port() const; @@ -44,7 +44,7 @@ class SIPDLLEXPORT TomahawkXMPPMessage : public Jreen::Payload const QString key() const; bool visible() const; private: - QScopedPointer d_ptr; + QScopedPointer d_ptr; }; #endif // ENTITYTIME_H diff --git a/src/sip/jabber/tomahawkxmppmessagefactory.cpp b/src/sip/xmpp/tomahawkxmppmessagefactory.cpp similarity index 85% rename from src/sip/jabber/tomahawkxmppmessagefactory.cpp rename to src/sip/xmpp/tomahawkxmppmessagefactory.cpp index 785146b6b..b20d4756a 100644 --- a/src/sip/jabber/tomahawkxmppmessagefactory.cpp +++ b/src/sip/xmpp/tomahawkxmppmessagefactory.cpp @@ -26,29 +26,29 @@ using namespace Jreen; -TomahawkXMPPMessageFactory::TomahawkXMPPMessageFactory() +TomahawkXmppMessageFactory::TomahawkXmppMessageFactory() { m_depth = 0; m_state = AtNowhere; } -TomahawkXMPPMessageFactory::~TomahawkXMPPMessageFactory() +TomahawkXmppMessageFactory::~TomahawkXmppMessageFactory() { } -QStringList TomahawkXMPPMessageFactory::features() const +QStringList TomahawkXmppMessageFactory::features() const { 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; } -void TomahawkXMPPMessageFactory::handleStartElement(const QStringRef &name, const QStringRef &uri, +void TomahawkXmppMessageFactory::handleStartElement(const QStringRef &name, const QStringRef &uri, const QXmlStreamAttributes &attributes) { m_depth++; @@ -83,7 +83,7 @@ void TomahawkXMPPMessageFactory::handleStartElement(const QStringRef &name, cons 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 = AtNowhere; @@ -92,7 +92,7 @@ void TomahawkXMPPMessageFactory::handleEndElement(const QStringRef &name, const m_depth--; } -void TomahawkXMPPMessageFactory::handleCharacterData(const QStringRef &text) +void TomahawkXmppMessageFactory::handleCharacterData(const QStringRef &text) { /*if (m_state == AtUtc) { //m_utc = Util::fromStamp(text.toString()); @@ -105,9 +105,9 @@ void TomahawkXMPPMessageFactory::handleCharacterData(const QStringRef &text) Q_UNUSED(text); } -void TomahawkXMPPMessageFactory::serialize(Payload *extension, QXmlStreamWriter *writer) +void TomahawkXmppMessageFactory::serialize(Payload *extension, QXmlStreamWriter *writer) { - TomahawkXMPPMessage *sipMessage = se_cast(extension); + TomahawkXmppMessage *sipMessage = se_cast(extension); writer->writeStartElement(QLatin1String("tomahawk")); writer->writeDefaultNamespace(TOMAHAWK_SIP_MESSAGE_NS); @@ -137,10 +137,10 @@ void TomahawkXMPPMessageFactory::serialize(Payload *extension, QXmlStreamWriter writer->writeEndElement(); } -Payload::Ptr TomahawkXMPPMessageFactory::createPayload() +Payload::Ptr TomahawkXmppMessageFactory::createPayload() { if(m_visible) - return Payload::Ptr(new TomahawkXMPPMessage(m_ip, m_port, m_uniqname, m_key)); + return Payload::Ptr(new TomahawkXmppMessage(m_ip, m_port, m_uniqname, m_key)); else - return Payload::Ptr(new TomahawkXMPPMessage()); + return Payload::Ptr(new TomahawkXmppMessage()); } diff --git a/src/sip/jabber/tomahawkxmppmessagefactory.h b/src/sip/xmpp/tomahawkxmppmessagefactory.h similarity index 90% rename from src/sip/jabber/tomahawkxmppmessagefactory.h rename to src/sip/xmpp/tomahawkxmppmessagefactory.h index d96db5988..9d9aa6cab 100644 --- a/src/sip/jabber/tomahawkxmppmessagefactory.h +++ b/src/sip/xmpp/tomahawkxmppmessagefactory.h @@ -25,11 +25,11 @@ #include "../sipdllmacro.h" -class SIPDLLEXPORT TomahawkXMPPMessageFactory : public Jreen::PayloadFactory +class SIPDLLEXPORT TomahawkXmppMessageFactory : public Jreen::PayloadFactory { public: - TomahawkXMPPMessageFactory(); - virtual ~TomahawkXMPPMessageFactory(); + 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); diff --git a/src/sip/jabber/xmlconsole.cpp b/src/sip/xmpp/xmlconsole.cpp similarity index 100% rename from src/sip/jabber/xmlconsole.cpp rename to src/sip/xmpp/xmlconsole.cpp diff --git a/src/sip/jabber/xmlconsole.h b/src/sip/xmpp/xmlconsole.h similarity index 100% rename from src/sip/jabber/xmlconsole.h rename to src/sip/xmpp/xmlconsole.h diff --git a/src/sip/jabber/xmlconsole.ui b/src/sip/xmpp/xmlconsole.ui similarity index 100% rename from src/sip/jabber/xmlconsole.ui rename to src/sip/xmpp/xmlconsole.ui diff --git a/src/sip/jabber/jabber.cpp b/src/sip/xmpp/xmppsip.cpp similarity index 79% rename from src/sip/jabber/jabber.cpp rename to src/sip/xmpp/xmppsip.cpp index e173c40ae..6a29279a3 100644 --- a/src/sip/jabber/jabber.cpp +++ b/src/sip/xmpp/xmppsip.cpp @@ -17,14 +17,12 @@ * along with Tomahawk. If not, see . */ -#include "jabber.h" -#include "ui_configwidget.h" +#include "xmppsip.h" #include "xmlconsole.h" #include "config.h" -#include "tomahawksettings.h" #include "tomahawkxmppmessage.h" #include "tomahawkxmppmessagefactory.h" @@ -49,54 +47,30 @@ #include #include -#include "utils/logger.h" +#include +#include -SipPlugin* -JabberFactory::createPlugin( const QString& pluginId ) -{ - return new JabberPlugin( pluginId.isEmpty() ? generateId() : pluginId ); -} - -QIcon -JabberFactory::icon() const -{ - return QIcon( ":/jabber-icon.png" ); -} - -JabberPlugin::JabberPlugin( const QString& pluginId ) - : SipPlugin( pluginId ) +XmppSipPlugin::XmppSipPlugin( Tomahawk::Accounts::Account *account ) + : SipPlugin( account ) , m_menu( 0 ) , m_xmlConsole( 0 ) , m_state( Disconnected ) { qDebug() << Q_FUNC_INFO; - m_configWidget = QWeakPointer< QWidget >( new QWidget ); - m_ui = new Ui_JabberConfig; - m_ui->setupUi( m_configWidget.data() ); - m_configWidget.data()->setVisible( false ); - - m_currentUsername = accountName(); + m_currentUsername = readUsername(); m_currentServer = readServer(); m_currentPassword = readPassword(); m_currentPort = readPort(); - m_ui->jabberUsername->setText( m_currentUsername ); - m_ui->jabberPassword->setText( m_currentPassword ); - m_ui->jabberServer->setText( m_currentServer ); - m_ui->jabberPort->setValue( m_currentPort ); - m_ui->jidExistsLabel->hide(); - - - connect( m_ui->jabberUsername, SIGNAL( textChanged( QString ) ), SLOT( onCheckJidExists( QString ) ) ); // setup JID object - Jreen::JID jid = Jreen::JID( accountName() ); + Jreen::JID jid = Jreen::JID( readUsername() ); // general client setup m_client = new Jreen::Client( jid, m_currentPassword ); setupClientHelper(); - m_client->registerPayload(new TomahawkXMPPMessageFactory); + m_client->registerPayload( new TomahawkXmppMessageFactory ); m_currentResource = QString::fromAscii( "tomahawk%1" ).arg( QString::number( qrand() % 10000 ) ); m_client->setResource( m_currentResource ); @@ -145,55 +119,22 @@ JabberPlugin::JabberPlugin( const QString& pluginId ) connect(m_avatarManager, SIGNAL(newAvatar(QString)), SLOT(onNewAvatar(QString))); } -JabberPlugin::~JabberPlugin() +XmppSipPlugin::~XmppSipPlugin() { delete m_avatarManager; delete m_roster; delete m_xmlConsole; delete m_client; - delete m_ui; -} - - -const QString -JabberPlugin::name() const -{ - return QString( MYNAME ); -} - -const QString -JabberPlugin::friendlyName() const -{ - return QString( "Jabber" ); -} - -const QString -JabberPlugin::accountName() const -{ - return TomahawkSettings::instance()->value( pluginId() + "/username" ).toString(); } QMenu* -JabberPlugin::menu() +XmppSipPlugin::menu() { return m_menu; } -QWidget* -JabberPlugin::configWidget() -{ - return m_configWidget.data(); -} - -QIcon -JabberPlugin::icon() const -{ - return QIcon( ":/jabber-icon.png" ); -} - - bool -JabberPlugin::connectPlugin() +XmppSipPlugin::connectPlugin() { qDebug() << Q_FUNC_INFO; @@ -203,7 +144,7 @@ JabberPlugin::connectPlugin() return true; //FIXME: should i return false here?! } - qDebug() << "Connecting to the XMPP server..." << m_client->jid().full(); + qDebug() << "Connecting to the Xmpp server..." << m_client->jid().full(); //FIXME: we're badly workarounding some missing reconnection api here, to be fixed soon QTimer::singleShot( 1000, m_client, SLOT( connectToServer() ) ); @@ -217,7 +158,7 @@ JabberPlugin::connectPlugin() } void -JabberPlugin::disconnectPlugin() +XmppSipPlugin::disconnectPlugin() { if (!m_client->isConnected()) { @@ -242,7 +183,7 @@ JabberPlugin::disconnectPlugin() } void -JabberPlugin::onConnect() +XmppSipPlugin::onConnect() { // qDebug() << Q_FUNC_INFO; @@ -254,7 +195,7 @@ JabberPlugin::onConnect() emit jidChanged( m_client->jid().full() ); } - qDebug() << "Connected to jabber as:" << m_client->jid().full(); + qDebug() << "Connected to xmpp as:" << m_client->jid().full(); // set presence to least valid value m_client->setPresence(Jreen::Presence::XA, "Got Tomahawk? http://gettomahawk.com", -127); @@ -284,7 +225,7 @@ JabberPlugin::onConnect() } void -JabberPlugin::onDisconnect( Jreen::Client::DisconnectReason reason ) +XmppSipPlugin::onDisconnect( Jreen::Client::DisconnectReason reason ) { qDebug() << Q_FUNC_INFO; @@ -325,13 +266,13 @@ JabberPlugin::onDisconnect( Jreen::Client::DisconnectReason reason ) } void -JabberPlugin::onError( const Jreen::Connection::SocketError& e ) +XmppSipPlugin::onError( const Jreen::Connection::SocketError& e ) { tLog() << "JABBER error:" << e; } QString -JabberPlugin::errorMessage( Jreen::Client::DisconnectReason reason ) +XmppSipPlugin::errorMessage( Jreen::Client::DisconnectReason reason ) { switch( reason ) { @@ -380,7 +321,7 @@ JabberPlugin::errorMessage( Jreen::Client::DisconnectReason reason ) } void -JabberPlugin::sendMsg(const QString& to, const QString& msg) +XmppSipPlugin::sendMsg(const QString& to, const QString& msg) { qDebug() << Q_FUNC_INFO << to << msg; @@ -396,16 +337,16 @@ JabberPlugin::sendMsg(const QString& to, const QString& msg) QVariant v = parser.parse( msg.toAscii(), &ok ); if ( !ok || v.type() != QVariant::Map ) { - qDebug() << "Invalid JSON in XMPP msg"; + qDebug() << "Invalid JSON in Xmpp msg"; return; } QVariantMap m = v.toMap(); /*******************************************************/ - TomahawkXMPPMessage *sipMessage; + TomahawkXmppMessage *sipMessage; if(m["visible"].toBool()) { - sipMessage = new TomahawkXMPPMessage(m["ip"].toString(), + sipMessage = new TomahawkXmppMessage(m["ip"].toString(), m["port"].toInt(), m["uniqname"].toString(), m["key"].toString() @@ -413,7 +354,7 @@ JabberPlugin::sendMsg(const QString& to, const QString& msg) } else { - sipMessage = new TomahawkXMPPMessage(); + sipMessage = new TomahawkXmppMessage(); } qDebug() << "Send sip messsage to " << to; @@ -425,7 +366,7 @@ JabberPlugin::sendMsg(const QString& to, const QString& msg) } void -JabberPlugin::broadcastMsg(const QString& msg) +XmppSipPlugin::broadcastMsg(const QString& msg) { qDebug() << Q_FUNC_INFO; @@ -439,7 +380,7 @@ JabberPlugin::broadcastMsg(const QString& msg) } void -JabberPlugin::addContact(const QString& jid, const QString& msg) +XmppSipPlugin::addContact(const QString& jid, const QString& msg) { // Add contact to the Tomahawk group on the roster @@ -453,40 +394,48 @@ JabberPlugin::addContact(const QString& jid, const QString& msg) } void -JabberPlugin::showAddFriendDialog() +XmppSipPlugin::showAddFriendDialog() { bool ok; QString id = QInputDialog::getText( TomahawkUtils::tomahawkWindow(), tr( "Add Friend" ), - tr( "Enter Jabber ID:" ), QLineEdit::Normal, "", &ok ); + tr( "Enter Xmpp ID:" ), QLineEdit::Normal, "", &ok ); if ( !ok ) return; - qDebug() << "Attempting to add jabber contact to roster:" << id; + qDebug() << "Attempting to add xmpp contact to roster:" << id; addContact( id ); } QString -JabberPlugin::defaultSuffix() const +XmppSipPlugin::defaultSuffix() const { - return "@jabber.org"; + return "@xmpp.org"; } void -JabberPlugin::showXmlConsole() +XmppSipPlugin::showXmlConsole() { m_xmlConsole->show(); } + void -JabberPlugin::checkSettings() +XmppSipPlugin::checkSettings() +{ + configurationChanged(); +} + + +void +XmppSipPlugin::configurationChanged() { bool reconnect = false; QString username, password, server; int port; - username = accountName(); + username = readUsername(); password = readPassword(); server = readServer(); port = readPort(); @@ -515,7 +464,10 @@ JabberPlugin::checkSettings() if ( !m_currentUsername.contains( '@' ) ) { m_currentUsername += defaultSuffix(); - TomahawkSettings::instance()->setValue( pluginId() + "/username", m_currentUsername ); + QVariantHash credentials = m_account->credentials(); + credentials[ "username" ] = m_currentUsername; + m_account->setCredentials( credentials ); + m_account->syncConfig(); } if ( reconnect ) @@ -530,7 +482,7 @@ JabberPlugin::checkSettings() } } -void JabberPlugin::setupClientHelper() +void XmppSipPlugin::setupClientHelper() { Jreen::JID jid = Jreen::JID( m_currentUsername ); m_client->setJID( jid ); @@ -550,11 +502,11 @@ void JabberPlugin::setupClientHelper() } } -void JabberPlugin::addMenuHelper() +void XmppSipPlugin::addMenuHelper() { if( !m_menu ) { - m_menu = new QMenu( QString( "%1 (" ).arg( friendlyName() ).append( accountName() ).append(")" ) ); + m_menu = new QMenu( QString( "%1 (" ).arg( friendlyName() ).append( readUsername() ).append(")" ) ); QAction* addFriendAction = m_menu->addAction( tr( "Add Friend..." ) ); connect( addFriendAction, SIGNAL( triggered() ), this, SLOT( showAddFriendDialog() ) ); @@ -569,7 +521,7 @@ void JabberPlugin::addMenuHelper() } } -void JabberPlugin::removeMenuHelper() +void XmppSipPlugin::removeMenuHelper() { if( m_menu ) { @@ -580,7 +532,7 @@ void JabberPlugin::removeMenuHelper() } } -void JabberPlugin::onNewMessage(const Jreen::Message& message) +void XmppSipPlugin::onNewMessage(const Jreen::Message& message) { if ( m_state != Connected ) return; @@ -621,7 +573,7 @@ void JabberPlugin::onNewMessage(const Jreen::Message& message) } -void JabberPlugin::onPresenceReceived( const Jreen::RosterItem::Ptr &item, const Jreen::Presence& presence ) +void XmppSipPlugin::onPresenceReceived( const Jreen::RosterItem::Ptr &item, const Jreen::Presence& presence ) { Q_UNUSED(item); if ( m_state != Connected ) @@ -664,7 +616,7 @@ void JabberPlugin::onPresenceReceived( const Jreen::RosterItem::Ptr &item, const } } -void JabberPlugin::onSubscriptionReceived(const Jreen::RosterItem::Ptr& item, const Jreen::Presence& presence) +void XmppSipPlugin::onSubscriptionReceived(const Jreen::RosterItem::Ptr& item, const Jreen::Presence& presence) { if ( m_state != Connected ) return; @@ -716,7 +668,7 @@ void JabberPlugin::onSubscriptionReceived(const Jreen::RosterItem::Ptr& item, co } void -JabberPlugin::onSubscriptionRequestConfirmed( int result ) +XmppSipPlugin::onSubscriptionRequestConfirmed( int result ) { qDebug() << Q_FUNC_INFO << result; @@ -750,7 +702,7 @@ JabberPlugin::onSubscriptionRequestConfirmed( int result ) m_roster->allowSubscription( jid, allowSubscription == QMessageBox::Yes ); } -void JabberPlugin::onNewIq(const Jreen::IQ& iq) +void XmppSipPlugin::onNewIq(const Jreen::IQ& iq) { if ( m_state != Connected ) return; @@ -802,7 +754,7 @@ void JabberPlugin::onNewIq(const Jreen::IQ& iq) }*/ else { - TomahawkXMPPMessage::Ptr sipMessage = iq.payload(); + TomahawkXmppMessage::Ptr sipMessage = iq.payload(); if(sipMessage) { iq.accept(); @@ -831,7 +783,7 @@ void JabberPlugin::onNewIq(const Jreen::IQ& iq) } } -bool JabberPlugin::presenceMeansOnline(Jreen::Presence::Type p) +bool XmppSipPlugin::presenceMeansOnline(Jreen::Presence::Type p) { switch(p) { @@ -845,7 +797,7 @@ bool JabberPlugin::presenceMeansOnline(Jreen::Presence::Type p) } } -void JabberPlugin::handlePeerStatus(const Jreen::JID& jid, Jreen::Presence::Type presenceType) +void XmppSipPlugin::handlePeerStatus(const Jreen::JID& jid, Jreen::Presence::Type presenceType) { QString fulljid = jid.full(); @@ -892,7 +844,7 @@ void JabberPlugin::handlePeerStatus(const Jreen::JID& jid, Jreen::Presence::Type m_peers[ jid ] = presenceType; } -void JabberPlugin::onNewAvatar(const QString& jid) +void XmppSipPlugin::onNewAvatar(const QString& jid) { // qDebug() << Q_FUNC_INFO << jid; if ( m_state != Connected ) @@ -918,82 +870,49 @@ void JabberPlugin::onNewAvatar(const QString& jid) emit avatarReceived ( jid, m_avatarManager->avatar( jid ) ); } + bool -JabberPlugin::readXmlConsoleEnabled() +XmppSipPlugin::readXmlConsoleEnabled() { - return TomahawkSettings::instance()->value( pluginId() + "/xmlconsole", QVariant( false ) ).toBool(); + QVariantHash configuration = m_account->configuration(); + return configuration.contains( "xmlconsole" ) && configuration[ "xmlconsole" ].toBool(); } QString -JabberPlugin::readPassword() +XmppSipPlugin::readUsername() { - return TomahawkSettings::instance()->value( pluginId() + "/password" ).toString(); + QVariantHash credentials = m_account->credentials(); + return credentials.contains( "username" ) ? credentials[ "username" ].toString() : QString(); } + +QString +XmppSipPlugin::readPassword() +{ + QVariantHash credentials = m_account->credentials(); + return credentials.contains( "password" ) ? credentials[ "password" ].toString() : QString(); +} + + int -JabberPlugin::readPort() +XmppSipPlugin::readPort() { - return TomahawkSettings::instance()->value( pluginId() + "/port", 5222 ).toInt(); + QVariantHash configuration = m_account->configuration(); + return configuration.contains( "port" ) ? configuration[ "port" ].toInt() : 5222; } + QString -JabberPlugin::readServer() +XmppSipPlugin::readServer() { - return TomahawkSettings::instance()->value( pluginId() + "/server" ).toString(); -} - - -void -JabberPlugin::onCheckJidExists( QString jid ) -{ - for ( int i=0; isipPlugins().count(); i++ ) - { - QString savedUsername = TomahawkSettings::instance()->value( - TomahawkSettings::instance()->sipPlugins().at( i ) + "/username" ).toString(); - QStringList splitUserName = TomahawkSettings::instance()->value( - TomahawkSettings::instance()->sipPlugins().at( i ) + "/username" ).toString().split("@"); - QString server = TomahawkSettings::instance()->value( - TomahawkSettings::instance()->sipPlugins().at( i ) + "/server" ).toString(); - - if ( ( savedUsername == jid || splitUserName.contains( jid ) ) && - server == m_ui->jabberServer->text() && !jid.trimmed().isEmpty() ) - { - m_ui->jidExistsLabel->show(); - // the already jid exists - emit dataError( true ); - return; - } - } - m_ui->jidExistsLabel->hide(); - emit dataError( false ); -} - - -void -JabberPlugin::saveConfig() -{ - TomahawkSettings::instance()->setValue( pluginId() + "/username", m_ui->jabberUsername->text() ); - TomahawkSettings::instance()->setValue( pluginId() + "/password", m_ui->jabberPassword->text() ); - TomahawkSettings::instance()->setValue( pluginId() + "/port", m_ui->jabberPort->value() ); - TomahawkSettings::instance()->setValue( pluginId() + "/server", m_ui->jabberServer->text() ); - - checkSettings(); -} - -void -JabberPlugin::deletePlugin() -{ - TomahawkSettings::instance()->remove( pluginId() ); + QVariantHash configuration = m_account->configuration(); + return configuration.contains( "server" ) ? configuration[ "server" ].toString() : QString(); } SipPlugin::ConnectionState -JabberPlugin::connectionState() const +XmppSipPlugin::connectionState() const { return m_state; } - -#ifndef GOOGLE_WRAPPER -Q_EXPORT_PLUGIN2( sipfactory, JabberFactory ) -#endif diff --git a/src/sip/jabber/jabber.h b/src/sip/xmpp/xmppsip.h similarity index 77% rename from src/sip/jabber/jabber.h rename to src/sip/xmpp/xmppsip.h index c2b7d4585..4b582cd98 100644 --- a/src/sip/jabber/jabber.h +++ b/src/sip/xmpp/xmppsip.h @@ -17,8 +17,8 @@ * along with Tomahawk. If not, see . */ -#ifndef JABBER_H -#define JABBER_H +#ifndef XMPPSIP_H +#define XMPPSIP_H #include "sip/SipPlugin.h" @@ -40,57 +40,32 @@ #include -#define MYNAME "SIPJREEN" #define TOMAHAWK_FEATURE QLatin1String( "tomahawk:sip:v1" ) #define TOMAHAWK_CAP_NODE_NAME QLatin1String( "http://tomahawk-player.org/" ) #include "../sipdllmacro.h" -class Ui_JabberConfig; - -class SIPDLLEXPORT JabberFactory : public SipPluginFactory -{ - Q_OBJECT - Q_INTERFACES( SipPluginFactory ) - -public: - JabberFactory() {} - virtual ~JabberFactory() {} - - virtual QString prettyName() const { return "Jabber"; } - virtual QString factoryId() const { return "sipjabber"; } - virtual QIcon icon() const; - virtual SipPlugin* createPlugin( const QString& pluginId ); -}; - -class SIPDLLEXPORT JabberPlugin : public SipPlugin +class SIPDLLEXPORT XmppSipPlugin : public SipPlugin { Q_OBJECT public: - JabberPlugin( const QString& pluginId ); - virtual ~JabberPlugin(); + XmppSipPlugin( Tomahawk::Accounts::Account* account ); + virtual ~XmppSipPlugin(); //FIXME: Make this more correct virtual bool isValid() const { return true; } - virtual const QString name() const; - virtual const QString friendlyName() const; - virtual const QString accountName() const; virtual ConnectionState connectionState() const; virtual QMenu* menu(); - virtual QIcon icon() const; - virtual QWidget* configWidget(); - virtual void saveConfig(); - virtual void deletePlugin(); signals: - void dataError( bool exists ); void jidChanged( const QString& ); public slots: virtual bool connectPlugin(); void disconnectPlugin(); void checkSettings(); + void configurationChanged(); void sendMsg( const QString& to, const QString& msg ); void broadcastMsg( const QString &msg ); void addContact( const QString &jid, const QString& msg = QString() ); @@ -99,8 +74,6 @@ public slots: protected: virtual QString defaultSuffix() const; - Ui_JabberConfig* m_ui; // so the google wrapper can change the config dialog a bit - private slots: void showXmlConsole(); void onConnect(); @@ -114,10 +87,10 @@ private slots: void onError( const Jreen::Connection::SocketError& e ); void onNewIq( const Jreen::IQ &iq ); void onNewAvatar( const QString &jid ); - void onCheckJidExists( QString jid ); private: bool readXmlConsoleEnabled(); + QString readUsername(); QString readPassword(); QString readServer(); int readPort(); @@ -140,8 +113,6 @@ private: int m_currentPort; ConnectionState m_state; - QWeakPointer< QWidget > m_configWidget; - QString m_currentResource; // sort out From 8b862774c93db71228680fc9f0f32f7627fad67f Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Sat, 5 Nov 2011 19:32:57 -0400 Subject: [PATCH 012/104] Protect-ize account members and some methods --- src/libtomahawk/accounts/account.h | 12 ++++++------ src/sip/twitter/twittersip.h | 2 +- src/sip/xmpp/xmppsip.cpp | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libtomahawk/accounts/account.h b/src/libtomahawk/accounts/account.h index 050c88725..0d62147f3 100644 --- a/src/libtomahawk/accounts/account.h +++ b/src/libtomahawk/accounts/account.h @@ -129,9 +129,14 @@ public: syncConfig(); } + virtual void sync() { QMutexLocker locker( &m_mutex ); syncConfig(); }; + +signals: + void configurationChanged(); + +protected: virtual void loadFromConfig( const QString &accountId ) { - QMutexLocker locker( &m_mutex ); m_accountId = accountId; TomahawkSettings* s = TomahawkSettings::instance(); s->beginGroup( "accounts/" + m_accountId ); @@ -147,7 +152,6 @@ public: virtual void syncConfig() { - QMutexLocker locker( &m_mutex ); TomahawkSettings* s = TomahawkSettings::instance(); s->beginGroup( "accounts/" + m_accountId ); s->setValue( "accountfriendlyname", m_accountFriendlyName ); @@ -171,10 +175,6 @@ public: QVariantMap m_acl; QStringList m_types; mutable QMutex m_mutex; - -signals: - void configurationChanged(); - }; class DLLEXPORT AccountFactory : public QObject diff --git a/src/sip/twitter/twittersip.h b/src/sip/twitter/twittersip.h index 65b7ef9f0..0da977ac6 100644 --- a/src/sip/twitter/twittersip.h +++ b/src/sip/twitter/twittersip.h @@ -94,7 +94,7 @@ private slots: void profilePicReply(); private: - inline void syncConfig() { m_account->setCredentials( m_credentials ); m_account->setConfiguration( m_configuration ); m_account->syncConfig(); } + inline void syncConfig() { m_account->setCredentials( m_credentials ); m_account->setConfiguration( m_configuration ); m_account->sync(); } bool refreshTwitterAuth(); void parseGotTomahawk( const QRegExp ®ex, const QString &screenName, const QString &text ); diff --git a/src/sip/xmpp/xmppsip.cpp b/src/sip/xmpp/xmppsip.cpp index 6a29279a3..6ac88c882 100644 --- a/src/sip/xmpp/xmppsip.cpp +++ b/src/sip/xmpp/xmppsip.cpp @@ -467,7 +467,7 @@ XmppSipPlugin::configurationChanged() QVariantHash credentials = m_account->credentials(); credentials[ "username" ] = m_currentUsername; m_account->setCredentials( credentials ); - m_account->syncConfig(); + m_account->sync(); } if ( reconnect ) From ccde46447ed8f800fd40cf4b7380c0099eec0ce5 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Sat, 5 Nov 2011 20:17:18 -0400 Subject: [PATCH 013/104] Put canSelfAuthenticate in the right place --- src/accounts/twitter/twitteraccount.h | 2 +- src/accounts/xmpp/xmppaccount.h | 2 +- src/libtomahawk/accounts/account.cpp | 7 +++++++ src/libtomahawk/accounts/account.h | 1 + 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/accounts/twitter/twitteraccount.h b/src/accounts/twitter/twitteraccount.h index a305cd7e5..7368dbf69 100644 --- a/src/accounts/twitter/twitteraccount.h +++ b/src/accounts/twitter/twitteraccount.h @@ -60,7 +60,7 @@ public: QIcon icon() const { return QIcon( ":/twitter-icon.png" ); } - bool canSelfAuthenticate() { return false; } + bool canSelfAuthenticate() const { return false; } bool authenticate() { return false; } bool isAuthenticated() const { return m_isAuthenticated; } diff --git a/src/accounts/xmpp/xmppaccount.h b/src/accounts/xmpp/xmppaccount.h index 10b1a556e..51d39393b 100644 --- a/src/accounts/xmpp/xmppaccount.h +++ b/src/accounts/xmpp/xmppaccount.h @@ -60,7 +60,7 @@ public: QIcon icon() const { return QIcon( ":/xmpp-icon.png" ); } - bool canSelfAuthenticate() { return false; } + bool canSelfAuthenticate() const { return false; } bool authenticate() { return false; } bool isAuthenticated() const { return m_isAuthenticated; } diff --git a/src/libtomahawk/accounts/account.cpp b/src/libtomahawk/accounts/account.cpp index 3a0e53b9e..ee2559c8b 100644 --- a/src/libtomahawk/accounts/account.cpp +++ b/src/libtomahawk/accounts/account.cpp @@ -45,6 +45,13 @@ Account::icon() const } +bool +Account::canSelfAuthenticate() const +{ + return false; +} + + bool Account::authenticate() { diff --git a/src/libtomahawk/accounts/account.h b/src/libtomahawk/accounts/account.h index 0d62147f3..7350854a3 100644 --- a/src/libtomahawk/accounts/account.h +++ b/src/libtomahawk/accounts/account.h @@ -79,6 +79,7 @@ public: virtual QIcon icon() const = 0; + virtual bool canSelfAuthenticate() const = 0; virtual bool authenticate() = 0; //if none needed, just return true virtual bool isAuthenticated() const = 0; From bfcf4d3bdb56378dc501c5e80460551bb365c69c Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Sun, 6 Nov 2011 13:18:19 -0500 Subject: [PATCH 014/104] More cleanup work. Also, move twitter authentication to the account, so it's centralized --- src/accounts/twitter/tomahawkoauthtwitter.h | 3 +- src/accounts/twitter/twitteraccount.cpp | 89 +++++++++- src/accounts/twitter/twitteraccount.h | 16 +- src/accounts/xmpp/xmppaccount.cpp | 14 ++ src/accounts/xmpp/xmppaccount.h | 5 +- src/libtomahawk/accounts/account.cpp | 18 +- src/libtomahawk/accounts/account.h | 9 +- src/libtomahawk/sip/SipPlugin.h | 2 +- src/sip/twitter/twittersip.cpp | 184 +++++++------------- src/sip/twitter/twittersip.h | 8 +- src/sip/xmpp/xmppsip.cpp | 8 +- src/sip/xmpp/xmppsip.h | 2 +- 12 files changed, 215 insertions(+), 143 deletions(-) diff --git a/src/accounts/twitter/tomahawkoauthtwitter.h b/src/accounts/twitter/tomahawkoauthtwitter.h index 72cd3329c..12def04d3 100644 --- a/src/accounts/twitter/tomahawkoauthtwitter.h +++ b/src/accounts/twitter/tomahawkoauthtwitter.h @@ -2,6 +2,7 @@ #define TOMAHAWKOAUTHTWITTERACCOUNT #include "dllmacro.h" +#include #include #include @@ -11,7 +12,7 @@ class DLLEXPORT TomahawkOAuthTwitter : public OAuthTwitter Q_OBJECT public: - TomahawkOAuthTwitter( QNetworkAccessManager *nam, QObject *parent = 0 ); + TomahawkOAuthTwitter( QNetworkAccessManager *nam = TomahawkUtils::nam() , QObject *parent = 0 ); ~TomahawkOAuthTwitter() {} diff --git a/src/accounts/twitter/twitteraccount.cpp b/src/accounts/twitter/twitteraccount.cpp index 277a5cbd7..33fd3d148 100644 --- a/src/accounts/twitter/twitteraccount.cpp +++ b/src/accounts/twitter/twitteraccount.cpp @@ -17,11 +17,16 @@ */ #include "twitteraccount.h" - #include "twitterconfigwidget.h" +#include "accounts/twitter/tomahawkoauthtwitter.h" #include "sip/SipPlugin.h" +#include +#include +#include +#include + #include namespace Tomahawk @@ -50,6 +55,8 @@ TwitterAccount::TwitterAccount( const QString &accountId ) m_configWidget = QWeakPointer< TwitterConfigWidget >( new TwitterConfigWidget( this, 0 ) ); connect( m_configWidget.data(), SIGNAL( twitterAuthed( bool ) ), SLOT( configDialogAuthedSignalSlot( bool ) ) ); + + m_twitterAuth = QWeakPointer< TomahawkOAuthTwitter >( new TomahawkOAuthTwitter( TomahawkUtils::nam(), this ) ); } @@ -83,6 +90,86 @@ TwitterAccount::sipPlugin() } +void +TwitterAccount::authenticate() +{ + tDebug() << Q_FUNC_INFO << "credentials: " << m_credentials.keys(); + + if ( m_credentials[ "oauthtoken" ].toString().isEmpty() || m_credentials[ "oauthtokensecret" ].toString().isEmpty() ) + { + qDebug() << "TwitterSipPlugin has empty Twitter credentials; not connecting"; + return; + } + + if ( refreshTwitterAuth() ) + { + QTweetAccountVerifyCredentials *credVerifier = new QTweetAccountVerifyCredentials( m_twitterAuth.data(), this ); + connect( credVerifier, SIGNAL( parsedUser( const QTweetUser & ) ), SLOT( connectAuthVerifyReply( const QTweetUser & ) ) ); + credVerifier->verify(); + } +} + + +void +TwitterAccount::deauthenticate() +{ + if ( sipPlugin() ) + sipPlugin()->disconnectPlugin(); + + m_isAuthenticated = false; + emit nowDeauthenticated(); +} + + + +bool +TwitterAccount::refreshTwitterAuth() +{ + qDebug() << Q_FUNC_INFO << " begin"; + if( !m_twitterAuth.isNull() ) + delete m_twitterAuth.data(); + + Q_ASSERT( TomahawkUtils::nam() != 0 ); + qDebug() << Q_FUNC_INFO << " with nam " << TomahawkUtils::nam(); + m_twitterAuth = QWeakPointer< TomahawkOAuthTwitter >( new TomahawkOAuthTwitter( TomahawkUtils::nam(), this ) ); + + if( m_twitterAuth.isNull() ) + return false; + + m_twitterAuth.data()->setOAuthToken( m_credentials[ "oauthtoken" ].toString().toLatin1() ); + m_twitterAuth.data()->setOAuthTokenSecret( m_credentials[ "oauthtokensecret" ].toString().toLatin1() ); + + return true; +} + + +void +TwitterAccount::connectAuthVerifyReply( const QTweetUser &user ) +{ + if ( user.id() == 0 ) + { + qDebug() << "TwitterAccount could not authenticate to Twitter"; + deauthenticate(); + } + else + { + tDebug() << "TwitterAccount successfully authenticated to Twitter as user " << user.screenName(); + m_configuration[ "screenname" ] = user.screenName(); + sync(); + emit nowAuthenticated( m_twitterAuth, user ); + } +} + + +void +TwitterAccount::refreshProxy() +{ + //FIXME: Could this cause a race condition if a client is threaded? + if ( !m_twitterAuth.isNull() ) + m_twitterAuth.data()->setNetworkAccessManager( TomahawkUtils::nam() ); +} + + } } diff --git a/src/accounts/twitter/twitteraccount.h b/src/accounts/twitter/twitteraccount.h index 7368dbf69..9daa74139 100644 --- a/src/accounts/twitter/twitteraccount.h +++ b/src/accounts/twitter/twitteraccount.h @@ -60,8 +60,9 @@ public: QIcon icon() const { return QIcon( ":/twitter-icon.png" ); } - bool canSelfAuthenticate() const { return false; } - bool authenticate() { return false; } + bool canSelfAuthenticate() const { return true; } + void authenticate(); + void deauthenticate(); bool isAuthenticated() const { return m_isAuthenticated; } Tomahawk::InfoSystem::InfoPlugin* infoPlugin() { return 0; } @@ -70,11 +71,22 @@ public: QWidget* configurationWidget() { return m_configWidget.data(); } QWidget* aclWidget() { return 0; } + bool refreshTwitterAuth(); + TomahawkOAuthTwitter* twitterAuth() const { return m_twitterAuth.data(); } + + void refreshProxy(); + +signals: + void nowAuthenticated( const QWeakPointer< TomahawkOAuthTwitter >&, const QTweetUser &user ); + void nowDeauthenticated(); + private slots: void configDialogAuthedSignalSlot( bool authed ); + void connectAuthVerifyReply( const QTweetUser &user ); private: bool m_isAuthenticated; + QWeakPointer< TomahawkOAuthTwitter > m_twitterAuth; QWeakPointer< TwitterConfigWidget > m_configWidget; QWeakPointer< TwitterSipPlugin > m_twitterSipPlugin; diff --git a/src/accounts/xmpp/xmppaccount.cpp b/src/accounts/xmpp/xmppaccount.cpp index 298a46036..43129551b 100644 --- a/src/accounts/xmpp/xmppaccount.cpp +++ b/src/accounts/xmpp/xmppaccount.cpp @@ -56,6 +56,20 @@ XmppAccount::~XmppAccount() } +void +XmppAccount::authenticate() +{ + return; +} + + +void +XmppAccount::deauthenticate() +{ + return; +} + + SipPlugin* XmppAccount::sipPlugin() { diff --git a/src/accounts/xmpp/xmppaccount.h b/src/accounts/xmpp/xmppaccount.h index 51d39393b..4074224e6 100644 --- a/src/accounts/xmpp/xmppaccount.h +++ b/src/accounts/xmpp/xmppaccount.h @@ -61,7 +61,8 @@ public: QIcon icon() const { return QIcon( ":/xmpp-icon.png" ); } bool canSelfAuthenticate() const { return false; } - bool authenticate() { return false; } + void authenticate(); + void deauthenticate(); bool isAuthenticated() const { return m_isAuthenticated; } Tomahawk::InfoSystem::InfoPlugin* infoPlugin() { return 0; } @@ -70,6 +71,8 @@ public: QWidget* configurationWidget() { return m_configWidget.data(); } QWidget* aclWidget() { return 0; } + void refreshProxy() {}; + private: Ui_XmppConfigWidget* m_ui; // so the google wrapper can change the config dialog a bit bool m_isAuthenticated; diff --git a/src/libtomahawk/accounts/account.cpp b/src/libtomahawk/accounts/account.cpp index ee2559c8b..c7b3f947e 100644 --- a/src/libtomahawk/accounts/account.cpp +++ b/src/libtomahawk/accounts/account.cpp @@ -52,10 +52,17 @@ Account::canSelfAuthenticate() const } -bool +void Account::authenticate() { - return false; + return; +} + + +void +Account::deauthenticate() +{ + return; } @@ -66,6 +73,13 @@ Account::isAuthenticated() const } +void +Account::refreshProxy() +{ + +} + + } } \ No newline at end of file diff --git a/src/libtomahawk/accounts/account.h b/src/libtomahawk/accounts/account.h index 7350854a3..c8c98c385 100644 --- a/src/libtomahawk/accounts/account.h +++ b/src/libtomahawk/accounts/account.h @@ -80,7 +80,8 @@ public: virtual QIcon icon() const = 0; virtual bool canSelfAuthenticate() const = 0; - virtual bool authenticate() = 0; //if none needed, just return true + virtual void authenticate() = 0; + virtual void deauthenticate() = 0; virtual bool isAuthenticated() const = 0; virtual Tomahawk::InfoSystem::InfoPlugin* infoPlugin() = 0; @@ -106,11 +107,8 @@ public: virtual void setAutoConnect( bool autoConnect ) { QMutexLocker locker( &m_mutex ); m_autoConnect = autoConnect; } virtual void setAccountId( const QString &accountId ) { QMutexLocker locker( &m_mutex ); m_accountId = accountId; } virtual void setCredentials( const QVariantHash &credentialHash ) { QMutexLocker locker( &m_mutex ); m_credentials = credentialHash; } - virtual void setConfiguration( const QVariantHash &configuration ) { QMutexLocker locker( &m_mutex ); m_configuration = configuration; } - virtual void setAcl( const QVariantMap &acl ) { QMutexLocker locker( &m_mutex ); m_acl = acl; } - virtual void setTypes( const QSet< AccountType > types ) { QMutexLocker locker( &m_mutex ); @@ -130,10 +128,13 @@ public: syncConfig(); } + virtual void refreshProxy() = 0; + virtual void sync() { QMutexLocker locker( &m_mutex ); syncConfig(); }; signals: void configurationChanged(); + void authenticated( bool ); protected: virtual void loadFromConfig( const QString &accountId ) diff --git a/src/libtomahawk/sip/SipPlugin.h b/src/libtomahawk/sip/SipPlugin.h index 26d2d42b5..b66429f07 100644 --- a/src/libtomahawk/sip/SipPlugin.h +++ b/src/libtomahawk/sip/SipPlugin.h @@ -60,7 +60,7 @@ public: virtual const QStringList peersOnline() const; public slots: - virtual bool connectPlugin() = 0; + virtual void connectPlugin() = 0; virtual void disconnectPlugin() = 0; virtual void checkSettings() = 0; virtual void configurationChanged() = 0; diff --git a/src/sip/twitter/twittersip.cpp b/src/sip/twitter/twittersip.cpp index 4314f466d..0c80930e9 100644 --- a/src/sip/twitter/twittersip.cpp +++ b/src/sip/twitter/twittersip.cpp @@ -38,14 +38,12 @@ #include "utils/logger.h" #include "accounts/twitter/tomahawkoauthtwitter.h" +#include static QString s_gotTomahawkRegex = QString( "^(@[a-zA-Z0-9]+ )?(Got Tomahawk\\?) (\\{[a-fA-F0-9\\-]+\\}) (.*)$" ); TwitterSipPlugin::TwitterSipPlugin( Tomahawk::Accounts::Account* account ) : SipPlugin( account ) - , m_configuration( account->configuration() ) - , m_credentials( account->credentials() ) - , m_isAuthed( false ) , m_checkTimer( this ) , m_connectTimer( this ) , m_dmPollTimer( this ) @@ -58,6 +56,8 @@ TwitterSipPlugin::TwitterSipPlugin( Tomahawk::Accounts::Account* account ) { qDebug() << Q_FUNC_INFO; + connect( account, SIGNAL( nowAuthenticated( const QWeakPointer< TomahawkOAuthTwitter > &, const QTweetUser & ) ), SLOT( accountAuthenticated( const QWeakPointer< TomahawkOAuthTwitter > &, const QTweetUser & ) ) ); + if ( Database::instance()->dbid() != m_configuration[ "saveddbid" ].toString() ) { m_configuration[ "cachedpeers" ] = QVariantHash(); @@ -82,7 +82,7 @@ TwitterSipPlugin::TwitterSipPlugin( Tomahawk::Accounts::Account* account ) bool TwitterSipPlugin::isValid() const { - return m_account->enabled() && m_isAuthed; + return m_account->enabled() && m_account->isAuthenticated() && !m_cachedTwitterAuth.isNull(); } @@ -93,68 +93,37 @@ TwitterSipPlugin::connectionState() const } -void TwitterSipPlugin::checkSettings() +void +TwitterSipPlugin::checkSettings() { configurationChanged(); } -bool +void TwitterSipPlugin::connectPlugin() { tDebug() << Q_FUNC_INFO; if ( !m_account->enabled() ) { tDebug() << Q_FUNC_INFO << "account isn't enabled"; - return false; + return; } - + m_cachedPeers = m_configuration[ "cachedpeers" ].toHash(); QStringList peerList = m_cachedPeers.keys(); qStableSort( peerList.begin(), peerList.end() ); - - registerOffers( peerList ); - - tDebug() << Q_FUNC_INFO << "credentials: " << m_credentials.keys(); - if ( m_credentials[ "oauthtoken" ].toString().isEmpty() || m_credentials[ "oauthtokensecret" ].toString().isEmpty() ) + if ( !m_account->isAuthenticated() ) { - qDebug() << "TwitterSipPlugin has empty Twitter credentials; not connecting"; - return m_cachedPeers.isEmpty(); + tDebug() << Q_FUNC_INFO << "account isn't authenticated, attempting"; + m_account->authenticate(); } - if ( refreshTwitterAuth() ) - { - QTweetAccountVerifyCredentials *credVerifier = new QTweetAccountVerifyCredentials( m_twitterAuth.data(), this ); - connect( credVerifier, SIGNAL( parsedUser( const QTweetUser & ) ), SLOT( connectAuthVerifyReply( const QTweetUser & ) ) ); - credVerifier->verify(); - - m_state = Connecting; - emit stateChanged( m_state ); - } - - return true; + m_state = Connecting; + emit stateChanged( m_state ); } -bool -TwitterSipPlugin::refreshTwitterAuth() -{ - qDebug() << Q_FUNC_INFO << " begin"; - if( !m_twitterAuth.isNull() ) - delete m_twitterAuth.data(); - - Q_ASSERT( TomahawkUtils::nam() != 0 ); - qDebug() << Q_FUNC_INFO << " with nam " << TomahawkUtils::nam(); - m_twitterAuth = QWeakPointer< TomahawkOAuthTwitter >( new TomahawkOAuthTwitter( TomahawkUtils::nam(), this ) ); - - if( m_twitterAuth.isNull() ) - return false; - - m_twitterAuth.data()->setOAuthToken( m_credentials[ "oauthtoken" ].toString().toLatin1() ); - m_twitterAuth.data()->setOAuthTokenSecret( m_credentials[ "oauthtokensecret" ].toString().toLatin1() ); - - return true; -} void TwitterSipPlugin::disconnectPlugin() @@ -173,9 +142,9 @@ TwitterSipPlugin::disconnectPlugin() delete m_directMessageNew.data(); if( !m_directMessageDestroy.isNull() ) delete m_directMessageDestroy.data(); - if( !m_twitterAuth.isNull() ) - delete m_twitterAuth.data(); + m_cachedTwitterAuth.clear(); + m_configuration[ "cachedpeers" ] = m_cachedPeers; syncConfig(); m_cachedPeers.empty(); @@ -184,72 +153,42 @@ TwitterSipPlugin::disconnectPlugin() } void -TwitterSipPlugin::connectAuthVerifyReply( const QTweetUser &user ) +TwitterSipPlugin::accountAuthenticated( const QWeakPointer< TomahawkOAuthTwitter > &twitterAuth, const QTweetUser &user ) { - if ( user.id() == 0 ) - { - qDebug() << "TwitterSipPlugin could not authenticate to Twitter"; - m_isAuthed = false; - m_state = Disconnected; - m_connectTimer.stop(); - m_checkTimer.stop(); - m_dmPollTimer.stop(); - emit stateChanged( m_state ); - } - else - { - qDebug() << "TwitterSipPlugin successfully authenticated to Twitter as user " << user.screenName(); - m_isAuthed = true; - if ( !m_twitterAuth.isNull() ) - { - m_configuration[ "screenname" ] = user.screenName(); - syncConfig(); - m_friendsTimeline = QWeakPointer( new QTweetFriendsTimeline( m_twitterAuth.data(), this ) ); - m_mentions = QWeakPointer( new QTweetMentions( m_twitterAuth.data(), this ) ); - m_directMessages = QWeakPointer( new QTweetDirectMessages( m_twitterAuth.data(), this ) ); - m_directMessageNew = QWeakPointer( new QTweetDirectMessageNew( m_twitterAuth.data(), this ) ); - m_directMessageDestroy = QWeakPointer( new QTweetDirectMessageDestroy( m_twitterAuth.data(), this ) ); - connect( m_friendsTimeline.data(), SIGNAL( parsedStatuses(const QList< QTweetStatus > &) ), SLOT( friendsTimelineStatuses(const QList &) ) ); - connect( m_mentions.data(), SIGNAL( parsedStatuses(const QList< QTweetStatus > &) ), SLOT( mentionsStatuses(const QList &) ) ); - connect( m_directMessages.data(), SIGNAL( parsedDirectMessages(const QList &)), SLOT( directMessages(const QList &) ) ); - 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 = Connected; - emit stateChanged( m_state ); - m_connectTimer.start(); - m_checkTimer.start(); - m_dmPollTimer.start(); - QMetaObject::invokeMethod( this, "checkTimerFired", Qt::AutoConnection ); - QTimer::singleShot( 20000, this, SLOT( connectTimerFired() ) ); - } - else - { - if ( refreshTwitterAuth() ) - { - QTweetAccountVerifyCredentials *credVerifier = new QTweetAccountVerifyCredentials( m_twitterAuth.data(), this ); - connect( credVerifier, SIGNAL( parsedUser(const QTweetUser &) ), SLOT( connectAuthVerifyReply(const QTweetUser &) ) ); - credVerifier->verify(); - } - else - { - qDebug() << "TwitterSipPlugin auth pointer was null!"; - m_isAuthed = false; - m_state = Disconnected; - m_connectTimer.stop(); - m_checkTimer.stop(); - m_dmPollTimer.stop(); - emit stateChanged( m_state ); - } - } - } + if ( !isValid() ) + return; + + m_cachedTwitterAuth = twitterAuth; + + m_friendsTimeline = QWeakPointer( new QTweetFriendsTimeline( m_cachedTwitterAuth.data(), this ) ); + m_mentions = QWeakPointer( new QTweetMentions( m_cachedTwitterAuth.data(), this ) ); + m_directMessages = QWeakPointer( new QTweetDirectMessages( m_cachedTwitterAuth.data(), this ) ); + m_directMessageNew = QWeakPointer( new QTweetDirectMessageNew( m_cachedTwitterAuth.data(), this ) ); + m_directMessageDestroy = QWeakPointer( new QTweetDirectMessageDestroy( m_cachedTwitterAuth.data(), this ) ); + connect( m_friendsTimeline.data(), SIGNAL( parsedStatuses(const QList< QTweetStatus > &) ), SLOT( friendsTimelineStatuses(const QList &) ) ); + connect( m_mentions.data(), SIGNAL( parsedStatuses(const QList< QTweetStatus > &) ), SLOT( mentionsStatuses(const QList &) ) ); + connect( m_directMessages.data(), SIGNAL( parsedDirectMessages(const QList &)), SLOT( directMessages(const QList &) ) ); + 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 = Connected; + emit stateChanged( m_state ); + QStringList peerList = m_cachedPeers.keys(); + qStableSort( peerList.begin(), peerList.end() ); + registerOffers( peerList ); + m_connectTimer.start(); + m_checkTimer.start(); + m_dmPollTimer.start(); + + QMetaObject::invokeMethod( this, "checkTimerFired", Qt::AutoConnection ); + QTimer::singleShot( 20000, this, SLOT( connectTimerFired() ) ); } void TwitterSipPlugin::checkTimerFired() { - if ( !isValid() || m_twitterAuth.isNull() ) + if ( !isValid() ) return; if ( m_cachedFriendsSinceId == 0 ) @@ -273,6 +212,9 @@ TwitterSipPlugin::checkTimerFired() void TwitterSipPlugin::registerOffers( const QStringList &peerList ) { + if ( !isValid() ) + return; + foreach( QString screenName, peerList ) { QVariantHash peerData = m_cachedPeers[screenName].toHash(); @@ -318,14 +260,12 @@ void TwitterSipPlugin::connectTimerFired() { tDebug() << Q_FUNC_INFO << " beginning"; - if ( !isValid() || m_cachedPeers.isEmpty() || m_twitterAuth.isNull() ) + 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"; - if ( m_twitterAuth.isNull() ) - tDebug() << Q_FUNC_INFO << " has null twitterAuth"; return; } @@ -388,7 +328,7 @@ TwitterSipPlugin::parseGotTomahawk( const QRegExp ®ex, const QString &screenN void TwitterSipPlugin::friendsTimelineStatuses( const QList< QTweetStatus > &statuses ) { - qDebug() << Q_FUNC_INFO; + tDebug() << Q_FUNC_INFO; QRegExp regex( s_gotTomahawkRegex, Qt::CaseSensitive, QRegExp::RegExp2 ); QHash< QString, QTweetStatus > latestHash; @@ -411,7 +351,7 @@ TwitterSipPlugin::friendsTimelineStatuses( const QList< QTweetStatus > &statuses if ( status.id() > m_cachedFriendsSinceId ) m_cachedFriendsSinceId = status.id(); - qDebug() << "TwitterSipPlugin checking mention from " << status.user().screenName() << " with content " << status.text(); + tDebug() << "TwitterSipPlugin checking mention from " << status.user().screenName() << " with content " << status.text(); parseGotTomahawk( regex, status.user().screenName(), status.text() ); } @@ -422,7 +362,7 @@ TwitterSipPlugin::friendsTimelineStatuses( const QList< QTweetStatus > &statuses void TwitterSipPlugin::mentionsStatuses( const QList< QTweetStatus > &statuses ) { - qDebug() << Q_FUNC_INFO; + tDebug() << Q_FUNC_INFO; QRegExp regex( s_gotTomahawkRegex, Qt::CaseSensitive, QRegExp::RegExp2 ); QHash< QString, QTweetStatus > latestHash; @@ -445,7 +385,7 @@ TwitterSipPlugin::mentionsStatuses( const QList< QTweetStatus > &statuses ) if ( status.id() > m_cachedMentionsSinceId ) m_cachedMentionsSinceId = status.id(); - qDebug() << "TwitterSipPlugin checking mention from " << status.user().screenName() << " with content " << status.text(); + tDebug() << "TwitterSipPlugin checking mention from " << status.user().screenName() << " with content " << status.text(); parseGotTomahawk( regex, status.user().screenName(), status.text() ); } @@ -462,7 +402,7 @@ TwitterSipPlugin::pollDirectMessages() if ( m_cachedDirectMessagesSinceId == 0 ) m_cachedDirectMessagesSinceId = m_configuration[ "cacheddirectmentionssinceid" ].toLongLong(); - qDebug() << "TwitterSipPlugin looking for direct messages since id " << m_cachedDirectMessagesSinceId; + tDebug() << "TwitterSipPlugin looking for direct messages since id " << m_cachedDirectMessagesSinceId; if ( !m_directMessages.isNull() ) m_directMessages.data()->fetch( m_cachedDirectMessagesSinceId, 0, 800 ); @@ -471,7 +411,7 @@ TwitterSipPlugin::pollDirectMessages() void TwitterSipPlugin::directMessages( const QList< QTweetDMStatus > &messages ) { - qDebug() << Q_FUNC_INFO; + tDebug() << Q_FUNC_INFO; QRegExp regex( s_gotTomahawkRegex, Qt::CaseSensitive, QRegExp::RegExp2 ); QString myScreenName = m_configuration[ "screenname" ].toString(); @@ -709,9 +649,10 @@ void TwitterSipPlugin::fetchAvatar( const QString& screenName ) { qDebug() << Q_FUNC_INFO; - if ( m_twitterAuth.isNull() ) + if ( !isValid() ) return; - QTweetUserShow *userShowFetch = new QTweetUserShow( m_twitterAuth.data(), this ); + + QTweetUserShow *userShowFetch = new QTweetUserShow( m_cachedTwitterAuth.data(), this ); connect( userShowFetch, SIGNAL( parsedUserInfo( QTweetUser ) ), SLOT( avatarUserDataSlot( QTweetUser ) ) ); userShowFetch->fetch( screenName ); } @@ -720,11 +661,11 @@ void TwitterSipPlugin::avatarUserDataSlot( const QTweetUser &user ) { tDebug() << Q_FUNC_INFO; - if ( user.profileImageUrl().isEmpty() || m_twitterAuth.isNull() ) + if ( !isValid() || user.profileImageUrl().isEmpty()) return; QNetworkRequest request( user.profileImageUrl() ); - QNetworkReply *reply = m_twitterAuth.data()->networkAccessManager()->get( request ); + QNetworkReply *reply = m_cachedTwitterAuth.data()->networkAccessManager()->get( request ); reply->setProperty( "screenname", user.screenName() ); connect( reply, SIGNAL( finished() ), this, SLOT( profilePicReply() ) ); } @@ -732,8 +673,7 @@ TwitterSipPlugin::avatarUserDataSlot( const QTweetUser &user ) void TwitterSipPlugin::refreshProxy() { - if ( !m_twitterAuth.isNull() ) - m_twitterAuth.data()->setNetworkAccessManager( TomahawkUtils::nam() ); + //handled by TwitterAccount::refreshProxy() } void @@ -761,6 +701,6 @@ TwitterSipPlugin::configurationChanged() { tDebug() << Q_FUNC_INFO; if ( m_state != Disconnected ) - disconnectPlugin(); + m_account->deauthenticate(); connectPlugin(); } diff --git a/src/sip/twitter/twittersip.h b/src/sip/twitter/twittersip.h index 0da977ac6..5036f9594 100644 --- a/src/sip/twitter/twittersip.h +++ b/src/sip/twitter/twittersip.h @@ -50,7 +50,7 @@ public: virtual ConnectionState connectionState() const; public slots: - virtual bool connectPlugin(); + virtual void connectPlugin(); void disconnectPlugin(); void refreshProxy(); void configurationChanged(); @@ -75,7 +75,7 @@ public slots: void checkSettings(); private slots: - void connectAuthVerifyReply( const QTweetUser &user ); + void accountAuthenticated( const QWeakPointer< TomahawkOAuthTwitter > &twitterAuth, const QTweetUser &user ); void checkTimerFired(); void connectTimerFired(); void friendsTimelineStatuses( const QList< QTweetStatus > &statuses ); @@ -98,7 +98,8 @@ private: bool refreshTwitterAuth(); void parseGotTomahawk( const QRegExp ®ex, const QString &screenName, const QString &text ); - QWeakPointer< TomahawkOAuthTwitter > m_twitterAuth; + QWeakPointer< TomahawkOAuthTwitter > m_cachedTwitterAuth; + QWeakPointer< QTweetFriendsTimeline > m_friendsTimeline; QWeakPointer< QTweetMentions > m_mentions; QWeakPointer< QTweetDirectMessages > m_directMessages; @@ -108,7 +109,6 @@ private: QVariantHash m_configuration; QVariantHash m_credentials; - bool m_isAuthed; QTimer m_checkTimer; QTimer m_connectTimer; QTimer m_dmPollTimer; diff --git a/src/sip/xmpp/xmppsip.cpp b/src/sip/xmpp/xmppsip.cpp index 6ac88c882..eb965be44 100644 --- a/src/sip/xmpp/xmppsip.cpp +++ b/src/sip/xmpp/xmppsip.cpp @@ -133,15 +133,15 @@ XmppSipPlugin::menu() return m_menu; } -bool +void XmppSipPlugin::connectPlugin() { qDebug() << Q_FUNC_INFO; - if(m_client->isConnected()) + if( m_client->isConnected() ) { qDebug() << Q_FUNC_INFO << "Already connected to server, not connecting again..."; - return true; //FIXME: should i return false here?! + return; //FIXME: should i return false here?! } qDebug() << "Connecting to the Xmpp server..." << m_client->jid().full(); @@ -154,7 +154,7 @@ XmppSipPlugin::connectPlugin() m_state = Connecting; emit stateChanged( m_state ); - return true; + return; } void diff --git a/src/sip/xmpp/xmppsip.h b/src/sip/xmpp/xmppsip.h index 4b582cd98..f4e973f92 100644 --- a/src/sip/xmpp/xmppsip.h +++ b/src/sip/xmpp/xmppsip.h @@ -62,7 +62,7 @@ signals: void jidChanged( const QString& ); public slots: - virtual bool connectPlugin(); + virtual void connectPlugin(); void disconnectPlugin(); void checkSettings(); void configurationChanged(); From 01aa3ee9a516ed247b3965904b00e1f63351173b Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Mon, 14 Nov 2011 16:10:31 -0500 Subject: [PATCH 015/104] Rename sip libraries --- src/accounts/twitter/CMakeLists.txt | 2 +- src/accounts/xmpp/CMakeLists.txt | 2 +- src/sip/twitter/CMakeLists.txt | 6 +++--- src/sip/xmpp/CMakeLists.txt | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/accounts/twitter/CMakeLists.txt b/src/accounts/twitter/CMakeLists.txt index 804707edd..3cda7f736 100644 --- a/src/accounts/twitter/CMakeLists.txt +++ b/src/accounts/twitter/CMakeLists.txt @@ -57,7 +57,7 @@ target_link_libraries( tomahawk_oauth_twitter target_link_libraries( tomahawk_account_twitter tomahawk_oauth_twitter - tomahawk_siptwitter + tomahawk_sip_twitter ${TOMAHAWK_LIBRARIES} ${QTWEETLIB_LIBRARIES} ${QT_LIBRARIES} diff --git a/src/accounts/xmpp/CMakeLists.txt b/src/accounts/xmpp/CMakeLists.txt index 5ead4733b..8660914e4 100644 --- a/src/accounts/xmpp/CMakeLists.txt +++ b/src/accounts/xmpp/CMakeLists.txt @@ -39,7 +39,7 @@ SET( OS_SPECIFIC_LINK_LIBRARIES ENDIF( WIN32 ) target_link_libraries( tomahawk_account_xmpp - tomahawk_sipxmpp + tomahawk_sip_xmpp ${TOMAHAWK_LIBRARIES} ${JREEN_LIBRARY} ${QT_LIBRARIES} diff --git a/src/sip/twitter/CMakeLists.txt b/src/sip/twitter/CMakeLists.txt index 6f3256ba7..72f3a192e 100644 --- a/src/sip/twitter/CMakeLists.txt +++ b/src/sip/twitter/CMakeLists.txt @@ -21,7 +21,7 @@ include_directories( . ${CMAKE_CURRENT_BINARY_DIR} .. qt4_add_resources( RC_SRCS "resources.qrc" ) qt4_wrap_cpp( twitterMoc ${twitterHeaders} ) -add_library( tomahawk_siptwitter SHARED ${twitterSources} ${twitterMoc} ${RC_SRCS} ) +add_library( tomahawk_sip_twitter SHARED ${twitterSources} ${twitterMoc} ${RC_SRCS} ) IF( WIN32 ) SET( OS_SPECIFIC_LINK_LIBRARIES @@ -31,7 +31,7 @@ SET( OS_SPECIFIC_LINK_LIBRARIES ) ENDIF( WIN32 ) -target_link_libraries( tomahawk_siptwitter +target_link_libraries( tomahawk_sip_twitter tomahawk_oauth_twitter ${TOMAHAWK_LIBRARIES} ${QTWEETLIB_LIBRARIES} @@ -43,4 +43,4 @@ IF( APPLE ) # SET( CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} "-undefined dynamic_lookup" ) ENDIF( APPLE ) -install( TARGETS tomahawk_siptwitter DESTINATION lib${LIB_SUFFIX} ) +install( TARGETS tomahawk_sip_twitter DESTINATION lib${LIB_SUFFIX} ) diff --git a/src/sip/xmpp/CMakeLists.txt b/src/sip/xmpp/CMakeLists.txt index c1ad08f4b..8cdd707ef 100644 --- a/src/sip/xmpp/CMakeLists.txt +++ b/src/sip/xmpp/CMakeLists.txt @@ -31,7 +31,7 @@ include_directories( . ${CMAKE_CURRENT_BINARY_DIR} .. qt4_wrap_ui( xmppSipUI_H ${xmppSipUI} ) qt4_wrap_cpp( xmppSipMoc ${xmppSipHeaders} ) -add_library( tomahawk_sipxmpp SHARED ${xmppSipSources} ${xmppSipMoc} ${xmppSipUI_H} ${RC_SRCS} ) +add_library( tomahawk_sip_xmpp SHARED ${xmppSipSources} ${xmppSipMoc} ${xmppSipUI_H} ${RC_SRCS} ) IF( WIN32 ) SET( OS_SPECIFIC_LINK_LIBRARIES @@ -42,7 +42,7 @@ SET( OS_SPECIFIC_LINK_LIBRARIES ) ENDIF( WIN32 ) -target_link_libraries( tomahawk_sipxmpp +target_link_libraries( tomahawk_sip_xmpp ${QT_LIBRARIES} ${LIBJREEN_LIBRARY} ${OS_SPECIFIC_LINK_LIBRARIES} @@ -53,7 +53,7 @@ IF( APPLE ) # SET( CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} "-undefined dynamic_lookup" ) ENDIF( APPLE ) -install( TARGETS tomahawk_sipxmpp DESTINATION lib${LIB_SUFFIX} ) +install( TARGETS tomahawk_sip_xmpp DESTINATION lib${LIB_SUFFIX} ) #add_subdirectory(googlewrapper) From aae400bea973df8b1c0fc6b417089fbc296ff23a Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Mon, 14 Nov 2011 17:39:13 -0500 Subject: [PATCH 016/104] Move sip into accounts, and redo the exports so that it links on boxes with --as-needed by default (and presumably Windows too) --- src/accounts/accountdllmacro.h | 32 ++++++++++++ src/accounts/twitter/CMakeLists.txt | 26 ++-------- .../twitter/sip}/twittersip.cpp | 2 + .../twitter/sip}/twittersip.h | 4 +- src/accounts/twitter/tomahawkoauthtwitter.cpp | 2 +- src/accounts/twitter/tomahawkoauthtwitter.h | 4 +- src/accounts/twitter/twitteraccount.h | 7 ++- src/accounts/xmpp/CMakeLists.txt | 17 +++++-- .../xmpp/googlewrapper/CMakeLists.txt | 0 .../xmpp/googlewrapper/gmail-logo.png | Bin .../xmpp/googlewrapper/googlewrapper.cpp | 0 .../xmpp/googlewrapper/googlewrapper.h | 0 .../xmpp/googlewrapper/resources.qrc | 0 .../xmpp/sip}/avatarmanager.cpp | 0 .../xmpp/sip}/avatarmanager.h | 8 +-- .../xmpp/sip}/tomahawkxmppmessage.cpp | 0 .../xmpp/sip}/tomahawkxmppmessage.h | 4 +- .../xmpp/sip}/tomahawkxmppmessagefactory.cpp | 0 .../xmpp/sip}/tomahawkxmppmessagefactory.h | 4 +- .../xmpp => accounts/xmpp/sip}/xmlconsole.cpp | 0 .../xmpp => accounts/xmpp/sip}/xmlconsole.h | 12 ++--- .../xmpp => accounts/xmpp/sip}/xmlconsole.ui | 0 .../xmpp => accounts/xmpp/sip}/xmppsip.cpp | 0 src/{sip/xmpp => accounts/xmpp/sip}/xmppsip.h | 4 +- src/accounts/xmpp/xmppaccount.h | 7 ++- src/sip/CMakeLists.txt | 8 --- src/sip/twitter/CMakeLists.txt | 46 ------------------ src/sip/twitter/resources.qrc | 5 -- src/sip/twitter/twitter-icon.png | Bin 2970 -> 0 bytes 29 files changed, 80 insertions(+), 112 deletions(-) create mode 100644 src/accounts/accountdllmacro.h rename src/{sip/twitter => accounts/twitter/sip}/twittersip.cpp (99%) rename src/{sip/twitter => accounts/twitter/sip}/twittersip.h (97%) rename src/{sip => accounts}/xmpp/googlewrapper/CMakeLists.txt (100%) rename src/{sip => accounts}/xmpp/googlewrapper/gmail-logo.png (100%) rename src/{sip => accounts}/xmpp/googlewrapper/googlewrapper.cpp (100%) rename src/{sip => accounts}/xmpp/googlewrapper/googlewrapper.h (100%) rename src/{sip => accounts}/xmpp/googlewrapper/resources.qrc (100%) rename src/{sip/xmpp => accounts/xmpp/sip}/avatarmanager.cpp (100%) rename src/{sip/xmpp => accounts/xmpp/sip}/avatarmanager.h (92%) rename src/{sip/xmpp => accounts/xmpp/sip}/tomahawkxmppmessage.cpp (100%) rename src/{sip/xmpp => accounts/xmpp/sip}/tomahawkxmppmessage.h (94%) rename src/{sip/xmpp => accounts/xmpp/sip}/tomahawkxmppmessagefactory.cpp (100%) rename src/{sip/xmpp => accounts/xmpp/sip}/tomahawkxmppmessagefactory.h (92%) rename src/{sip/xmpp => accounts/xmpp/sip}/xmlconsole.cpp (100%) rename src/{sip/xmpp => accounts/xmpp/sip}/xmlconsole.h (94%) rename src/{sip/xmpp => accounts/xmpp/sip}/xmlconsole.ui (100%) rename src/{sip/xmpp => accounts/xmpp/sip}/xmppsip.cpp (100%) rename src/{sip/xmpp => accounts/xmpp/sip}/xmppsip.h (97%) delete mode 100644 src/sip/twitter/CMakeLists.txt delete mode 100644 src/sip/twitter/resources.qrc delete mode 100644 src/sip/twitter/twitter-icon.png diff --git a/src/accounts/accountdllmacro.h b/src/accounts/accountdllmacro.h new file mode 100644 index 000000000..bca08fc02 --- /dev/null +++ b/src/accounts/accountdllmacro.h @@ -0,0 +1,32 @@ +/* === 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 ACCOUNTDLLMACRO_H +#define ACCOUNTDLLMACRO_H + +#ifdef Q_WS_WIN + #ifdef ACCOUNTDLLEXPORT_PRO + #define ACCOUNTDLLEXPORT __declspec(dllexport) + #else + #define ACCOUNTDLLEXPORT __declspec(dllimport) + #endif +#else + #define ACCOUNTDLLEXPORT +#endif + +#endif diff --git a/src/accounts/twitter/CMakeLists.txt b/src/accounts/twitter/CMakeLists.txt index 3cda7f736..0b667d85f 100644 --- a/src/accounts/twitter/CMakeLists.txt +++ b/src/accounts/twitter/CMakeLists.txt @@ -4,37 +4,31 @@ include( ${QT_USE_FILE} ) add_definitions( ${QT_DEFINITIONS} ) add_definitions( -DQT_PLUGIN ) add_definitions( -DQT_SHARED ) -add_definitions( -DDLLEXPORT_PRO ) +add_definitions( -DACCOUNTDLLEXPORT_PRO ) set( twitterAccountSources twitteraccount.cpp twitterconfigwidget.cpp + tomahawkoauthtwitter.cpp + sip/twittersip.cpp ) set( twitterAccountHeaders twitteraccount.h twitterconfigwidget.h + tomahawkoauthtwitter.h + sip/twittersip.h ) set( twitterAccountUI twitterconfigwidget.ui ) -set( tomahawkOAuthTwitterSources - tomahawkoauthtwitter.cpp -) - -set( tomahawkOAuthTwitterHeaders - tomahawkoauthtwitter.h -) - include_directories( . ${CMAKE_CURRENT_BINARY_DIR} .. ${QT_INCLUDE_DIR} ${QTWEETLIB_INCLUDE_DIR} ) -qt4_wrap_cpp( tomahawkOAuthTwitterMoc ${tomahawkOAuthTwitterHeaders} ) -add_library( tomahawk_oauth_twitter SHARED ${tomahawkOAuthTwitterSources} ${tomahawkOAuthTwitterMoc} ) qt4_wrap_cpp( twitterAccountMoc ${twitterAccountHeaders} ) qt4_wrap_ui( twitterAccountUI_H ${twitterAccountUI} ) qt4_add_resources( RC_SRCS "resources.qrc" ) @@ -48,16 +42,7 @@ SET( OS_SPECIFIC_LINK_LIBRARIES ) ENDIF( WIN32 ) -target_link_libraries( tomahawk_oauth_twitter - ${TOMAHAWK_LIBRARIES} - ${QTWEETLIB_LIBRARIES} - ${QT_LIBRARIES} - ${OS_SPECIFIC_LINK_LIBRARIES} -) - target_link_libraries( tomahawk_account_twitter - tomahawk_oauth_twitter - tomahawk_sip_twitter ${TOMAHAWK_LIBRARIES} ${QTWEETLIB_LIBRARIES} ${QT_LIBRARIES} @@ -68,5 +53,4 @@ IF( APPLE ) # SET( CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} "-undefined dynamic_lookup" ) ENDIF( APPLE ) -install( TARGETS tomahawk_oauth_twitter DESTINATION lib${LIB_SUFFIX} ) install( TARGETS tomahawk_account_twitter DESTINATION lib${LIB_SUFFIX} ) diff --git a/src/sip/twitter/twittersip.cpp b/src/accounts/twitter/sip/twittersip.cpp similarity index 99% rename from src/sip/twitter/twittersip.cpp rename to src/accounts/twitter/sip/twittersip.cpp index 0c80930e9..ddeba632b 100644 --- a/src/sip/twitter/twittersip.cpp +++ b/src/accounts/twitter/sip/twittersip.cpp @@ -155,6 +155,8 @@ TwitterSipPlugin::disconnectPlugin() void TwitterSipPlugin::accountAuthenticated( const QWeakPointer< TomahawkOAuthTwitter > &twitterAuth, const QTweetUser &user ) { + Q_UNUSED( user ); + if ( !isValid() ) return; diff --git a/src/sip/twitter/twittersip.h b/src/accounts/twitter/sip/twittersip.h similarity index 97% rename from src/sip/twitter/twittersip.h rename to src/accounts/twitter/sip/twittersip.h index 5036f9594..76631ac39 100644 --- a/src/sip/twitter/twittersip.h +++ b/src/accounts/twitter/sip/twittersip.h @@ -32,12 +32,12 @@ #include #include -#include "../sipdllmacro.h" +#include "accounts/accountdllmacro.h" #include "sip/SipPlugin.h" #include "accounts/account.h" #include "accounts/twitter/tomahawkoauthtwitter.h" -class SIPDLLEXPORT TwitterSipPlugin : public SipPlugin +class ACCOUNTDLLEXPORT TwitterSipPlugin : public SipPlugin { Q_OBJECT diff --git a/src/accounts/twitter/tomahawkoauthtwitter.cpp b/src/accounts/twitter/tomahawkoauthtwitter.cpp index 35cd98a9e..b9b7e653d 100644 --- a/src/accounts/twitter/tomahawkoauthtwitter.cpp +++ b/src/accounts/twitter/tomahawkoauthtwitter.cpp @@ -1,6 +1,6 @@ #include "tomahawkoauthtwitter.h" -#include +#include #include "utils/logger.h" diff --git a/src/accounts/twitter/tomahawkoauthtwitter.h b/src/accounts/twitter/tomahawkoauthtwitter.h index 12def04d3..7cd243efe 100644 --- a/src/accounts/twitter/tomahawkoauthtwitter.h +++ b/src/accounts/twitter/tomahawkoauthtwitter.h @@ -1,13 +1,13 @@ #ifndef TOMAHAWKOAUTHTWITTERACCOUNT #define TOMAHAWKOAUTHTWITTERACCOUNT -#include "dllmacro.h" +#include "accounts/accountdllmacro.h" #include #include #include -class DLLEXPORT TomahawkOAuthTwitter : public OAuthTwitter +class ACCOUNTDLLEXPORT TomahawkOAuthTwitter : public OAuthTwitter { Q_OBJECT diff --git a/src/accounts/twitter/twitteraccount.h b/src/accounts/twitter/twitteraccount.h index 9daa74139..a440f44bf 100644 --- a/src/accounts/twitter/twitteraccount.h +++ b/src/accounts/twitter/twitteraccount.h @@ -19,12 +19,11 @@ #ifndef TWITTERACCOUNT_H #define TWITTERACCOUNT_H -#include "dllmacro.h" - #include "twitterconfigwidget.h" #include "tomahawkoauthtwitter.h" -#include "sip/twitter/twittersip.h" +#include "sip/twittersip.h" +#include "accounts/accountdllmacro.h" #include "accounts/account.h" #define MYNAME "ACCOUNTTWITTER" @@ -35,7 +34,7 @@ namespace Tomahawk namespace Accounts { -class DLLEXPORT TwitterAccountFactory : public AccountFactory +class ACCOUNTDLLEXPORT TwitterAccountFactory : public AccountFactory { Q_OBJECT Q_INTERFACES( Tomahawk::Accounts::AccountFactory ) diff --git a/src/accounts/xmpp/CMakeLists.txt b/src/accounts/xmpp/CMakeLists.txt index 8660914e4..69fa87122 100644 --- a/src/accounts/xmpp/CMakeLists.txt +++ b/src/accounts/xmpp/CMakeLists.txt @@ -4,20 +4,29 @@ include( ${QT_USE_FILE} ) add_definitions( ${QT_DEFINITIONS} ) add_definitions( -DQT_PLUGIN ) add_definitions( -DQT_SHARED ) -add_definitions( -DDLLEXPORT_PRO ) +add_definitions( -DACCOUNTDLLEXPORT_PRO ) set( xmppAccountSources xmppaccount.cpp xmppconfigwidget.cpp + sip/xmppsip.cpp + sip/tomahawkxmppmessage.cpp + sip/tomahawkxmppmessagefactory.cpp + sip/avatarmanager.cpp + sip/xmlconsole.cpp ) set( xmppAccountHeaders xmppaccount.h xmppconfigwidget.h + sip/xmppsip.h + sip/avatarmanager.h + sip/xmlconsole.h ) set( xmppAccountUI xmppconfigwidget.ui + sip/xmlconsole.ui ) include_directories( . ${CMAKE_CURRENT_BINARY_DIR} .. @@ -39,9 +48,8 @@ SET( OS_SPECIFIC_LINK_LIBRARIES ENDIF( WIN32 ) target_link_libraries( tomahawk_account_xmpp - tomahawk_sip_xmpp ${TOMAHAWK_LIBRARIES} - ${JREEN_LIBRARY} + ${LIBJREEN_LIBRARY} ${QT_LIBRARIES} ${OS_SPECIFIC_LINK_LIBRARIES} ) @@ -51,3 +59,6 @@ IF( APPLE ) ENDIF( APPLE ) install( TARGETS tomahawk_account_xmpp DESTINATION lib${LIB_SUFFIX} ) + +#add_subdirectory(googlewrapper) + diff --git a/src/sip/xmpp/googlewrapper/CMakeLists.txt b/src/accounts/xmpp/googlewrapper/CMakeLists.txt similarity index 100% rename from src/sip/xmpp/googlewrapper/CMakeLists.txt rename to src/accounts/xmpp/googlewrapper/CMakeLists.txt diff --git a/src/sip/xmpp/googlewrapper/gmail-logo.png b/src/accounts/xmpp/googlewrapper/gmail-logo.png similarity index 100% rename from src/sip/xmpp/googlewrapper/gmail-logo.png rename to src/accounts/xmpp/googlewrapper/gmail-logo.png diff --git a/src/sip/xmpp/googlewrapper/googlewrapper.cpp b/src/accounts/xmpp/googlewrapper/googlewrapper.cpp similarity index 100% rename from src/sip/xmpp/googlewrapper/googlewrapper.cpp rename to src/accounts/xmpp/googlewrapper/googlewrapper.cpp diff --git a/src/sip/xmpp/googlewrapper/googlewrapper.h b/src/accounts/xmpp/googlewrapper/googlewrapper.h similarity index 100% rename from src/sip/xmpp/googlewrapper/googlewrapper.h rename to src/accounts/xmpp/googlewrapper/googlewrapper.h diff --git a/src/sip/xmpp/googlewrapper/resources.qrc b/src/accounts/xmpp/googlewrapper/resources.qrc similarity index 100% rename from src/sip/xmpp/googlewrapper/resources.qrc rename to src/accounts/xmpp/googlewrapper/resources.qrc diff --git a/src/sip/xmpp/avatarmanager.cpp b/src/accounts/xmpp/sip/avatarmanager.cpp similarity index 100% rename from src/sip/xmpp/avatarmanager.cpp rename to src/accounts/xmpp/sip/avatarmanager.cpp diff --git a/src/sip/xmpp/avatarmanager.h b/src/accounts/xmpp/sip/avatarmanager.h similarity index 92% rename from src/sip/xmpp/avatarmanager.h rename to src/accounts/xmpp/sip/avatarmanager.h index ea755d76e..c16711453 100644 --- a/src/sip/xmpp/avatarmanager.h +++ b/src/accounts/xmpp/sip/avatarmanager.h @@ -21,12 +21,12 @@ #include -#include -#include +#include +#include -#include "../sipdllmacro.h" +#include "accounts/accountdllmacro.h" -class SIPDLLEXPORT AvatarManager : public QObject +class ACCOUNTDLLEXPORT AvatarManager : public QObject { Q_OBJECT diff --git a/src/sip/xmpp/tomahawkxmppmessage.cpp b/src/accounts/xmpp/sip/tomahawkxmppmessage.cpp similarity index 100% rename from src/sip/xmpp/tomahawkxmppmessage.cpp rename to src/accounts/xmpp/sip/tomahawkxmppmessage.cpp diff --git a/src/sip/xmpp/tomahawkxmppmessage.h b/src/accounts/xmpp/sip/tomahawkxmppmessage.h similarity index 94% rename from src/sip/xmpp/tomahawkxmppmessage.h rename to src/accounts/xmpp/sip/tomahawkxmppmessage.h index 5d6e0b14f..8661c30bd 100644 --- a/src/sip/xmpp/tomahawkxmppmessage.h +++ b/src/accounts/xmpp/sip/tomahawkxmppmessage.h @@ -23,10 +23,10 @@ #define TOMAHAWK_SIP_MESSAGE_NS QLatin1String("http://www.tomhawk-player.org/sip/transports") -#include "../sipdllmacro.h" +#include "accounts/accountdllmacro.h" class TomahawkXmppMessagePrivate; -class SIPDLLEXPORT TomahawkXmppMessage : public Jreen::Payload +class ACCOUNTDLLEXPORT TomahawkXmppMessage : public Jreen::Payload { J_PAYLOAD(TomahawkXmppMessage) Q_DECLARE_PRIVATE(TomahawkXmppMessage) diff --git a/src/sip/xmpp/tomahawkxmppmessagefactory.cpp b/src/accounts/xmpp/sip/tomahawkxmppmessagefactory.cpp similarity index 100% rename from src/sip/xmpp/tomahawkxmppmessagefactory.cpp rename to src/accounts/xmpp/sip/tomahawkxmppmessagefactory.cpp diff --git a/src/sip/xmpp/tomahawkxmppmessagefactory.h b/src/accounts/xmpp/sip/tomahawkxmppmessagefactory.h similarity index 92% rename from src/sip/xmpp/tomahawkxmppmessagefactory.h rename to src/accounts/xmpp/sip/tomahawkxmppmessagefactory.h index 9d9aa6cab..ab713f30f 100644 --- a/src/sip/xmpp/tomahawkxmppmessagefactory.h +++ b/src/accounts/xmpp/sip/tomahawkxmppmessagefactory.h @@ -23,9 +23,9 @@ #include -#include "../sipdllmacro.h" +#include "accounts/accountdllmacro.h" -class SIPDLLEXPORT TomahawkXmppMessageFactory : public Jreen::PayloadFactory +class ACCOUNTDLLEXPORT TomahawkXmppMessageFactory : public Jreen::PayloadFactory { public: TomahawkXmppMessageFactory(); diff --git a/src/sip/xmpp/xmlconsole.cpp b/src/accounts/xmpp/sip/xmlconsole.cpp similarity index 100% rename from src/sip/xmpp/xmlconsole.cpp rename to src/accounts/xmpp/sip/xmlconsole.cpp diff --git a/src/sip/xmpp/xmlconsole.h b/src/accounts/xmpp/sip/xmlconsole.h similarity index 94% rename from src/sip/xmpp/xmlconsole.h rename to src/accounts/xmpp/sip/xmlconsole.h index 6254df941..4c8476953 100644 --- a/src/sip/xmpp/xmlconsole.h +++ b/src/accounts/xmpp/sip/xmlconsole.h @@ -23,18 +23,18 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include namespace Ui { class XmlConsole; } -#include "../sipdllmacro.h" +#include "accounts/accountdllmacro.h" -class SIPDLLEXPORT XmlConsole : public QWidget, public Jreen::XmlStreamHandler +class ACCOUNTDLLEXPORT XmlConsole : public QWidget, public Jreen::XmlStreamHandler { Q_OBJECT diff --git a/src/sip/xmpp/xmlconsole.ui b/src/accounts/xmpp/sip/xmlconsole.ui similarity index 100% rename from src/sip/xmpp/xmlconsole.ui rename to src/accounts/xmpp/sip/xmlconsole.ui diff --git a/src/sip/xmpp/xmppsip.cpp b/src/accounts/xmpp/sip/xmppsip.cpp similarity index 100% rename from src/sip/xmpp/xmppsip.cpp rename to src/accounts/xmpp/sip/xmppsip.cpp diff --git a/src/sip/xmpp/xmppsip.h b/src/accounts/xmpp/sip/xmppsip.h similarity index 97% rename from src/sip/xmpp/xmppsip.h rename to src/accounts/xmpp/sip/xmppsip.h index f4e973f92..aa8efb10e 100644 --- a/src/sip/xmpp/xmppsip.h +++ b/src/accounts/xmpp/sip/xmppsip.h @@ -43,9 +43,9 @@ #define TOMAHAWK_FEATURE QLatin1String( "tomahawk:sip:v1" ) #define TOMAHAWK_CAP_NODE_NAME QLatin1String( "http://tomahawk-player.org/" ) -#include "../sipdllmacro.h" +#include "accounts/accountdllmacro.h" -class SIPDLLEXPORT XmppSipPlugin : public SipPlugin +class ACCOUNTDLLEXPORT XmppSipPlugin : public SipPlugin { Q_OBJECT diff --git a/src/accounts/xmpp/xmppaccount.h b/src/accounts/xmpp/xmppaccount.h index 4074224e6..9c0b314cf 100644 --- a/src/accounts/xmpp/xmppaccount.h +++ b/src/accounts/xmpp/xmppaccount.h @@ -20,9 +20,8 @@ #ifndef XMPPACCOUNT_H #define XMPPACCOUNT_H -#include "dllmacro.h" - -#include "sip/xmpp/xmppsip.h" +#include "sip/xmppsip.h" +#include "accounts/accountdllmacro.h" #include "accounts/account.h" #define MYNAME "ACCOUNTJABBER" @@ -35,7 +34,7 @@ namespace Tomahawk namespace Accounts { -class DLLEXPORT XmppAccountFactory : public AccountFactory +class ACCOUNTDLLEXPORT XmppAccountFactory : public AccountFactory { Q_OBJECT Q_INTERFACES( Tomahawk::Accounts::AccountFactory ) diff --git a/src/sip/CMakeLists.txt b/src/sip/CMakeLists.txt index a85c4010a..0f75b1e32 100644 --- a/src/sip/CMakeLists.txt +++ b/src/sip/CMakeLists.txt @@ -1,9 +1 @@ -IF( LIBJREEN_FOUND ) - ADD_SUBDIRECTORY( xmpp ) -ENDIF( LIBJREEN_FOUND ) - -IF( QTWEETLIB_FOUND ) - ADD_SUBDIRECTORY( twitter ) -ENDIF( QTWEETLIB_FOUND ) - #ADD_SUBDIRECTORY( zeroconf ) diff --git a/src/sip/twitter/CMakeLists.txt b/src/sip/twitter/CMakeLists.txt deleted file mode 100644 index 72f3a192e..000000000 --- a/src/sip/twitter/CMakeLists.txt +++ /dev/null @@ -1,46 +0,0 @@ -project( tomahawk ) - -include( ${QT_USE_FILE} ) -add_definitions( ${QT_DEFINITIONS} ) -add_definitions( -DQT_PLUGIN ) -add_definitions( -DQT_SHARED ) -add_definitions( -DSIPDLLEXPORT_PRO ) - -set( twitterSources - twittersip.cpp -) - -set( twitterHeaders - twittersip.h -) - -include_directories( . ${CMAKE_CURRENT_BINARY_DIR} .. - ${QT_INCLUDE_DIR} - ${QTWEETLIB_INCLUDE_DIR} -) - -qt4_add_resources( RC_SRCS "resources.qrc" ) -qt4_wrap_cpp( twitterMoc ${twitterHeaders} ) -add_library( tomahawk_sip_twitter SHARED ${twitterSources} ${twitterMoc} ${RC_SRCS} ) - -IF( WIN32 ) -SET( OS_SPECIFIC_LINK_LIBRARIES - ${OS_SPECIFIC_LINK_LIBRARIES} - "winmm.dll" - "iphlpapi.a" -) -ENDIF( WIN32 ) - -target_link_libraries( tomahawk_sip_twitter - tomahawk_oauth_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_sip_twitter DESTINATION lib${LIB_SUFFIX} ) diff --git a/src/sip/twitter/resources.qrc b/src/sip/twitter/resources.qrc deleted file mode 100644 index fc7df302f..000000000 --- a/src/sip/twitter/resources.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - -twitter-icon.png - - diff --git a/src/sip/twitter/twitter-icon.png b/src/sip/twitter/twitter-icon.png deleted file mode 100644 index aab1fca8755c0cc5b051bde0d373d5c8bf825c3f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2970 zcmV;L3uW|)P)|0rI6xS8K-7`J=rd>h^jSUiD2nZ)}Y*z&fmBZp6WXI(=KSnqp6Q?THhf}Gt zVQ?vb);s6j<=xj$0AI=%Tew`l{LRxBtMO2eYEC$s7kR8NuHDneXLfJ3er^bO z^VG%NcxWWRDy3l7Yt>*hXrZXU0D@c&CW9{N^LD2Q!B7Y$rkvn#y20i4g3lkECgjvJ zjayGII|8~+UZ9a~BGqeE=F0LSs3J3CP>Y!S|gH9y_J*o_eafxo|xjg`*6AlQ4BSb`7QwBsxBH+Zk7mRplLEtT`Doadj zsw+XER5HL*Vi5eHXiof9Dd(U-Con<+em{I_9fUiBV|FB>9dEbqec};E&Ix$q-R{lg zizS6d^M;yLpwsDK${k`Fi9{hE!t+RkR?buuMYz#>2gW8HlfEqq?d1r53y!>tz}r&?PkFq$SOvv;0pzk6&!KP> z#$7?Mj{DfWAQv)>eI$3FK1Z+h)QybWDMRc{+X8;~_W4$=M%lLYflc5Ja%q95G*wrv zn*lyshzN^SWN9;JmVhK^g(zJ7*Hv(P{B6%Ywe3*K1pM~xbDQNdndPDT*Mp$a!N8<1 zt&#uwy#@x}fkCpP#{-u}W8^(ts(|KN4Hz+K5eXmOcIM0yNLCiAAm|g}gO6_F-wW3r zc&gz_N-ls|t#jS#m7vw>;j>XMMAJxfW;FY0@QNv4^D0?WF%1A zn?s(Q5ip1YcTcGv2+Oq|E6p0W%t@uQFTDQNxfcvtb=}Gp<;?6U+7kh(YOz6x1yCIM zMDWu>*XSMzwN2;U=_>V|Fc22PMA#N3faccs)tbQ@jLqkxF^fo91zGHs(`G-POy8rn z>ApW*B@BdR?dnwwTT&PJ%^%P0G3m7?qrm`u<9=jO`V^1MeIdDS56+xFy0Kuvc0nA% zF=r5N*}NIWiebAS-OU7qjWGV;>4vU(EdcShR92K=zK>u{9+hNvsfaU}T0^ps6*#$h zu*SeLi&R%2EQE=$5ypA5z_0&su39O``?fx~3C6|P15#w?rb2csdut?VyN62@i@qx{ zYmhZu>T#kuOY4_T$wRS@gNy&T3jSco{KM}ySnqa$C^Q;$YT$SQ{l*8mmSirnP}W#o zriN?%Zb^TS3bzu23JBxaq>EOpj^5=0Xz=v~CIfi<6!@h7WLpxmMwwB_sBeUgFcQ`| zK@huc)@d~?*hH78yiF-lP_-2&13)?{ZEEH8TBoaVCD0>K$!fW%Zm%xzEhrZTLS<0 z9tXJnk&NR9vx51i!ZZGn#gWWZ0tlQIIR1kbV>Z?w6EV)23L`HTyVD6ufy>G~AeEV3 z${o+r4`CyWgmu1JpwH#Pj}X%yJfv`Eq0ubvQ7x?j> zZ&^d(h-GYI3QJF3a*m~M1|%B`gsjAY#9ClQfkJY>2oqr=jD&Um^#FkO!C@O-jG(!2 zl2%{_kN|Q6k|SI6S*-=ggr)R}un;D~Mi>`d5__p>dzZ%-wA)5UkukaCVDryg&KWB> z`hYR(wLrQ`SO^ngBaBJc1hIYFz>p2NND$M8G{$Wh2WZwt^7K7wMgq<5GOYyy@me4q zB@BdxFh%EC6P!c9%X_yUMW!tM1A}0|)Wb<+{c@iOw@1A*Bv2re5)%?@fq_YXT796t z69&RUml1AE=G+U?2{9KSQw_XK8+oIcBTMj-ucl47I5GUb;UZZNNsi}bw8jCZ- zZ+TUPN~UE7MM`84@P0J=tNmhHi?jxOw;X%i+uI8+kFOKKr~h$uS`PjG{f~7TRb5TZ z8hoX|J~S+6(KGNt1pg_B9-pQ4d)v1pYtN_f&U%-}Yw1BY!vS~9w6a#7WbcRiM17+^ z_OOxnvb_O|flE0zwH`lvLXh!I)vKz&SWv{=AsAjBb+dp)4w=1UY67fx`so`&=b?Q& zva>}dQ4StI`vT8FdueeYlvS*RFvK=NF6AaED!lk;7;M7>FgiX-eQ7zoZ^zM8-;wt0 ziilY&ktoz^T);4}t1?C#JcPkrD9v161NR9^StrciZF= z<&|S+TQPvN=yV!WX;}qm^akbr~RGtKOjSQCg&2aMW=!RhkY5k>ov{W}gx zB~!Az(s8yL15g{sL6b_UfTE&e79V(-oRL8q%FsXLXy@ePq>*rl`T4}eIQaauLJXZ8 zaBWALcjR}g>}>f-#~CBSq_3_`a-KJ9bz0CHaN>hjAt;n=Juj4Iz@*h1+W!{}_(60z z!G$C47Tri_giIZQL;FvgcRI4+PFaH{`Fe!gDC0P@Uay17>eY;dRE>dx8-X9R z-U63Pgm5(4hnHv(=XQ2QqLI$Q0gO{vm-8Gf z2%p`$+9)xqc+rb_Ewh9H37dku*-q?nnbtT zJ~1{N`}Qzv{OKCqqc+r*p83BafaI44c3q)SofsPh52iIfVWo-A=^EXmHqhq6X`9cst^5X07?Sa_;|FH$j*Pef@Ybp9Mhk(DH z>!y`rU0k&^F-thA6I2yfWr8Z=O79TjDvSRvi@V&ka{uo4vE{0-RjEEsNC-4t49Ab5 z_<1mXPRBrk`s3=0t2aSC2}+v_=|iRXXhXgKu9{;hS8@=z1-_J}mH!Gb01k Date: Sun, 6 Nov 2011 18:58:58 -0500 Subject: [PATCH 017/104] Some work on accounts --- src/CMakeLists.txt | 4 +- src/accountdelegate.cpp | 235 +++++++++++++++ ...{sipconfigdelegate.h => accountdelegate.h} | 23 +- src/configdelegatebase.cpp | 43 ++- src/configdelegatebase.h | 3 +- src/libtomahawk/CMakeLists.txt | 4 +- src/libtomahawk/accounts/accountmanager.cpp | 4 +- src/libtomahawk/accounts/accountmanager.h | 10 +- src/libtomahawk/accounts/accountmodel.cpp | 155 ++++++++++ .../SipModel.h => accounts/accountmodel.h} | 55 ++-- src/libtomahawk/sip/SipHandler.cpp | 2 +- src/libtomahawk/sip/SipModel.cpp | 227 -------------- src/sipconfigdelegate.cpp | 282 ------------------ src/tomahawkapp.cpp | 2 +- 14 files changed, 475 insertions(+), 574 deletions(-) create mode 100644 src/accountdelegate.cpp rename src/{sipconfigdelegate.h => accountdelegate.h} (80%) create mode 100644 src/libtomahawk/accounts/accountmodel.cpp rename src/libtomahawk/{sip/SipModel.h => accounts/accountmodel.h} (56%) delete mode 100644 src/libtomahawk/sip/SipModel.cpp delete mode 100644 src/sipconfigdelegate.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6466f60e7..a5e859bf4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -71,7 +71,7 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui} settingsdialog.cpp diagnosticsdialog.cpp configdelegatebase.cpp - sipconfigdelegate.cpp + accountdelegate.cpp resolverconfigdelegate.cpp settingslistdelegate.cpp resolversmodel.cpp @@ -122,7 +122,7 @@ SET( tomahawkHeadersGui ${tomahawkHeadersGui} diagnosticsdialog.h configdelegatebase.h resolverconfigdelegate.h - sipconfigdelegate.h + accountdelegate.h settingslistdelegate.h resolversmodel.h delegateconfigwrapper.h diff --git a/src/accountdelegate.cpp b/src/accountdelegate.cpp new file mode 100644 index 000000000..e2de7bbc1 --- /dev/null +++ b/src/accountdelegate.cpp @@ -0,0 +1,235 @@ +/* + Copyright (C) 2011 Leo Franchi + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + + +#include "accountdelegate.h" + +#include +#include + +#include "accounts/accountmodel.h" +#include "accounts/account.h" + +#include "utils/tomahawkutils.h" +#include "utils/logger.h" + +#define ICONSIZE 36 +#define WRENCH_SIZE 24 +#define STATUS_ICON_SIZE 18 +#define CHECK_LEFT_EDGE 8 + +using namespace Tomahawk; +using namespace Accounts; + +AccountDelegate::AccountDelegate( QObject* parent ) + : ConfigDelegateBase ( parent ) +{ + connect( this, SIGNAL( configPressed( QModelIndex ) ), this, SLOT( askedForEdit( QModelIndex ) ) ); +} + +bool +AccountDelegate::editorEvent ( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index ) +{ + return ConfigDelegateBase::editorEvent( event, model, option, index ); +} + +void +AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const +{ + QStyleOptionViewItemV4 opt = option; + initStyleOption( &opt, index ); + const QRect itemRect = opt.rect; + const int top = itemRect.top(); + const int mid = itemRect.height() / 2; + + // one line bold for account name + // space below it for account description + // checkbox, icon, name, online/offline status, config icon + QFont name = opt.font; + name.setPointSize( name.pointSize() + 2 ); + name.setBold( true ); + + QFont desc = opt.font; + desc.setItalic( true ); + desc.setPointSize( error.pointSize() - 2 ); + + // draw the background + const QWidget* w = opt.widget; + QStyle* style = w ? w->style() : QApplication::style(); + style->drawPrimitive( QStyle::PE_PanelItemViewItem, &opt, painter, w ); + + int iconLeftEdge = CHECK_LEFT_EDGE + ICONSIZE + PADDING; + int textLeftEdge = iconLeftEdge + ICONSIZE + PADDING; + + // draw checkbox first + int pos = ( mid ) - ( WRENCH_SIZE / 2 ); + QRect checkRect = QRect( CHECK_LEFT_EDGE, pos + top, WRENCH_SIZE, WRENCH_SIZE ); + opt.rect = checkRect; + drawCheckBox( opt, painter, w ); + + // draw the icon if it exists + pos = mid - ( ICONSIZE / 2 ); + if( !index.data( Qt::DecorationRole ).value< QIcon >().isNull() ) { + QRect prect = QRect( iconLeftEdge, pos + top, ICONSIZE, ICONSIZE ); + + painter->save(); + painter->drawPixmap( prect, index.data( Qt::DecorationRole ).value< QIcon >().pixmap( prect.size() ) ); + painter->restore(); + } + + // from the right edge--config status and online/offline + QRect confRect = QRect( itemRect.width() - WRENCH_SIZE - 2 * PADDING, mid - WRENCH_SIZE / 2 + top, WRENCH_SIZE, WRENCH_SIZE ); + if( index.data( SipModel::HasConfig ).toBool() ) { + + QStyleOptionToolButton topt; + topt.rect = confRect; + topt.pos = confRect.topLeft(); + + drawConfigWrench( painter, opt, topt ); + } + + + // draw the online/offline status + const bool hasCapability = ( static_cast< AccountModel::BasicCapabilities >( index.data( AccountModel::BasicCapabilityRole ).toInt() ) != AccountModel::NoCapabilities ); + const int quarter = mid - ( itemRect.height() / 4 ); + const int statusY = hasCapability ? quarter : mid; + const int statusX = confRect.left() - 2*PADDING - STATUS_ICON_SIZE; + + QFont statusF = opt.font; + statusF.setPointSize( statusF.pointSize() - 2 ); + QFontMetrics statusFM( statusF ); + + QPixmap p; + QString statusText; + Account::ConnectionState state = static_cast< Account::ConnectionState >( index.data( AccountModel::ConnectionStateRole ).toInt() ); + if( state == SipPlugin::Connected ) { + p = QPixmap( RESPATH "images/sipplugin-online.png" ); + statusText = tr( "Online" ); + } else if( state == SipPlugin::Connecting ) { + p = QPixmap( RESPATH "images/sipplugin-offline.png" ); + statusText = tr( "Connecting..." ); + } else { + p = QPixmap( RESPATH "images/sipplugin-offline.png" ); + statusText = tr( "Offline" ); + } + p = p.scaled( STATUS_ICON_SIZE, STATUS_ICON_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation ); + painter->drawPixmap( statusX, statusY - STATUS_ICON_SIZE / 2 + top, STATUS_ICON_SIZE, STATUS_ICON_SIZE, p ); + const int width = statusFM.width( statusText ); + int statusTextX = statusX - PADDING - width; + painter->save(); + painter->setFont( statusF ); + painter->drawText( QRect( statusTextX, statusY - statusFM.height() / 2 + top, width, statusFM.height() ), statusText ); + + // draw optional capability text if it exists + if ( hasCapability ) + { + QString capString; + AccountModel::BasicCapabilities cap = static_cast< AccountModel::BasicCapabilities >( index.data( AccountModel::BasicCapabilityRole ).toInt() ); + if ( ( cap & AccountModel::SipCapability ) && ( cap & AccountModel::ResolverCapability ) ) + capString = tr( "Connect to and play from friends" ); + else if ( cap & AccountModel::SipCapability ) + capString = tr( "Connect to friends" ); + else if ( cap & AccountModel::ResolverCapability ) + capString = tr( "Find Music"); + + // checkbox for capability + const int capY = statusY + ( itemRect.height() / 2 ); + QRect capCheckRect( statusX, capY - STATUS_ICON_SIZE / 2 + top, STATUS_ICON_SIZE, STATUS_ICON_SIZE ); + opt.rect = capCheckRect; + drawCheckBox( opt, painter, w ); + + // text to accompany checkbox + const int capW = statusFM.width( capString ); + const int capTextX = statusX - PADDING - capW; + painter->drawText( QRect( capTextX, capY - statusFM.height() / 2 + top, capW, statusFM.height() ) ); + + if ( capTextX < statusTextX ) + statusTextX = capTextX; + } + painter->restore(); + + // name + painter->save(); + painter->setFont( name ); + QFontMetrics namefm( name ); + // pos will the top-left point of the text rect + pos = mid - ( nameHeight / 2 ) + top; + // TODO bound with config icon and offline/online status + width = itemRect.width() - statusTextX; + QRect nameRect( textLeftEdge, pos, width, namefm.height() ); + painter->drawText( nameRect, index.data( AccountModel::AccountName ).toString() ); + + nameRect.translate( mid, 0 ); // move down by half the hight + painter->drawText( nameRect, index.data( AccountModel::DescText ).toString() ); + painter->restore(); + +} + +QRect +AccountDelegate::checkRectForIndex( const QStyleOptionViewItem &option, const QModelIndex &idx, int role ) const +{ + if ( role == Qt::CheckStateRole ) + { + // the whole resolver checkbox + QStyleOptionViewItemV4 opt = option; + initStyleOption( &opt, idx ); + const int mid = opt.rect.height() / 2; + const int pos = mid - ( ICONSIZE / 2 ); + QRect checkRect( CHECK_LEFT_EDGE, pos + opt.rect.top(), ICONSIZE, ICONSIZE ); + + return checkRect; + } else if ( role == AccountModel::BasicCapabilityRole ) + { + // The capabilities checkbox + QStyleOptionViewItemV4 opt = option; + initStyleOption( &opt, idx ); + const int quarter = opt.rect.height() / 4 + opt.rect.height() / 2; + const int leftEdge = opt.rect.width() - PADDING - WRENCH_SIZE - PADDING - WRENCH_SIZE; + QRect checkRect( leftEdge, quarter, WRENCH_SIZE, WRENCH_SIZE ); + return checkRect; + } + return QRect(); +} + +QRect +AccountDelegate::configRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const +{ + if( !idx.data( SipModel::FactoryItemRole ).toBool() && !idx.data( SipModel::FactoryRole ).toBool() ) + { + QStyleOptionViewItemV4 opt = option; + initStyleOption( &opt, idx ); + QRect itemRect = opt.rect; + QRect confRect = QRect( itemRect.width() - ICONSIZE - 2 * PADDING, (opt.rect.height() / 2) - ICONSIZE / 2 + opt.rect.top(), ICONSIZE, ICONSIZE ); + return confRect; + } + return QRect(); +} + + +QSize +AccountDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const +{ + return ConfigDelegateBase::sizeHint( option, index ); +} + +void +AccountDelegate::askedForEdit( const QModelIndex& idx ) +{ + emit openConfig( qobject_cast< SipPlugin* >( idx.data( SipModel::SipPluginData ).value< QObject* >() ) ); +} + + diff --git a/src/sipconfigdelegate.h b/src/accountdelegate.h similarity index 80% rename from src/sipconfigdelegate.h rename to src/accountdelegate.h index cccc82a61..e1fba2092 100644 --- a/src/sipconfigdelegate.h +++ b/src/accountdelegate.h @@ -21,26 +21,35 @@ #include "configdelegatebase.h" -class SipPlugin; -class SipPluginFactory; -class SipConfigDelegate : public ConfigDelegateBase +namespace Tomahawk +{ +namespace Accounts +{ + +class Account; + +class AccountDelegate : public ConfigDelegateBase { Q_OBJECT public: - SipConfigDelegate( QObject* parent = 0); + AccountDelegate( QObject* parent = 0); virtual void paint ( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const; virtual bool editorEvent ( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index ); virtual QSize sizeHint ( const QStyleOptionViewItem& option, const QModelIndex& index ) const; - virtual QRect checkRectForIndex( const QStyleOptionViewItem &option, const QModelIndex &idx ) const; + virtual QRect checkRectForIndex( const QStyleOptionViewItem &option, const QModelIndex &idx, int role ) const; virtual QRect configRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const; + + virtual QList extraCheckRoles() const { return QList() << (int)AccountModel::BasicCapabilityRole; } private slots: void askedForEdit( const QModelIndex& idx ); signals: - void sipFactoryClicked( SipPluginFactory* ); - void openConfig( SipPlugin* ); + void openConfig( Account* ); }; +} +} + #endif // SIPCONFIGDELEGATE_H diff --git a/src/configdelegatebase.cpp b/src/configdelegatebase.cpp index ce6f2baae..bdf826bfc 100644 --- a/src/configdelegatebase.cpp +++ b/src/configdelegatebase.cpp @@ -25,6 +25,8 @@ #include "utils/tomahawkutils.h" #include "utils/logger.h" +#define ROW_HEIGHT 50 + ConfigDelegateBase::ConfigDelegateBase ( QObject* parent ) : QStyledItemDelegate ( parent ) { @@ -36,23 +38,7 @@ QSize ConfigDelegateBase::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const { int width = QStyledItemDelegate::sizeHint( option, index ).width(); - - QStyleOptionViewItemV4 opt = option; - initStyleOption( &opt, index ); - - - QFont name = opt.font; - name.setPointSize( name.pointSize() + 2 ); - name.setBold( true ); - - QFont path = opt.font; - path.setItalic( true ); - path.setPointSize( path.pointSize() - 1 ); - - - QFontMetrics bfm( name ); - QFontMetrics sfm( path ); - return QSize( width, 2 * PADDING + bfm.height() + sfm.height() ); + return QSize( width, ROW_HEIGHT ); } void @@ -94,17 +80,24 @@ ConfigDelegateBase::editorEvent ( QEvent* event, QAbstractItemModel* model, cons m_configPressed = QModelIndex(); QMouseEvent* me = static_cast< QMouseEvent* >( event ); - if( me->button() != Qt::LeftButton || !checkRectForIndex( option, index ).contains( me->pos() ) ) - return false; + QList roles = QList() << (int)Qt::CheckStateRole; + roles.append( extraCheckRoles() ); - // eat the double click events inside the check rect - if( event->type() == QEvent::MouseButtonDblClick ) { - return true; + foreach ( int role, roles ) + { + if( me->button() != Qt::LeftButton || !checkRectForIndex( option, index, role ).contains( me->pos() ) ) + return false; + + // eat the double click events inside the check rect + if( event->type() == QEvent::MouseButtonDblClick ) { + return true; + } + + Qt::CheckState curState = static_cast< Qt::CheckState >( index.data( role ).toInt() ); + Qt::CheckState newState = curState == Qt::Checked ? Qt::Unchecked : Qt::Checked; + return model->setData( index, newState, role ); } - Qt::CheckState curState = static_cast< Qt::CheckState >( index.data( Qt::CheckStateRole ).toInt() ); - Qt::CheckState newState = curState == Qt::Checked ? Qt::Unchecked : Qt::Checked; - return model->setData( index, newState, Qt::CheckStateRole ); } else if( event->type() == QEvent::MouseButtonPress ) { QMouseEvent* me = static_cast< QMouseEvent* >( event ); diff --git a/src/configdelegatebase.h b/src/configdelegatebase.h index d86baad1a..929467a00 100644 --- a/src/configdelegatebase.h +++ b/src/configdelegatebase.h @@ -36,10 +36,11 @@ public: virtual bool editorEvent ( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index ); // if you want to use a checkbox, you need to have this say where to paint it - virtual QRect checkRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const = 0; + virtual QRect checkRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx, int role ) const = 0; // if you want to use a config wrench, you need to have this say where to paint it virtual QRect configRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const = 0; + virtual QList extraCheckRoles() const { return QList(); } signals: void configPressed( const QModelIndex& idx ); diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index 9be5e79e7..72e56e0d2 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -61,10 +61,10 @@ set( libSources accounts/accountmanager.cpp accounts/account.cpp + accounts/accountmodel.cpp sip/SipPlugin.cpp sip/SipHandler.cpp - sip/SipModel.cpp sip/sipinfo.cpp audio/audioengine.cpp @@ -286,12 +286,12 @@ set( libHeaders accounts/account.h accounts/accountmanager.h + accounts/accountmodel.h EchonestCatalogSynchronizer.h sip/SipPlugin.h sip/SipHandler.h - sip/SipModel.h sip/sipinfo.h audio/audioengine.h diff --git a/src/libtomahawk/accounts/accountmanager.cpp b/src/libtomahawk/accounts/accountmanager.cpp index b340ec4ab..9e33b782c 100644 --- a/src/libtomahawk/accounts/accountmanager.cpp +++ b/src/libtomahawk/accounts/accountmanager.cpp @@ -187,8 +187,8 @@ AccountManager::addAccountPlugin( Account* account ) foreach( AccountType type, account->types() ) m_accountsByAccountType[ type ].append( account ); - //TODO:? - //emit pluginAdded( account ); + + emit accountAdded( account ); } diff --git a/src/libtomahawk/accounts/accountmanager.h b/src/libtomahawk/accounts/accountmanager.h index 8020c5759..3cb914042 100644 --- a/src/libtomahawk/accounts/accountmanager.h +++ b/src/libtomahawk/accounts/accountmanager.h @@ -52,8 +52,12 @@ public: Account* loadPlugin( const QString &accountId ); QString factoryFromId( const QString& accountId ) const; - QList< Account* > getAccounts() { return m_accounts; }; - QList< Account* > getAccounts( Tomahawk::Accounts::AccountType type ) { return m_accountsByAccountType[ type ]; } + QList< Account* > accounts() const { return m_accounts; }; + QList< Account* > accounts( Tomahawk::Accounts::AccountType type ) const { return m_accountsByAccountType[ type ]; } + +signals: + void accountAdded( Tomahawk::Accounts::Account* ); + void accountRemoved( Tomahawk::Accounts::Account* ); private: QList< Account* > m_accounts; @@ -67,4 +71,4 @@ private: }; -#endif \ No newline at end of file +#endif diff --git a/src/libtomahawk/accounts/accountmodel.cpp b/src/libtomahawk/accounts/accountmodel.cpp new file mode 100644 index 000000000..e4254a1c1 --- /dev/null +++ b/src/libtomahawk/accounts/accountmodel.cpp @@ -0,0 +1,155 @@ +/* + Copyright (C) 2011 Leo Franchi + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + + +#include "accountmodel.h" + +#include "tomahawksettings.h" +#include "accounts/accountmanager.h" +#include "accounts/account.h" + +#include "utils/logger.h" + +using namespace Tomahawk; +using namespace Accounts; + +AccountModel::AccountModel( QObject* parent ) + : QAbstractListModel( parent ) +{ + connect( AccountManager::instance(), SIGNAL( accountAdded( Tomahawk::Accounts::Account* ) ), this, SLOT( accountAdded( Tomahawk::Accounts::Account* ) ) ); + connect( AccountManager::instance(), SIGNAL( accountRemoved( Tomahawk::Accounts::Account* ) ), this, SLOT( accountRemoved( Tomahawk::Accounts::Account* ) ) ); +} + + +AccountModel::~AccountModel() +{ +} + + +QVariant +AccountModel::data( const QModelIndex& index, int role ) const +{ + if( !index.isValid() ) + return QVariant(); + + QList< Account* > accounts = AccountManager::instance()->accounts(); + Q_ASSERT( index.row() <= accounts.size() ); + Account* account = accounts[ index.row() ]; + switch( role ) + { + case Qt::DisplayRole: + case AccountModel::AccountName: + return account->accountServiceName(); + case AccountModel::ConnectionStateRole: + return account->connectionState(); + case AccountModel::HasConfig: + return ( account->configurationWidget() != 0 ); + case Qt::DecorationRole: + return account->icon(); + case AccountModel::AccountData: + return QVariant::fromValue< QObject* >( account ); + case Qt::CheckStateRole: + return account->enabled() ? Qt::Checked : Qt::Unchecked; + default: + return QVariant(); + } + return QVariant(); +} + + +bool +AccountModel::setData( const QModelIndex& index, const QVariant& value, int role ) +{ + Q_ASSERT( index.isValid() && index.row() <= AccountManager::instance()->accounts().count() ); + + if ( role == Qt::CheckStateRole ) { + Qt::CheckState state = static_cast< Qt::CheckState >( value.toInt() ); + QList< Account* > accounts = AccountManager::instance()->accounts(); + Account* account = accounts[ index.row() ]; + + if( state == Qt::Checked && !account->enabled() ) { + account->setEnabled( true ); + } else if( state == Qt::Unchecked ) { + account->setEnabled( false ); + } + dataChanged( index, index ); + + return true; + } + else if ( role == BasicCapabilityRole ) + { + // TODO + } + return false; +} + +int +AccountModel::rowCount( const QModelIndex& parent ) const +{ + return AccountManager::instance()->accounts().size(); +} + +Qt::ItemFlags +AccountModel::flags( const QModelIndex& index ) const +{ + return QAbstractListModel::flags( index ) | Qt::ItemIsUserCheckable; +} + + +void +AccountModel::accountAdded( Account* account ) +{ + Q_UNUSED( p ); + // we assume account plugins are added at the end of the list. + Q_ASSERT( AccountManager::instance()->accounts().last() == account ); + if ( account->types().contains( SipType ) ) + connect( account->sipPlugin(), SIGNAL( stateChanged( SipPlugin::ConnectionState ) ), this, SLOT( sipStateChanged( SipPlugin::ConnectionState ) ) ); + + int size = AccountManager::instance()->accounts().count() - 1; + beginInsertRows( QModelIndex(), size, size ); + endInsertRows(); +} + + +void +AccountModel::accountRemoved( Account* account ) +{ + int idx = AccountManager::instance()->allPlugins().indexOf( account ); + beginRemoveRows( QModelIndex(), idx, idx ); + endRemoveRows(); +} + + +void +AccountModel::sipStateChanged( SipPlugin::ConnectionState state ) +{ + SipPlugin* p = qobject_cast< SipPlugin* >( sender() ); + Q_ASSERT( a ); + + for ( int i = 0; i < AccountManager::instance()->accounts().size(); i++ ) + { + if ( AccountManager::instance()->accounts()[i] && + AccountManager::instance()->accounts()[i]->sipPlugin() && + AccountManager::instance()->accounts()[i]->sipPlugin() == p ) + { + QModelIndex idx = index( i, 0, QModelIndex() ); + emit dataChanged( idx, idx ); + return; + } + } +} + diff --git a/src/libtomahawk/sip/SipModel.h b/src/libtomahawk/accounts/accountmodel.h similarity index 56% rename from src/libtomahawk/sip/SipModel.h rename to src/libtomahawk/accounts/accountmodel.h index 7f4901032..9f02363d2 100644 --- a/src/libtomahawk/sip/SipModel.h +++ b/src/libtomahawk/accounts/accountmodel.h @@ -1,5 +1,4 @@ /* - Copyright (C) 2011 Leo Franchi This program is free software: you can redistribute it and/or modify @@ -21,43 +20,57 @@ #define SIPMODEL_H #include "dllmacro.h" +#include "sip/SipPlugin.h" #include #include -class SipPlugin; +namespace Tomahawk +{ +namespace Accounts +{ -class DLLEXPORT SipModel : public QAbstractItemModel +class Account; + +class DLLEXPORT AccountModel : public QAbstractListModel { Q_OBJECT public: - enum Roles { - PluginName = Qt::UserRole + 15, - ConnectionStateRole = Qt::UserRole + 17, - HasConfig = Qt::UserRole + 18, - FactoryRole = Qt::UserRole + 19, - ErrorString = Qt::UserRole + 20, - FactoryItemRole = Qt::UserRole + 21, - FactoryItemIcon = Qt::UserRole + 22, - SipPluginData = Qt::UserRole + 23, - SipPluginFactoryData = Qt::UserRole + 24 + enum BasicCapabilities + { + NoCapabilities = 0, + SipCapability = 0x1, + ResolverCapability = 0x2 }; - explicit SipModel( QObject* parent = 0 ); - virtual ~SipModel(); + enum Roles { + AccountName = Qt::UserRole + 15, + AccountIcon = Qt::UserRole + 16, + HeadlineText = Qt::UserRole + 17, + DescText = Qt::UserRole + 18, + BasicCapabilityRole = Qt::UserRole + 19, + ConnectionStateRole = Qt::UserRole + 20, + HasConfig = Qt::UserRole + 21, + ErrorString = Qt::UserRole + 22, + AccountData = Qt::UserRole + 23 // raw plugin + }; + + explicit AccountModel( QObject* parent = 0 ); + virtual ~AccountModel(); - virtual QModelIndex index ( int row, int column, const QModelIndex& parent = QModelIndex() ) const; - virtual QModelIndex parent ( const QModelIndex& child ) const; virtual QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const; virtual int rowCount( const QModelIndex& parent = QModelIndex() ) const; - virtual int columnCount( const QModelIndex& parent ) const; virtual Qt::ItemFlags flags(const QModelIndex& index) const; virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole); private slots: - void pluginAdded( SipPlugin* p ); - void pluginRemoved( SipPlugin* p ); - void pluginStateChanged( SipPlugin* p ); + void accountAdded( Tomahawk::Accounts::Account* p ); + void accountRemoved( Tomahawk::Accounts::Account* p ); + void sipStateChanged( SipPlugin::ConnectionState state ); }; +} + +} + #endif // SIPMODEL_H diff --git a/src/libtomahawk/sip/SipHandler.cpp b/src/libtomahawk/sip/SipHandler.cpp index 5c9c4d496..7254eb229 100644 --- a/src/libtomahawk/sip/SipHandler.cpp +++ b/src/libtomahawk/sip/SipHandler.cpp @@ -174,7 +174,7 @@ void SipHandler::loadFromAccountManager() { tDebug() << Q_FUNC_INFO; - QList< Tomahawk::Accounts::Account* > accountList = Tomahawk::Accounts::AccountManager::instance()->getAccounts( Tomahawk::Accounts::SipType ); + QList< Tomahawk::Accounts::Account* > accountList = Tomahawk::Accounts::AccountManager::instance()->accounts( Tomahawk::Accounts::SipType ); foreach( Tomahawk::Accounts::Account* account, accountList ) { tDebug() << Q_FUNC_INFO << "adding plugin " << account->accountId(); diff --git a/src/libtomahawk/sip/SipModel.cpp b/src/libtomahawk/sip/SipModel.cpp deleted file mode 100644 index 093d81c88..000000000 --- a/src/libtomahawk/sip/SipModel.cpp +++ /dev/null @@ -1,227 +0,0 @@ -/* - Copyright (C) 2011 Leo Franchi - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - - -#include "SipModel.h" - -#include "tomahawksettings.h" -#include "sip/SipHandler.h" -#include "sip/SipPlugin.h" - -#include "utils/logger.h" - - -SipModel::SipModel( QObject* parent ) - : QAbstractItemModel( parent ) -{ - connect( SipHandler::instance(), SIGNAL( stateChanged( SipPlugin*, SipPlugin::ConnectionState ) ), this, SLOT( pluginStateChanged( SipPlugin* ) ) ); - connect( SipHandler::instance(), SIGNAL( pluginAdded( SipPlugin* ) ), this, SLOT( pluginAdded( SipPlugin* ) ) ); - connect( SipHandler::instance(), SIGNAL( pluginRemoved( SipPlugin* ) ), this, SLOT( pluginRemoved( SipPlugin* ) ) ); - - // TODO disable inline factories for now - /* - foreach( SipPluginFactory* f, SipHandler::instance()->pluginFactories() ) { - if( f->isCreatable() ) - m_factories << f; - } */ - -} - - -SipModel::~SipModel() -{ -} - - -QVariant -SipModel::data( const QModelIndex& index, int role ) const -{ - if( !index.isValid() ) - return QVariant(); - - if( !index.parent().isValid() && index.row() == SipHandler::instance()->allPlugins().count() ) { // last row, this is the factory - if( role == Qt::DisplayRole ) - return tr( "Add New Account..." ); - else if( role == FactoryRole ) - return true; - else - return QVariant(); - } - - if( !index.parent().isValid() ) { // account - QList< SipPlugin* > plugins = SipHandler::instance()->allPlugins(); - Q_ASSERT( index.row() <= plugins.size() ); - SipPlugin* p = plugins[ index.row() ]; - switch( role ) - { - case Qt::DisplayRole: - case SipModel::PluginName: - return p->account()->accountServiceName(); - case SipModel::ConnectionStateRole: - return p->connectionState(); - case SipModel::HasConfig: - return ( p->account()->configurationWidget() != 0 ); - case SipModel::FactoryRole: - return false; - case Qt::DecorationRole: - return p->icon(); - case SipModel::SipPluginData: - return QVariant::fromValue< QObject* >( p ); - case Qt::CheckStateRole: - return p->account()->enabled() ? Qt::Checked : Qt::Unchecked; - default: - return QVariant(); - } - } - - /* - * m_factories never actually populated yet, so just disable - if( index.parent().isValid() ) { // this is a factory type - SipPluginFactory* p = m_factories.at( index.row() ); - switch( role ) - { - case Qt::DisplayRole: - return p->prettyName(); - case SipModel::FactoryItemRole: - return true; - case SipModel::FactoryItemIcon: - return p->icon(); - case SipModel::SipPluginFactoryData: - return QVariant::fromValue< QObject* >( p ); - default: - return QVariant(); - } - } - */ - return QVariant(); -} - - -bool -SipModel::setData( const QModelIndex& index, const QVariant& value, int role ) -{ - Q_ASSERT( index.isValid() && index.row() <= SipHandler::instance()->allPlugins().count() ); - - if( role == Qt::CheckStateRole ) { - Qt::CheckState state = static_cast< Qt::CheckState >( value.toInt() ); - QList< SipPlugin* > plugins = SipHandler::instance()->allPlugins(); - SipPlugin* p = plugins[ index.row() ]; - - if( state == Qt::Checked && !p->account()->enabled() ) { - p->account()->setEnabled( true ); - } else if( state == Qt::Unchecked ) { - p->account()->setEnabled( false ); - } - dataChanged( index, index ); - - return true; - } - return false; -} - - -QModelIndex -SipModel::index( int row, int column, const QModelIndex& parent ) const -{ - if( !parent.isValid() ) - return hasIndex( row, column, parent ) ? createIndex( row, column, 0 ) : QModelIndex(); - -// qDebug() << "Creating index for non-top level row!"; - // it's a child of the Add Account, e.g. a factory - if( hasIndex( row, column, parent ) ) { - return createIndex( row, column, 1 /* magic */ ); - } - - return QModelIndex(); -} - - -QModelIndex -SipModel::parent( const QModelIndex& child ) const -{ - if( !child.isValid() ) - return QModelIndex(); - - if( child.internalId() == 1 ) { - return index( SipHandler::instance()->allPlugins().size(), 0, QModelIndex() ); - } - - return QModelIndex(); -} - - -int -SipModel::rowCount( const QModelIndex& parent ) const -{ - if( !parent.isValid() ) // invalid root node - return SipHandler::instance()->allPlugins().size() /* TODO inline factories disabled + 1*/; - if( parent.isValid() && !parent.parent().isValid() ) { // top level item - if( parent.row() == SipHandler::instance()->allPlugins().count() ) {// last row, this is the factory - //return m_factories.count(); - } - } - - return 0; -} - - -int -SipModel::columnCount(const QModelIndex& parent) const -{ - Q_UNUSED( parent ); - return 1; -} - - -Qt::ItemFlags -SipModel::flags( const QModelIndex& index ) const -{ - if( index.data( SipModel::FactoryRole ).toBool() || index.data( SipModel::FactoryItemRole ).toBool() ) - return QAbstractItemModel::flags( index ) & ~Qt::ItemIsSelectable; - return QAbstractItemModel::flags( index ) | Qt::ItemIsUserCheckable; -} - - -void -SipModel::pluginAdded( SipPlugin* p ) -{ - Q_UNUSED( p ); - // we assume sip plugins are added at the end of the list. - Q_ASSERT( SipHandler::instance()->allPlugins().last() == p ); - int size = SipHandler::instance()->allPlugins().count() - 1; - beginInsertRows( QModelIndex(), size, size ); - endInsertRows(); -} - - -void -SipModel::pluginRemoved( SipPlugin* p ) -{ - int idx = SipHandler::instance()->allPlugins().indexOf( p ); - beginRemoveRows( QModelIndex(), idx, idx ); - endRemoveRows(); -} - - -void -SipModel::pluginStateChanged( SipPlugin* p ) -{ - int at = SipHandler::instance()->allPlugins().indexOf( p ); - QModelIndex idx = index( at, 0, QModelIndex() ); - emit dataChanged( idx, idx ); -} - diff --git a/src/sipconfigdelegate.cpp b/src/sipconfigdelegate.cpp deleted file mode 100644 index 20cfcb891..000000000 --- a/src/sipconfigdelegate.cpp +++ /dev/null @@ -1,282 +0,0 @@ -/* - Copyright (C) 2011 Leo Franchi - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - - -#include "sipconfigdelegate.h" - -#include -#include - -#include "sip/SipModel.h" -#include "sip/SipPlugin.h" - -#include "utils/tomahawkutils.h" -#include "utils/logger.h" - -#define ICONSIZE 24 -#define CHECK_LEFT_EDGE 8 - - -SipConfigDelegate::SipConfigDelegate( QObject* parent ) - : ConfigDelegateBase ( parent ) -{ - connect( this, SIGNAL( configPressed( QModelIndex ) ), this, SLOT( askedForEdit( QModelIndex ) ) ); -} - -bool -SipConfigDelegate::editorEvent ( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index ) -{ - return ConfigDelegateBase::editorEvent( event, model, option, index ); -} - -void -SipConfigDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const -{ - QStyleOptionViewItemV4 opt = option; - initStyleOption( &opt, index ); - QRect itemRect = opt.rect; - int top = itemRect.top(); - int mid = itemRect.height() / 2; - - // one line bold for account name - // space below it fro an error - // checkbox, icon, name, online/offline status, config icon - QFont name = opt.font; - name.setPointSize( name.pointSize() + 2 ); - name.setBold( true ); - - QFont error = opt.font; - error.setItalic( true ); - error.setPointSize( error.pointSize() - 2 ); - - // draw the background - const QWidget* w = opt.widget; - QStyle* style = w ? w->style() : QApplication::style(); - style->drawPrimitive( QStyle::PE_PanelItemViewItem, &opt, painter, w ); - - int iconLeftEdge = CHECK_LEFT_EDGE + ICONSIZE + PADDING; - int textLeftEdge = iconLeftEdge + ICONSIZE + PADDING; - - if( index.data( SipModel::FactoryRole ).toBool() ) { // this is the "add new account" row - // draw a border and background - painter->save(); - painter->setRenderHints( QPainter::Antialiasing ); - painter->setBrush( QApplication::palette().color( QPalette::Active, QPalette::Highlight ).lighter( 150 ) ); - QPainterPath roundedRect; - roundedRect.addRoundedRect( itemRect.adjusted( 1, 1, -1, -1 ), 3, 3 ); - painter->drawPath( roundedRect ); - painter->setBrush( QApplication::palette().color( QPalette::Active, QPalette::Highlight ).lighter( 170 ) ); - painter->fillPath( roundedRect, painter->brush() ); - painter->restore(); - - // draw "+" icon in checkbox column - int rectW = 18; - int diff = ( ICONSIZE/ 2 ) - ( rectW / 2) ; - int pos = ( mid ) - ( rectW / 2 ); - QRect plusRect = QRect( CHECK_LEFT_EDGE + diff, pos + top, rectW, rectW ); - QPixmap p( RESPATH "images/list-add.png" ); - painter->drawPixmap( plusRect, p ); - - // draw text - QFont f = opt.font; - f.setPointSize( f.pointSize() ); - f.setBold( true ); - QFontMetrics fm( f ); - QString text = index.data( Qt::DisplayRole ).toString(); - QRect textR = fm.boundingRect( text ); - textR.moveLeft( textLeftEdge ); - textR.moveTop( mid - ( textR.height() / 2 ) + top ); - textR.setRight( itemRect.right() ); - painter->setFont( f ); - painter->drawText( textR, text ); - } else if( index.data( SipModel::FactoryItemRole ).toBool() ) { // this is an account type - -// ConfigDelegateBase::paint( painter, opt, index ); -// int indent = 10; - // draw a border and background - painter->save(); - painter->setRenderHints( QPainter::Antialiasing ); - painter->setBrush( QApplication::palette().color( QPalette::Active, QPalette::Highlight ).lighter( 170 ) ); - QPainterPath roundedRect; - roundedRect.addRoundedRect( itemRect.adjusted( 1, 1, -1, -1 ), 3, 3 ); - painter->drawPath( roundedRect ); - painter->setBrush( QApplication::palette().color( QPalette::Active, QPalette::Highlight ).lighter( 180 ) ); - painter->fillPath( roundedRect, painter->brush() ); - painter->restore(); - - QIcon icon = index.data( SipModel::FactoryItemIcon ).value< QIcon >(); - if( !icon.isNull() ) { - int rectW = 18; - int diff = ( ICONSIZE/ 2 ) - ( rectW / 2) ; - int pos = ( mid ) - ( rectW / 2 ); - QRect rect = QRect( CHECK_LEFT_EDGE + diff, pos + top, rectW, rectW ); - QPixmap p( icon.pixmap( rect.size() ) ); - painter->drawPixmap( rect, p ); - } - - // draw text - QFont f = opt.font; - f.setPointSize( f.pointSize() ); - f.setBold( true ); - QFontMetrics fm( f ); - QString text = index.data( Qt::DisplayRole ).toString(); - QRect textR = fm.boundingRect( text ); - textR.moveLeft( textLeftEdge ); - textR.moveTop( mid - ( textR.height() / 2 ) + top ); - textR.setRight( itemRect.right() ); - painter->setFont( f ); - painter->drawText( textR, text ); - } else { // this is an existing account to show - // draw checkbox first - int pos = ( mid ) - ( ICONSIZE / 2 ); - QRect checkRect = QRect( CHECK_LEFT_EDGE, pos + top, ICONSIZE, ICONSIZE ); - opt.rect = checkRect; - drawCheckBox( opt, painter, w ); - - // draw the icon if it exists - pos = ( mid ) - ( ICONSIZE / 2 ); - if( !index.data( Qt::DecorationRole ).value< QIcon >().isNull() ) { - QRect prect = QRect( iconLeftEdge, pos + top, ICONSIZE, ICONSIZE ); - - painter->save(); - painter->drawPixmap( prect, index.data( Qt::DecorationRole ).value< QIcon >().pixmap( prect.size() ) ); - painter->restore(); - } - - // from the right edge--config status and online/offline - QRect confRect = QRect( itemRect.width() - ICONSIZE - 2 * PADDING, mid - ICONSIZE / 2 + top, ICONSIZE, ICONSIZE ); - if( index.data( SipModel::HasConfig ).toBool() ) { - - QStyleOptionToolButton topt; - topt.rect = confRect; - topt.pos = confRect.topLeft(); - - drawConfigWrench( painter, opt, topt ); - } - - // draw the online/offline status - int statusIconSize = 18; - int statusX = confRect.left() - 2*PADDING - statusIconSize; - QFont statusF = opt.font; - statusF.setPointSize( statusF.pointSize() - 2 ); - QFontMetrics statusFM( statusF ); - - QPixmap p; - QString statusText; - SipPlugin::ConnectionState state = static_cast< SipPlugin::ConnectionState >( index.data( SipModel::ConnectionStateRole ).toInt() ); - if( state == SipPlugin::Connected ) { - p = QPixmap( RESPATH "images/sipplugin-online.png" ); - statusText = tr( "Online" ); - } else if( state == SipPlugin::Connecting ) { - p = QPixmap( RESPATH "images/sipplugin-offline.png" ); - statusText = tr( "Connecting..." ); - } else { - p = QPixmap( RESPATH "images/sipplugin-offline.png" ); - statusText = tr( "Offline" ); - } - p = p.scaled( statusIconSize, statusIconSize, Qt::KeepAspectRatio, Qt::SmoothTransformation ); - painter->drawPixmap( statusX, mid - statusIconSize / 2 + top, statusIconSize, statusIconSize, p ); - int width = statusFM.width( statusText ); - statusX = statusX - PADDING - width; - painter->save(); - painter->setFont( statusF ); - painter->drawText( QRect( statusX, mid - statusFM.height() / 2 + top, width, statusFM.height() ), statusText ); - painter->restore(); - - // name - painter->save(); - QFontMetrics namefm( name ); - int nameHeight = namefm.boundingRect( "test" ).height(); - // pos will the top-left point of the text rect - pos = mid - ( nameHeight / 2 ); - // TODO bound with config icon and offline/online status - width = itemRect.width() - textLeftEdge; - - if( !index.data( SipModel::ErrorString ).toString().isEmpty() ) { // error, show that too - QRect errorRect( textLeftEdge, mid + top, width, mid - PADDING + 1 ); - - QFontMetrics errorFm( error ); - QString str = errorFm.elidedText( index.data( SipModel::ErrorString ).toString(), Qt::ElideRight, errorRect.width() ); - painter->setFont( error ); - painter->drawText( errorRect, str ); - - pos = mid - errorRect.height() - 2; // move the name rect up - } - QString nameStr = namefm.elidedText( index.data( Qt::DisplayRole ).toString(), Qt::ElideRight, width ); - painter->setFont( name ); - painter->drawText( QRect( textLeftEdge, pos + top, width, nameHeight + 1 ), nameStr ); - painter->restore(); - } -} - -QRect -SipConfigDelegate::checkRectForIndex( const QStyleOptionViewItem &option, const QModelIndex &idx ) const -{ - if( !idx.data( SipModel::FactoryItemRole ).toBool() && !idx.data( SipModel::FactoryRole ).toBool() ) - { - QStyleOptionViewItemV4 opt = option; - initStyleOption( &opt, idx ); - int mid = opt.rect.height() / 2; - int pos = ( mid ) - ( ICONSIZE / 2 ); - QRect checkRect = QRect( CHECK_LEFT_EDGE, pos + opt.rect.top(), ICONSIZE, ICONSIZE ); - - return checkRect; - } - return QRect(); -} - -QRect -SipConfigDelegate::configRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const -{ - if( !idx.data( SipModel::FactoryItemRole ).toBool() && !idx.data( SipModel::FactoryRole ).toBool() ) - { - QStyleOptionViewItemV4 opt = option; - initStyleOption( &opt, idx ); - QRect itemRect = opt.rect; - QRect confRect = QRect( itemRect.width() - ICONSIZE - 2 * PADDING, (opt.rect.height() / 2) - ICONSIZE / 2 + opt.rect.top(), ICONSIZE, ICONSIZE ); - return confRect; - } - return QRect(); -} - - -QSize -SipConfigDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const -{ - if( index.data( SipModel::FactoryRole ).toBool() || index.data( SipModel::FactoryItemRole ).toBool() ) { // this is the "add new account" row - // enough space for one line of text - QStyleOptionViewItemV4 opt = option; - initStyleOption( &opt, index ); - int width = QStyledItemDelegate::sizeHint( option, index ).width(); - - QFont name = opt.font; - name.setPointSize( name.pointSize() + 1 ); - name.setBold( true ); - QFontMetrics sfm( name ); - return QSize( width, 3 * PADDING + sfm.height() ); - } else { // this is an existing account to show - return ConfigDelegateBase::sizeHint( option, index ); - } -} - -void -SipConfigDelegate::askedForEdit( const QModelIndex& idx ) -{ - emit openConfig( qobject_cast< SipPlugin* >( idx.data( SipModel::SipPluginData ).value< QObject* >() ) ); -} - - diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index 6e48af576..18194dff8 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -505,7 +505,7 @@ void TomahawkApp::initSIP() { tDebug() << Q_FUNC_INFO; - foreach ( Tomahawk::Accounts::Account* account, Tomahawk::Accounts::AccountManager::instance()->getAccounts() ) + foreach ( Tomahawk::Accounts::Account* account, Tomahawk::Accounts::AccountManager::instance()->accounts() ) { tDebug() << Q_FUNC_INFO << "testing account with name " << account->accountServiceName(); if ( account->configurationWidget() && account->configuration().isEmpty() ) From eedf940e5f5e7dee4870d719e1fdb1cd67e13a6f Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 18 Nov 2011 16:56:23 -0500 Subject: [PATCH 018/104] Bit more work --- src/accounts/twitter/twitteraccount.h | 5 ++--- src/accounts/xmpp/xmppaccount.h | 3 +-- src/libtomahawk/accounts/account.h | 13 +++++++++---- src/libtomahawk/accounts/accountmodel.cpp | 2 +- src/libtomahawk/sip/SipPlugin.h | 5 +---- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/accounts/twitter/twitteraccount.h b/src/accounts/twitter/twitteraccount.h index a440f44bf..ac7ad5c6e 100644 --- a/src/accounts/twitter/twitteraccount.h +++ b/src/accounts/twitter/twitteraccount.h @@ -56,10 +56,9 @@ class DLLEXPORT TwitterAccount : public Account public: TwitterAccount( const QString &accountId ); virtual ~TwitterAccount(); - + QIcon icon() const { return QIcon( ":/twitter-icon.png" ); } - bool canSelfAuthenticate() const { return true; } void authenticate(); void deauthenticate(); bool isAuthenticated() const { return m_isAuthenticated; } @@ -82,7 +81,7 @@ signals: private slots: void configDialogAuthedSignalSlot( bool authed ); void connectAuthVerifyReply( const QTweetUser &user ); - + private: bool m_isAuthenticated; QWeakPointer< TomahawkOAuthTwitter > m_twitterAuth; diff --git a/src/accounts/xmpp/xmppaccount.h b/src/accounts/xmpp/xmppaccount.h index 9c0b314cf..d7f54514e 100644 --- a/src/accounts/xmpp/xmppaccount.h +++ b/src/accounts/xmpp/xmppaccount.h @@ -59,7 +59,6 @@ public: QIcon icon() const { return QIcon( ":/xmpp-icon.png" ); } - bool canSelfAuthenticate() const { return false; } void authenticate(); void deauthenticate(); bool isAuthenticated() const { return m_isAuthenticated; } @@ -77,7 +76,7 @@ private: bool m_isAuthenticated; QWeakPointer< QWidget > m_configWidget; QWeakPointer< XmppSipPlugin > m_xmppSipPlugin; - + // for settings access friend class XmppConfigWidget; diff --git a/src/libtomahawk/accounts/account.h b/src/libtomahawk/accounts/account.h index c8c98c385..062cd51ef 100644 --- a/src/libtomahawk/accounts/account.h +++ b/src/libtomahawk/accounts/account.h @@ -39,7 +39,7 @@ namespace InfoSystem { class InfoPlugin; } - + namespace Accounts { @@ -54,8 +54,11 @@ inline QString generateId( const QString &factoryId ) class DLLEXPORT Account : public QObject { Q_OBJECT - + public: + enum AuthErrorCode { AuthError, ConnectionError }; + enum ConnectionState { Disconnected, Connecting, Connected, Disconnecting }; + explicit Account( const QString &accountId ) : QObject() , m_enabled( false ) @@ -79,9 +82,9 @@ public: virtual QIcon icon() const = 0; - virtual bool canSelfAuthenticate() const = 0; virtual void authenticate() = 0; virtual void deauthenticate() = 0; + virtual ConnectionState connectionState() = 0;s virtual bool isAuthenticated() const = 0; virtual Tomahawk::InfoSystem::InfoPlugin* infoPlugin() = 0; @@ -133,6 +136,8 @@ public: virtual void sync() { QMutexLocker locker( &m_mutex ); syncConfig(); }; signals: + void connectionStateChanged( Tomahawk::Accounts::Account::ConnectionState state ); + void configurationChanged(); void authenticated( bool ); @@ -203,4 +208,4 @@ public: Q_DECLARE_INTERFACE( Tomahawk::Accounts::AccountFactory, "tomahawk.AccountFactory/1.0" ) -#endif \ No newline at end of file +#endif diff --git a/src/libtomahawk/accounts/accountmodel.cpp b/src/libtomahawk/accounts/accountmodel.cpp index e4254a1c1..5bd33f293 100644 --- a/src/libtomahawk/accounts/accountmodel.cpp +++ b/src/libtomahawk/accounts/accountmodel.cpp @@ -1,4 +1,4 @@ -/* + 4/* Copyright (C) 2011 Leo Franchi This program is free software: you can redistribute it and/or modify diff --git a/src/libtomahawk/sip/SipPlugin.h b/src/libtomahawk/sip/SipPlugin.h index f0b591aa6..5cb1ec7de 100644 --- a/src/libtomahawk/sip/SipPlugin.h +++ b/src/libtomahawk/sip/SipPlugin.h @@ -40,9 +40,6 @@ class DLLEXPORT SipPlugin : public QObject Q_OBJECT public: - enum SipErrorCode { AuthError, ConnectionError }; // Placeholder for errors, to be defined - enum ConnectionState { Disconnected, Connecting, Connected, Disconnecting }; - SipPlugin(); explicit SipPlugin( Tomahawk::Accounts::Account *account, QObject* parent = 0 ); virtual ~SipPlugin(); @@ -107,7 +104,7 @@ private slots: protected: Tomahawk::Accounts::Account *m_account; - + private: QString m_cachedError; QStringList m_peersOnline; From cef9c620dcdb3005cdd7acf27d6afa70a7863064 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 18 Nov 2011 21:17:06 -0500 Subject: [PATCH 019/104] Revert last two commits, were not meant to be pushed --- src/CMakeLists.txt | 4 +- src/accountdelegate.cpp | 235 --------------- src/accounts/twitter/twitteraccount.h | 5 +- src/accounts/xmpp/xmppaccount.h | 3 +- src/configdelegatebase.cpp | 43 +-- src/configdelegatebase.h | 3 +- src/libtomahawk/CMakeLists.txt | 4 +- src/libtomahawk/accounts/account.h | 13 +- src/libtomahawk/accounts/accountmanager.cpp | 4 +- src/libtomahawk/accounts/accountmanager.h | 10 +- src/libtomahawk/accounts/accountmodel.cpp | 155 ---------- src/libtomahawk/sip/SipHandler.cpp | 2 +- src/libtomahawk/sip/SipModel.cpp | 227 ++++++++++++++ .../accountmodel.h => sip/SipModel.h} | 53 ++-- src/libtomahawk/sip/SipPlugin.h | 5 +- src/sipconfigdelegate.cpp | 282 ++++++++++++++++++ ...{accountdelegate.h => sipconfigdelegate.h} | 23 +- src/tomahawkapp.cpp | 2 +- 18 files changed, 586 insertions(+), 487 deletions(-) delete mode 100644 src/accountdelegate.cpp delete mode 100644 src/libtomahawk/accounts/accountmodel.cpp create mode 100644 src/libtomahawk/sip/SipModel.cpp rename src/libtomahawk/{accounts/accountmodel.h => sip/SipModel.h} (56%) create mode 100644 src/sipconfigdelegate.cpp rename src/{accountdelegate.h => sipconfigdelegate.h} (80%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a5e859bf4..6466f60e7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -71,7 +71,7 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui} settingsdialog.cpp diagnosticsdialog.cpp configdelegatebase.cpp - accountdelegate.cpp + sipconfigdelegate.cpp resolverconfigdelegate.cpp settingslistdelegate.cpp resolversmodel.cpp @@ -122,7 +122,7 @@ SET( tomahawkHeadersGui ${tomahawkHeadersGui} diagnosticsdialog.h configdelegatebase.h resolverconfigdelegate.h - accountdelegate.h + sipconfigdelegate.h settingslistdelegate.h resolversmodel.h delegateconfigwrapper.h diff --git a/src/accountdelegate.cpp b/src/accountdelegate.cpp deleted file mode 100644 index e2de7bbc1..000000000 --- a/src/accountdelegate.cpp +++ /dev/null @@ -1,235 +0,0 @@ -/* - Copyright (C) 2011 Leo Franchi - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - - -#include "accountdelegate.h" - -#include -#include - -#include "accounts/accountmodel.h" -#include "accounts/account.h" - -#include "utils/tomahawkutils.h" -#include "utils/logger.h" - -#define ICONSIZE 36 -#define WRENCH_SIZE 24 -#define STATUS_ICON_SIZE 18 -#define CHECK_LEFT_EDGE 8 - -using namespace Tomahawk; -using namespace Accounts; - -AccountDelegate::AccountDelegate( QObject* parent ) - : ConfigDelegateBase ( parent ) -{ - connect( this, SIGNAL( configPressed( QModelIndex ) ), this, SLOT( askedForEdit( QModelIndex ) ) ); -} - -bool -AccountDelegate::editorEvent ( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index ) -{ - return ConfigDelegateBase::editorEvent( event, model, option, index ); -} - -void -AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const -{ - QStyleOptionViewItemV4 opt = option; - initStyleOption( &opt, index ); - const QRect itemRect = opt.rect; - const int top = itemRect.top(); - const int mid = itemRect.height() / 2; - - // one line bold for account name - // space below it for account description - // checkbox, icon, name, online/offline status, config icon - QFont name = opt.font; - name.setPointSize( name.pointSize() + 2 ); - name.setBold( true ); - - QFont desc = opt.font; - desc.setItalic( true ); - desc.setPointSize( error.pointSize() - 2 ); - - // draw the background - const QWidget* w = opt.widget; - QStyle* style = w ? w->style() : QApplication::style(); - style->drawPrimitive( QStyle::PE_PanelItemViewItem, &opt, painter, w ); - - int iconLeftEdge = CHECK_LEFT_EDGE + ICONSIZE + PADDING; - int textLeftEdge = iconLeftEdge + ICONSIZE + PADDING; - - // draw checkbox first - int pos = ( mid ) - ( WRENCH_SIZE / 2 ); - QRect checkRect = QRect( CHECK_LEFT_EDGE, pos + top, WRENCH_SIZE, WRENCH_SIZE ); - opt.rect = checkRect; - drawCheckBox( opt, painter, w ); - - // draw the icon if it exists - pos = mid - ( ICONSIZE / 2 ); - if( !index.data( Qt::DecorationRole ).value< QIcon >().isNull() ) { - QRect prect = QRect( iconLeftEdge, pos + top, ICONSIZE, ICONSIZE ); - - painter->save(); - painter->drawPixmap( prect, index.data( Qt::DecorationRole ).value< QIcon >().pixmap( prect.size() ) ); - painter->restore(); - } - - // from the right edge--config status and online/offline - QRect confRect = QRect( itemRect.width() - WRENCH_SIZE - 2 * PADDING, mid - WRENCH_SIZE / 2 + top, WRENCH_SIZE, WRENCH_SIZE ); - if( index.data( SipModel::HasConfig ).toBool() ) { - - QStyleOptionToolButton topt; - topt.rect = confRect; - topt.pos = confRect.topLeft(); - - drawConfigWrench( painter, opt, topt ); - } - - - // draw the online/offline status - const bool hasCapability = ( static_cast< AccountModel::BasicCapabilities >( index.data( AccountModel::BasicCapabilityRole ).toInt() ) != AccountModel::NoCapabilities ); - const int quarter = mid - ( itemRect.height() / 4 ); - const int statusY = hasCapability ? quarter : mid; - const int statusX = confRect.left() - 2*PADDING - STATUS_ICON_SIZE; - - QFont statusF = opt.font; - statusF.setPointSize( statusF.pointSize() - 2 ); - QFontMetrics statusFM( statusF ); - - QPixmap p; - QString statusText; - Account::ConnectionState state = static_cast< Account::ConnectionState >( index.data( AccountModel::ConnectionStateRole ).toInt() ); - if( state == SipPlugin::Connected ) { - p = QPixmap( RESPATH "images/sipplugin-online.png" ); - statusText = tr( "Online" ); - } else if( state == SipPlugin::Connecting ) { - p = QPixmap( RESPATH "images/sipplugin-offline.png" ); - statusText = tr( "Connecting..." ); - } else { - p = QPixmap( RESPATH "images/sipplugin-offline.png" ); - statusText = tr( "Offline" ); - } - p = p.scaled( STATUS_ICON_SIZE, STATUS_ICON_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation ); - painter->drawPixmap( statusX, statusY - STATUS_ICON_SIZE / 2 + top, STATUS_ICON_SIZE, STATUS_ICON_SIZE, p ); - const int width = statusFM.width( statusText ); - int statusTextX = statusX - PADDING - width; - painter->save(); - painter->setFont( statusF ); - painter->drawText( QRect( statusTextX, statusY - statusFM.height() / 2 + top, width, statusFM.height() ), statusText ); - - // draw optional capability text if it exists - if ( hasCapability ) - { - QString capString; - AccountModel::BasicCapabilities cap = static_cast< AccountModel::BasicCapabilities >( index.data( AccountModel::BasicCapabilityRole ).toInt() ); - if ( ( cap & AccountModel::SipCapability ) && ( cap & AccountModel::ResolverCapability ) ) - capString = tr( "Connect to and play from friends" ); - else if ( cap & AccountModel::SipCapability ) - capString = tr( "Connect to friends" ); - else if ( cap & AccountModel::ResolverCapability ) - capString = tr( "Find Music"); - - // checkbox for capability - const int capY = statusY + ( itemRect.height() / 2 ); - QRect capCheckRect( statusX, capY - STATUS_ICON_SIZE / 2 + top, STATUS_ICON_SIZE, STATUS_ICON_SIZE ); - opt.rect = capCheckRect; - drawCheckBox( opt, painter, w ); - - // text to accompany checkbox - const int capW = statusFM.width( capString ); - const int capTextX = statusX - PADDING - capW; - painter->drawText( QRect( capTextX, capY - statusFM.height() / 2 + top, capW, statusFM.height() ) ); - - if ( capTextX < statusTextX ) - statusTextX = capTextX; - } - painter->restore(); - - // name - painter->save(); - painter->setFont( name ); - QFontMetrics namefm( name ); - // pos will the top-left point of the text rect - pos = mid - ( nameHeight / 2 ) + top; - // TODO bound with config icon and offline/online status - width = itemRect.width() - statusTextX; - QRect nameRect( textLeftEdge, pos, width, namefm.height() ); - painter->drawText( nameRect, index.data( AccountModel::AccountName ).toString() ); - - nameRect.translate( mid, 0 ); // move down by half the hight - painter->drawText( nameRect, index.data( AccountModel::DescText ).toString() ); - painter->restore(); - -} - -QRect -AccountDelegate::checkRectForIndex( const QStyleOptionViewItem &option, const QModelIndex &idx, int role ) const -{ - if ( role == Qt::CheckStateRole ) - { - // the whole resolver checkbox - QStyleOptionViewItemV4 opt = option; - initStyleOption( &opt, idx ); - const int mid = opt.rect.height() / 2; - const int pos = mid - ( ICONSIZE / 2 ); - QRect checkRect( CHECK_LEFT_EDGE, pos + opt.rect.top(), ICONSIZE, ICONSIZE ); - - return checkRect; - } else if ( role == AccountModel::BasicCapabilityRole ) - { - // The capabilities checkbox - QStyleOptionViewItemV4 opt = option; - initStyleOption( &opt, idx ); - const int quarter = opt.rect.height() / 4 + opt.rect.height() / 2; - const int leftEdge = opt.rect.width() - PADDING - WRENCH_SIZE - PADDING - WRENCH_SIZE; - QRect checkRect( leftEdge, quarter, WRENCH_SIZE, WRENCH_SIZE ); - return checkRect; - } - return QRect(); -} - -QRect -AccountDelegate::configRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const -{ - if( !idx.data( SipModel::FactoryItemRole ).toBool() && !idx.data( SipModel::FactoryRole ).toBool() ) - { - QStyleOptionViewItemV4 opt = option; - initStyleOption( &opt, idx ); - QRect itemRect = opt.rect; - QRect confRect = QRect( itemRect.width() - ICONSIZE - 2 * PADDING, (opt.rect.height() / 2) - ICONSIZE / 2 + opt.rect.top(), ICONSIZE, ICONSIZE ); - return confRect; - } - return QRect(); -} - - -QSize -AccountDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const -{ - return ConfigDelegateBase::sizeHint( option, index ); -} - -void -AccountDelegate::askedForEdit( const QModelIndex& idx ) -{ - emit openConfig( qobject_cast< SipPlugin* >( idx.data( SipModel::SipPluginData ).value< QObject* >() ) ); -} - - diff --git a/src/accounts/twitter/twitteraccount.h b/src/accounts/twitter/twitteraccount.h index ac7ad5c6e..a440f44bf 100644 --- a/src/accounts/twitter/twitteraccount.h +++ b/src/accounts/twitter/twitteraccount.h @@ -56,9 +56,10 @@ class DLLEXPORT TwitterAccount : public Account public: TwitterAccount( const QString &accountId ); virtual ~TwitterAccount(); - + QIcon icon() const { return QIcon( ":/twitter-icon.png" ); } + bool canSelfAuthenticate() const { return true; } void authenticate(); void deauthenticate(); bool isAuthenticated() const { return m_isAuthenticated; } @@ -81,7 +82,7 @@ signals: private slots: void configDialogAuthedSignalSlot( bool authed ); void connectAuthVerifyReply( const QTweetUser &user ); - + private: bool m_isAuthenticated; QWeakPointer< TomahawkOAuthTwitter > m_twitterAuth; diff --git a/src/accounts/xmpp/xmppaccount.h b/src/accounts/xmpp/xmppaccount.h index d7f54514e..9c0b314cf 100644 --- a/src/accounts/xmpp/xmppaccount.h +++ b/src/accounts/xmpp/xmppaccount.h @@ -59,6 +59,7 @@ public: QIcon icon() const { return QIcon( ":/xmpp-icon.png" ); } + bool canSelfAuthenticate() const { return false; } void authenticate(); void deauthenticate(); bool isAuthenticated() const { return m_isAuthenticated; } @@ -76,7 +77,7 @@ private: bool m_isAuthenticated; QWeakPointer< QWidget > m_configWidget; QWeakPointer< XmppSipPlugin > m_xmppSipPlugin; - + // for settings access friend class XmppConfigWidget; diff --git a/src/configdelegatebase.cpp b/src/configdelegatebase.cpp index bdf826bfc..ce6f2baae 100644 --- a/src/configdelegatebase.cpp +++ b/src/configdelegatebase.cpp @@ -25,8 +25,6 @@ #include "utils/tomahawkutils.h" #include "utils/logger.h" -#define ROW_HEIGHT 50 - ConfigDelegateBase::ConfigDelegateBase ( QObject* parent ) : QStyledItemDelegate ( parent ) { @@ -38,7 +36,23 @@ QSize ConfigDelegateBase::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const { int width = QStyledItemDelegate::sizeHint( option, index ).width(); - return QSize( width, ROW_HEIGHT ); + + QStyleOptionViewItemV4 opt = option; + initStyleOption( &opt, index ); + + + QFont name = opt.font; + name.setPointSize( name.pointSize() + 2 ); + name.setBold( true ); + + QFont path = opt.font; + path.setItalic( true ); + path.setPointSize( path.pointSize() - 1 ); + + + QFontMetrics bfm( name ); + QFontMetrics sfm( path ); + return QSize( width, 2 * PADDING + bfm.height() + sfm.height() ); } void @@ -80,24 +94,17 @@ ConfigDelegateBase::editorEvent ( QEvent* event, QAbstractItemModel* model, cons m_configPressed = QModelIndex(); QMouseEvent* me = static_cast< QMouseEvent* >( event ); - QList roles = QList() << (int)Qt::CheckStateRole; - roles.append( extraCheckRoles() ); + if( me->button() != Qt::LeftButton || !checkRectForIndex( option, index ).contains( me->pos() ) ) + return false; - foreach ( int role, roles ) - { - if( me->button() != Qt::LeftButton || !checkRectForIndex( option, index, role ).contains( me->pos() ) ) - return false; - - // eat the double click events inside the check rect - if( event->type() == QEvent::MouseButtonDblClick ) { - return true; - } - - Qt::CheckState curState = static_cast< Qt::CheckState >( index.data( role ).toInt() ); - Qt::CheckState newState = curState == Qt::Checked ? Qt::Unchecked : Qt::Checked; - return model->setData( index, newState, role ); + // eat the double click events inside the check rect + if( event->type() == QEvent::MouseButtonDblClick ) { + return true; } + Qt::CheckState curState = static_cast< Qt::CheckState >( index.data( Qt::CheckStateRole ).toInt() ); + Qt::CheckState newState = curState == Qt::Checked ? Qt::Unchecked : Qt::Checked; + return model->setData( index, newState, Qt::CheckStateRole ); } else if( event->type() == QEvent::MouseButtonPress ) { QMouseEvent* me = static_cast< QMouseEvent* >( event ); diff --git a/src/configdelegatebase.h b/src/configdelegatebase.h index 929467a00..d86baad1a 100644 --- a/src/configdelegatebase.h +++ b/src/configdelegatebase.h @@ -36,11 +36,10 @@ public: virtual bool editorEvent ( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index ); // if you want to use a checkbox, you need to have this say where to paint it - virtual QRect checkRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx, int role ) const = 0; + virtual QRect checkRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const = 0; // if you want to use a config wrench, you need to have this say where to paint it virtual QRect configRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const = 0; - virtual QList extraCheckRoles() const { return QList(); } signals: void configPressed( const QModelIndex& idx ); diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index 72e56e0d2..9be5e79e7 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -61,10 +61,10 @@ set( libSources accounts/accountmanager.cpp accounts/account.cpp - accounts/accountmodel.cpp sip/SipPlugin.cpp sip/SipHandler.cpp + sip/SipModel.cpp sip/sipinfo.cpp audio/audioengine.cpp @@ -286,12 +286,12 @@ set( libHeaders accounts/account.h accounts/accountmanager.h - accounts/accountmodel.h EchonestCatalogSynchronizer.h sip/SipPlugin.h sip/SipHandler.h + sip/SipModel.h sip/sipinfo.h audio/audioengine.h diff --git a/src/libtomahawk/accounts/account.h b/src/libtomahawk/accounts/account.h index 062cd51ef..c8c98c385 100644 --- a/src/libtomahawk/accounts/account.h +++ b/src/libtomahawk/accounts/account.h @@ -39,7 +39,7 @@ namespace InfoSystem { class InfoPlugin; } - + namespace Accounts { @@ -54,11 +54,8 @@ inline QString generateId( const QString &factoryId ) class DLLEXPORT Account : public QObject { Q_OBJECT - + public: - enum AuthErrorCode { AuthError, ConnectionError }; - enum ConnectionState { Disconnected, Connecting, Connected, Disconnecting }; - explicit Account( const QString &accountId ) : QObject() , m_enabled( false ) @@ -82,9 +79,9 @@ public: virtual QIcon icon() const = 0; + virtual bool canSelfAuthenticate() const = 0; virtual void authenticate() = 0; virtual void deauthenticate() = 0; - virtual ConnectionState connectionState() = 0;s virtual bool isAuthenticated() const = 0; virtual Tomahawk::InfoSystem::InfoPlugin* infoPlugin() = 0; @@ -136,8 +133,6 @@ public: virtual void sync() { QMutexLocker locker( &m_mutex ); syncConfig(); }; signals: - void connectionStateChanged( Tomahawk::Accounts::Account::ConnectionState state ); - void configurationChanged(); void authenticated( bool ); @@ -208,4 +203,4 @@ public: Q_DECLARE_INTERFACE( Tomahawk::Accounts::AccountFactory, "tomahawk.AccountFactory/1.0" ) -#endif +#endif \ No newline at end of file diff --git a/src/libtomahawk/accounts/accountmanager.cpp b/src/libtomahawk/accounts/accountmanager.cpp index 9e33b782c..b340ec4ab 100644 --- a/src/libtomahawk/accounts/accountmanager.cpp +++ b/src/libtomahawk/accounts/accountmanager.cpp @@ -187,8 +187,8 @@ AccountManager::addAccountPlugin( Account* account ) foreach( AccountType type, account->types() ) m_accountsByAccountType[ type ].append( account ); - - emit accountAdded( account ); + //TODO:? + //emit pluginAdded( account ); } diff --git a/src/libtomahawk/accounts/accountmanager.h b/src/libtomahawk/accounts/accountmanager.h index 3cb914042..8020c5759 100644 --- a/src/libtomahawk/accounts/accountmanager.h +++ b/src/libtomahawk/accounts/accountmanager.h @@ -52,12 +52,8 @@ public: Account* loadPlugin( const QString &accountId ); QString factoryFromId( const QString& accountId ) const; - QList< Account* > accounts() const { return m_accounts; }; - QList< Account* > accounts( Tomahawk::Accounts::AccountType type ) const { return m_accountsByAccountType[ type ]; } - -signals: - void accountAdded( Tomahawk::Accounts::Account* ); - void accountRemoved( Tomahawk::Accounts::Account* ); + QList< Account* > getAccounts() { return m_accounts; }; + QList< Account* > getAccounts( Tomahawk::Accounts::AccountType type ) { return m_accountsByAccountType[ type ]; } private: QList< Account* > m_accounts; @@ -71,4 +67,4 @@ private: }; -#endif +#endif \ No newline at end of file diff --git a/src/libtomahawk/accounts/accountmodel.cpp b/src/libtomahawk/accounts/accountmodel.cpp deleted file mode 100644 index 5bd33f293..000000000 --- a/src/libtomahawk/accounts/accountmodel.cpp +++ /dev/null @@ -1,155 +0,0 @@ - 4/* - Copyright (C) 2011 Leo Franchi - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - - -#include "accountmodel.h" - -#include "tomahawksettings.h" -#include "accounts/accountmanager.h" -#include "accounts/account.h" - -#include "utils/logger.h" - -using namespace Tomahawk; -using namespace Accounts; - -AccountModel::AccountModel( QObject* parent ) - : QAbstractListModel( parent ) -{ - connect( AccountManager::instance(), SIGNAL( accountAdded( Tomahawk::Accounts::Account* ) ), this, SLOT( accountAdded( Tomahawk::Accounts::Account* ) ) ); - connect( AccountManager::instance(), SIGNAL( accountRemoved( Tomahawk::Accounts::Account* ) ), this, SLOT( accountRemoved( Tomahawk::Accounts::Account* ) ) ); -} - - -AccountModel::~AccountModel() -{ -} - - -QVariant -AccountModel::data( const QModelIndex& index, int role ) const -{ - if( !index.isValid() ) - return QVariant(); - - QList< Account* > accounts = AccountManager::instance()->accounts(); - Q_ASSERT( index.row() <= accounts.size() ); - Account* account = accounts[ index.row() ]; - switch( role ) - { - case Qt::DisplayRole: - case AccountModel::AccountName: - return account->accountServiceName(); - case AccountModel::ConnectionStateRole: - return account->connectionState(); - case AccountModel::HasConfig: - return ( account->configurationWidget() != 0 ); - case Qt::DecorationRole: - return account->icon(); - case AccountModel::AccountData: - return QVariant::fromValue< QObject* >( account ); - case Qt::CheckStateRole: - return account->enabled() ? Qt::Checked : Qt::Unchecked; - default: - return QVariant(); - } - return QVariant(); -} - - -bool -AccountModel::setData( const QModelIndex& index, const QVariant& value, int role ) -{ - Q_ASSERT( index.isValid() && index.row() <= AccountManager::instance()->accounts().count() ); - - if ( role == Qt::CheckStateRole ) { - Qt::CheckState state = static_cast< Qt::CheckState >( value.toInt() ); - QList< Account* > accounts = AccountManager::instance()->accounts(); - Account* account = accounts[ index.row() ]; - - if( state == Qt::Checked && !account->enabled() ) { - account->setEnabled( true ); - } else if( state == Qt::Unchecked ) { - account->setEnabled( false ); - } - dataChanged( index, index ); - - return true; - } - else if ( role == BasicCapabilityRole ) - { - // TODO - } - return false; -} - -int -AccountModel::rowCount( const QModelIndex& parent ) const -{ - return AccountManager::instance()->accounts().size(); -} - -Qt::ItemFlags -AccountModel::flags( const QModelIndex& index ) const -{ - return QAbstractListModel::flags( index ) | Qt::ItemIsUserCheckable; -} - - -void -AccountModel::accountAdded( Account* account ) -{ - Q_UNUSED( p ); - // we assume account plugins are added at the end of the list. - Q_ASSERT( AccountManager::instance()->accounts().last() == account ); - if ( account->types().contains( SipType ) ) - connect( account->sipPlugin(), SIGNAL( stateChanged( SipPlugin::ConnectionState ) ), this, SLOT( sipStateChanged( SipPlugin::ConnectionState ) ) ); - - int size = AccountManager::instance()->accounts().count() - 1; - beginInsertRows( QModelIndex(), size, size ); - endInsertRows(); -} - - -void -AccountModel::accountRemoved( Account* account ) -{ - int idx = AccountManager::instance()->allPlugins().indexOf( account ); - beginRemoveRows( QModelIndex(), idx, idx ); - endRemoveRows(); -} - - -void -AccountModel::sipStateChanged( SipPlugin::ConnectionState state ) -{ - SipPlugin* p = qobject_cast< SipPlugin* >( sender() ); - Q_ASSERT( a ); - - for ( int i = 0; i < AccountManager::instance()->accounts().size(); i++ ) - { - if ( AccountManager::instance()->accounts()[i] && - AccountManager::instance()->accounts()[i]->sipPlugin() && - AccountManager::instance()->accounts()[i]->sipPlugin() == p ) - { - QModelIndex idx = index( i, 0, QModelIndex() ); - emit dataChanged( idx, idx ); - return; - } - } -} - diff --git a/src/libtomahawk/sip/SipHandler.cpp b/src/libtomahawk/sip/SipHandler.cpp index 7254eb229..5c9c4d496 100644 --- a/src/libtomahawk/sip/SipHandler.cpp +++ b/src/libtomahawk/sip/SipHandler.cpp @@ -174,7 +174,7 @@ void SipHandler::loadFromAccountManager() { tDebug() << Q_FUNC_INFO; - QList< Tomahawk::Accounts::Account* > accountList = Tomahawk::Accounts::AccountManager::instance()->accounts( Tomahawk::Accounts::SipType ); + QList< Tomahawk::Accounts::Account* > accountList = Tomahawk::Accounts::AccountManager::instance()->getAccounts( Tomahawk::Accounts::SipType ); foreach( Tomahawk::Accounts::Account* account, accountList ) { tDebug() << Q_FUNC_INFO << "adding plugin " << account->accountId(); diff --git a/src/libtomahawk/sip/SipModel.cpp b/src/libtomahawk/sip/SipModel.cpp new file mode 100644 index 000000000..093d81c88 --- /dev/null +++ b/src/libtomahawk/sip/SipModel.cpp @@ -0,0 +1,227 @@ +/* + Copyright (C) 2011 Leo Franchi + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + + +#include "SipModel.h" + +#include "tomahawksettings.h" +#include "sip/SipHandler.h" +#include "sip/SipPlugin.h" + +#include "utils/logger.h" + + +SipModel::SipModel( QObject* parent ) + : QAbstractItemModel( parent ) +{ + connect( SipHandler::instance(), SIGNAL( stateChanged( SipPlugin*, SipPlugin::ConnectionState ) ), this, SLOT( pluginStateChanged( SipPlugin* ) ) ); + connect( SipHandler::instance(), SIGNAL( pluginAdded( SipPlugin* ) ), this, SLOT( pluginAdded( SipPlugin* ) ) ); + connect( SipHandler::instance(), SIGNAL( pluginRemoved( SipPlugin* ) ), this, SLOT( pluginRemoved( SipPlugin* ) ) ); + + // TODO disable inline factories for now + /* + foreach( SipPluginFactory* f, SipHandler::instance()->pluginFactories() ) { + if( f->isCreatable() ) + m_factories << f; + } */ + +} + + +SipModel::~SipModel() +{ +} + + +QVariant +SipModel::data( const QModelIndex& index, int role ) const +{ + if( !index.isValid() ) + return QVariant(); + + if( !index.parent().isValid() && index.row() == SipHandler::instance()->allPlugins().count() ) { // last row, this is the factory + if( role == Qt::DisplayRole ) + return tr( "Add New Account..." ); + else if( role == FactoryRole ) + return true; + else + return QVariant(); + } + + if( !index.parent().isValid() ) { // account + QList< SipPlugin* > plugins = SipHandler::instance()->allPlugins(); + Q_ASSERT( index.row() <= plugins.size() ); + SipPlugin* p = plugins[ index.row() ]; + switch( role ) + { + case Qt::DisplayRole: + case SipModel::PluginName: + return p->account()->accountServiceName(); + case SipModel::ConnectionStateRole: + return p->connectionState(); + case SipModel::HasConfig: + return ( p->account()->configurationWidget() != 0 ); + case SipModel::FactoryRole: + return false; + case Qt::DecorationRole: + return p->icon(); + case SipModel::SipPluginData: + return QVariant::fromValue< QObject* >( p ); + case Qt::CheckStateRole: + return p->account()->enabled() ? Qt::Checked : Qt::Unchecked; + default: + return QVariant(); + } + } + + /* + * m_factories never actually populated yet, so just disable + if( index.parent().isValid() ) { // this is a factory type + SipPluginFactory* p = m_factories.at( index.row() ); + switch( role ) + { + case Qt::DisplayRole: + return p->prettyName(); + case SipModel::FactoryItemRole: + return true; + case SipModel::FactoryItemIcon: + return p->icon(); + case SipModel::SipPluginFactoryData: + return QVariant::fromValue< QObject* >( p ); + default: + return QVariant(); + } + } + */ + return QVariant(); +} + + +bool +SipModel::setData( const QModelIndex& index, const QVariant& value, int role ) +{ + Q_ASSERT( index.isValid() && index.row() <= SipHandler::instance()->allPlugins().count() ); + + if( role == Qt::CheckStateRole ) { + Qt::CheckState state = static_cast< Qt::CheckState >( value.toInt() ); + QList< SipPlugin* > plugins = SipHandler::instance()->allPlugins(); + SipPlugin* p = plugins[ index.row() ]; + + if( state == Qt::Checked && !p->account()->enabled() ) { + p->account()->setEnabled( true ); + } else if( state == Qt::Unchecked ) { + p->account()->setEnabled( false ); + } + dataChanged( index, index ); + + return true; + } + return false; +} + + +QModelIndex +SipModel::index( int row, int column, const QModelIndex& parent ) const +{ + if( !parent.isValid() ) + return hasIndex( row, column, parent ) ? createIndex( row, column, 0 ) : QModelIndex(); + +// qDebug() << "Creating index for non-top level row!"; + // it's a child of the Add Account, e.g. a factory + if( hasIndex( row, column, parent ) ) { + return createIndex( row, column, 1 /* magic */ ); + } + + return QModelIndex(); +} + + +QModelIndex +SipModel::parent( const QModelIndex& child ) const +{ + if( !child.isValid() ) + return QModelIndex(); + + if( child.internalId() == 1 ) { + return index( SipHandler::instance()->allPlugins().size(), 0, QModelIndex() ); + } + + return QModelIndex(); +} + + +int +SipModel::rowCount( const QModelIndex& parent ) const +{ + if( !parent.isValid() ) // invalid root node + return SipHandler::instance()->allPlugins().size() /* TODO inline factories disabled + 1*/; + if( parent.isValid() && !parent.parent().isValid() ) { // top level item + if( parent.row() == SipHandler::instance()->allPlugins().count() ) {// last row, this is the factory + //return m_factories.count(); + } + } + + return 0; +} + + +int +SipModel::columnCount(const QModelIndex& parent) const +{ + Q_UNUSED( parent ); + return 1; +} + + +Qt::ItemFlags +SipModel::flags( const QModelIndex& index ) const +{ + if( index.data( SipModel::FactoryRole ).toBool() || index.data( SipModel::FactoryItemRole ).toBool() ) + return QAbstractItemModel::flags( index ) & ~Qt::ItemIsSelectable; + return QAbstractItemModel::flags( index ) | Qt::ItemIsUserCheckable; +} + + +void +SipModel::pluginAdded( SipPlugin* p ) +{ + Q_UNUSED( p ); + // we assume sip plugins are added at the end of the list. + Q_ASSERT( SipHandler::instance()->allPlugins().last() == p ); + int size = SipHandler::instance()->allPlugins().count() - 1; + beginInsertRows( QModelIndex(), size, size ); + endInsertRows(); +} + + +void +SipModel::pluginRemoved( SipPlugin* p ) +{ + int idx = SipHandler::instance()->allPlugins().indexOf( p ); + beginRemoveRows( QModelIndex(), idx, idx ); + endRemoveRows(); +} + + +void +SipModel::pluginStateChanged( SipPlugin* p ) +{ + int at = SipHandler::instance()->allPlugins().indexOf( p ); + QModelIndex idx = index( at, 0, QModelIndex() ); + emit dataChanged( idx, idx ); +} + diff --git a/src/libtomahawk/accounts/accountmodel.h b/src/libtomahawk/sip/SipModel.h similarity index 56% rename from src/libtomahawk/accounts/accountmodel.h rename to src/libtomahawk/sip/SipModel.h index 9f02363d2..7f4901032 100644 --- a/src/libtomahawk/accounts/accountmodel.h +++ b/src/libtomahawk/sip/SipModel.h @@ -1,4 +1,5 @@ /* + Copyright (C) 2011 Leo Franchi This program is free software: you can redistribute it and/or modify @@ -20,57 +21,43 @@ #define SIPMODEL_H #include "dllmacro.h" -#include "sip/SipPlugin.h" #include #include -namespace Tomahawk -{ -namespace Accounts -{ +class SipPlugin; -class Account; - -class DLLEXPORT AccountModel : public QAbstractListModel +class DLLEXPORT SipModel : public QAbstractItemModel { Q_OBJECT public: - enum BasicCapabilities - { - NoCapabilities = 0, - SipCapability = 0x1, - ResolverCapability = 0x2 - }; - enum Roles { - AccountName = Qt::UserRole + 15, - AccountIcon = Qt::UserRole + 16, - HeadlineText = Qt::UserRole + 17, - DescText = Qt::UserRole + 18, - BasicCapabilityRole = Qt::UserRole + 19, - ConnectionStateRole = Qt::UserRole + 20, - HasConfig = Qt::UserRole + 21, - ErrorString = Qt::UserRole + 22, - AccountData = Qt::UserRole + 23 // raw plugin + PluginName = Qt::UserRole + 15, + ConnectionStateRole = Qt::UserRole + 17, + HasConfig = Qt::UserRole + 18, + FactoryRole = Qt::UserRole + 19, + ErrorString = Qt::UserRole + 20, + FactoryItemRole = Qt::UserRole + 21, + FactoryItemIcon = Qt::UserRole + 22, + SipPluginData = Qt::UserRole + 23, + SipPluginFactoryData = Qt::UserRole + 24 }; - explicit AccountModel( QObject* parent = 0 ); - virtual ~AccountModel(); + explicit SipModel( QObject* parent = 0 ); + virtual ~SipModel(); + virtual QModelIndex index ( int row, int column, const QModelIndex& parent = QModelIndex() ) const; + virtual QModelIndex parent ( const QModelIndex& child ) const; virtual QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const; virtual int rowCount( const QModelIndex& parent = QModelIndex() ) const; + virtual int columnCount( const QModelIndex& parent ) const; virtual Qt::ItemFlags flags(const QModelIndex& index) const; virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole); private slots: - void accountAdded( Tomahawk::Accounts::Account* p ); - void accountRemoved( Tomahawk::Accounts::Account* p ); - void sipStateChanged( SipPlugin::ConnectionState state ); + void pluginAdded( SipPlugin* p ); + void pluginRemoved( SipPlugin* p ); + void pluginStateChanged( SipPlugin* p ); }; -} - -} - #endif // SIPMODEL_H diff --git a/src/libtomahawk/sip/SipPlugin.h b/src/libtomahawk/sip/SipPlugin.h index 5cb1ec7de..f0b591aa6 100644 --- a/src/libtomahawk/sip/SipPlugin.h +++ b/src/libtomahawk/sip/SipPlugin.h @@ -40,6 +40,9 @@ class DLLEXPORT SipPlugin : public QObject Q_OBJECT public: + enum SipErrorCode { AuthError, ConnectionError }; // Placeholder for errors, to be defined + enum ConnectionState { Disconnected, Connecting, Connected, Disconnecting }; + SipPlugin(); explicit SipPlugin( Tomahawk::Accounts::Account *account, QObject* parent = 0 ); virtual ~SipPlugin(); @@ -104,7 +107,7 @@ private slots: protected: Tomahawk::Accounts::Account *m_account; - + private: QString m_cachedError; QStringList m_peersOnline; diff --git a/src/sipconfigdelegate.cpp b/src/sipconfigdelegate.cpp new file mode 100644 index 000000000..20cfcb891 --- /dev/null +++ b/src/sipconfigdelegate.cpp @@ -0,0 +1,282 @@ +/* + Copyright (C) 2011 Leo Franchi + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + + +#include "sipconfigdelegate.h" + +#include +#include + +#include "sip/SipModel.h" +#include "sip/SipPlugin.h" + +#include "utils/tomahawkutils.h" +#include "utils/logger.h" + +#define ICONSIZE 24 +#define CHECK_LEFT_EDGE 8 + + +SipConfigDelegate::SipConfigDelegate( QObject* parent ) + : ConfigDelegateBase ( parent ) +{ + connect( this, SIGNAL( configPressed( QModelIndex ) ), this, SLOT( askedForEdit( QModelIndex ) ) ); +} + +bool +SipConfigDelegate::editorEvent ( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index ) +{ + return ConfigDelegateBase::editorEvent( event, model, option, index ); +} + +void +SipConfigDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const +{ + QStyleOptionViewItemV4 opt = option; + initStyleOption( &opt, index ); + QRect itemRect = opt.rect; + int top = itemRect.top(); + int mid = itemRect.height() / 2; + + // one line bold for account name + // space below it fro an error + // checkbox, icon, name, online/offline status, config icon + QFont name = opt.font; + name.setPointSize( name.pointSize() + 2 ); + name.setBold( true ); + + QFont error = opt.font; + error.setItalic( true ); + error.setPointSize( error.pointSize() - 2 ); + + // draw the background + const QWidget* w = opt.widget; + QStyle* style = w ? w->style() : QApplication::style(); + style->drawPrimitive( QStyle::PE_PanelItemViewItem, &opt, painter, w ); + + int iconLeftEdge = CHECK_LEFT_EDGE + ICONSIZE + PADDING; + int textLeftEdge = iconLeftEdge + ICONSIZE + PADDING; + + if( index.data( SipModel::FactoryRole ).toBool() ) { // this is the "add new account" row + // draw a border and background + painter->save(); + painter->setRenderHints( QPainter::Antialiasing ); + painter->setBrush( QApplication::palette().color( QPalette::Active, QPalette::Highlight ).lighter( 150 ) ); + QPainterPath roundedRect; + roundedRect.addRoundedRect( itemRect.adjusted( 1, 1, -1, -1 ), 3, 3 ); + painter->drawPath( roundedRect ); + painter->setBrush( QApplication::palette().color( QPalette::Active, QPalette::Highlight ).lighter( 170 ) ); + painter->fillPath( roundedRect, painter->brush() ); + painter->restore(); + + // draw "+" icon in checkbox column + int rectW = 18; + int diff = ( ICONSIZE/ 2 ) - ( rectW / 2) ; + int pos = ( mid ) - ( rectW / 2 ); + QRect plusRect = QRect( CHECK_LEFT_EDGE + diff, pos + top, rectW, rectW ); + QPixmap p( RESPATH "images/list-add.png" ); + painter->drawPixmap( plusRect, p ); + + // draw text + QFont f = opt.font; + f.setPointSize( f.pointSize() ); + f.setBold( true ); + QFontMetrics fm( f ); + QString text = index.data( Qt::DisplayRole ).toString(); + QRect textR = fm.boundingRect( text ); + textR.moveLeft( textLeftEdge ); + textR.moveTop( mid - ( textR.height() / 2 ) + top ); + textR.setRight( itemRect.right() ); + painter->setFont( f ); + painter->drawText( textR, text ); + } else if( index.data( SipModel::FactoryItemRole ).toBool() ) { // this is an account type + +// ConfigDelegateBase::paint( painter, opt, index ); +// int indent = 10; + // draw a border and background + painter->save(); + painter->setRenderHints( QPainter::Antialiasing ); + painter->setBrush( QApplication::palette().color( QPalette::Active, QPalette::Highlight ).lighter( 170 ) ); + QPainterPath roundedRect; + roundedRect.addRoundedRect( itemRect.adjusted( 1, 1, -1, -1 ), 3, 3 ); + painter->drawPath( roundedRect ); + painter->setBrush( QApplication::palette().color( QPalette::Active, QPalette::Highlight ).lighter( 180 ) ); + painter->fillPath( roundedRect, painter->brush() ); + painter->restore(); + + QIcon icon = index.data( SipModel::FactoryItemIcon ).value< QIcon >(); + if( !icon.isNull() ) { + int rectW = 18; + int diff = ( ICONSIZE/ 2 ) - ( rectW / 2) ; + int pos = ( mid ) - ( rectW / 2 ); + QRect rect = QRect( CHECK_LEFT_EDGE + diff, pos + top, rectW, rectW ); + QPixmap p( icon.pixmap( rect.size() ) ); + painter->drawPixmap( rect, p ); + } + + // draw text + QFont f = opt.font; + f.setPointSize( f.pointSize() ); + f.setBold( true ); + QFontMetrics fm( f ); + QString text = index.data( Qt::DisplayRole ).toString(); + QRect textR = fm.boundingRect( text ); + textR.moveLeft( textLeftEdge ); + textR.moveTop( mid - ( textR.height() / 2 ) + top ); + textR.setRight( itemRect.right() ); + painter->setFont( f ); + painter->drawText( textR, text ); + } else { // this is an existing account to show + // draw checkbox first + int pos = ( mid ) - ( ICONSIZE / 2 ); + QRect checkRect = QRect( CHECK_LEFT_EDGE, pos + top, ICONSIZE, ICONSIZE ); + opt.rect = checkRect; + drawCheckBox( opt, painter, w ); + + // draw the icon if it exists + pos = ( mid ) - ( ICONSIZE / 2 ); + if( !index.data( Qt::DecorationRole ).value< QIcon >().isNull() ) { + QRect prect = QRect( iconLeftEdge, pos + top, ICONSIZE, ICONSIZE ); + + painter->save(); + painter->drawPixmap( prect, index.data( Qt::DecorationRole ).value< QIcon >().pixmap( prect.size() ) ); + painter->restore(); + } + + // from the right edge--config status and online/offline + QRect confRect = QRect( itemRect.width() - ICONSIZE - 2 * PADDING, mid - ICONSIZE / 2 + top, ICONSIZE, ICONSIZE ); + if( index.data( SipModel::HasConfig ).toBool() ) { + + QStyleOptionToolButton topt; + topt.rect = confRect; + topt.pos = confRect.topLeft(); + + drawConfigWrench( painter, opt, topt ); + } + + // draw the online/offline status + int statusIconSize = 18; + int statusX = confRect.left() - 2*PADDING - statusIconSize; + QFont statusF = opt.font; + statusF.setPointSize( statusF.pointSize() - 2 ); + QFontMetrics statusFM( statusF ); + + QPixmap p; + QString statusText; + SipPlugin::ConnectionState state = static_cast< SipPlugin::ConnectionState >( index.data( SipModel::ConnectionStateRole ).toInt() ); + if( state == SipPlugin::Connected ) { + p = QPixmap( RESPATH "images/sipplugin-online.png" ); + statusText = tr( "Online" ); + } else if( state == SipPlugin::Connecting ) { + p = QPixmap( RESPATH "images/sipplugin-offline.png" ); + statusText = tr( "Connecting..." ); + } else { + p = QPixmap( RESPATH "images/sipplugin-offline.png" ); + statusText = tr( "Offline" ); + } + p = p.scaled( statusIconSize, statusIconSize, Qt::KeepAspectRatio, Qt::SmoothTransformation ); + painter->drawPixmap( statusX, mid - statusIconSize / 2 + top, statusIconSize, statusIconSize, p ); + int width = statusFM.width( statusText ); + statusX = statusX - PADDING - width; + painter->save(); + painter->setFont( statusF ); + painter->drawText( QRect( statusX, mid - statusFM.height() / 2 + top, width, statusFM.height() ), statusText ); + painter->restore(); + + // name + painter->save(); + QFontMetrics namefm( name ); + int nameHeight = namefm.boundingRect( "test" ).height(); + // pos will the top-left point of the text rect + pos = mid - ( nameHeight / 2 ); + // TODO bound with config icon and offline/online status + width = itemRect.width() - textLeftEdge; + + if( !index.data( SipModel::ErrorString ).toString().isEmpty() ) { // error, show that too + QRect errorRect( textLeftEdge, mid + top, width, mid - PADDING + 1 ); + + QFontMetrics errorFm( error ); + QString str = errorFm.elidedText( index.data( SipModel::ErrorString ).toString(), Qt::ElideRight, errorRect.width() ); + painter->setFont( error ); + painter->drawText( errorRect, str ); + + pos = mid - errorRect.height() - 2; // move the name rect up + } + QString nameStr = namefm.elidedText( index.data( Qt::DisplayRole ).toString(), Qt::ElideRight, width ); + painter->setFont( name ); + painter->drawText( QRect( textLeftEdge, pos + top, width, nameHeight + 1 ), nameStr ); + painter->restore(); + } +} + +QRect +SipConfigDelegate::checkRectForIndex( const QStyleOptionViewItem &option, const QModelIndex &idx ) const +{ + if( !idx.data( SipModel::FactoryItemRole ).toBool() && !idx.data( SipModel::FactoryRole ).toBool() ) + { + QStyleOptionViewItemV4 opt = option; + initStyleOption( &opt, idx ); + int mid = opt.rect.height() / 2; + int pos = ( mid ) - ( ICONSIZE / 2 ); + QRect checkRect = QRect( CHECK_LEFT_EDGE, pos + opt.rect.top(), ICONSIZE, ICONSIZE ); + + return checkRect; + } + return QRect(); +} + +QRect +SipConfigDelegate::configRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const +{ + if( !idx.data( SipModel::FactoryItemRole ).toBool() && !idx.data( SipModel::FactoryRole ).toBool() ) + { + QStyleOptionViewItemV4 opt = option; + initStyleOption( &opt, idx ); + QRect itemRect = opt.rect; + QRect confRect = QRect( itemRect.width() - ICONSIZE - 2 * PADDING, (opt.rect.height() / 2) - ICONSIZE / 2 + opt.rect.top(), ICONSIZE, ICONSIZE ); + return confRect; + } + return QRect(); +} + + +QSize +SipConfigDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const +{ + if( index.data( SipModel::FactoryRole ).toBool() || index.data( SipModel::FactoryItemRole ).toBool() ) { // this is the "add new account" row + // enough space for one line of text + QStyleOptionViewItemV4 opt = option; + initStyleOption( &opt, index ); + int width = QStyledItemDelegate::sizeHint( option, index ).width(); + + QFont name = opt.font; + name.setPointSize( name.pointSize() + 1 ); + name.setBold( true ); + QFontMetrics sfm( name ); + return QSize( width, 3 * PADDING + sfm.height() ); + } else { // this is an existing account to show + return ConfigDelegateBase::sizeHint( option, index ); + } +} + +void +SipConfigDelegate::askedForEdit( const QModelIndex& idx ) +{ + emit openConfig( qobject_cast< SipPlugin* >( idx.data( SipModel::SipPluginData ).value< QObject* >() ) ); +} + + diff --git a/src/accountdelegate.h b/src/sipconfigdelegate.h similarity index 80% rename from src/accountdelegate.h rename to src/sipconfigdelegate.h index e1fba2092..cccc82a61 100644 --- a/src/accountdelegate.h +++ b/src/sipconfigdelegate.h @@ -21,35 +21,26 @@ #include "configdelegatebase.h" -namespace Tomahawk -{ -namespace Accounts -{ - -class Account; - -class AccountDelegate : public ConfigDelegateBase +class SipPlugin; +class SipPluginFactory; +class SipConfigDelegate : public ConfigDelegateBase { Q_OBJECT public: - AccountDelegate( QObject* parent = 0); + SipConfigDelegate( QObject* parent = 0); virtual void paint ( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const; virtual bool editorEvent ( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index ); virtual QSize sizeHint ( const QStyleOptionViewItem& option, const QModelIndex& index ) const; - virtual QRect checkRectForIndex( const QStyleOptionViewItem &option, const QModelIndex &idx, int role ) const; + virtual QRect checkRectForIndex( const QStyleOptionViewItem &option, const QModelIndex &idx ) const; virtual QRect configRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const; - - virtual QList extraCheckRoles() const { return QList() << (int)AccountModel::BasicCapabilityRole; } private slots: void askedForEdit( const QModelIndex& idx ); signals: - void openConfig( Account* ); + void sipFactoryClicked( SipPluginFactory* ); + void openConfig( SipPlugin* ); }; -} -} - #endif // SIPCONFIGDELEGATE_H diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index 18194dff8..6e48af576 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -505,7 +505,7 @@ void TomahawkApp::initSIP() { tDebug() << Q_FUNC_INFO; - foreach ( Tomahawk::Accounts::Account* account, Tomahawk::Accounts::AccountManager::instance()->accounts() ) + foreach ( Tomahawk::Accounts::Account* account, Tomahawk::Accounts::AccountManager::instance()->getAccounts() ) { tDebug() << Q_FUNC_INFO << "testing account with name " << account->accountServiceName(); if ( account->configurationWidget() && account->configuration().isEmpty() ) From 328d055ee16a0e35db310a556a397aab4d1f5a80 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Mon, 28 Nov 2011 13:17:27 -0500 Subject: [PATCH 020/104] some work --- src/AccountDelegate.cpp | 235 +++++++++++++++ ...{sipconfigdelegate.h => AccountDelegate.h} | 29 +- src/CMakeLists.txt | 4 +- src/accounts/twitter/twitteraccount.cpp | 10 +- src/accounts/twitter/twitteraccount.h | 5 +- src/accounts/xmpp/xmppaccount.h | 3 +- src/configdelegatebase.cpp | 43 ++- src/configdelegatebase.h | 3 +- src/libtomahawk/CMakeLists.txt | 14 +- .../accounts/{account.cpp => Account.cpp} | 20 +- .../accounts/{account.h => Account.h} | 35 ++- ...{accountmanager.cpp => AccountManager.cpp} | 13 +- .../{accountmanager.h => AccountManager.h} | 26 +- src/libtomahawk/accounts/AccountModel.cpp | 153 ++++++++++ .../SipModel.h => accounts/AccountModel.h} | 55 ++-- src/libtomahawk/database/databaseworker.cpp | 1 + src/libtomahawk/sip/SipHandler.cpp | 7 +- src/libtomahawk/sip/SipHandler.h | 8 +- src/libtomahawk/sip/SipModel.cpp | 227 -------------- src/libtomahawk/sip/SipPlugin.cpp | 4 - src/libtomahawk/sip/SipPlugin.h | 16 +- src/settingsdialog.cpp | 8 +- src/sipconfigdelegate.cpp | 282 ------------------ src/tomahawkapp.cpp | 7 +- 24 files changed, 556 insertions(+), 652 deletions(-) create mode 100644 src/AccountDelegate.cpp rename src/{sipconfigdelegate.h => AccountDelegate.h} (75%) rename src/libtomahawk/accounts/{account.cpp => Account.cpp} (67%) rename src/libtomahawk/accounts/{account.h => Account.h} (89%) rename src/libtomahawk/accounts/{accountmanager.cpp => AccountManager.cpp} (97%) rename src/libtomahawk/accounts/{accountmanager.h => AccountManager.h} (77%) create mode 100644 src/libtomahawk/accounts/AccountModel.cpp rename src/libtomahawk/{sip/SipModel.h => accounts/AccountModel.h} (56%) delete mode 100644 src/libtomahawk/sip/SipModel.cpp delete mode 100644 src/sipconfigdelegate.cpp diff --git a/src/AccountDelegate.cpp b/src/AccountDelegate.cpp new file mode 100644 index 000000000..de1199013 --- /dev/null +++ b/src/AccountDelegate.cpp @@ -0,0 +1,235 @@ +/* + Copyright (C) 2011 Leo Franchi + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + + +#include "AccountDelegate.h" + +#include +#include + +#include "accounts/AccountModel.h" +#include "accounts/Account.h" + +#include "utils/tomahawkutils.h" +#include "utils/logger.h" + +#define ICONSIZE 36 +#define WRENCH_SIZE 24 +#define STATUS_ICON_SIZE 18 +#define CHECK_LEFT_EDGE 8 + +using namespace Tomahawk; +using namespace Accounts; + +AccountDelegate::AccountDelegate( QObject* parent ) + : ConfigDelegateBase ( parent ) +{ + connect( this, SIGNAL( configPressed( QModelIndex ) ), this, SLOT( askedForEdit( QModelIndex ) ) ); +} + +bool +AccountDelegate::editorEvent ( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index ) +{ + return ConfigDelegateBase::editorEvent( event, model, option, index ); +} + +void +AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const +{ + QStyleOptionViewItemV4 opt = option; + initStyleOption( &opt, index ); + const QRect itemRect = opt.rect; + const int top = itemRect.top(); + const int mid = itemRect.height() / 2; + + // one line bold for account name + // space below it for account description + // checkbox, icon, name, online/offline status, config icon + QFont name = opt.font; + name.setPointSize( name.pointSize() + 2 ); + name.setBold( true ); + + QFont desc = opt.font; + desc.setItalic( true ); + desc.setPointSize( error.pointSize() - 2 ); + + // draw the background + const QWidget* w = opt.widget; + QStyle* style = w ? w->style() : QApplication::style(); + style->drawPrimitive( QStyle::PE_PanelItemViewItem, &opt, painter, w ); + + int iconLeftEdge = CHECK_LEFT_EDGE + ICONSIZE + PADDING; + int textLeftEdge = iconLeftEdge + ICONSIZE + PADDING; + + // draw checkbox first + int pos = ( mid ) - ( WRENCH_SIZE / 2 ); + QRect checkRect = QRect( CHECK_LEFT_EDGE, pos + top, WRENCH_SIZE, WRENCH_SIZE ); + opt.rect = checkRect; + drawCheckBox( opt, painter, w ); + + // draw the icon if it exists + pos = mid - ( ICONSIZE / 2 ); + if( !index.data( Qt::DecorationRole ).value< QIcon >().isNull() ) { + QRect prect = QRect( iconLeftEdge, pos + top, ICONSIZE, ICONSIZE ); + + painter->save(); + painter->drawPixmap( prect, index.data( Qt::DecorationRole ).value< QIcon >().pixmap( prect.size() ) ); + painter->restore(); + } + + // from the right edge--config status and online/offline + QRect confRect = QRect( itemRect.width() - WRENCH_SIZE - 2 * PADDING, mid - WRENCH_SIZE / 2 + top, WRENCH_SIZE, WRENCH_SIZE ); + if( index.data( SipModel::HasConfig ).toBool() ) { + + QStyleOptionToolButton topt; + topt.rect = confRect; + topt.pos = confRect.topLeft(); + + drawConfigWrench( painter, opt, topt ); + } + + + // draw the online/offline status + const bool hasCapability = ( static_cast< AccountModel::BasicCapabilities >( index.data( AccountModel::BasicCapabilityRole ).toInt() ) != AccountModel::NoCapabilities ); + const int quarter = mid - ( itemRect.height() / 4 ); + const int statusY = hasCapability ? quarter : mid; + const int statusX = confRect.left() - 2*PADDING - STATUS_ICON_SIZE; + + QFont statusF = opt.font; + statusF.setPointSize( statusF.pointSize() - 2 ); + QFontMetrics statusFM( statusF ); + + QPixmap p; + QString statusText; + Account::ConnectionState state = static_cast< Account::ConnectionState >( index.data( AccountModel::ConnectionStateRole ).toInt() ); + if( state == SipPlugin::Connected ) { + p = QPixmap( RESPATH "images/sipplugin-online.png" ); + statusText = tr( "Online" ); + } else if( state == SipPlugin::Connecting ) { + p = QPixmap( RESPATH "images/sipplugin-offline.png" ); + statusText = tr( "Connecting..." ); + } else { + p = QPixmap( RESPATH "images/sipplugin-offline.png" ); + statusText = tr( "Offline" ); + } + p = p.scaled( STATUS_ICON_SIZE, STATUS_ICON_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation ); + painter->drawPixmap( statusX, statusY - STATUS_ICON_SIZE / 2 + top, STATUS_ICON_SIZE, STATUS_ICON_SIZE, p ); + const int width = statusFM.width( statusText ); + int statusTextX = statusX - PADDING - width; + painter->save(); + painter->setFont( statusF ); + painter->drawText( QRect( statusTextX, statusY - statusFM.height() / 2 + top, width, statusFM.height() ), statusText ); + + // draw optional capability text if it exists + if ( hasCapability ) + { + QString capString; + AccountModel::BasicCapabilities cap = static_cast< AccountModel::BasicCapabilities >( index.data( AccountModel::BasicCapabilityRole ).toInt() ); + if ( ( cap & AccountModel::SipCapability ) && ( cap & AccountModel::ResolverCapability ) ) + capString = tr( "Connect to and play from friends" ); + else if ( cap & AccountModel::SipCapability ) + capString = tr( "Connect to friends" ); + else if ( cap & AccountModel::ResolverCapability ) + capString = tr( "Find Music"); + + // checkbox for capability + const int capY = statusY + ( itemRect.height() / 2 ); + QRect capCheckRect( statusX, capY - STATUS_ICON_SIZE / 2 + top, STATUS_ICON_SIZE, STATUS_ICON_SIZE ); + opt.rect = capCheckRect; + drawCheckBox( opt, painter, w ); + + // text to accompany checkbox + const int capW = statusFM.width( capString ); + const int capTextX = statusX - PADDING - capW; + painter->drawText( QRect( capTextX, capY - statusFM.height() / 2 + top, capW, statusFM.height() ) ); + + if ( capTextX < statusTextX ) + statusTextX = capTextX; + } + painter->restore(); + + // name + painter->save(); + painter->setFont( name ); + QFontMetrics namefm( name ); + // pos will the top-left point of the text rect + pos = mid - ( nameHeight / 2 ) + top; + // TODO bound with config icon and offline/online status + width = itemRect.width() - statusTextX; + QRect nameRect( textLeftEdge, pos, width, namefm.height() ); + painter->drawText( nameRect, index.data( AccountModel::AccountName ).toString() ); + + nameRect.translate( mid, 0 ); // move down by half the hight + painter->drawText( nameRect, index.data( AccountModel::DescText ).toString() ); + painter->restore(); + +} + +QRect +AccountDelegate::checkRectForIndex( const QStyleOptionViewItem &option, const QModelIndex &idx, int role ) const +{ + if ( role == Qt::CheckStateRole ) + { + // the whole resolver checkbox + QStyleOptionViewItemV4 opt = option; + initStyleOption( &opt, idx ); + const int mid = opt.rect.height() / 2; + const int pos = mid - ( ICONSIZE / 2 ); + QRect checkRect( CHECK_LEFT_EDGE, pos + opt.rect.top(), ICONSIZE, ICONSIZE ); + + return checkRect; + } else if ( role == AccountModel::BasicCapabilityRole ) + { + // The capabilities checkbox + QStyleOptionViewItemV4 opt = option; + initStyleOption( &opt, idx ); + const int quarter = opt.rect.height() / 4 + opt.rect.height() / 2; + const int leftEdge = opt.rect.width() - PADDING - WRENCH_SIZE - PADDING - WRENCH_SIZE; + QRect checkRect( leftEdge, quarter, WRENCH_SIZE, WRENCH_SIZE ); + return checkRect; + } + return QRect(); +} + +QRect +AccountDelegate::configRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const +{ + if( !idx.data( SipModel::FactoryItemRole ).toBool() && !idx.data( SipModel::FactoryRole ).toBool() ) + { + QStyleOptionViewItemV4 opt = option; + initStyleOption( &opt, idx ); + QRect itemRect = opt.rect; + QRect confRect = QRect( itemRect.width() - ICONSIZE - 2 * PADDING, (opt.rect.height() / 2) - ICONSIZE / 2 + opt.rect.top(), ICONSIZE, ICONSIZE ); + return confRect; + } + return QRect(); +} + + +QSize +AccountDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const +{ + return ConfigDelegateBase::sizeHint( option, index ); +} + +void +AccountDelegate::askedForEdit( const QModelIndex& idx ) +{ + emit openConfig( qobject_cast< SipPlugin* >( idx.data( SipModel::SipPluginData ).value< QObject* >() ) ); +} + + diff --git a/src/sipconfigdelegate.h b/src/AccountDelegate.h similarity index 75% rename from src/sipconfigdelegate.h rename to src/AccountDelegate.h index cccc82a61..99607e5f6 100644 --- a/src/sipconfigdelegate.h +++ b/src/AccountDelegate.h @@ -16,31 +16,40 @@ */ -#ifndef SIPCONFIGDELEGATE_H -#define SIPCONFIGDELEGATE_H +#ifndef ACCOUNTDELEGATE_H +#define ACCOUNTDELEGATE_H #include "configdelegatebase.h" -class SipPlugin; -class SipPluginFactory; -class SipConfigDelegate : public ConfigDelegateBase +namespace Tomahawk +{ +namespace Accounts +{ + +class Account; + +class AccountDelegate : public ConfigDelegateBase { Q_OBJECT public: - SipConfigDelegate( QObject* parent = 0); + AccountDelegate( QObject* parent = 0); virtual void paint ( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const; virtual bool editorEvent ( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index ); virtual QSize sizeHint ( const QStyleOptionViewItem& option, const QModelIndex& index ) const; - virtual QRect checkRectForIndex( const QStyleOptionViewItem &option, const QModelIndex &idx ) const; + virtual QRect checkRectForIndex( const QStyleOptionViewItem &option, const QModelIndex &idx, int role ) const; virtual QRect configRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const; + + virtual QList extraCheckRoles() const { return QList() << (int)AccountModel::BasicCapabilityRole; } private slots: void askedForEdit( const QModelIndex& idx ); signals: - void sipFactoryClicked( SipPluginFactory* ); - void openConfig( SipPlugin* ); + void openConfig( Account* ); }; -#endif // SIPCONFIGDELEGATE_H +} +} + +#endif // ACCOUNTDELEGATE_H diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6466f60e7..d5dc7d5fb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -71,7 +71,7 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui} settingsdialog.cpp diagnosticsdialog.cpp configdelegatebase.cpp - sipconfigdelegate.cpp + AccountDelegate.cpp resolverconfigdelegate.cpp settingslistdelegate.cpp resolversmodel.cpp @@ -122,7 +122,7 @@ SET( tomahawkHeadersGui ${tomahawkHeadersGui} diagnosticsdialog.h configdelegatebase.h resolverconfigdelegate.h - sipconfigdelegate.h + AccountDelegate.h settingslistdelegate.h resolversmodel.h delegateconfigwrapper.h diff --git a/src/accounts/twitter/twitteraccount.cpp b/src/accounts/twitter/twitteraccount.cpp index 33fd3d148..552828201 100644 --- a/src/accounts/twitter/twitteraccount.cpp +++ b/src/accounts/twitter/twitteraccount.cpp @@ -52,7 +52,7 @@ TwitterAccount::TwitterAccount( const QString &accountId ) QSet< AccountType > types; types << InfoType << SipType; setTypes( types ); - + m_configWidget = QWeakPointer< TwitterConfigWidget >( new TwitterConfigWidget( this, 0 ) ); connect( m_configWidget.data(), SIGNAL( twitterAuthed( bool ) ), SLOT( configDialogAuthedSignalSlot( bool ) ) ); @@ -93,9 +93,9 @@ TwitterAccount::sipPlugin() void TwitterAccount::authenticate() { - tDebug() << Q_FUNC_INFO << "credentials: " << m_credentials.keys(); + tDebug() << Q_FUNC_INFO << "credentials: " << credentials().keys(); - if ( m_credentials[ "oauthtoken" ].toString().isEmpty() || m_credentials[ "oauthtokensecret" ].toString().isEmpty() ) + if ( credentials[ "oauthtoken" ].toString().isEmpty() || credentials()[ "oauthtokensecret" ].toString().isEmpty() ) { qDebug() << "TwitterSipPlugin has empty Twitter credentials; not connecting"; return; @@ -154,7 +154,9 @@ TwitterAccount::connectAuthVerifyReply( const QTweetUser &user ) else { tDebug() << "TwitterAccount successfully authenticated to Twitter as user " << user.screenName(); - m_configuration[ "screenname" ] = user.screenName(); + QVariantHash config = configuration(); + config[ "screenname" ] = user.screenName(); + setConfiguration( config ); sync(); emit nowAuthenticated( m_twitterAuth, user ); } diff --git a/src/accounts/twitter/twitteraccount.h b/src/accounts/twitter/twitteraccount.h index a440f44bf..ac7ad5c6e 100644 --- a/src/accounts/twitter/twitteraccount.h +++ b/src/accounts/twitter/twitteraccount.h @@ -56,10 +56,9 @@ class DLLEXPORT TwitterAccount : public Account public: TwitterAccount( const QString &accountId ); virtual ~TwitterAccount(); - + QIcon icon() const { return QIcon( ":/twitter-icon.png" ); } - bool canSelfAuthenticate() const { return true; } void authenticate(); void deauthenticate(); bool isAuthenticated() const { return m_isAuthenticated; } @@ -82,7 +81,7 @@ signals: private slots: void configDialogAuthedSignalSlot( bool authed ); void connectAuthVerifyReply( const QTweetUser &user ); - + private: bool m_isAuthenticated; QWeakPointer< TomahawkOAuthTwitter > m_twitterAuth; diff --git a/src/accounts/xmpp/xmppaccount.h b/src/accounts/xmpp/xmppaccount.h index 9c0b314cf..d7f54514e 100644 --- a/src/accounts/xmpp/xmppaccount.h +++ b/src/accounts/xmpp/xmppaccount.h @@ -59,7 +59,6 @@ public: QIcon icon() const { return QIcon( ":/xmpp-icon.png" ); } - bool canSelfAuthenticate() const { return false; } void authenticate(); void deauthenticate(); bool isAuthenticated() const { return m_isAuthenticated; } @@ -77,7 +76,7 @@ private: bool m_isAuthenticated; QWeakPointer< QWidget > m_configWidget; QWeakPointer< XmppSipPlugin > m_xmppSipPlugin; - + // for settings access friend class XmppConfigWidget; diff --git a/src/configdelegatebase.cpp b/src/configdelegatebase.cpp index ce6f2baae..bdf826bfc 100644 --- a/src/configdelegatebase.cpp +++ b/src/configdelegatebase.cpp @@ -25,6 +25,8 @@ #include "utils/tomahawkutils.h" #include "utils/logger.h" +#define ROW_HEIGHT 50 + ConfigDelegateBase::ConfigDelegateBase ( QObject* parent ) : QStyledItemDelegate ( parent ) { @@ -36,23 +38,7 @@ QSize ConfigDelegateBase::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const { int width = QStyledItemDelegate::sizeHint( option, index ).width(); - - QStyleOptionViewItemV4 opt = option; - initStyleOption( &opt, index ); - - - QFont name = opt.font; - name.setPointSize( name.pointSize() + 2 ); - name.setBold( true ); - - QFont path = opt.font; - path.setItalic( true ); - path.setPointSize( path.pointSize() - 1 ); - - - QFontMetrics bfm( name ); - QFontMetrics sfm( path ); - return QSize( width, 2 * PADDING + bfm.height() + sfm.height() ); + return QSize( width, ROW_HEIGHT ); } void @@ -94,17 +80,24 @@ ConfigDelegateBase::editorEvent ( QEvent* event, QAbstractItemModel* model, cons m_configPressed = QModelIndex(); QMouseEvent* me = static_cast< QMouseEvent* >( event ); - if( me->button() != Qt::LeftButton || !checkRectForIndex( option, index ).contains( me->pos() ) ) - return false; + QList roles = QList() << (int)Qt::CheckStateRole; + roles.append( extraCheckRoles() ); - // eat the double click events inside the check rect - if( event->type() == QEvent::MouseButtonDblClick ) { - return true; + foreach ( int role, roles ) + { + if( me->button() != Qt::LeftButton || !checkRectForIndex( option, index, role ).contains( me->pos() ) ) + return false; + + // eat the double click events inside the check rect + if( event->type() == QEvent::MouseButtonDblClick ) { + return true; + } + + Qt::CheckState curState = static_cast< Qt::CheckState >( index.data( role ).toInt() ); + Qt::CheckState newState = curState == Qt::Checked ? Qt::Unchecked : Qt::Checked; + return model->setData( index, newState, role ); } - Qt::CheckState curState = static_cast< Qt::CheckState >( index.data( Qt::CheckStateRole ).toInt() ); - Qt::CheckState newState = curState == Qt::Checked ? Qt::Unchecked : Qt::Checked; - return model->setData( index, newState, Qt::CheckStateRole ); } else if( event->type() == QEvent::MouseButtonPress ) { QMouseEvent* me = static_cast< QMouseEvent* >( event ); diff --git a/src/configdelegatebase.h b/src/configdelegatebase.h index d86baad1a..929467a00 100644 --- a/src/configdelegatebase.h +++ b/src/configdelegatebase.h @@ -36,10 +36,11 @@ public: virtual bool editorEvent ( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index ); // if you want to use a checkbox, you need to have this say where to paint it - virtual QRect checkRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const = 0; + virtual QRect checkRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx, int role ) const = 0; // if you want to use a config wrench, you need to have this say where to paint it virtual QRect configRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const = 0; + virtual QList extraCheckRoles() const { return QList(); } signals: void configPressed( const QModelIndex& idx ); diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index 9be5e79e7..93f9a5b78 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -59,12 +59,12 @@ set( libSources EchonestCatalogSynchronizer.cpp - accounts/accountmanager.cpp - accounts/account.cpp + accounts/AccountManager.cpp + accounts/Account.cpp + accounts/AccountModel.cpp sip/SipPlugin.cpp sip/SipHandler.cpp - sip/SipModel.cpp sip/sipinfo.cpp audio/audioengine.cpp @@ -284,14 +284,14 @@ set( libHeaders album.h playlist.h - accounts/account.h - accounts/accountmanager.h + accounts/Account.h + accounts/AccountManager.h + accounts/AccountModel.h EchonestCatalogSynchronizer.h sip/SipPlugin.h sip/SipHandler.h - sip/SipModel.h sip/sipinfo.h audio/audioengine.h @@ -484,7 +484,7 @@ set( libHeaders set( libHeaders_NoMOC viewpage.h - accounts/account.h + accounts/Account.h infosystem/infoplugins/unix/imageconverter.h diff --git a/src/libtomahawk/accounts/account.cpp b/src/libtomahawk/accounts/Account.cpp similarity index 67% rename from src/libtomahawk/accounts/account.cpp rename to src/libtomahawk/accounts/Account.cpp index c7b3f947e..699ccfccf 100644 --- a/src/libtomahawk/accounts/account.cpp +++ b/src/libtomahawk/accounts/Account.cpp @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * - * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2011, Christian Muehlhaeuser + * Copyright 2011, Leo Franchi . */ -#include "account.h" +#include "Account.h" namespace Tomahawk { @@ -24,6 +25,16 @@ namespace Tomahawk namespace Accounts { +Account::Account( const QString& accountId ) + : QObject() + , m_enabled( false ) + , m_autoConnect( false ) + , m_accountId( accountId ) +{ + connect( this, SIGNAL( error( int, QString ) ), this, SLOT( onError( int,QString ) ) ); + connect( this, SIGNAL( connectionStateChanged( Tomahawk::Accounts::Account::ConnectionState ) ) , this, SLOT( onConnectionStateChanged( Tomahawk::Accounts::Account::ConnectionState ) ) ); +} + QWidget* Account::configurationWidget() { @@ -77,9 +88,4 @@ void Account::refreshProxy() { -} - - -} - } \ No newline at end of file diff --git a/src/libtomahawk/accounts/account.h b/src/libtomahawk/accounts/Account.h similarity index 89% rename from src/libtomahawk/accounts/account.h rename to src/libtomahawk/accounts/Account.h index c8c98c385..06f79d52b 100644 --- a/src/libtomahawk/accounts/account.h +++ b/src/libtomahawk/accounts/Account.h @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * - * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2011, Christian Muehlhaeuser + * Copyright 2011, Leo Franchi sync(); } +private slots: + void onConnectionStateChanged( Tomahawk::Accounts::Account::ConnectionState ); + void onError( int,QString ); + +private: QString m_accountServiceName; QString m_accountFriendlyName; + QString m_cachedError; bool m_enabled; bool m_autoConnect; QString m_accountId; @@ -203,4 +214,4 @@ public: Q_DECLARE_INTERFACE( Tomahawk::Accounts::AccountFactory, "tomahawk.AccountFactory/1.0" ) -#endif \ No newline at end of file +#endif diff --git a/src/libtomahawk/accounts/accountmanager.cpp b/src/libtomahawk/accounts/AccountManager.cpp similarity index 97% rename from src/libtomahawk/accounts/accountmanager.cpp rename to src/libtomahawk/accounts/AccountManager.cpp index b340ec4ab..42fffc75b 100644 --- a/src/libtomahawk/accounts/accountmanager.cpp +++ b/src/libtomahawk/accounts/AccountManager.cpp @@ -16,7 +16,7 @@ * along with Tomahawk. If not, see . */ -#include "accountmanager.h" +#include "AccountManager.h" #include "config.h" #include @@ -48,13 +48,14 @@ AccountManager::AccountManager( QObject *parent ) loadPluginFactories( findPluginFactories() ); } - + AccountManager::~AccountManager() { - + disconnectAll(); + qDeleteAll( m_accounts ); } - + QStringList AccountManager::findPluginFactories() { @@ -187,8 +188,8 @@ AccountManager::addAccountPlugin( Account* account ) foreach( AccountType type, account->types() ) m_accountsByAccountType[ type ].append( account ); - //TODO:? - //emit pluginAdded( account ); + + emit accountAdded( account ); } diff --git a/src/libtomahawk/accounts/accountmanager.h b/src/libtomahawk/accounts/AccountManager.h similarity index 77% rename from src/libtomahawk/accounts/accountmanager.h rename to src/libtomahawk/accounts/AccountManager.h index 8020c5759..ee45c46a6 100644 --- a/src/libtomahawk/accounts/accountmanager.h +++ b/src/libtomahawk/accounts/AccountManager.h @@ -25,7 +25,7 @@ #include "dllmacro.h" #include "infosystem/infosystem.h" #include "sip/SipPlugin.h" -#include "account.h" +#include "Account.h" namespace Tomahawk { @@ -36,10 +36,10 @@ namespace Accounts class DLLEXPORT AccountManager : public QObject { Q_OBJECT - + public: static AccountManager* instance(); - + explicit AccountManager( QObject *parent ); virtual ~AccountManager(); @@ -51,12 +51,24 @@ public: void addAccountPlugin( Account* account ); Account* loadPlugin( const QString &accountId ); QString factoryFromId( const QString& accountId ) const; - - QList< Account* > getAccounts() { return m_accounts; }; - QList< Account* > getAccounts( Tomahawk::Accounts::AccountType type ) { return m_accountsByAccountType[ type ]; } + + QList< Account* > accounts() const { return m_accounts; }; + QList< Account* > accounts( Tomahawk::Accounts::AccountType type ) const { return m_accountsByAccountType[ type ]; } + +public slots: + void connectAll(); + void disconnectAll(); + +signals: + void accountAdded( Tomahawk::Accounts::Account* ); + void accountRemoved( Tomahawk::Accounts::Account* ); private: QList< Account* > m_accounts; + QList< Account* > m_enabledAccounts; + QList< Account* > m_connectedAccounts; + bool m_connected; + QHash< AccountType, QList< Account* > > m_accountsByAccountType; QHash< QString, AccountFactory* > m_accountFactories; @@ -67,4 +79,4 @@ private: }; -#endif \ No newline at end of file +#endif diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp new file mode 100644 index 000000000..1e4dfd481 --- /dev/null +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -0,0 +1,153 @@ + /* + Copyright (C) 2011 Leo Franchi + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + + +#include "AccountModel.h" + +#include "tomahawksettings.h" +#include "accounts/AccountManager.h" +#include "accounts/Account.h" + +#include "utils/logger.h" + +using namespace Tomahawk; +using namespace Accounts; + +AccountModel::AccountModel( QObject* parent ) + : QAbstractListModel( parent ) +{ + connect( AccountManager::instance(), SIGNAL( accountAdded( Tomahawk::Accounts::Account* ) ), this, SLOT( accountAdded( Tomahawk::Accounts::Account* ) ) ); + connect( AccountManager::instance(), SIGNAL( accountRemoved( Tomahawk::Accounts::Account* ) ), this, SLOT( accountRemoved( Tomahawk::Accounts::Account* ) ) ); +} + + +AccountModel::~AccountModel() +{ +} + + +QVariant +AccountModel::data( const QModelIndex& index, int role ) const +{ + if( !index.isValid() ) + return QVariant(); + + QList< Account* > accounts = AccountManager::instance()->accounts(); + Q_ASSERT( index.row() <= accounts.size() ); + Account* account = accounts[ index.row() ]; + switch( role ) + { + case Qt::DisplayRole: + case AccountModel::AccountName: + return account->accountServiceName(); + case AccountModel::ConnectionStateRole: + return account->connectionState(); + case AccountModel::HasConfig: + return ( account->configurationWidget() != 0 ); + case Qt::DecorationRole: + return account->icon(); + case AccountModel::AccountData: + return QVariant::fromValue< QObject* >( account ); + case Qt::CheckStateRole: + return account->enabled() ? Qt::Checked : Qt::Unchecked; + default: + return QVariant(); + } + return QVariant(); +} + + +bool +AccountModel::setData( const QModelIndex& index, const QVariant& value, int role ) +{ + Q_ASSERT( index.isValid() && index.row() <= AccountManager::instance()->accounts().count() ); + + if ( role == Qt::CheckStateRole ) { + Qt::CheckState state = static_cast< Qt::CheckState >( value.toInt() ); + QList< Account* > accounts = AccountManager::instance()->accounts(); + Account* account = accounts[ index.row() ]; + + if( state == Qt::Checked && !account->enabled() ) { + account->setEnabled( true ); + } else if( state == Qt::Unchecked ) { + account->setEnabled( false ); + } + dataChanged( index, index ); + + return true; + } + else if ( role == BasicCapabilityRole ) + { + // TODO + } + return false; +} + +int +AccountModel::rowCount( const QModelIndex& parent ) const +{ + return AccountManager::instance()->accounts().size(); +} + +Qt::ItemFlags +AccountModel::flags( const QModelIndex& index ) const +{ + return QAbstractListModel::flags( index ) | Qt::ItemIsUserCheckable; +} + + +void +AccountModel::accountAdded( Account* account ) +{ + Q_UNUSED( p ); + // we assume account plugins are added at the end of the list. + Q_ASSERT( AccountManager::instance()->accounts().last() == account ); + if ( account->types().contains( SipType ) ) + connect( account, SIGNAL( connectionStateChanged( Tomahawk::Accounts::Account::ConnectionState ) ), this, SLOT( accountStateChanged( Tomahawk::Accounts::Account::ConnectionState ) ) ); + + int size = AccountManager::instance()->accounts().count() - 1; + beginInsertRows( QModelIndex(), size, size ); + endInsertRows(); +} + + +void +AccountModel::accountRemoved( Account* account ) +{ + int idx = AccountManager::instance()->allPlugins().indexOf( account ); + beginRemoveRows( QModelIndex(), idx, idx ); + endRemoveRows(); +} + + +void +AccountModel::accountStateChanged( Tomahawk::Accounts::Account::ConnectionState state ) +{ + Account* account = qobject_cast< Account* >( sender() ); + Q_ASSERT( a ); + + for ( int i = 0; i < AccountManager::instance()->accounts().size(); i++ ) + { + if ( AccountManager::instance()->accounts()[i] == account ) + { + QModelIndex idx = index( i, 0, QModelIndex() ); + emit dataChanged( idx, idx ); + return; + } + } +} + diff --git a/src/libtomahawk/sip/SipModel.h b/src/libtomahawk/accounts/AccountModel.h similarity index 56% rename from src/libtomahawk/sip/SipModel.h rename to src/libtomahawk/accounts/AccountModel.h index 7f4901032..72b3cdada 100644 --- a/src/libtomahawk/sip/SipModel.h +++ b/src/libtomahawk/accounts/AccountModel.h @@ -1,5 +1,4 @@ /* - Copyright (C) 2011 Leo Franchi This program is free software: you can redistribute it and/or modify @@ -21,43 +20,57 @@ #define SIPMODEL_H #include "dllmacro.h" +#include "sip/SipPlugin.h" #include #include -class SipPlugin; +namespace Tomahawk +{ +namespace Accounts +{ -class DLLEXPORT SipModel : public QAbstractItemModel +class Account; + +class DLLEXPORT AccountModel : public QAbstractListModel { Q_OBJECT public: - enum Roles { - PluginName = Qt::UserRole + 15, - ConnectionStateRole = Qt::UserRole + 17, - HasConfig = Qt::UserRole + 18, - FactoryRole = Qt::UserRole + 19, - ErrorString = Qt::UserRole + 20, - FactoryItemRole = Qt::UserRole + 21, - FactoryItemIcon = Qt::UserRole + 22, - SipPluginData = Qt::UserRole + 23, - SipPluginFactoryData = Qt::UserRole + 24 + enum BasicCapabilities + { + NoCapabilities = 0, + SipCapability = 0x1, + ResolverCapability = 0x2 }; - explicit SipModel( QObject* parent = 0 ); - virtual ~SipModel(); + enum Roles { + AccountName = Qt::UserRole + 15, + AccountIcon = Qt::UserRole + 16, + HeadlineText = Qt::UserRole + 17, + DescText = Qt::UserRole + 18, + BasicCapabilityRole = Qt::UserRole + 19, + ConnectionStateRole = Qt::UserRole + 20, + HasConfig = Qt::UserRole + 21, + ErrorString = Qt::UserRole + 22, + AccountData = Qt::UserRole + 23 // raw plugin + }; + + explicit AccountModel( QObject* parent = 0 ); + virtual ~AccountModel(); - virtual QModelIndex index ( int row, int column, const QModelIndex& parent = QModelIndex() ) const; - virtual QModelIndex parent ( const QModelIndex& child ) const; virtual QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const; virtual int rowCount( const QModelIndex& parent = QModelIndex() ) const; - virtual int columnCount( const QModelIndex& parent ) const; virtual Qt::ItemFlags flags(const QModelIndex& index) const; virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole); private slots: - void pluginAdded( SipPlugin* p ); - void pluginRemoved( SipPlugin* p ); - void pluginStateChanged( SipPlugin* p ); + void accountAdded( Tomahawk::Accounts::Account* p ); + void accountRemoved( Tomahawk::Accounts::Account* p ); + void accountStateChanged( Tomahawk::Accounts::Account::ConnectionState ); }; +} + +} + #endif // SIPMODEL_H diff --git a/src/libtomahawk/database/databaseworker.cpp b/src/libtomahawk/database/databaseworker.cpp index 91a543772..45f05b834 100644 --- a/src/libtomahawk/database/databaseworker.cpp +++ b/src/libtomahawk/database/databaseworker.cpp @@ -223,6 +223,7 @@ void DatabaseWorker::logOp( DatabaseCommandLoggable* command ) { TomahawkSqlQuery oplogquery = m_dbimpl->newquery(); + qDebug() << "INSERTING INTO OPTLOG:" << command->source()->id() << command->guid() << command->commandname(); oplogquery.prepare( "INSERT INTO oplog(source, guid, command, singleton, compressed, json) " "VALUES(?, ?, ?, ?, ?, ?)" ); diff --git a/src/libtomahawk/sip/SipHandler.cpp b/src/libtomahawk/sip/SipHandler.cpp index 5c9c4d496..582d67600 100644 --- a/src/libtomahawk/sip/SipHandler.cpp +++ b/src/libtomahawk/sip/SipHandler.cpp @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2010-2011, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -32,7 +33,7 @@ #include "sourcelist.h" #include "tomahawksettings.h" #include "utils/logger.h" -#include "accounts/accountmanager.h" +#include "accounts/AccountManager.h" #include "config.h" @@ -62,8 +63,6 @@ SipHandler::SipHandler( QObject* parent ) SipHandler::~SipHandler() { qDebug() << Q_FUNC_INFO; - disconnectAll(); - qDeleteAll( m_allPlugins ); } @@ -174,7 +173,7 @@ void SipHandler::loadFromAccountManager() { tDebug() << Q_FUNC_INFO; - QList< Tomahawk::Accounts::Account* > accountList = Tomahawk::Accounts::AccountManager::instance()->getAccounts( Tomahawk::Accounts::SipType ); + QList< Tomahawk::Accounts::Account* > accountList = Tomahawk::Accounts::AccountManager::instance()->accounts( Tomahawk::Accounts::SipType ); foreach( Tomahawk::Accounts::Account* account, accountList ) { tDebug() << Q_FUNC_INFO << "adding plugin " << account->accountId(); diff --git a/src/libtomahawk/sip/SipHandler.h b/src/libtomahawk/sip/SipHandler.h index 49e1076cf..1d2ef1688 100644 --- a/src/libtomahawk/sip/SipHandler.h +++ b/src/libtomahawk/sip/SipHandler.h @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2010-2011, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -60,8 +61,6 @@ public slots: void connectPlugin( const QString &pluginId = QString() ); void disconnectPlugin( const QString &pluginId = QString() ); - void connectAll(); - void disconnectAll(); void toggleConnect(); @@ -105,11 +104,6 @@ private: void loadPluginFactory( const QString& path ); QString factoryFromId( const QString& pluginId ) const; - QList< SipPlugin* > m_allPlugins; - QList< SipPlugin* > m_enabledPlugins; - QList< SipPlugin* > m_connectedPlugins; - bool m_connected; - //TODO: move this to source QHash m_peersSipInfos; QHash m_usernameAvatars; diff --git a/src/libtomahawk/sip/SipModel.cpp b/src/libtomahawk/sip/SipModel.cpp deleted file mode 100644 index 093d81c88..000000000 --- a/src/libtomahawk/sip/SipModel.cpp +++ /dev/null @@ -1,227 +0,0 @@ -/* - Copyright (C) 2011 Leo Franchi - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - - -#include "SipModel.h" - -#include "tomahawksettings.h" -#include "sip/SipHandler.h" -#include "sip/SipPlugin.h" - -#include "utils/logger.h" - - -SipModel::SipModel( QObject* parent ) - : QAbstractItemModel( parent ) -{ - connect( SipHandler::instance(), SIGNAL( stateChanged( SipPlugin*, SipPlugin::ConnectionState ) ), this, SLOT( pluginStateChanged( SipPlugin* ) ) ); - connect( SipHandler::instance(), SIGNAL( pluginAdded( SipPlugin* ) ), this, SLOT( pluginAdded( SipPlugin* ) ) ); - connect( SipHandler::instance(), SIGNAL( pluginRemoved( SipPlugin* ) ), this, SLOT( pluginRemoved( SipPlugin* ) ) ); - - // TODO disable inline factories for now - /* - foreach( SipPluginFactory* f, SipHandler::instance()->pluginFactories() ) { - if( f->isCreatable() ) - m_factories << f; - } */ - -} - - -SipModel::~SipModel() -{ -} - - -QVariant -SipModel::data( const QModelIndex& index, int role ) const -{ - if( !index.isValid() ) - return QVariant(); - - if( !index.parent().isValid() && index.row() == SipHandler::instance()->allPlugins().count() ) { // last row, this is the factory - if( role == Qt::DisplayRole ) - return tr( "Add New Account..." ); - else if( role == FactoryRole ) - return true; - else - return QVariant(); - } - - if( !index.parent().isValid() ) { // account - QList< SipPlugin* > plugins = SipHandler::instance()->allPlugins(); - Q_ASSERT( index.row() <= plugins.size() ); - SipPlugin* p = plugins[ index.row() ]; - switch( role ) - { - case Qt::DisplayRole: - case SipModel::PluginName: - return p->account()->accountServiceName(); - case SipModel::ConnectionStateRole: - return p->connectionState(); - case SipModel::HasConfig: - return ( p->account()->configurationWidget() != 0 ); - case SipModel::FactoryRole: - return false; - case Qt::DecorationRole: - return p->icon(); - case SipModel::SipPluginData: - return QVariant::fromValue< QObject* >( p ); - case Qt::CheckStateRole: - return p->account()->enabled() ? Qt::Checked : Qt::Unchecked; - default: - return QVariant(); - } - } - - /* - * m_factories never actually populated yet, so just disable - if( index.parent().isValid() ) { // this is a factory type - SipPluginFactory* p = m_factories.at( index.row() ); - switch( role ) - { - case Qt::DisplayRole: - return p->prettyName(); - case SipModel::FactoryItemRole: - return true; - case SipModel::FactoryItemIcon: - return p->icon(); - case SipModel::SipPluginFactoryData: - return QVariant::fromValue< QObject* >( p ); - default: - return QVariant(); - } - } - */ - return QVariant(); -} - - -bool -SipModel::setData( const QModelIndex& index, const QVariant& value, int role ) -{ - Q_ASSERT( index.isValid() && index.row() <= SipHandler::instance()->allPlugins().count() ); - - if( role == Qt::CheckStateRole ) { - Qt::CheckState state = static_cast< Qt::CheckState >( value.toInt() ); - QList< SipPlugin* > plugins = SipHandler::instance()->allPlugins(); - SipPlugin* p = plugins[ index.row() ]; - - if( state == Qt::Checked && !p->account()->enabled() ) { - p->account()->setEnabled( true ); - } else if( state == Qt::Unchecked ) { - p->account()->setEnabled( false ); - } - dataChanged( index, index ); - - return true; - } - return false; -} - - -QModelIndex -SipModel::index( int row, int column, const QModelIndex& parent ) const -{ - if( !parent.isValid() ) - return hasIndex( row, column, parent ) ? createIndex( row, column, 0 ) : QModelIndex(); - -// qDebug() << "Creating index for non-top level row!"; - // it's a child of the Add Account, e.g. a factory - if( hasIndex( row, column, parent ) ) { - return createIndex( row, column, 1 /* magic */ ); - } - - return QModelIndex(); -} - - -QModelIndex -SipModel::parent( const QModelIndex& child ) const -{ - if( !child.isValid() ) - return QModelIndex(); - - if( child.internalId() == 1 ) { - return index( SipHandler::instance()->allPlugins().size(), 0, QModelIndex() ); - } - - return QModelIndex(); -} - - -int -SipModel::rowCount( const QModelIndex& parent ) const -{ - if( !parent.isValid() ) // invalid root node - return SipHandler::instance()->allPlugins().size() /* TODO inline factories disabled + 1*/; - if( parent.isValid() && !parent.parent().isValid() ) { // top level item - if( parent.row() == SipHandler::instance()->allPlugins().count() ) {// last row, this is the factory - //return m_factories.count(); - } - } - - return 0; -} - - -int -SipModel::columnCount(const QModelIndex& parent) const -{ - Q_UNUSED( parent ); - return 1; -} - - -Qt::ItemFlags -SipModel::flags( const QModelIndex& index ) const -{ - if( index.data( SipModel::FactoryRole ).toBool() || index.data( SipModel::FactoryItemRole ).toBool() ) - return QAbstractItemModel::flags( index ) & ~Qt::ItemIsSelectable; - return QAbstractItemModel::flags( index ) | Qt::ItemIsUserCheckable; -} - - -void -SipModel::pluginAdded( SipPlugin* p ) -{ - Q_UNUSED( p ); - // we assume sip plugins are added at the end of the list. - Q_ASSERT( SipHandler::instance()->allPlugins().last() == p ); - int size = SipHandler::instance()->allPlugins().count() - 1; - beginInsertRows( QModelIndex(), size, size ); - endInsertRows(); -} - - -void -SipModel::pluginRemoved( SipPlugin* p ) -{ - int idx = SipHandler::instance()->allPlugins().indexOf( p ); - beginRemoveRows( QModelIndex(), idx, idx ); - endRemoveRows(); -} - - -void -SipModel::pluginStateChanged( SipPlugin* p ) -{ - int at = SipHandler::instance()->allPlugins().indexOf( p ); - QModelIndex idx = index( at, 0, QModelIndex() ); - emit dataChanged( idx, idx ); -} - diff --git a/src/libtomahawk/sip/SipPlugin.cpp b/src/libtomahawk/sip/SipPlugin.cpp index 54301cfaa..148479a71 100644 --- a/src/libtomahawk/sip/SipPlugin.cpp +++ b/src/libtomahawk/sip/SipPlugin.cpp @@ -29,10 +29,6 @@ SipPlugin::SipPlugin( Tomahawk::Accounts::Account *account, QObject* parent ) : QObject( parent ) , m_account( account ) { - connect( this, SIGNAL( error( int, QString ) ), this, SLOT( onError( int,QString ) ) ); - connect( this, SIGNAL( stateChanged( SipPlugin::ConnectionState ) ), this, SLOT( onStateChange( SipPlugin::ConnectionState ) ) ); - connect( this, SIGNAL( peerOnline( QString ) ), this, SLOT( onPeerOnline( QString ) ) ); - connect( this, SIGNAL( peerOffline( QString ) ), this, SLOT( onPeerOffline( QString ) ) ); } diff --git a/src/libtomahawk/sip/SipPlugin.h b/src/libtomahawk/sip/SipPlugin.h index f0b591aa6..af622dd11 100644 --- a/src/libtomahawk/sip/SipPlugin.h +++ b/src/libtomahawk/sip/SipPlugin.h @@ -26,7 +26,7 @@ #include #include -#include "accounts/account.h" +#include "accounts/Account.h" #ifndef ENABLE_HEADLESS #include #endif @@ -40,9 +40,6 @@ class DLLEXPORT SipPlugin : public QObject Q_OBJECT public: - enum SipErrorCode { AuthError, ConnectionError }; // Placeholder for errors, to be defined - enum ConnectionState { Disconnected, Connecting, Connected, Disconnecting }; - SipPlugin(); explicit SipPlugin( Tomahawk::Accounts::Account *account, QObject* parent = 0 ); virtual ~SipPlugin(); @@ -53,8 +50,6 @@ public: virtual bool isValid() const = 0; virtual const QString friendlyName() const; virtual const QString serviceName() const; - virtual ConnectionState connectionState() const = 0; - virtual QString errorMessage() const; #ifndef ENABLE_HEADLESS virtual QMenu* menu(); #endif @@ -76,9 +71,6 @@ public slots: virtual void refreshProxy(); signals: - void error( int, const QString& ); - void stateChanged( SipPlugin::ConnectionState state ); - void peerOnline( const QString& ); void peerOffline( const QString& ); void msgReceived( const QString& from, const QString& msg ); @@ -99,17 +91,13 @@ signals: void dataError( bool ); private slots: - void onError( int, const QString& ); - void onStateChange( SipPlugin::ConnectionState state ); - void onPeerOnline( const QString &peerId ); void onPeerOffline( const QString &peerId ); protected: Tomahawk::Accounts::Account *m_account; - + private: - QString m_cachedError; QStringList m_peersOnline; }; diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index b4c41601b..34cd01b1b 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -51,7 +51,7 @@ #include "network/servent.h" #include "playlist/dynamic/widgets/LoadingSpinner.h" #include "sip/SipHandler.h" -#include "sip/SipModel.h" +#include "sip/AccountModel.h" #include "utils/logger.h" #include "ui_proxydialog.h" @@ -417,7 +417,7 @@ SettingsDialog::testLastFmLogin() // ensure they have up-to-date settings lastfm::setNetworkAccessManager( TomahawkUtils::nam() ); - + QNetworkReply* authJob = lastfm::ws::post( query ); connect( authJob, SIGNAL( finished() ), SLOT( onLastFmFinished() ) ); @@ -877,7 +877,7 @@ ProxyDialog::saveSettings() qDebug() << Q_FUNC_INFO; QNetworkProxy::ProxyType type = static_cast< QNetworkProxy::ProxyType>( m_backwardMap[ ui->typeBox->currentIndex() ] ); - + //First set settings TomahawkSettings* s = TomahawkSettings::instance(); s->setProxyHost( ui->hostLineEdit->text() ); @@ -890,7 +890,7 @@ ProxyDialog::saveSettings() s->setProxyType( type ); s->setProxyDns( ui->checkBoxUseProxyForDns->checkState() == Qt::Checked ); s->sync(); - + TomahawkUtils::NetworkProxyFactory* proxyFactory = TomahawkUtils::proxyFactory(); tDebug() << Q_FUNC_INFO << "Got proxyFactory: " << proxyFactory; if ( type == QNetworkProxy::NoProxy ) diff --git a/src/sipconfigdelegate.cpp b/src/sipconfigdelegate.cpp deleted file mode 100644 index 20cfcb891..000000000 --- a/src/sipconfigdelegate.cpp +++ /dev/null @@ -1,282 +0,0 @@ -/* - Copyright (C) 2011 Leo Franchi - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - - -#include "sipconfigdelegate.h" - -#include -#include - -#include "sip/SipModel.h" -#include "sip/SipPlugin.h" - -#include "utils/tomahawkutils.h" -#include "utils/logger.h" - -#define ICONSIZE 24 -#define CHECK_LEFT_EDGE 8 - - -SipConfigDelegate::SipConfigDelegate( QObject* parent ) - : ConfigDelegateBase ( parent ) -{ - connect( this, SIGNAL( configPressed( QModelIndex ) ), this, SLOT( askedForEdit( QModelIndex ) ) ); -} - -bool -SipConfigDelegate::editorEvent ( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index ) -{ - return ConfigDelegateBase::editorEvent( event, model, option, index ); -} - -void -SipConfigDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const -{ - QStyleOptionViewItemV4 opt = option; - initStyleOption( &opt, index ); - QRect itemRect = opt.rect; - int top = itemRect.top(); - int mid = itemRect.height() / 2; - - // one line bold for account name - // space below it fro an error - // checkbox, icon, name, online/offline status, config icon - QFont name = opt.font; - name.setPointSize( name.pointSize() + 2 ); - name.setBold( true ); - - QFont error = opt.font; - error.setItalic( true ); - error.setPointSize( error.pointSize() - 2 ); - - // draw the background - const QWidget* w = opt.widget; - QStyle* style = w ? w->style() : QApplication::style(); - style->drawPrimitive( QStyle::PE_PanelItemViewItem, &opt, painter, w ); - - int iconLeftEdge = CHECK_LEFT_EDGE + ICONSIZE + PADDING; - int textLeftEdge = iconLeftEdge + ICONSIZE + PADDING; - - if( index.data( SipModel::FactoryRole ).toBool() ) { // this is the "add new account" row - // draw a border and background - painter->save(); - painter->setRenderHints( QPainter::Antialiasing ); - painter->setBrush( QApplication::palette().color( QPalette::Active, QPalette::Highlight ).lighter( 150 ) ); - QPainterPath roundedRect; - roundedRect.addRoundedRect( itemRect.adjusted( 1, 1, -1, -1 ), 3, 3 ); - painter->drawPath( roundedRect ); - painter->setBrush( QApplication::palette().color( QPalette::Active, QPalette::Highlight ).lighter( 170 ) ); - painter->fillPath( roundedRect, painter->brush() ); - painter->restore(); - - // draw "+" icon in checkbox column - int rectW = 18; - int diff = ( ICONSIZE/ 2 ) - ( rectW / 2) ; - int pos = ( mid ) - ( rectW / 2 ); - QRect plusRect = QRect( CHECK_LEFT_EDGE + diff, pos + top, rectW, rectW ); - QPixmap p( RESPATH "images/list-add.png" ); - painter->drawPixmap( plusRect, p ); - - // draw text - QFont f = opt.font; - f.setPointSize( f.pointSize() ); - f.setBold( true ); - QFontMetrics fm( f ); - QString text = index.data( Qt::DisplayRole ).toString(); - QRect textR = fm.boundingRect( text ); - textR.moveLeft( textLeftEdge ); - textR.moveTop( mid - ( textR.height() / 2 ) + top ); - textR.setRight( itemRect.right() ); - painter->setFont( f ); - painter->drawText( textR, text ); - } else if( index.data( SipModel::FactoryItemRole ).toBool() ) { // this is an account type - -// ConfigDelegateBase::paint( painter, opt, index ); -// int indent = 10; - // draw a border and background - painter->save(); - painter->setRenderHints( QPainter::Antialiasing ); - painter->setBrush( QApplication::palette().color( QPalette::Active, QPalette::Highlight ).lighter( 170 ) ); - QPainterPath roundedRect; - roundedRect.addRoundedRect( itemRect.adjusted( 1, 1, -1, -1 ), 3, 3 ); - painter->drawPath( roundedRect ); - painter->setBrush( QApplication::palette().color( QPalette::Active, QPalette::Highlight ).lighter( 180 ) ); - painter->fillPath( roundedRect, painter->brush() ); - painter->restore(); - - QIcon icon = index.data( SipModel::FactoryItemIcon ).value< QIcon >(); - if( !icon.isNull() ) { - int rectW = 18; - int diff = ( ICONSIZE/ 2 ) - ( rectW / 2) ; - int pos = ( mid ) - ( rectW / 2 ); - QRect rect = QRect( CHECK_LEFT_EDGE + diff, pos + top, rectW, rectW ); - QPixmap p( icon.pixmap( rect.size() ) ); - painter->drawPixmap( rect, p ); - } - - // draw text - QFont f = opt.font; - f.setPointSize( f.pointSize() ); - f.setBold( true ); - QFontMetrics fm( f ); - QString text = index.data( Qt::DisplayRole ).toString(); - QRect textR = fm.boundingRect( text ); - textR.moveLeft( textLeftEdge ); - textR.moveTop( mid - ( textR.height() / 2 ) + top ); - textR.setRight( itemRect.right() ); - painter->setFont( f ); - painter->drawText( textR, text ); - } else { // this is an existing account to show - // draw checkbox first - int pos = ( mid ) - ( ICONSIZE / 2 ); - QRect checkRect = QRect( CHECK_LEFT_EDGE, pos + top, ICONSIZE, ICONSIZE ); - opt.rect = checkRect; - drawCheckBox( opt, painter, w ); - - // draw the icon if it exists - pos = ( mid ) - ( ICONSIZE / 2 ); - if( !index.data( Qt::DecorationRole ).value< QIcon >().isNull() ) { - QRect prect = QRect( iconLeftEdge, pos + top, ICONSIZE, ICONSIZE ); - - painter->save(); - painter->drawPixmap( prect, index.data( Qt::DecorationRole ).value< QIcon >().pixmap( prect.size() ) ); - painter->restore(); - } - - // from the right edge--config status and online/offline - QRect confRect = QRect( itemRect.width() - ICONSIZE - 2 * PADDING, mid - ICONSIZE / 2 + top, ICONSIZE, ICONSIZE ); - if( index.data( SipModel::HasConfig ).toBool() ) { - - QStyleOptionToolButton topt; - topt.rect = confRect; - topt.pos = confRect.topLeft(); - - drawConfigWrench( painter, opt, topt ); - } - - // draw the online/offline status - int statusIconSize = 18; - int statusX = confRect.left() - 2*PADDING - statusIconSize; - QFont statusF = opt.font; - statusF.setPointSize( statusF.pointSize() - 2 ); - QFontMetrics statusFM( statusF ); - - QPixmap p; - QString statusText; - SipPlugin::ConnectionState state = static_cast< SipPlugin::ConnectionState >( index.data( SipModel::ConnectionStateRole ).toInt() ); - if( state == SipPlugin::Connected ) { - p = QPixmap( RESPATH "images/sipplugin-online.png" ); - statusText = tr( "Online" ); - } else if( state == SipPlugin::Connecting ) { - p = QPixmap( RESPATH "images/sipplugin-offline.png" ); - statusText = tr( "Connecting..." ); - } else { - p = QPixmap( RESPATH "images/sipplugin-offline.png" ); - statusText = tr( "Offline" ); - } - p = p.scaled( statusIconSize, statusIconSize, Qt::KeepAspectRatio, Qt::SmoothTransformation ); - painter->drawPixmap( statusX, mid - statusIconSize / 2 + top, statusIconSize, statusIconSize, p ); - int width = statusFM.width( statusText ); - statusX = statusX - PADDING - width; - painter->save(); - painter->setFont( statusF ); - painter->drawText( QRect( statusX, mid - statusFM.height() / 2 + top, width, statusFM.height() ), statusText ); - painter->restore(); - - // name - painter->save(); - QFontMetrics namefm( name ); - int nameHeight = namefm.boundingRect( "test" ).height(); - // pos will the top-left point of the text rect - pos = mid - ( nameHeight / 2 ); - // TODO bound with config icon and offline/online status - width = itemRect.width() - textLeftEdge; - - if( !index.data( SipModel::ErrorString ).toString().isEmpty() ) { // error, show that too - QRect errorRect( textLeftEdge, mid + top, width, mid - PADDING + 1 ); - - QFontMetrics errorFm( error ); - QString str = errorFm.elidedText( index.data( SipModel::ErrorString ).toString(), Qt::ElideRight, errorRect.width() ); - painter->setFont( error ); - painter->drawText( errorRect, str ); - - pos = mid - errorRect.height() - 2; // move the name rect up - } - QString nameStr = namefm.elidedText( index.data( Qt::DisplayRole ).toString(), Qt::ElideRight, width ); - painter->setFont( name ); - painter->drawText( QRect( textLeftEdge, pos + top, width, nameHeight + 1 ), nameStr ); - painter->restore(); - } -} - -QRect -SipConfigDelegate::checkRectForIndex( const QStyleOptionViewItem &option, const QModelIndex &idx ) const -{ - if( !idx.data( SipModel::FactoryItemRole ).toBool() && !idx.data( SipModel::FactoryRole ).toBool() ) - { - QStyleOptionViewItemV4 opt = option; - initStyleOption( &opt, idx ); - int mid = opt.rect.height() / 2; - int pos = ( mid ) - ( ICONSIZE / 2 ); - QRect checkRect = QRect( CHECK_LEFT_EDGE, pos + opt.rect.top(), ICONSIZE, ICONSIZE ); - - return checkRect; - } - return QRect(); -} - -QRect -SipConfigDelegate::configRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const -{ - if( !idx.data( SipModel::FactoryItemRole ).toBool() && !idx.data( SipModel::FactoryRole ).toBool() ) - { - QStyleOptionViewItemV4 opt = option; - initStyleOption( &opt, idx ); - QRect itemRect = opt.rect; - QRect confRect = QRect( itemRect.width() - ICONSIZE - 2 * PADDING, (opt.rect.height() / 2) - ICONSIZE / 2 + opt.rect.top(), ICONSIZE, ICONSIZE ); - return confRect; - } - return QRect(); -} - - -QSize -SipConfigDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const -{ - if( index.data( SipModel::FactoryRole ).toBool() || index.data( SipModel::FactoryItemRole ).toBool() ) { // this is the "add new account" row - // enough space for one line of text - QStyleOptionViewItemV4 opt = option; - initStyleOption( &opt, index ); - int width = QStyledItemDelegate::sizeHint( option, index ).width(); - - QFont name = opt.font; - name.setPointSize( name.pointSize() + 1 ); - name.setBold( true ); - QFontMetrics sfm( name ); - return QSize( width, 3 * PADDING + sfm.height() ); - } else { // this is an existing account to show - return ConfigDelegateBase::sizeHint( option, index ); - } -} - -void -SipConfigDelegate::askedForEdit( const QModelIndex& idx ) -{ - emit openConfig( qobject_cast< SipPlugin* >( idx.data( SipModel::SipPluginData ).value< QObject* >() ) ); -} - - diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index 6e48af576..7aefdfe7d 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -211,7 +211,7 @@ TomahawkApp::init() 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 ) ); @@ -505,7 +505,8 @@ void TomahawkApp::initSIP() { tDebug() << Q_FUNC_INFO; - foreach ( Tomahawk::Accounts::Account* account, Tomahawk::Accounts::AccountManager::instance()->getAccounts() ) + // TODO debugging hack only + foreach ( Tomahawk::Accounts::Account* account, Tomahawk::Accounts::AccountManager::instance()->accounts() ) { tDebug() << Q_FUNC_INFO << "testing account with name " << account->accountServiceName(); if ( account->configurationWidget() && account->configuration().isEmpty() ) @@ -513,7 +514,7 @@ TomahawkApp::initSIP() if ( !account->enabled() ) account->setEnabled( true ); } - + //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" ) ) { From b6911525a4b0334651b3f661232f9ca9ed0623c4 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sun, 11 Dec 2011 22:41:59 -0500 Subject: [PATCH 021/104] separate more stuff into siphandler/accountmanager --- src/AccountDelegate.h | 1 + src/accounts/twitter/twitteraccount.h | 4 +- src/accounts/xmpp/xmppaccount.h | 6 +- src/libtomahawk/accounts/Account.cpp | 27 ++- src/libtomahawk/accounts/Account.h | 8 +- src/libtomahawk/accounts/AccountManager.cpp | 126 ++++++++++-- src/libtomahawk/accounts/AccountManager.h | 21 +- src/libtomahawk/accounts/AccountModel.cpp | 15 +- src/libtomahawk/accounts/AccountModel.h | 1 + src/libtomahawk/sip/SipHandler.cpp | 204 +------------------- src/libtomahawk/sip/SipHandler.h | 45 +---- src/libtomahawk/sip/SipPlugin.cpp | 24 +-- src/libtomahawk/sip/SipPlugin.h | 1 + src/tomahawkapp.cpp | 14 +- src/tomahawkapp.h | 1 + src/tomahawkwindow.cpp | 60 +++--- src/tomahawkwindow.h | 18 +- 17 files changed, 228 insertions(+), 348 deletions(-) diff --git a/src/AccountDelegate.h b/src/AccountDelegate.h index 99607e5f6..a3d5c2196 100644 --- a/src/AccountDelegate.h +++ b/src/AccountDelegate.h @@ -20,6 +20,7 @@ #define ACCOUNTDELEGATE_H #include "configdelegatebase.h" +#include "accounts/AccountModel.h" namespace Tomahawk { diff --git a/src/accounts/twitter/twitteraccount.h b/src/accounts/twitter/twitteraccount.h index ac7ad5c6e..f003e39b8 100644 --- a/src/accounts/twitter/twitteraccount.h +++ b/src/accounts/twitter/twitteraccount.h @@ -24,7 +24,7 @@ #include "sip/twittersip.h" #include "accounts/accountdllmacro.h" -#include "accounts/account.h" +#include "accounts/Account.h" #define MYNAME "ACCOUNTTWITTER" @@ -77,7 +77,7 @@ public: signals: void nowAuthenticated( const QWeakPointer< TomahawkOAuthTwitter >&, const QTweetUser &user ); void nowDeauthenticated(); - + private slots: void configDialogAuthedSignalSlot( bool authed ); void connectAuthVerifyReply( const QTweetUser &user ); diff --git a/src/accounts/xmpp/xmppaccount.h b/src/accounts/xmpp/xmppaccount.h index d7f54514e..cb9d9fba9 100644 --- a/src/accounts/xmpp/xmppaccount.h +++ b/src/accounts/xmpp/xmppaccount.h @@ -22,7 +22,7 @@ #include "sip/xmppsip.h" #include "accounts/accountdllmacro.h" -#include "accounts/account.h" +#include "accounts/Account.h" #define MYNAME "ACCOUNTJABBER" @@ -33,7 +33,7 @@ namespace Tomahawk namespace Accounts { - + class ACCOUNTDLLEXPORT XmppAccountFactory : public AccountFactory { Q_OBJECT @@ -70,7 +70,7 @@ public: QWidget* aclWidget() { return 0; } void refreshProxy() {}; - + private: Ui_XmppConfigWidget* m_ui; // so the google wrapper can change the config dialog a bit bool m_isAuthenticated; diff --git a/src/libtomahawk/accounts/Account.cpp b/src/libtomahawk/accounts/Account.cpp index 699ccfccf..238118f81 100644 --- a/src/libtomahawk/accounts/Account.cpp +++ b/src/libtomahawk/accounts/Account.cpp @@ -55,14 +55,6 @@ Account::icon() const return QIcon(); } - -bool -Account::canSelfAuthenticate() const -{ - return false; -} - - void Account::authenticate() { @@ -88,4 +80,23 @@ void Account::refreshProxy() { +} + +void +Account::onError(int errorCode, const QString& error ) +{ + QMutexLocker locker( &m_mutex ); + m_cachedError = error; +} + + +void +Account::onConnectionStateChanged( Account::ConnectionState ) +{ + m_cachedError.clear(); +} + + +} + } \ No newline at end of file diff --git a/src/libtomahawk/accounts/Account.h b/src/libtomahawk/accounts/Account.h index 06f79d52b..556fd49bb 100644 --- a/src/libtomahawk/accounts/Account.h +++ b/src/libtomahawk/accounts/Account.h @@ -79,8 +79,6 @@ public: virtual QIcon icon() const = 0; - virtual void authenticate() = 0; - virtual void deauthenticate() = 0; virtual ConnectionState connectionState() = 0; virtual bool isAuthenticated() const = 0; @@ -134,6 +132,10 @@ public: virtual void sync() { QMutexLocker locker( &m_mutex ); syncConfig(); }; +public slots: + virtual void authenticate() = 0; + virtual void deauthenticate() = 0; + signals: void error( int errorId, const QString& errorStr ); void connectionStateChanged( Tomahawk::Accounts::Account::ConnectionState state ); @@ -174,7 +176,7 @@ protected: private slots: void onConnectionStateChanged( Tomahawk::Accounts::Account::ConnectionState ); - void onError( int,QString ); + void onError( int, const QString& ); private: QString m_accountServiceName; diff --git a/src/libtomahawk/accounts/AccountManager.cpp b/src/libtomahawk/accounts/AccountManager.cpp index 42fffc75b..7aec4fbf3 100644 --- a/src/libtomahawk/accounts/AccountManager.cpp +++ b/src/libtomahawk/accounts/AccountManager.cpp @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2010-2011, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,11 +19,14 @@ #include "AccountManager.h" #include "config.h" +#include "sourcelist.h" #include #include #include #include +#include +#include namespace Tomahawk { @@ -63,7 +67,7 @@ AccountManager::findPluginFactories() QList< QDir > pluginDirs; QDir appDir( qApp->applicationDirPath() ); - #ifdef Q_WS_MAC +#ifdef Q_WS_MAC if ( appDir.dirName() == "MacOS" ) { // Development convenience-hack @@ -71,7 +75,7 @@ AccountManager::findPluginFactories() appDir.cdUp(); appDir.cdUp(); } - #endif +#endif QDir libDir( CMAKE_INSTALL_PREFIX "/lib" ); @@ -141,19 +145,46 @@ AccountManager::loadPluginFactory( const QString& path ) } + +void +AccountManager::connectAll() +{ + foreach( Account* acc, m_accounts ) + { + if ( acc->types().contains( Accounts::SipType ) && acc->sipPlugin() ) + acc->sipPlugin()->connectPlugin(); + + } + m_connected = true; +} + + +void +AccountManager::disconnectAll() +{ + foreach( Account* acc, m_connectedAccounts ) + acc->sipPlugin()->disconnectPlugin(); + + SourceList::instance()->removeAllRemote(); + m_connected = false; +} + + +void +AccountManager::toggleAccountsConnected() +{ + if ( m_connected ) + disconnectAll(); + else + connectAll(); +} + + void AccountManager::loadFromConfig() { QStringList accountIds = TomahawkSettings::instance()->accounts(); - //FIXME: this is just for debugging - if ( accountIds.isEmpty() ) - { - Account* account = m_accountFactories[ "twitteraccount" ]->createAccount(); - addAccountPlugin( account ); - TomahawkSettings::instance()->addAccount( account->accountId() ); - } - foreach( const QString& accountId, accountIds ) { QString pluginFactory = factoryFromId( accountId ); @@ -165,6 +196,18 @@ AccountManager::loadFromConfig() } } +void +AccountManager::initSIP() +{ + tDebug() << Q_FUNC_INFO; + foreach( Account* account, accounts( Tomahawk::Accounts::SipType ) ) + { + tDebug() << Q_FUNC_INFO << "adding plugin " << account->accountId(); + SipPlugin* p = account->sipPlugin(); + SipHandler::instance()->hookUpPlugin( p ); + } +} + Account* @@ -175,8 +218,8 @@ AccountManager::loadPlugin( const QString& accountId ) Q_ASSERT( m_accountFactories.contains( factoryName ) ); Account* account = m_accountFactories[ factoryName ]->createAccount( accountId ); + hookupAccount( account ); - // caller responsible for calling pluginAdded() and hookupPlugin return account; } @@ -189,7 +232,66 @@ AccountManager::addAccountPlugin( Account* account ) foreach( AccountType type, account->types() ) m_accountsByAccountType[ type ].append( account ); - emit accountAdded( account ); + emit added( account ); +} + +void +AccountManager::hookupAccount( Account* account ) const +{ + connect( account, SIGNAL( error( int, QString ) ), SLOT( onError( int, QString ) ) ); + connect( account, SIGNAL( stateChanged( SipPlugin::ConnectionState ) ), SLOT( onStateChanged( Accounts::Account::ConnectionState ) ) ); +} + + + +void +AccountManager::onError( int code, const QString& msg ) +{ + Account* account = qobject_cast< Account* >( sender() ); + Q_ASSERT( account ); + + + qWarning() << "Failed to connect to SIP:" << account->accountFriendlyName() << code << msg; + + if ( code == Account::AuthError ) + { + emit authError( account ); + } + else + { + QTimer::singleShot( 10000, account, SLOT( authenticate() ) ); + } +} + +void +AccountManager::onSettingsChanged() +{ + foreach( Account* account, m_accounts ) + { + if ( account->types().contains( Accounts::SipType ) && account->sipPlugin() ) + account->sipPlugin()->checkSettings(); + } +} + + +void +AccountManager::onStateChanged( Account::ConnectionState state ) +{ + Account* account = qobject_cast< Account* >( sender() ); + Q_ASSERT( account ); + + if ( account->connectionState() == Account::Disconnected ) + { + m_connectedAccounts.removeAll( account ); + emit disconnected( account ); + } + else if ( account->connectionState() == Account::Connected ) + { + m_connectedAccounts << account; + emit connected( account ); + } + + emit stateChanged( account, state ); } diff --git a/src/libtomahawk/accounts/AccountManager.h b/src/libtomahawk/accounts/AccountManager.h index ee45c46a6..482c55648 100644 --- a/src/libtomahawk/accounts/AccountManager.h +++ b/src/libtomahawk/accounts/AccountManager.h @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2010-2011, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -47,6 +48,8 @@ public: void loadPluginFactories( const QStringList &paths ); void loadFromConfig(); + void initSIP(); + void loadPluginFactory( const QString &path ); void addAccountPlugin( Account* account ); Account* loadPlugin( const QString &accountId ); @@ -58,12 +61,26 @@ public: public slots: void connectAll(); void disconnectAll(); + void toggleAccountsConnected(); signals: - void accountAdded( Tomahawk::Accounts::Account* ); - void accountRemoved( Tomahawk::Accounts::Account* ); + void added( Tomahawk::Accounts::Account* ); + void removed( Tomahawk::Accounts::Account* ); + void connected( Tomahawk::Accounts::Account* ); + void disconnected( Tomahawk::Accounts::Account* ); + void authError( Tomahawk::Accounts::Account* ); + + void stateChanged( Account* p, Accounts::Account::ConnectionState state ); + +private slots: + void onStateChanged( Accounts::Account::ConnectionState state ); + void onError( int code, const QString& msg ); + + void onSettingsChanged(); private: + void hookupAccount( Account* ) const; + QList< Account* > m_accounts; QList< Account* > m_enabledAccounts; QList< Account* > m_connectedAccounts; diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index 1e4dfd481..f49d4a2a8 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -30,8 +30,8 @@ using namespace Accounts; AccountModel::AccountModel( QObject* parent ) : QAbstractListModel( parent ) { - connect( AccountManager::instance(), SIGNAL( accountAdded( Tomahawk::Accounts::Account* ) ), this, SLOT( accountAdded( Tomahawk::Accounts::Account* ) ) ); - connect( AccountManager::instance(), SIGNAL( accountRemoved( Tomahawk::Accounts::Account* ) ), this, SLOT( accountRemoved( Tomahawk::Accounts::Account* ) ) ); + connect( AccountManager::instance(), SIGNAL( added( Tomahawk::Accounts::Account* ) ), this, SLOT( accountAdded( Tomahawk::Accounts::Account* ) ) ); + connect( AccountManager::instance(), SIGNAL( removed( Tomahawk::Accounts::Account* ) ), this, SLOT( accountRemoved( Tomahawk::Accounts::Account* ) ) ); } @@ -98,7 +98,7 @@ AccountModel::setData( const QModelIndex& index, const QVariant& value, int role } int -AccountModel::rowCount( const QModelIndex& parent ) const +AccountModel::rowCount( const QModelIndex& ) const { return AccountManager::instance()->accounts().size(); } @@ -113,8 +113,7 @@ AccountModel::flags( const QModelIndex& index ) const void AccountModel::accountAdded( Account* account ) { - Q_UNUSED( p ); - // we assume account plugins are added at the end of the list. + // TODO HACK we assume account plugins are added at the end of the list. Q_ASSERT( AccountManager::instance()->accounts().last() == account ); if ( account->types().contains( SipType ) ) connect( account, SIGNAL( connectionStateChanged( Tomahawk::Accounts::Account::ConnectionState ) ), this, SLOT( accountStateChanged( Tomahawk::Accounts::Account::ConnectionState ) ) ); @@ -128,17 +127,17 @@ AccountModel::accountAdded( Account* account ) void AccountModel::accountRemoved( Account* account ) { - int idx = AccountManager::instance()->allPlugins().indexOf( account ); + int idx = AccountManager::instance()->accounts().indexOf( account ); beginRemoveRows( QModelIndex(), idx, idx ); endRemoveRows(); } void -AccountModel::accountStateChanged( Tomahawk::Accounts::Account::ConnectionState state ) +AccountModel::accountStateChanged( Tomahawk::Accounts::Account::ConnectionState ) { Account* account = qobject_cast< Account* >( sender() ); - Q_ASSERT( a ); + Q_ASSERT( account ); for ( int i = 0; i < AccountManager::instance()->accounts().size(); i++ ) { diff --git a/src/libtomahawk/accounts/AccountModel.h b/src/libtomahawk/accounts/AccountModel.h index 72b3cdada..96b23d2b3 100644 --- a/src/libtomahawk/accounts/AccountModel.h +++ b/src/libtomahawk/accounts/AccountModel.h @@ -22,6 +22,7 @@ #include "dllmacro.h" #include "sip/SipPlugin.h" +#include #include #include diff --git a/src/libtomahawk/sip/SipHandler.cpp b/src/libtomahawk/sip/SipHandler.cpp index 582d67600..5d08009cb 100644 --- a/src/libtomahawk/sip/SipHandler.cpp +++ b/src/libtomahawk/sip/SipHandler.cpp @@ -52,7 +52,6 @@ SipHandler::instance() SipHandler::SipHandler( QObject* parent ) : QObject( parent ) - , m_connected( false ) { s_instance = this; @@ -97,13 +96,6 @@ SipHandler::versionString( const QString& peerId ) const } -void -SipHandler::onSettingsChanged() -{ - checkSettings(); -} - - void SipHandler::hookUpPlugin( SipPlugin* sip ) { @@ -113,164 +105,13 @@ SipHandler::hookUpPlugin( SipPlugin* sip ) QObject::connect( sip, SIGNAL( sipInfoReceived( QString, SipInfo ) ), SLOT( onSipInfo( QString, SipInfo ) ) ); QObject::connect( sip, SIGNAL( softwareVersionReceived( QString, QString ) ), SLOT( onSoftwareVersion( QString, QString ) ) ); - QObject::connect( sip, SIGNAL( error( int, QString ) ), SLOT( onError( int, QString ) ) ); - QObject::connect( sip, SIGNAL( stateChanged( SipPlugin::ConnectionState ) ), SLOT( onStateChanged( SipPlugin::ConnectionState ) ) ); - QObject::connect( sip, SIGNAL( avatarReceived( QString, QPixmap ) ), SLOT( onAvatarReceived( QString, QPixmap ) ) ); QObject::connect( sip, SIGNAL( avatarReceived( QPixmap ) ), SLOT( onAvatarReceived( QPixmap ) ) ); QObject::connect( sip->account(), SIGNAL( configurationChanged() ), sip, SLOT( configurationChanged() ) ); } - -bool -SipHandler::pluginLoaded( const QString& pluginId ) const -{ - foreach( SipPlugin* plugin, m_allPlugins ) - { - if ( plugin->pluginId() == pluginId ) - return true; - } - - return false; -} - - -void -SipHandler::checkSettings() -{ - foreach( SipPlugin* sip, m_allPlugins ) - { - sip->checkSettings(); - } -} - - -void -SipHandler::addSipPlugin( SipPlugin* p ) -{ - m_allPlugins << p; - - hookUpPlugin( p ); - p->connectPlugin(); - - emit pluginAdded( p ); -} - - -void -SipHandler::removeSipPlugin( SipPlugin* p ) -{ - p->disconnectPlugin(); - - emit pluginRemoved( p ); - - m_allPlugins.removeAll( p ); -} - - -void -SipHandler::loadFromAccountManager() -{ - tDebug() << Q_FUNC_INFO; - QList< Tomahawk::Accounts::Account* > accountList = Tomahawk::Accounts::AccountManager::instance()->accounts( Tomahawk::Accounts::SipType ); - foreach( Tomahawk::Accounts::Account* account, accountList ) - { - tDebug() << Q_FUNC_INFO << "adding plugin " << account->accountId(); - SipPlugin* p = account->sipPlugin(); - addSipPlugin( p ); - } - m_connected = true; -} - - -void -SipHandler::connectAll() -{ - foreach( SipPlugin* sip, m_allPlugins ) - { - sip->connectPlugin(); - } - m_connected = true; -} - - -void -SipHandler::disconnectAll() -{ - foreach( SipPlugin* p, m_connectedPlugins ) - p->disconnectPlugin(); - - SourceList::instance()->removeAllRemote(); - m_connected = false; -} - - -void -SipHandler::connectPlugin( const QString &pluginId ) -{ -#ifndef TOMAHAWK_HEADLESS - if ( !TomahawkSettings::instance()->acceptedLegalWarning() ) - { - int result = QMessageBox::question( - //TomahawkApp::instance()->mainWindow(), - 0, tr( "Legal Warning" ), - tr( "By pressing OK below, you agree that your use of Tomahawk will be in accordance with any applicable laws, including copyright and intellectual property laws, in effect in your country of residence, and indemnify the Tomahawk developers and project from liability should you choose to break those laws.\n\nFor more information, please see http://gettomahawk.com/legal" ), - tr( "I Do Not Agree" ), tr( "I Agree" ) - ); - if ( result != 1 ) - return; - else - TomahawkSettings::instance()->setAcceptedLegalWarning( true ); - } -#endif - foreach( SipPlugin* sip, m_allPlugins ) - { - if ( sip->pluginId() == pluginId ) - { - Q_ASSERT( m_allPlugins.contains( sip ) ); // make sure the plugin we're connecting is enabled. should always be the case - //each sip should refreshProxy() or take care of that function in some other way during connection - sip->connectPlugin(); - } - } -} - - -void -SipHandler::disconnectPlugin( const QString &pluginName ) -{ - foreach( SipPlugin* sip, m_connectedPlugins ) - { - if ( sip->account()->accountId() == pluginName ) - sip->disconnectPlugin(); - } -} - - -QList< SipPlugin* > -SipHandler::allPlugins() const -{ - return m_allPlugins; -} - - -QList< SipPlugin* > -SipHandler::connectedPlugins() const -{ - return m_connectedPlugins; -} - - -void -SipHandler::toggleConnect() -{ - if( m_connected ) - disconnectAll(); - else - connectAll(); -} - - +/* void SipHandler::refreshProxy() { @@ -278,7 +119,7 @@ SipHandler::refreshProxy() foreach( SipPlugin* sip, m_allPlugins ) sip->refreshProxy(); -} +}*/ void @@ -381,47 +222,6 @@ SipHandler::onMessage( const QString& from, const QString& msg ) qDebug() << Q_FUNC_INFO << from << msg; } - -void -SipHandler::onError( int code, const QString& msg ) -{ - SipPlugin* sip = qobject_cast< SipPlugin* >( sender() ); - Q_ASSERT( sip ); - - qWarning() << "Failed to connect to SIP:" << sip->account()->accountFriendlyName() << code << msg; - - if ( code == SipPlugin::AuthError ) - { - emit authError( sip ); - } - else - { - QTimer::singleShot( 10000, sip, SLOT( connectPlugin() ) ); - } -} - - -void -SipHandler::onStateChanged( SipPlugin::ConnectionState state ) -{ - SipPlugin* sip = qobject_cast< SipPlugin* >( sender() ); - Q_ASSERT( sip ); - - if ( sip->connectionState() == SipPlugin::Disconnected ) - { - m_connectedPlugins.removeAll( sip ); - emit disconnected( sip ); - } - else if ( sip->connectionState() == SipPlugin::Connected ) - { - m_connectedPlugins << sip; - emit connected( sip ); - } - - emit stateChanged( sip, state ); -} - - void SipHandler::onAvatarReceived( const QString& from, const QPixmap& avatar ) { diff --git a/src/libtomahawk/sip/SipHandler.h b/src/libtomahawk/sip/SipHandler.h index 1d2ef1688..a7ab5eff4 100644 --- a/src/libtomahawk/sip/SipHandler.h +++ b/src/libtomahawk/sip/SipHandler.h @@ -31,8 +31,12 @@ #include #endif +/** + * Manages SIP plugins for connecting to friends. External interface to SIP plugins is + * through AccountManager, this is an internal class. + */ -class DLLEXPORT SipHandler : public QObject +class SipHandler : public QObject { Q_OBJECT @@ -42,13 +46,8 @@ public: SipHandler( QObject* parent ); ~SipHandler(); - QList< SipPlugin* > allPlugins() const; - QList< SipPlugin* > connectedPlugins() const; void loadFromAccountManager(); - void addSipPlugin( SipPlugin* p ); - void removeSipPlugin( SipPlugin* p ); - bool hasPluginType( const QString& factoryId ) const; const QPixmap avatar( const QString& name ) const; @@ -56,25 +55,11 @@ public: const SipInfo sipInfo( const QString& peerId ) const; const QString versionString( const QString& peerId ) const; + void hookUpPlugin( SipPlugin* p ); + public slots: - void checkSettings(); - - void connectPlugin( const QString &pluginId = QString() ); - void disconnectPlugin( const QString &pluginId = QString() ); - - void toggleConnect(); - - void refreshProxy(); - -signals: - void connected( SipPlugin* ); - void disconnected( SipPlugin* ); - void authError( SipPlugin* ); - - void stateChanged( SipPlugin* p, SipPlugin::ConnectionState state ); - - void pluginAdded( SipPlugin* p ); - void pluginRemoved( SipPlugin* p ); +// TODO no longer called from anywhere... can we remove it? +// void refreshProxy(); private slots: void onSipInfo( const QString& peerId, const SipInfo& info ); @@ -82,10 +67,6 @@ private slots: void onMessage( const QString&, const QString& ); void onPeerOffline( const QString& ); void onPeerOnline( const QString& ); - void onError( int code, const QString& msg ); - void onStateChanged( SipPlugin::ConnectionState ); - - void onSettingsChanged(); // set data for local source void onAvatarReceived( const QPixmap& avatar ); @@ -96,14 +77,6 @@ private slots: private: static SipHandler *s_instance; - QStringList findPluginFactories(); - bool pluginLoaded( const QString& pluginId ) const; - void hookUpPlugin( SipPlugin* p ); - - void loadPluginFactories( const QStringList& paths ); - void loadPluginFactory( const QString& path ); - QString factoryFromId( const QString& pluginId ) const; - //TODO: move this to source QHash m_peersSipInfos; QHash m_usernameAvatars; diff --git a/src/libtomahawk/sip/SipPlugin.cpp b/src/libtomahawk/sip/SipPlugin.cpp index 148479a71..54a5fdf37 100644 --- a/src/libtomahawk/sip/SipPlugin.cpp +++ b/src/libtomahawk/sip/SipPlugin.cpp @@ -2,6 +2,7 @@ * * Copyright 2010-2011, Christian Muehlhaeuser * 2011, Dominik Schmidt + * 2010-2011, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -67,13 +68,6 @@ SipPlugin::account() const } -QString -SipPlugin::errorMessage() const -{ - return m_cachedError; -} - - QIcon SipPlugin::icon() const { @@ -95,22 +89,6 @@ SipPlugin::refreshProxy() } -void -SipPlugin::onError( int code, const QString& error ) -{ - Q_UNUSED( code ); - m_cachedError = error; -} - - -void -SipPlugin::onStateChange( SipPlugin::ConnectionState state ) -{ - Q_UNUSED( state ); - m_cachedError.clear(); -} - - void SipPlugin::onPeerOnline( const QString& peerId ) { diff --git a/src/libtomahawk/sip/SipPlugin.h b/src/libtomahawk/sip/SipPlugin.h index af622dd11..08c9efb9b 100644 --- a/src/libtomahawk/sip/SipPlugin.h +++ b/src/libtomahawk/sip/SipPlugin.h @@ -2,6 +2,7 @@ * * Copyright 2010-2011, Christian Muehlhaeuser * 2011, Dominik Schmidt + * 2010-2011, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index 7aefdfe7d..a299c2579 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -35,7 +35,7 @@ #include "album.h" #include "collection.h" #include "infosystem/infosystem.h" -#include "accounts/accountmanager.h" +#include "accounts/AccountManager.h" #include "database/database.h" #include "database/databasecollection.h" #include "database/databasecommand_collectionstats.h" @@ -505,16 +505,6 @@ void TomahawkApp::initSIP() { tDebug() << Q_FUNC_INFO; - // TODO debugging hack only - foreach ( Tomahawk::Accounts::Account* account, Tomahawk::Accounts::AccountManager::instance()->accounts() ) - { - tDebug() << Q_FUNC_INFO << "testing account with name " << account->accountServiceName(); - if ( account->configurationWidget() && account->configuration().isEmpty() ) - account->configurationWidget()->show(); - if ( !account->enabled() ) - account->setEnabled( true ); - } - //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" ) ) { @@ -523,7 +513,7 @@ TomahawkApp::initSIP() #endif tDebug( LOGINFO ) << "Connecting SIP classes"; - SipHandler::instance()->loadFromAccountManager(); + Accounts::AccountManager::instance()->loadFromConfig(); } } diff --git a/src/tomahawkapp.h b/src/tomahawkapp.h index 548b37ff5..c1ac7648b 100644 --- a/src/tomahawkapp.h +++ b/src/tomahawkapp.h @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2010-2011, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/tomahawkwindow.cpp b/src/tomahawkwindow.cpp index 2e90e2ffe..97b023604 100644 --- a/src/tomahawkwindow.cpp +++ b/src/tomahawkwindow.cpp @@ -39,7 +39,7 @@ #include "artist.h" #include "audio/audioengine.h" #include "viewmanager.h" -#include "sip/SipHandler.h" +#include "accounts/AccountManager.h" #include "sourcetree/sourcetreeview.h" #include "network/servent.h" #include "utils/proxystyle.h" @@ -73,7 +73,7 @@ #include using namespace Tomahawk; - +using namespace Accounts; TomahawkWindow::TomahawkWindow( QWidget* parent ) : QMainWindow( parent ) @@ -106,12 +106,12 @@ TomahawkWindow::TomahawkWindow( QWidget* parent ) ui->menu_Help->addSeparator(); ui->menu_Help->addAction( "Crash now...", this, SLOT( crashNow() ) ); } - + ui->menuApp->insertAction( ui->actionCreatePlaylist, ActionCollection::instance()->getAction( "togglePrivacy" ) ); ui->menuApp->insertSeparator( ui->actionCreatePlaylist ); // set initial state - onSipDisconnected(); + onAccountDisconnected(); vm->setQueue( m_queueView ); vm->showWelcomePage(); } @@ -306,7 +306,7 @@ TomahawkWindow::setupSignals() // connect( ui->actionAddPeerManually, SIGNAL( triggered() ), SLOT( addPeerManually() ) ); connect( ui->actionPreferences, SIGNAL( triggered() ), SLOT( showSettingsDialog() ) ); connect( ui->actionDiagnostics, SIGNAL( triggered() ), SLOT( showDiagnosticsDialog() ) ); - connect( ui->actionToggleConnect, SIGNAL( triggered() ), SipHandler::instance(), SLOT( toggleConnect() ) ); + connect( ui->actionToggleConnect, SIGNAL( triggered() ), AccountManager::instance(), SLOT( toggleAccountsConnected() ) ); connect( ui->actionUpdateCollection, SIGNAL( triggered() ), SLOT( updateCollectionManually() ) ); connect( ui->actionRescanCollection, SIGNAL( triggered() ), SLOT( rescanCollectionManually() ) ); connect( ui->actionLoadXSPF, SIGNAL( triggered() ), SLOT( loadSpiff() )); @@ -328,18 +328,20 @@ TomahawkWindow::setupSignals() ui->menuWindow->menuAction()->setVisible( false ); #endif - // - connect( SipHandler::instance(), SIGNAL( connected( SipPlugin* ) ), SLOT( onSipConnected() ) ); - connect( SipHandler::instance(), SIGNAL( disconnected( SipPlugin* ) ), SLOT( onSipDisconnected() ) ); - connect( SipHandler::instance(), SIGNAL( authError( SipPlugin* ) ), SLOT( onSipError() ) ); + // + connect( AccountManager::instance(), SIGNAL( connected( Tomahawk::Accounts::Account* ) ), SLOT( onAccountConnected() ) ); + connect( AccountManager::instance(), SIGNAL( disconnected( Tomahawk::Accounts::Account* ) ), SLOT( onAccountDisconnected() ) ); + connect( AccountManager::instance(), SIGNAL( authError( Tomahawk::Accounts::Account* ) ), SLOT( onAccountError() ) ); - // - connect( SipHandler::instance(), SIGNAL( pluginAdded( SipPlugin* ) ), this, SLOT( onSipPluginAdded( SipPlugin* ) ) ); - connect( SipHandler::instance(), SIGNAL( pluginRemoved( SipPlugin* ) ), this, SLOT( onSipPluginRemoved( SipPlugin* ) ) ); - foreach( SipPlugin *plugin, SipHandler::instance()->allPlugins() ) + // Menus for accounts that support them + connect( AccountManager::instance(), SIGNAL( added( Tomahawk::Accounts::Account* ) ), this, SLOT( onAccountAdded( Tomahawk::Accounts::Account* ) ) ); + foreach( Account* account, AccountManager::instance()->accounts( Tomahawk::Accounts::SipType ) ) { - connect( plugin, SIGNAL( addMenu( QMenu* ) ), this, SLOT( pluginMenuAdded( QMenu* ) ) ); - connect( plugin, SIGNAL( removeMenu( QMenu* ) ), this, SLOT( pluginMenuRemoved( QMenu* ) ) ); + if ( !account || !account->sipPlugin() ) + continue; + + connect( account->sipPlugin(), SIGNAL( addMenu( QMenu* ) ), this, SLOT( pluginMenuAdded( QMenu* ) ) ); + connect( account->sipPlugin(), SIGNAL( removeMenu( QMenu* ) ), this, SLOT( pluginMenuRemoved( QMenu* ) ) ); } } @@ -654,39 +656,37 @@ TomahawkWindow::onPlaybackLoading( const Tomahawk::result_ptr& result ) } void -TomahawkWindow::onSipConnected() +TomahawkWindow::onAccountConnected() { ui->actionToggleConnect->setText( tr( "Go &offline" ) ); } void -TomahawkWindow::onSipDisconnected() +TomahawkWindow::onAccountDisconnected() { ui->actionToggleConnect->setText( tr( "Go &online" ) ); } void -TomahawkWindow::onSipPluginAdded( SipPlugin* p ) +TomahawkWindow::onAccountAdded( Account* acc ) { - connect( p, SIGNAL( addMenu( QMenu* ) ), this, SLOT( pluginMenuAdded( QMenu* ) ) ); - connect( p, SIGNAL( removeMenu( QMenu* ) ), this, SLOT( pluginMenuRemoved( QMenu* ) ) ); + if ( !acc->types().contains( SipType ) || + !acc->sipPlugin() ) + return; + + connect( acc->sipPlugin(), SIGNAL( addMenu( QMenu* ) ), this, SLOT( pluginMenuAdded( QMenu* ) ) ); + connect( acc->sipPlugin(), SIGNAL( removeMenu( QMenu* ) ), this, SLOT( pluginMenuRemoved( QMenu* ) ) ); } - void -TomahawkWindow::onSipPluginRemoved( SipPlugin* p ) +TomahawkWindow::onAccountError() { - Q_UNUSED( p ); -} - - -void -TomahawkWindow::onSipError() -{ - onSipDisconnected(); + // TODO fix. +// onAccountDisconnected(); + // TODO real error message from plugin kthxbbq QMessageBox::warning( this, tr( "Authentication Error" ), QString( "Error connecting to SIP: Authentication failed!" ), diff --git a/src/tomahawkwindow.h b/src/tomahawkwindow.h index 5e0fcaa1d..802d4eda5 100644 --- a/src/tomahawkwindow.h +++ b/src/tomahawkwindow.h @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2010-2011, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,9 +29,14 @@ #include "result.h" #include "utils/xspfloader.h" +namespace Tomahawk { +namespace Accounts { + class Account; +} +} + class JobStatusModel; class QSearchField; -class SipPlugin; class SourceTreeView; class QAction; @@ -80,9 +86,10 @@ public slots: void showOfflineSources(); private slots: - void onSipConnected(); - void onSipDisconnected(); - void onSipError(); + void onAccountAdded( Tomahawk::Accounts::Account* account ); + void onAccountConnected(); + void onAccountDisconnected(); + void onAccountError(); void onXSPFError( XSPFLoader::XSPFErrorCode error ); void onXSPFOk( const Tomahawk::playlist_ptr& ); @@ -97,9 +104,6 @@ private slots: void showAboutTomahawk(); void checkForUpdates(); - void onSipPluginAdded( SipPlugin* p ); - void onSipPluginRemoved( SipPlugin* p ); - void onSearch( const QString& search ); void onFilterEdited(); From 00adb66cf0f41466a0b0f4719bb406a62eb304a7 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sun, 11 Dec 2011 22:57:14 -0500 Subject: [PATCH 022/104] ready for settings dialog work --- src/diagnosticsdialog.cpp | 148 ++++++++++++++++----------------- src/resolverconfigdelegate.cpp | 6 +- src/resolverconfigdelegate.h | 4 +- src/settingsdialog.cpp | 15 ++-- src/settingsdialog.h | 16 +++- 5 files changed, 101 insertions(+), 88 deletions(-) diff --git a/src/diagnosticsdialog.cpp b/src/diagnosticsdialog.cpp index f4d4473e9..cc77abab5 100644 --- a/src/diagnosticsdialog.cpp +++ b/src/diagnosticsdialog.cpp @@ -90,81 +90,81 @@ void DiagnosticsDialog::updateLogView() log.append("\n\n"); - // Peers - log.append("SIP PLUGINS:\n"); - QList< Tomahawk::source_ptr > sources = SourceList::instance()->sources( true ); - Q_FOREACH(SipPlugin *sip, SipHandler::instance()->allPlugins()) - { - Q_ASSERT(sip); - QString stateString; - switch( sip->connectionState() ) - { - case SipPlugin::Connecting: - stateString = "Connecting"; - break; + // Peers / Accounts, TODO + log.append("ACCOUNTS:\n"); +// QList< Tomahawk::source_ptr > sources = SourceList::instance()->sources( true ); +// Q_FOREACH(SipPlugin *sip, SipHandler::instance()->allPlugins()) +// { +// Q_ASSERT(sip); +// QString stateString; +// switch( sip->connectionState() ) +// { +// case SipPlugin::Connecting: +// stateString = "Connecting"; +// break; +// +// case SipPlugin::Connected: +// stateString = "Connected"; +// break; +// +// case SipPlugin::Disconnected: +// stateString = "Disconnected"; +// break; +// case SipPlugin::Disconnecting: +// stateString = "Disconnecting"; +// } +// log.append( +// QString(" %2 (%1): %3 (%4)\n") +// .arg(sip->account()->accountServiceName()) +// .arg(sip->friendlyName()) +// .arg(sip->account()->accountFriendlyName()) +// .arg(stateString) +// ); - case SipPlugin::Connected: - stateString = "Connected"; - break; - - case SipPlugin::Disconnected: - stateString = "Disconnected"; - break; - case SipPlugin::Disconnecting: - stateString = "Disconnecting"; - } - log.append( - QString(" %2 (%1): %3 (%4)\n") - .arg(sip->account()->accountServiceName()) - .arg(sip->friendlyName()) - .arg(sip->account()->accountFriendlyName()) - .arg(stateString) - ); - - Q_FOREACH( const QString &peerId, sip->peersOnline() ) - { - /* enable this again, when we check the source has this peerId - bool connected = false; - Q_FOREACH( const Tomahawk::source_ptr &source, sources ) - { - if( source->controlConnection() ) - { - connected = true; - break; - } - }*/ - - QString versionString = SipHandler::instance()->versionString( peerId ); - SipInfo sipInfo = SipHandler::instance()->sipInfo( peerId ); - if( !sipInfo.isValid() ) - log.append( - QString(" %1: %2 %3" /*"(%4)"*/ "\n") - .arg( peerId ) - .arg( "sipinfo invalid" ) - .arg( versionString ) - // .arg( connected ? "connected" : "not connected") - ); - else if( sipInfo.isVisible() ) - log.append( - QString(" %1: %2:%3 %4" /*" (%5)"*/ "\n") - .arg( peerId ) - .arg( sipInfo.host().hostName() ) - .arg( sipInfo.port() ) - .arg( versionString ) - // .arg( connected ? "connected" : "not connected") - - ); - else - log.append( - QString(" %1: visible: false %2" /*" (%3)"*/ "\n") - .arg( peerId ) - .arg( versionString ) - // .arg( connected ? "connected" : "not connected") - - ); - } - log.append("\n"); - } +// Q_FOREACH( const QString &peerId, sip->peersOnline() ) +// { +// /* enable this again, when we check the source has this peerId +// bool connected = false; +// Q_FOREACH( const Tomahawk::source_ptr &source, sources ) +// { +// if( source->controlConnection() ) +// { +// connected = true; +// break; +// } +// }*/ +// +// QString versionString = SipHandler::instance()->versionString( peerId ); +// SipInfo sipInfo = SipHandler::instance()->sipInfo( peerId ); +// if( !sipInfo.isValid() ) +// log.append( +// QString(" %1: %2 %3" /*"(%4)"*/ "\n") +// .arg( peerId ) +// .arg( "sipinfo invalid" ) +// .arg( versionString ) +// // .arg( connected ? "connected" : "not connected") +// ); +// else if( sipInfo.isVisible() ) +// log.append( +// QString(" %1: %2:%3 %4" /*" (%5)"*/ "\n") +// .arg( peerId ) +// .arg( sipInfo.host().hostName() ) +// .arg( sipInfo.port() ) +// .arg( versionString ) +// // .arg( connected ? "connected" : "not connected") +// +// ); +// else +// log.append( +// QString(" %1: visible: false %2" /*" (%3)"*/ "\n") +// .arg( peerId ) +// .arg( versionString ) +// // .arg( connected ? "connected" : "not connected") +// +// ); +// } +// log.append("\n"); +// } ui->logView->setPlainText(log); } diff --git a/src/resolverconfigdelegate.cpp b/src/resolverconfigdelegate.cpp index 9ff6c8f1a..1473a6a52 100644 --- a/src/resolverconfigdelegate.cpp +++ b/src/resolverconfigdelegate.cpp @@ -1,6 +1,6 @@ /* === This file is part of Tomahawk Player - === * - * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2010-2011, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -133,8 +133,10 @@ ResolverConfigDelegate::configRectForIndex( const QStyleOptionViewItem& option, } QRect -ResolverConfigDelegate::checkRectForIndex( const QStyleOptionViewItem &option, const QModelIndex &idx ) const +ResolverConfigDelegate::checkRectForIndex( const QStyleOptionViewItem &option, const QModelIndex &idx, int role ) const { + Q_UNUSED( role ); + QStyleOptionViewItemV4 opt = option; initStyleOption( &opt, idx ); QRect itemRect = opt.rect; diff --git a/src/resolverconfigdelegate.h b/src/resolverconfigdelegate.h index 62e3fe9ee..a6c8f32d8 100644 --- a/src/resolverconfigdelegate.h +++ b/src/resolverconfigdelegate.h @@ -1,6 +1,6 @@ /* === This file is part of Tomahawk Player - === * - * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2010-2011, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -29,7 +29,7 @@ public: explicit ResolverConfigDelegate( QObject* parent = 0 ); virtual void paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const; - virtual QRect checkRectForIndex( const QStyleOptionViewItem &option, const QModelIndex &idx ) const; + virtual QRect checkRectForIndex( const QStyleOptionViewItem &option, const QModelIndex &idx, int role ) const; virtual QRect configRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const; private slots: diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index 34cd01b1b..e4654ac29 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -46,17 +46,20 @@ #include "resolversmodel.h" #include "scanmanager.h" #include "settingslistdelegate.h" -#include "sipconfigdelegate.h" +#include "AccountDelegate.h" #include "database/database.h" #include "network/servent.h" #include "playlist/dynamic/widgets/LoadingSpinner.h" #include "sip/SipHandler.h" -#include "sip/AccountModel.h" +#include "accounts/AccountModel.h" #include "utils/logger.h" #include "ui_proxydialog.h" #include "ui_stackedsettingsdialog.h" +using namespace Tomahawk; +using namespace Accounts; + static QString md5( const QByteArray& src ) { @@ -69,7 +72,7 @@ SettingsDialog::SettingsDialog( QWidget *parent ) , ui( new Ui_StackedSettingsDialog ) , m_proxySettings( this ) , m_rejected( false ) - , m_sipModel( 0 ) + , m_accountModel( 0 ) , m_resolversModel( 0 ) , m_sipSpinner( 0 ) { @@ -107,7 +110,7 @@ SettingsDialog::SettingsDialog( QWidget *parent ) #endif // SIP PLUGINS - SipConfigDelegate* sipdel = new SipConfigDelegate( this ); + AccountDelegate* sipdel = new AccountDelegate( this ); ui->accountsView->setItemDelegate( sipdel ); ui->accountsView->setContextMenuPolicy( Qt::CustomContextMenu ); ui->accountsView->setVerticalScrollMode( QAbstractItemView::ScrollPerPixel ); @@ -115,8 +118,8 @@ SettingsDialog::SettingsDialog( QWidget *parent ) connect( ui->accountsView, SIGNAL( clicked( QModelIndex ) ), this, SLOT( sipItemClicked( QModelIndex ) ) ); connect( sipdel, SIGNAL( openConfig( SipPlugin* ) ), this, SLOT( openSipConfig( SipPlugin* ) ) ); connect( ui->accountsView, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( sipContextMenuRequest( QPoint ) ) ); - m_sipModel = new SipModel( this ); - ui->accountsView->setModel( m_sipModel ); + m_accountModel = new AccountModel( this ); + ui->accountsView->setModel( m_accountModel ); if ( !Servent::instance()->isReady() ) { diff --git a/src/settingsdialog.h b/src/settingsdialog.h index ef2d53eee..a2fa1de90 100644 --- a/src/settingsdialog.h +++ b/src/settingsdialog.h @@ -27,9 +27,7 @@ class LoadingSpinner; class QListWidgetItem; class Ui_StackedSettingsDialog; -class SipPluginFactory; class SipPlugin; -class SipModel; class ResolversModel; class QNetworkReply; @@ -39,6 +37,14 @@ namespace Ui class ProxyDialog; } +namespace Tomahawk +{ + namespace Accounts + { + class AccountModel; + } +} + class ProxyDialog : public QDialog { Q_OBJECT @@ -105,7 +111,7 @@ private slots: void sipCreateConfigClosed( int value ); */ void updateScanOptionsView(); - + void changePage( QListWidgetItem*, QListWidgetItem* ); void serventReady(); @@ -118,9 +124,11 @@ private: ProxyDialog m_proxySettings; bool m_rejected; - SipModel* m_sipModel; + Tomahawk::Accounts::AccountModel* m_accountModel; ResolversModel* m_resolversModel; LoadingSpinner* m_sipSpinner; }; #endif // SETTINGSDIALOG_H + +struct A; From aefec1eaac33e13d225dc3096157ca793c1c6fb7 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Mon, 12 Dec 2011 22:37:23 -0500 Subject: [PATCH 023/104] missing bits and pieces of accounts and auto-connect port settings dialog to new accounts fix adding and removing of accounts --- src/AccountDelegate.cpp | 30 ++- src/AccountDelegate.h | 2 +- src/accounts/CMakeLists.txt | 2 +- src/accounts/twitter/sip/twittersip.cpp | 26 ++- src/accounts/twitter/sip/twittersip.h | 12 +- src/accounts/twitter/twitteraccount.cpp | 10 +- src/accounts/twitter/twitteraccount.h | 3 +- src/accounts/xmpp/sip/xmppsip.cpp | 42 ++-- src/accounts/xmpp/sip/xmppsip.h | 23 ++- src/accounts/xmpp/xmppaccount.cpp | 40 +++- src/accounts/xmpp/xmppaccount.h | 7 +- src/accounts/xmpp/xmppconfigwidget.cpp | 21 +- src/accounts/xmpp/xmppconfigwidget.h | 6 +- src/libtomahawk/accounts/Account.cpp | 96 +++++++++- src/libtomahawk/accounts/Account.h | 115 ++++------- src/libtomahawk/accounts/AccountManager.cpp | 74 ++++++- src/libtomahawk/accounts/AccountManager.h | 22 ++- src/libtomahawk/sip/SipHandler.cpp | 13 +- src/libtomahawk/sip/SipHandler.h | 6 - src/libtomahawk/sip/SipPlugin.cpp | 7 - src/libtomahawk/sip/SipPlugin.h | 3 - src/libtomahawk/tomahawksettings.cpp | 2 +- src/libtomahawk/tomahawksettings.h | 2 +- src/settingsdialog.cpp | 202 ++++++++++---------- src/settingsdialog.h | 32 ++-- src/tomahawkapp.cpp | 5 +- 26 files changed, 456 insertions(+), 347 deletions(-) diff --git a/src/AccountDelegate.cpp b/src/AccountDelegate.cpp index de1199013..8062a2ef3 100644 --- a/src/AccountDelegate.cpp +++ b/src/AccountDelegate.cpp @@ -65,7 +65,7 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, QFont desc = opt.font; desc.setItalic( true ); - desc.setPointSize( error.pointSize() - 2 ); + desc.setPointSize( desc.pointSize() - 2 ); // draw the background const QWidget* w = opt.widget; @@ -93,7 +93,7 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, // from the right edge--config status and online/offline QRect confRect = QRect( itemRect.width() - WRENCH_SIZE - 2 * PADDING, mid - WRENCH_SIZE / 2 + top, WRENCH_SIZE, WRENCH_SIZE ); - if( index.data( SipModel::HasConfig ).toBool() ) { + if( index.data( AccountModel::HasConfig ).toBool() ) { QStyleOptionToolButton topt; topt.rect = confRect; @@ -116,10 +116,10 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, QPixmap p; QString statusText; Account::ConnectionState state = static_cast< Account::ConnectionState >( index.data( AccountModel::ConnectionStateRole ).toInt() ); - if( state == SipPlugin::Connected ) { + if( state == Account::Connected ) { p = QPixmap( RESPATH "images/sipplugin-online.png" ); statusText = tr( "Online" ); - } else if( state == SipPlugin::Connecting ) { + } else if( state == Account::Connecting ) { p = QPixmap( RESPATH "images/sipplugin-offline.png" ); statusText = tr( "Connecting..." ); } else { @@ -128,7 +128,7 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, } p = p.scaled( STATUS_ICON_SIZE, STATUS_ICON_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation ); painter->drawPixmap( statusX, statusY - STATUS_ICON_SIZE / 2 + top, STATUS_ICON_SIZE, STATUS_ICON_SIZE, p ); - const int width = statusFM.width( statusText ); + int width = statusFM.width( statusText ); int statusTextX = statusX - PADDING - width; painter->save(); painter->setFont( statusF ); @@ -155,7 +155,7 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, // text to accompany checkbox const int capW = statusFM.width( capString ); const int capTextX = statusX - PADDING - capW; - painter->drawText( QRect( capTextX, capY - statusFM.height() / 2 + top, capW, statusFM.height() ) ); + painter->drawText( QRect( capTextX, capY - statusFM.height() / 2 + top, capW, statusFM.height() ), capString ); if ( capTextX < statusTextX ) statusTextX = capTextX; @@ -167,7 +167,7 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, painter->setFont( name ); QFontMetrics namefm( name ); // pos will the top-left point of the text rect - pos = mid - ( nameHeight / 2 ) + top; + pos = mid - ( namefm.height() / 2 ) + top; // TODO bound with config icon and offline/online status width = itemRect.width() - statusTextX; QRect nameRect( textLeftEdge, pos, width, namefm.height() ); @@ -208,15 +208,11 @@ AccountDelegate::checkRectForIndex( const QStyleOptionViewItem &option, const QM QRect AccountDelegate::configRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const { - if( !idx.data( SipModel::FactoryItemRole ).toBool() && !idx.data( SipModel::FactoryRole ).toBool() ) - { - QStyleOptionViewItemV4 opt = option; - initStyleOption( &opt, idx ); - QRect itemRect = opt.rect; - QRect confRect = QRect( itemRect.width() - ICONSIZE - 2 * PADDING, (opt.rect.height() / 2) - ICONSIZE / 2 + opt.rect.top(), ICONSIZE, ICONSIZE ); - return confRect; - } - return QRect(); + QStyleOptionViewItemV4 opt = option; + initStyleOption( &opt, idx ); + QRect itemRect = opt.rect; + QRect confRect = QRect( itemRect.width() - ICONSIZE - 2 * PADDING, (opt.rect.height() / 2) - ICONSIZE / 2 + opt.rect.top(), ICONSIZE, ICONSIZE ); + return confRect; } @@ -229,7 +225,7 @@ AccountDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex void AccountDelegate::askedForEdit( const QModelIndex& idx ) { - emit openConfig( qobject_cast< SipPlugin* >( idx.data( SipModel::SipPluginData ).value< QObject* >() ) ); + emit openConfig( qobject_cast< Account* >( idx.data( AccountModel::AccountData ).value< QObject* >() ) ); } diff --git a/src/AccountDelegate.h b/src/AccountDelegate.h index a3d5c2196..757cc3923 100644 --- a/src/AccountDelegate.h +++ b/src/AccountDelegate.h @@ -47,7 +47,7 @@ private slots: void askedForEdit( const QModelIndex& idx ); signals: - void openConfig( Account* ); + void openConfig( Tomahawk::Accounts::Account* ); }; } diff --git a/src/accounts/CMakeLists.txt b/src/accounts/CMakeLists.txt index a001ab0b5..fbf805847 100644 --- a/src/accounts/CMakeLists.txt +++ b/src/accounts/CMakeLists.txt @@ -1,2 +1,2 @@ add_subdirectory( xmpp ) -add_subdirectory( twitter ) +#add_subdirectory( twitter ) diff --git a/src/accounts/twitter/sip/twittersip.cpp b/src/accounts/twitter/sip/twittersip.cpp index ddeba632b..75027ab35 100644 --- a/src/accounts/twitter/sip/twittersip.cpp +++ b/src/accounts/twitter/sip/twittersip.cpp @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2011, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -57,7 +58,7 @@ TwitterSipPlugin::TwitterSipPlugin( Tomahawk::Accounts::Account* account ) qDebug() << Q_FUNC_INFO; connect( account, SIGNAL( nowAuthenticated( const QWeakPointer< TomahawkOAuthTwitter > &, const QTweetUser & ) ), SLOT( accountAuthenticated( const QWeakPointer< TomahawkOAuthTwitter > &, const QTweetUser & ) ) ); - + if ( Database::instance()->dbid() != m_configuration[ "saveddbid" ].toString() ) { m_configuration[ "cachedpeers" ] = QVariantHash(); @@ -113,7 +114,7 @@ TwitterSipPlugin::connectPlugin() m_cachedPeers = m_configuration[ "cachedpeers" ].toHash(); QStringList peerList = m_cachedPeers.keys(); qStableSort( peerList.begin(), peerList.end() ); - + if ( !m_account->isAuthenticated() ) { tDebug() << Q_FUNC_INFO << "account isn't authenticated, attempting"; @@ -144,7 +145,7 @@ TwitterSipPlugin::disconnectPlugin() delete m_directMessageDestroy.data(); m_cachedTwitterAuth.clear(); - + m_configuration[ "cachedpeers" ] = m_cachedPeers; syncConfig(); m_cachedPeers.empty(); @@ -156,12 +157,12 @@ void TwitterSipPlugin::accountAuthenticated( const QWeakPointer< TomahawkOAuthTwitter > &twitterAuth, const QTweetUser &user ) { Q_UNUSED( user ); - + if ( !isValid() ) return; m_cachedTwitterAuth = twitterAuth; - + m_friendsTimeline = QWeakPointer( new QTweetFriendsTimeline( m_cachedTwitterAuth.data(), this ) ); m_mentions = QWeakPointer( new QTweetMentions( m_cachedTwitterAuth.data(), this ) ); m_directMessages = QWeakPointer( new QTweetDirectMessages( m_cachedTwitterAuth.data(), this ) ); @@ -216,7 +217,7 @@ TwitterSipPlugin::registerOffers( const QStringList &peerList ) { if ( !isValid() ) return; - + foreach( QString screenName, peerList ) { QVariantHash peerData = m_cachedPeers[screenName].toHash(); @@ -227,7 +228,7 @@ TwitterSipPlugin::registerOffers( const QStringList &peerList ) m_configuration[ "cachedpeers" ] = m_cachedPeers; syncConfig(); } - + if ( Servent::instance()->connectedToSession( peerData["node"].toString() ) ) { peerData["lastseen"] = QDateTime::currentMSecsSinceEpoch(); @@ -246,13 +247,13 @@ TwitterSipPlugin::registerOffers( const QStringList &peerList ) m_cachedAvatars.remove( screenName ); continue; } - + if ( !peerData.contains( "host" ) || !peerData.contains( "port" ) || !peerData.contains( "pkey" ) ) { qDebug() << "TwitterSipPlugin does not have host, port and/or pkey values for " << screenName << " (this is usually *not* a bug or problem but a normal part of the process)"; continue; } - + QMetaObject::invokeMethod( this, "registerOffer", Q_ARG( QString, screenName ), Q_ARG( QVariantHash, peerData ) ); } } @@ -653,7 +654,7 @@ TwitterSipPlugin::fetchAvatar( const QString& screenName ) qDebug() << Q_FUNC_INFO; if ( !isValid() ) return; - + QTweetUserShow *userShowFetch = new QTweetUserShow( m_cachedTwitterAuth.data(), this ); connect( userShowFetch, SIGNAL( parsedUserInfo( QTweetUser ) ), SLOT( avatarUserDataSlot( QTweetUser ) ) ); userShowFetch->fetch( screenName ); @@ -672,11 +673,6 @@ TwitterSipPlugin::avatarUserDataSlot( const QTweetUser &user ) connect( reply, SIGNAL( finished() ), this, SLOT( profilePicReply() ) ); } -void -TwitterSipPlugin::refreshProxy() -{ - //handled by TwitterAccount::refreshProxy() -} void TwitterSipPlugin::profilePicReply() diff --git a/src/accounts/twitter/sip/twittersip.h b/src/accounts/twitter/sip/twittersip.h index 76631ac39..84963fe17 100644 --- a/src/accounts/twitter/sip/twittersip.h +++ b/src/accounts/twitter/sip/twittersip.h @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2011, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -34,7 +35,7 @@ #include "accounts/accountdllmacro.h" #include "sip/SipPlugin.h" -#include "accounts/account.h" +#include "accounts/Account.h" #include "accounts/twitter/tomahawkoauthtwitter.h" class ACCOUNTDLLEXPORT TwitterSipPlugin : public SipPlugin @@ -52,7 +53,6 @@ public: public slots: virtual void connectPlugin(); void disconnectPlugin(); - void refreshProxy(); void configurationChanged(); void sendMsg( const QString& to, const QString& msg ) @@ -73,7 +73,7 @@ public slots: } void checkSettings(); - + private slots: void accountAuthenticated( const QWeakPointer< TomahawkOAuthTwitter > &twitterAuth, const QTweetUser &user ); void checkTimerFired(); @@ -92,14 +92,14 @@ private slots: void fetchAvatar( const QString &screenName ); void avatarUserDataSlot( const QTweetUser &user ); void profilePicReply(); - + private: inline void syncConfig() { m_account->setCredentials( m_credentials ); m_account->setConfiguration( m_configuration ); m_account->sync(); } bool refreshTwitterAuth(); void parseGotTomahawk( const QRegExp ®ex, const QString &screenName, const QString &text ); QWeakPointer< TomahawkOAuthTwitter > m_cachedTwitterAuth; - + QWeakPointer< QTweetFriendsTimeline > m_friendsTimeline; QWeakPointer< QTweetMentions > m_mentions; QWeakPointer< QTweetDirectMessages > m_directMessages; @@ -108,7 +108,7 @@ private: QVariantHash m_configuration; QVariantHash m_credentials; - + QTimer m_checkTimer; QTimer m_connectTimer; QTimer m_dmPollTimer; diff --git a/src/accounts/twitter/twitteraccount.cpp b/src/accounts/twitter/twitteraccount.cpp index 552828201..74990e3b7 100644 --- a/src/accounts/twitter/twitteraccount.cpp +++ b/src/accounts/twitter/twitteraccount.cpp @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2011, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -163,15 +164,6 @@ TwitterAccount::connectAuthVerifyReply( const QTweetUser &user ) } -void -TwitterAccount::refreshProxy() -{ - //FIXME: Could this cause a race condition if a client is threaded? - if ( !m_twitterAuth.isNull() ) - m_twitterAuth.data()->setNetworkAccessManager( TomahawkUtils::nam() ); -} - - } } diff --git a/src/accounts/twitter/twitteraccount.h b/src/accounts/twitter/twitteraccount.h index f003e39b8..0d45a893d 100644 --- a/src/accounts/twitter/twitteraccount.h +++ b/src/accounts/twitter/twitteraccount.h @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2011, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -72,8 +73,6 @@ public: bool refreshTwitterAuth(); TomahawkOAuthTwitter* twitterAuth() const { return m_twitterAuth.data(); } - void refreshProxy(); - signals: void nowAuthenticated( const QWeakPointer< TomahawkOAuthTwitter >&, const QTweetUser &user ); void nowDeauthenticated(); diff --git a/src/accounts/xmpp/sip/xmppsip.cpp b/src/accounts/xmpp/sip/xmppsip.cpp index eb965be44..fdd54307b 100644 --- a/src/accounts/xmpp/sip/xmppsip.cpp +++ b/src/accounts/xmpp/sip/xmppsip.cpp @@ -2,6 +2,7 @@ * * Copyright 2010-2011, Dominik Schmidt * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2011, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -48,13 +49,16 @@ #include #include -#include +#include -XmppSipPlugin::XmppSipPlugin( Tomahawk::Accounts::Account *account ) +using namespace Tomahawk; +using namespace Accounts; + +XmppSipPlugin::XmppSipPlugin( Account *account ) : SipPlugin( account ) , m_menu( 0 ) , m_xmlConsole( 0 ) - , m_state( Disconnected ) + , m_state( Account::Disconnected ) { qDebug() << Q_FUNC_INFO; @@ -152,7 +156,7 @@ XmppSipPlugin::connectPlugin() if ( m_client->connection() ) connect(m_client->connection(), SIGNAL(error(SocketError)), SLOT(onError(SocketError))); - m_state = Connecting; + m_state = Account::Connecting; emit stateChanged( m_state ); return; } @@ -162,10 +166,10 @@ XmppSipPlugin::disconnectPlugin() { if (!m_client->isConnected()) { - if ( m_state != Disconnected ) // might be Connecting + if ( m_state != Account::Disconnected ) // might be Connecting { - m_state = Disconnected; - emit stateChanged( m_state ); + m_state = Account::Disconnected; + emit stateChanged( m_state ); } return; } @@ -178,7 +182,7 @@ XmppSipPlugin::disconnectPlugin() m_peers.clear(); m_client->disconnectFromServer( true ); - m_state = Disconnecting; + m_state = Account::Disconnecting; emit stateChanged( m_state ); } @@ -218,7 +222,7 @@ XmppSipPlugin::onConnect() //connect( m_room, SIGNAL( messageReceived( Jreen::Message, bool ) ), this, SLOT( onNewMessage( Jreen::Message ) ) ); //connect( m_room, SIGNAL( presenceReceived( Jreen::Presence, const Jreen::MUCRoom::Participant* ) ), this, SLOT( onNewPresence( Jreen::Presence ) ) ); - m_state = Connected; + m_state = Account::Connected; emit stateChanged( m_state ); addMenuHelper(); @@ -235,7 +239,7 @@ XmppSipPlugin::onDisconnect( Jreen::Client::DisconnectReason reason ) break; case Jreen::Client::AuthorizationError: - emit error( SipPlugin::AuthError, errorMessage( reason ) ); + emit error( Account::AuthError, errorMessage( reason ) ); break; case Jreen::Client::HostUnknown: @@ -246,7 +250,7 @@ XmppSipPlugin::onDisconnect( Jreen::Client::DisconnectReason reason ) case Jreen::Client::SystemShutdown: case Jreen::Client::Conflict: case Jreen::Client::Unknown: - emit error( SipPlugin::ConnectionError, errorMessage( reason ) ); + emit error( Account::ConnectionError, errorMessage( reason ) ); break; default: @@ -254,7 +258,7 @@ XmppSipPlugin::onDisconnect( Jreen::Client::DisconnectReason reason ) Q_ASSERT(false); break; } - m_state = Disconnected; + m_state = Account::Disconnected; emit stateChanged( m_state ); removeMenuHelper(); @@ -314,7 +318,7 @@ XmppSipPlugin::errorMessage( Jreen::Client::DisconnectReason reason ) break; } - m_state = Disconnected; + m_state = Account::Disconnected; emit stateChanged( m_state ); return QString(); @@ -534,7 +538,7 @@ void XmppSipPlugin::removeMenuHelper() void XmppSipPlugin::onNewMessage(const Jreen::Message& message) { - if ( m_state != Connected ) + if ( m_state != Account::Connected ) return; // qDebug() << Q_FUNC_INFO << "message type" << message.subtype(); @@ -576,7 +580,7 @@ void XmppSipPlugin::onNewMessage(const Jreen::Message& message) void XmppSipPlugin::onPresenceReceived( const Jreen::RosterItem::Ptr &item, const Jreen::Presence& presence ) { Q_UNUSED(item); - if ( m_state != Connected ) + if ( m_state != Account::Connected ) return; Jreen::JID jid = presence.from(); @@ -618,7 +622,7 @@ void XmppSipPlugin::onPresenceReceived( const Jreen::RosterItem::Ptr &item, cons void XmppSipPlugin::onSubscriptionReceived(const Jreen::RosterItem::Ptr& item, const Jreen::Presence& presence) { - if ( m_state != Connected ) + if ( m_state != Account::Connected ) return; // qDebug() << Q_FUNC_INFO << "presence type:" << presence.subtype(); @@ -704,7 +708,7 @@ XmppSipPlugin::onSubscriptionRequestConfirmed( int result ) void XmppSipPlugin::onNewIq(const Jreen::IQ& iq) { - if ( m_state != Connected ) + if ( m_state != Account::Connected ) return; Jreen::IQReply *reply = qobject_cast(sender()); @@ -847,7 +851,7 @@ void XmppSipPlugin::handlePeerStatus(const Jreen::JID& jid, Jreen::Presence::Typ void XmppSipPlugin::onNewAvatar(const QString& jid) { // qDebug() << Q_FUNC_INFO << jid; - if ( m_state != Connected ) + if ( m_state != Account::Connected ) return; Q_ASSERT(!m_avatarManager->avatar( jid ).isNull()); @@ -911,7 +915,7 @@ XmppSipPlugin::readServer() } -SipPlugin::ConnectionState +Account::ConnectionState XmppSipPlugin::connectionState() const { return m_state; diff --git a/src/accounts/xmpp/sip/xmppsip.h b/src/accounts/xmpp/sip/xmppsip.h index aa8efb10e..0ae6a5b85 100644 --- a/src/accounts/xmpp/sip/xmppsip.h +++ b/src/accounts/xmpp/sip/xmppsip.h @@ -2,6 +2,7 @@ * * Copyright 2010-2011, Dominik Schmidt * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2011, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -55,20 +56,26 @@ public: //FIXME: Make this more correct virtual bool isValid() const { return true; } - virtual ConnectionState connectionState() const; virtual QMenu* menu(); + // used by XmppAccount to expose connection state and controls + Tomahawk::Accounts::Account::ConnectionState connectionState() const; + signals: void jidChanged( const QString& ); + // Used by XmppAccount + void stateChanged( Tomahawk::Accounts::Account::ConnectionState state ); + void error( int errorId, const QString& errorStr ); + public slots: virtual void connectPlugin(); - void disconnectPlugin(); - void checkSettings(); - void configurationChanged(); - void sendMsg( const QString& to, const QString& msg ); + virtual void disconnectPlugin(); + virtual void checkSettings(); + virtual void configurationChanged(); + virtual void sendMsg( const QString& to, const QString& msg ); void broadcastMsg( const QString &msg ); - void addContact( const QString &jid, const QString& msg = QString() ); + virtual void addContact( const QString &jid, const QString& msg = QString() ); void showAddFriendDialog(); protected: @@ -103,15 +110,13 @@ private: bool presenceMeansOnline( Jreen::Presence::Type p ); void handlePeerStatus( const Jreen::JID &jid, Jreen::Presence::Type presenceType ); - using SipPlugin::errorMessage; - QMenu* m_menu; XmlConsole* m_xmlConsole; QString m_currentUsername; QString m_currentPassword; QString m_currentServer; int m_currentPort; - ConnectionState m_state; + Tomahawk::Accounts::Account::ConnectionState m_state; QString m_currentResource; diff --git a/src/accounts/xmpp/xmppaccount.cpp b/src/accounts/xmpp/xmppaccount.cpp index 43129551b..b32aa2183 100644 --- a/src/accounts/xmpp/xmppaccount.cpp +++ b/src/accounts/xmpp/xmppaccount.cpp @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2011, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,6 +20,7 @@ #include "xmppaccount.h" #include "xmppconfigwidget.h" #include "sip/SipPlugin.h" +#include "ui_xmppconfigwidget.h" #include @@ -37,7 +39,6 @@ XmppAccountFactory::createAccount( const QString& accountId ) XmppAccount::XmppAccount( const QString &accountId ) : Account( accountId ) - , m_isAuthenticated( false ) { loadFromConfig( accountId ); @@ -46,27 +47,52 @@ XmppAccount::XmppAccount( const QString &accountId ) types << SipType; setTypes( types ); - m_configWidget = QWeakPointer< XmppConfigWidget >( new XmppConfigWidget( this, 0 ) ); + m_configWidget = QWeakPointer< QWidget >( new XmppConfigWidget( this, 0 ) ); } XmppAccount::~XmppAccount() { - + delete m_configWidget.data(); + delete m_xmppSipPlugin.data(); } void XmppAccount::authenticate() { - return; + if ( connectionState() != Account::Connected ) + sipPlugin()->connectPlugin(); } void XmppAccount::deauthenticate() { - return; + if ( connectionState() != Account::Disconnected ) + sipPlugin()->disconnectPlugin(); +} + +bool +XmppAccount::isAuthenticated() const +{ + return m_xmppSipPlugin.data()->connectionState() == Account::Connected; +} + + +Account::ConnectionState +XmppAccount::connectionState() const +{ + // Ensure we exist + const_cast( this )->sipPlugin(); + return m_xmppSipPlugin.data()->connectionState(); +} + +void +XmppAccount::saveConfig() +{ + if ( !m_configWidget.isNull() ) + static_cast< XmppConfigWidget* >( m_configWidget.data() )->saveConfig(); } @@ -76,6 +102,10 @@ XmppAccount::sipPlugin() if ( m_xmppSipPlugin.isNull() ) { m_xmppSipPlugin = QWeakPointer< XmppSipPlugin >( new XmppSipPlugin( this ) ); + + connect( m_xmppSipPlugin.data(), SIGNAL( stateChanged( Tomahawk::Accounts::Account::ConnectionState ) ), this, SIGNAL( connectionStateChanged( Tomahawk::Accounts::Account::ConnectionState ) ) ); + connect( m_xmppSipPlugin.data(), SIGNAL( error( int, QString ) ), this, SIGNAL( error( int, QString ) ) ); + return m_xmppSipPlugin.data(); } return m_xmppSipPlugin.data(); diff --git a/src/accounts/xmpp/xmppaccount.h b/src/accounts/xmpp/xmppaccount.h index cb9d9fba9..122d3171d 100644 --- a/src/accounts/xmpp/xmppaccount.h +++ b/src/accounts/xmpp/xmppaccount.h @@ -2,6 +2,7 @@ * * Copyright 2010-2011, Dominik Schmidt * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2011, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -61,19 +62,19 @@ public: void authenticate(); void deauthenticate(); - bool isAuthenticated() const { return m_isAuthenticated; } + bool isAuthenticated() const; Tomahawk::InfoSystem::InfoPlugin* infoPlugin() { return 0; } SipPlugin* sipPlugin(); QWidget* configurationWidget() { return m_configWidget.data(); } QWidget* aclWidget() { return 0; } + void saveConfig(); - void refreshProxy() {}; + virtual Tomahawk::Accounts::Account::ConnectionState connectionState() const; private: Ui_XmppConfigWidget* m_ui; // so the google wrapper can change the config dialog a bit - bool m_isAuthenticated; QWeakPointer< QWidget > m_configWidget; QWeakPointer< XmppSipPlugin > m_xmppSipPlugin; diff --git a/src/accounts/xmpp/xmppconfigwidget.cpp b/src/accounts/xmpp/xmppconfigwidget.cpp index 19f7b7735..9a9390e82 100644 --- a/src/accounts/xmpp/xmppconfigwidget.cpp +++ b/src/accounts/xmpp/xmppconfigwidget.cpp @@ -22,7 +22,7 @@ #include -#include +#include #include namespace Tomahawk @@ -53,16 +53,31 @@ XmppConfigWidget::~XmppConfigWidget() delete m_ui; } +void +XmppConfigWidget::saveConfig() +{ + QVariantHash credentials = m_account->credentials(); + credentials[ "username" ] = m_ui->xmppUsername->text(); + credentials[ "password" ] = m_ui->xmppPassword->text(); + credentials[ "server" ] = m_ui->xmppServer->text(); + credentials[ "port" ] = m_ui->xmppPort->text(); + m_account->setAccountFriendlyName( m_ui->xmppUsername->text() ); + m_account->setCredentials( credentials ); + m_account->sync(); + + static_cast< XmppSipPlugin* >( m_account->sipPlugin() )->checkSettings(); +} + void XmppConfigWidget::onCheckJidExists( QString jid ) { - QList< Tomahawk::Accounts::Account* > accounts = Tomahawk::Accounts::AccountManager::instance()->getAccounts( Tomahawk::Accounts::SipType ); + QList< Tomahawk::Accounts::Account* > accounts = Tomahawk::Accounts::AccountManager::instance()->accounts( Tomahawk::Accounts::SipType ); 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("@"); QString savedServer = account->configuration()[ "server" ].toString(); diff --git a/src/accounts/xmpp/xmppconfigwidget.h b/src/accounts/xmpp/xmppconfigwidget.h index 89a1827ca..ffe7e986b 100644 --- a/src/accounts/xmpp/xmppconfigwidget.h +++ b/src/accounts/xmpp/xmppconfigwidget.h @@ -45,12 +45,14 @@ public: explicit XmppConfigWidget( XmppAccount* account = 0, QWidget *parent = 0 ); virtual ~XmppConfigWidget(); + void saveConfig(); + signals: void dataError( bool exists ); - + private slots: void onCheckJidExists( QString jid ); - + private: Ui::XmppConfigWidget *m_ui; XmppAccount *m_account; diff --git a/src/libtomahawk/accounts/Account.cpp b/src/libtomahawk/accounts/Account.cpp index 238118f81..b25ac0e61 100644 --- a/src/libtomahawk/accounts/Account.cpp +++ b/src/libtomahawk/accounts/Account.cpp @@ -1,7 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2011, Christian Muehlhaeuser - * Copyright 2011, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -76,12 +76,6 @@ Account::isAuthenticated() const } -void -Account::refreshProxy() -{ - -} - void Account::onError(int errorCode, const QString& error ) { @@ -97,6 +91,94 @@ Account::onConnectionStateChanged( Account::ConnectionState ) } +void +Account::syncConfig() +{ + TomahawkSettings* s = TomahawkSettings::instance(); + s->beginGroup( "accounts/" + m_accountId ); + s->setValue( "accountfriendlyname", m_accountFriendlyName ); + s->setValue( "enabled", m_enabled ); + 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(); +} + + +void +Account::loadFromConfig( const QString& accountId ) +{ + m_accountId = accountId; + TomahawkSettings* s = TomahawkSettings::instance(); + s->beginGroup( "accounts/" + m_accountId ); + m_accountFriendlyName = s->value( "accountfriendlyname", QString() ).toString(); + m_enabled = s->value( "enabled", false ).toBool(); + 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(); +} + + +void +Account::removeFromConfig() +{ + TomahawkSettings* s = TomahawkSettings::instance(); + s->beginGroup( "accounts/" + m_accountId ); + s->remove( "accountfriendlyname" ); + s->remove( "enabled" ); + s->remove( "autoconnect" ); + s->remove( "credentials" ); + s->remove( "configuration" ); + s->remove( "acl" ); + s->remove( "types" ); + s->endGroup(); + s->remove( "accounts/" + m_accountId ); +} + + +void +Account::setTypes( const QSet< AccountType > types ) +{ + QMutexLocker locker( &m_mutex ); + m_types = QStringList(); + foreach ( AccountType type, types ) + { + switch( type ) + { + case InfoType: + m_types << "InfoType"; + break; + case SipType: + m_types << "SipType"; + break; + } + } + syncConfig(); +} + + +QSet< AccountType > +Account::types() const +{ + QMutexLocker locker( &m_mutex ); + QSet< AccountType > set; + foreach ( QString type, m_types ) + { + if ( type == "InfoType" ) + set << InfoType; + else if ( type == "SipType" ) + set << SipType; + } + return set; +} + + } } \ No newline at end of file diff --git a/src/libtomahawk/accounts/Account.h b/src/libtomahawk/accounts/Account.h index 556fd49bb..97a0882f2 100644 --- a/src/libtomahawk/accounts/Account.h +++ b/src/libtomahawk/accounts/Account.h @@ -1,7 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2011, Christian Muehlhaeuser - * Copyright 2011, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -63,23 +63,28 @@ public: explicit Account( const QString &accountId ); virtual ~Account() {} - virtual QString accountServiceName() const { QMutexLocker locker( &m_mutex ); return m_accountServiceName; } // e.g. "Twitter", "Last.fm" - virtual QString accountFriendlyName() const { QMutexLocker locker( &m_mutex ); return m_accountFriendlyName; } // e.g. screen name on the service, JID, etc. - virtual bool enabled() const { QMutexLocker locker( &m_mutex ); return m_enabled; } - virtual bool autoConnect() const { QMutexLocker locker( &m_mutex ); return m_autoConnect; } - virtual QString accountId() const { QMutexLocker locker( &m_mutex ); return m_accountId; } + QString accountServiceName() const { QMutexLocker locker( &m_mutex ); return m_accountServiceName; } // e.g. "Twitter", "Last.fm" + QString accountFriendlyName() const { QMutexLocker locker( &m_mutex ); return m_accountFriendlyName; } // e.g. screen name on the service, JID, etc. + bool enabled() const { QMutexLocker locker( &m_mutex ); return m_enabled; } + bool autoConnect() const { QMutexLocker locker( &m_mutex ); return m_autoConnect; } + QString accountId() const { QMutexLocker locker( &m_mutex ); return m_accountId; } - virtual QVariantHash configuration() const { QMutexLocker locker( &m_mutex ); return m_configuration; } + QVariantHash configuration() const { QMutexLocker locker( &m_mutex ); return m_configuration; } + + /** + * Configuration widgets can have a "dataError( bool )" signal to enable/disable the OK button in their wrapper dialogs. + */ virtual QWidget* configurationWidget() = 0; + virtual void saveConfig() {} // called when the widget has been edited. save values from config widget, call sync() to write to disk account generic settings - virtual QVariantHash credentials() { QMutexLocker locker( &m_mutex ); return m_credentials; } + QVariantHash credentials() { QMutexLocker locker( &m_mutex ); return m_credentials; } - virtual QVariantMap acl() const { QMutexLocker locker( &m_mutex ); return m_acl; } + QVariantMap acl() const { QMutexLocker locker( &m_mutex ); return m_acl; } virtual QWidget* aclWidget() = 0; virtual QIcon icon() const = 0; - virtual ConnectionState connectionState() = 0; + virtual ConnectionState connectionState() const = 0; virtual bool isAuthenticated() const = 0; virtual QString errorMessage() const { QMutexLocker locker( &m_mutex ); return m_cachedError; } @@ -87,51 +92,27 @@ public: virtual Tomahawk::InfoSystem::InfoPlugin* infoPlugin() = 0; virtual SipPlugin* sipPlugin() = 0; - virtual QSet< AccountType > types() const - { - QMutexLocker locker( &m_mutex ); - QSet< AccountType > set; - foreach ( QString type, m_types ) - { - if ( type == "InfoType" ) - set << InfoType; - else if ( type == "SipType" ) - set << SipType; - } - return set; - } + QSet< AccountType > types() const; - virtual void setAccountServiceName( const QString &serviceName ) { QMutexLocker locker( &m_mutex ); m_accountServiceName = serviceName; } - virtual void setAccountFriendlyName( const QString &friendlyName ) { QMutexLocker locker( &m_mutex ); m_accountFriendlyName = friendlyName; } - virtual void setEnabled( bool enabled ) { QMutexLocker locker( &m_mutex ); m_enabled = enabled; } - virtual void setAutoConnect( bool autoConnect ) { QMutexLocker locker( &m_mutex ); m_autoConnect = autoConnect; } - virtual void setAccountId( const QString &accountId ) { QMutexLocker locker( &m_mutex ); m_accountId = accountId; } - virtual void setCredentials( const QVariantHash &credentialHash ) { QMutexLocker locker( &m_mutex ); m_credentials = credentialHash; } - virtual void setConfiguration( const QVariantHash &configuration ) { QMutexLocker locker( &m_mutex ); m_configuration = configuration; } - virtual void setAcl( const QVariantMap &acl ) { QMutexLocker locker( &m_mutex ); m_acl = acl; } - virtual void setTypes( const QSet< AccountType > types ) - { - QMutexLocker locker( &m_mutex ); - m_types = QStringList(); - foreach ( AccountType type, types ) - { - switch( type ) - { - case InfoType: - m_types << "InfoType"; - break; - case SipType: - m_types << "SipType"; - break; - } - } - syncConfig(); - } - - virtual void refreshProxy() = 0; + void setAccountServiceName( const QString &serviceName ) { QMutexLocker locker( &m_mutex ); m_accountServiceName = serviceName; } + void setAccountFriendlyName( const QString &friendlyName ) { QMutexLocker locker( &m_mutex ); m_accountFriendlyName = friendlyName; } + void setEnabled( bool enabled ) { QMutexLocker locker( &m_mutex ); m_enabled = enabled; } + void setAutoConnect( bool autoConnect ) { QMutexLocker locker( &m_mutex ); m_autoConnect = autoConnect; } + void setAccountId( const QString &accountId ) { QMutexLocker locker( &m_mutex ); m_accountId = accountId; } + void setCredentials( const QVariantHash &credentialHash ) { QMutexLocker locker( &m_mutex ); m_credentials = credentialHash; } + void setConfiguration( const QVariantHash &configuration ) { QMutexLocker locker( &m_mutex ); m_configuration = configuration; } + void setAcl( const QVariantMap &acl ) { QMutexLocker locker( &m_mutex ); m_acl = acl; } + void setTypes( const QSet< AccountType > types ); virtual void sync() { QMutexLocker locker( &m_mutex ); syncConfig(); }; + /** + * Removes all the settings held in the config file for this account instance + * + * Re-implement if you have saved additional files or config settings outside the built-in ones + */ + virtual void removeFromConfig(); + public slots: virtual void authenticate() = 0; virtual void deauthenticate() = 0; @@ -141,38 +122,10 @@ signals: void connectionStateChanged( Tomahawk::Accounts::Account::ConnectionState state ); void configurationChanged(); - void authenticated( bool ); protected: - 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_enabled = s->value( "enabled", false ).toBool(); - 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(); - } - - virtual void syncConfig() - { - TomahawkSettings* s = TomahawkSettings::instance(); - s->beginGroup( "accounts/" + m_accountId ); - s->setValue( "accountfriendlyname", m_accountFriendlyName ); - s->setValue( "enabled", m_enabled ); - 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(); - } + virtual void loadFromConfig( const QString &accountId ); + virtual void syncConfig(); private slots: void onConnectionStateChanged( Tomahawk::Accounts::Account::ConnectionState ); diff --git a/src/libtomahawk/accounts/AccountManager.cpp b/src/libtomahawk/accounts/AccountManager.cpp index 7aec4fbf3..d78119154 100644 --- a/src/libtomahawk/accounts/AccountManager.cpp +++ b/src/libtomahawk/accounts/AccountManager.cpp @@ -49,12 +49,17 @@ AccountManager::AccountManager( QObject *parent ) : QObject( parent ) { s_instance = this; + + connect( TomahawkSettings::instance(), SIGNAL( changed() ), SLOT( onSettingsChanged() ) ); + loadPluginFactories( findPluginFactories() ); } AccountManager::~AccountManager() { + delete SipHandler::instance(); + disconnectAll(); qDeleteAll( m_accounts ); } @@ -116,12 +121,31 @@ AccountManager::loadPluginFactories( const QStringList& paths ) } +bool +AccountManager::hasPluginWithFactory( const QString& factory ) const +{ + foreach( Account* account, m_accounts ) { + if( factoryFromId( account->accountId() ) == factory ) + return true; + } + return false; + +} + + QString AccountManager::factoryFromId( const QString& accountId ) const { return accountId.split( "_" ).first(); } +AccountFactory* +AccountManager::factoryForAccount( Account* account ) const +{ + const QString factoryId = factoryFromId( account->accountId() ); + return m_accountFactories.value( factoryId, 0 ); +} + void AccountManager::loadPluginFactory( const QString& path ) @@ -191,7 +215,7 @@ AccountManager::loadFromConfig() if( m_accountFactories.contains( pluginFactory ) ) { Account* account = loadPlugin( accountId ); - addAccountPlugin( account ); + addAccount( account ); } } } @@ -203,13 +227,11 @@ AccountManager::initSIP() foreach( Account* account, accounts( Tomahawk::Accounts::SipType ) ) { tDebug() << Q_FUNC_INFO << "adding plugin " << account->accountId(); - SipPlugin* p = account->sipPlugin(); - SipHandler::instance()->hookUpPlugin( p ); + hookupAndEnable( account, true ); } } - Account* AccountManager::loadPlugin( const QString& accountId ) { @@ -223,8 +245,9 @@ AccountManager::loadPlugin( const QString& accountId ) return account; } + void -AccountManager::addAccountPlugin( Account* account ) +AccountManager::addAccount( Account* account ) { tDebug() << Q_FUNC_INFO << "adding account plugin"; m_accounts.append( account ); @@ -235,14 +258,53 @@ AccountManager::addAccountPlugin( Account* account ) emit added( account ); } + +void +AccountManager::removeAccount( Account* account ) +{ + account->deauthenticate(); + + // emit before moving from list so accountmodel can get indexOf + emit removed( account ); + + m_accounts.removeAll( account ); + m_enabledAccounts.removeAll( account ); + m_connectedAccounts.removeAll( account ); + foreach ( AccountType type, m_accountsByAccountType.keys() ) + { + QList< Account* > accounts = m_accountsByAccountType.value( type ); + accounts.removeAll( account ); + m_accountsByAccountType[ type ] = accounts; + } + + TomahawkSettings::instance()->removeAccount( account->accountId() ); + + account->removeFromConfig(); + account->deleteLater(); +} + + void AccountManager::hookupAccount( Account* account ) const { connect( account, SIGNAL( error( int, QString ) ), SLOT( onError( int, QString ) ) ); - connect( account, SIGNAL( stateChanged( SipPlugin::ConnectionState ) ), SLOT( onStateChanged( Accounts::Account::ConnectionState ) ) ); + connect( account, SIGNAL( connectionStateChanged( Tomahawk::Accounts::Account::ConnectionState ) ), SLOT( onStateChanged( Tomahawk::Accounts::Account::ConnectionState ) ) ); } +void +AccountManager::hookupAndEnable( Account* account, bool startup ) +{ + SipPlugin* p = account->sipPlugin(); + SipHandler::instance()->hookUpPlugin( p ); + + if ( account->enabled() && ( !startup || account->autoConnect() ) ) + { + account->authenticate(); + m_enabledAccounts << account; + } +} + void AccountManager::onError( int code, const QString& msg ) diff --git a/src/libtomahawk/accounts/AccountManager.h b/src/libtomahawk/accounts/AccountManager.h index 482c55648..2894dad6e 100644 --- a/src/libtomahawk/accounts/AccountManager.h +++ b/src/libtomahawk/accounts/AccountManager.h @@ -44,16 +44,16 @@ public: explicit AccountManager( QObject *parent ); virtual ~AccountManager(); - QStringList findPluginFactories(); - void loadPluginFactories( const QStringList &paths ); - void loadFromConfig(); void initSIP(); - void loadPluginFactory( const QString &path ); - void addAccountPlugin( Account* account ); - Account* loadPlugin( const QString &accountId ); - QString factoryFromId( const QString& accountId ) const; + QList< AccountFactory* > factories() const { return m_accountFactories.values(); } + bool hasPluginWithFactory( const QString& factory ) const; + AccountFactory* factoryForAccount( Account* account ) const; + + void addAccount( Account* account ); + void hookupAndEnable( Account* account, bool startup = false ); /// Hook up signals and start the plugin + void removeAccount( Account* account ); QList< Account* > accounts() const { return m_accounts; }; QList< Account* > accounts( Tomahawk::Accounts::AccountType type ) const { return m_accountsByAccountType[ type ]; } @@ -74,11 +74,17 @@ signals: void stateChanged( Account* p, Accounts::Account::ConnectionState state ); private slots: - void onStateChanged( Accounts::Account::ConnectionState state ); + void onStateChanged( Tomahawk::Accounts::Account::ConnectionState state ); void onError( int code, const QString& msg ); void onSettingsChanged(); private: + QStringList findPluginFactories(); + void loadPluginFactories( const QStringList &paths ); + void loadPluginFactory( const QString &path ); + QString factoryFromId( const QString& accountId ) const; + + Account* loadPlugin( const QString &accountId ); void hookupAccount( Account* ) const; QList< Account* > m_accounts; diff --git a/src/libtomahawk/sip/SipHandler.cpp b/src/libtomahawk/sip/SipHandler.cpp index 5d08009cb..af6c30290 100644 --- a/src/libtomahawk/sip/SipHandler.cpp +++ b/src/libtomahawk/sip/SipHandler.cpp @@ -54,14 +54,13 @@ SipHandler::SipHandler( QObject* parent ) : QObject( parent ) { s_instance = this; - - connect( TomahawkSettings::instance(), SIGNAL( changed() ), SLOT( onSettingsChanged() ) ); } SipHandler::~SipHandler() { qDebug() << Q_FUNC_INFO; + s_instance = 0; } @@ -111,16 +110,6 @@ SipHandler::hookUpPlugin( SipPlugin* sip ) QObject::connect( sip->account(), SIGNAL( configurationChanged() ), sip, SLOT( configurationChanged() ) ); } -/* -void -SipHandler::refreshProxy() -{ - qDebug() << Q_FUNC_INFO; - - foreach( SipPlugin* sip, m_allPlugins ) - sip->refreshProxy(); -}*/ - void SipHandler::onPeerOnline( const QString& jid ) diff --git a/src/libtomahawk/sip/SipHandler.h b/src/libtomahawk/sip/SipHandler.h index a7ab5eff4..6b0fe95ff 100644 --- a/src/libtomahawk/sip/SipHandler.h +++ b/src/libtomahawk/sip/SipHandler.h @@ -48,8 +48,6 @@ public: void loadFromAccountManager(); - bool hasPluginType( const QString& factoryId ) const; - const QPixmap avatar( const QString& name ) const; //TODO: implement a proper SipInfo class and maybe attach it to the source const SipInfo sipInfo( const QString& peerId ) const; @@ -57,10 +55,6 @@ public: void hookUpPlugin( SipPlugin* p ); -public slots: -// TODO no longer called from anywhere... can we remove it? -// void refreshProxy(); - private slots: void onSipInfo( const QString& peerId, const SipInfo& info ); void onSoftwareVersion( const QString& peerId, const QString& versionString ); diff --git a/src/libtomahawk/sip/SipPlugin.cpp b/src/libtomahawk/sip/SipPlugin.cpp index 54a5fdf37..03202c137 100644 --- a/src/libtomahawk/sip/SipPlugin.cpp +++ b/src/libtomahawk/sip/SipPlugin.cpp @@ -82,13 +82,6 @@ SipPlugin::peersOnline() const } -void -SipPlugin::refreshProxy() -{ - qDebug() << Q_FUNC_INFO << "Not implemented"; -} - - void SipPlugin::onPeerOnline( const QString& peerId ) { diff --git a/src/libtomahawk/sip/SipPlugin.h b/src/libtomahawk/sip/SipPlugin.h index 08c9efb9b..a72e7aa69 100644 --- a/src/libtomahawk/sip/SipPlugin.h +++ b/src/libtomahawk/sip/SipPlugin.h @@ -54,7 +54,6 @@ public: #ifndef ENABLE_HEADLESS virtual QMenu* menu(); #endif - virtual void saveConfig() {} // called when the widget has been edited virtual QIcon icon() const; virtual Tomahawk::Accounts::Account* account() const; // peer infos @@ -69,8 +68,6 @@ public slots: virtual void addContact( const QString &jid, const QString& msg = QString() ) = 0; virtual void sendMsg( const QString& to, const QString& msg ) = 0; - virtual void refreshProxy(); - signals: void peerOnline( const QString& ); void peerOffline( const QString& ); diff --git a/src/libtomahawk/tomahawksettings.cpp b/src/libtomahawk/tomahawksettings.cpp index bf19349b3..fb2fd069b 100644 --- a/src/libtomahawk/tomahawksettings.cpp +++ b/src/libtomahawk/tomahawksettings.cpp @@ -126,7 +126,7 @@ void TomahawkSettings::doInitialSetup() { // by default we add a local network resolver - addSipPlugin( "sipzeroconf_autocreated" ); + addAccount( "sipzeroconf_autocreated" ); } diff --git a/src/libtomahawk/tomahawksettings.h b/src/libtomahawk/tomahawksettings.h index 750b37094..9b3a6c976 100644 --- a/src/libtomahawk/tomahawksettings.h +++ b/src/libtomahawk/tomahawksettings.h @@ -114,7 +114,7 @@ public: void addAccount( const QString& accountId ); void removeAccount( const QString& accountId ); - + void setBookmarkPlaylist( const QString& guid ); QString bookmarkPlaylist() const; diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index e4654ac29..1a6e55894 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -50,8 +50,9 @@ #include "database/database.h" #include "network/servent.h" #include "playlist/dynamic/widgets/LoadingSpinner.h" -#include "sip/SipHandler.h" #include "accounts/AccountModel.h" +#include "accounts/Account.h" +#include "accounts/AccountManager.h" #include "utils/logger.h" #include "ui_proxydialog.h" @@ -115,9 +116,8 @@ SettingsDialog::SettingsDialog( QWidget *parent ) ui->accountsView->setContextMenuPolicy( Qt::CustomContextMenu ); ui->accountsView->setVerticalScrollMode( QAbstractItemView::ScrollPerPixel ); - connect( ui->accountsView, SIGNAL( clicked( QModelIndex ) ), this, SLOT( sipItemClicked( QModelIndex ) ) ); - connect( sipdel, SIGNAL( openConfig( SipPlugin* ) ), this, SLOT( openSipConfig( SipPlugin* ) ) ); - connect( ui->accountsView, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( sipContextMenuRequest( QPoint ) ) ); + connect( sipdel, SIGNAL( openConfig( Tomahawk::Accounts::Account* ) ), this, SLOT( openAccountConfig( Tomahawk::Accounts::Account* ) ) ); + connect( ui->accountsView, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( accountContextMenuRequest( QPoint ) ) ); m_accountModel = new AccountModel( this ); ui->accountsView->setModel( m_accountModel ); @@ -131,7 +131,7 @@ SettingsDialog::SettingsDialog( QWidget *parent ) connect( Servent::instance(), SIGNAL( ready() ), this, SLOT( serventReady() ) ); } - //setupSipButtons(); + setupAccountButtons(); ui->staticHostName->setText( s->externalHostname() ); ui->staticPort->setValue( s->externalPort() ); @@ -313,13 +313,13 @@ SettingsDialog::createIcons() connect( ui->listWidget, SIGNAL( currentItemChanged( QListWidgetItem*, QListWidgetItem* ) ), SLOT( changePage( QListWidgetItem*, QListWidgetItem* ) ) ); } -/* + void -SettingsDialog::setupSipButtons() +SettingsDialog::setupAccountButtons() { - foreach( SipPluginFactory* f, SipHandler::instance()->pluginFactories() ) + foreach( AccountFactory* f, AccountManager::instance()->factories() ) { - if( f->isUnique() && SipHandler::instance()->hasPluginType( f->factoryId() ) ) + if( f->isUnique() && AccountManager::instance()->hasPluginWithFactory( f->factoryId() ) ) { continue; } @@ -331,9 +331,9 @@ SettingsDialog::setupSipButtons() connect( action, SIGNAL( triggered(bool) ), this, SLOT( factoryActionTriggered( bool ) ) ); } - connect( ui->removeSipButton, SIGNAL( clicked( bool ) ), this, SLOT( sipPluginDeleted( bool ) ) ); + connect( ui->removeSipButton, SIGNAL( clicked( bool ) ), this, SLOT( accountDeleted( bool ) ) ); } -*/ + void SettingsDialog::changePage( QListWidgetItem* current, QListWidgetItem* previous ) @@ -591,39 +591,26 @@ SettingsDialog::resolverConfigClosed( int value ) } } -/* -void -SettingsDialog::sipItemClicked( const QModelIndex& item ) -{ - if( item.data( SipModel::FactoryRole ).toBool() ) - if( ui->accountsView->isExpanded( item ) ) - ui->accountsView->collapse( item ); - else - ui->accountsView->expand( item ); - else if( item.data( SipModel::FactoryItemRole ).toBool() ) - sipFactoryClicked( qobject_cast( item.data( SipModel::SipPluginFactoryData ).value< QObject* >() ) ); -} - void -SettingsDialog::openSipConfig( SipPlugin* p ) +SettingsDialog::openAccountConfig( Account* account ) { - if( p->configWidget() ) + if( account->configurationWidget() ) { #ifndef Q_WS_MAC - DelegateConfigWrapper dialog( p->configWidget(), QString("%1 Configuration" ).arg( p->friendlyName() ), this ); + DelegateConfigWrapper dialog( account->configurationWidget(), QString("%1 Configuration" ).arg( account->accountFriendlyName() ), this ); QWeakPointer< DelegateConfigWrapper > watcher( &dialog ); int ret = dialog.exec(); if( !watcher.isNull() && ret == QDialog::Accepted ) { // send changed config to resolver - p->saveConfig(); + account->saveConfig(); } #else // on osx a sheet needs to be non-modal - DelegateConfigWrapper* dialog = new DelegateConfigWrapper( p->configWidget(), QString("%1 Configuration" ).arg( p->friendlyName() ), this, Qt::Sheet ); - dialog->setProperty( "sipplugin", QVariant::fromValue< QObject* >( p ) ); - connect( dialog, SIGNAL( finished( int ) ), this, SLOT( sipConfigClosed( int ) ) ); + DelegateConfigWrapper* dialog = new DelegateConfigWrapper( account->configurationWidget(), QString("%1 Configuration" ).arg( account->accountFriendlyName() ), this, Qt::Sheet ); + dialog->setProperty( "accountplugin", QVariant::fromValue< QObject* >( account ) ); + connect( dialog, SIGNAL( finished( int ) ), this, SLOT( accountConfigClosed( int ) ) ); dialog->show(); #endif @@ -632,13 +619,13 @@ SettingsDialog::openSipConfig( SipPlugin* p ) void -SettingsDialog::sipConfigClosed( int value ) +SettingsDialog::accountConfigClosed( int value ) { if( value == QDialog::Accepted ) { DelegateConfigWrapper* dialog = qobject_cast< DelegateConfigWrapper* >( sender() ); - SipPlugin* p = qobject_cast< SipPlugin* >( dialog->property( "sipplugin" ).value< QObject* >() ); - p->saveConfig(); + Account* account = qobject_cast< Account* >( dialog->property( "accountplugin" ).value< QObject* >() ); + account->saveConfig(); } } @@ -649,149 +636,154 @@ SettingsDialog::factoryActionTriggered( bool ) Q_ASSERT( sender() && qobject_cast< QAction* >( sender() ) ); QAction* a = qobject_cast< QAction* >( sender() ); - Q_ASSERT( qobject_cast< SipPluginFactory* >( a->property( "factory" ).value< QObject* >() ) ); + Q_ASSERT( qobject_cast< AccountFactory* >( a->property( "factory" ).value< QObject* >() ) ); - SipPluginFactory* f = qobject_cast< SipPluginFactory* >( a->property( "factory" ).value< QObject* >() ); - sipFactoryClicked( f ); + AccountFactory* f = qobject_cast< AccountFactory* >( a->property( "factory" ).value< QObject* >() ); + accountFactoryClicked( f ); } void -SettingsDialog::sipFactoryClicked( SipPluginFactory* factory ) +SettingsDialog::accountFactoryClicked( AccountFactory* factory ) { //if exited with OK, create it, if not, delete it immediately! - SipPlugin* p = factory->createPlugin(); + Account* account = factory->createAccount(); bool added = false; - if( p->configWidget() ) + if( account->configurationWidget() ) { #ifdef Q_WS_MAC // on osx a sheet needs to be non-modal - DelegateConfigWrapper* dialog = new DelegateConfigWrapper( p->configWidget(), QString("%1 Config" ).arg( p->friendlyName() ), this, Qt::Sheet ); - dialog->setProperty( "sipplugin", QVariant::fromValue< QObject* >( p ) ); - connect( dialog, SIGNAL( finished( int ) ), this, SLOT( sipCreateConfigClosed( int ) ) ); - connect( p, SIGNAL( datatError( bool ) ), dialog, SLOT( toggleOkButton( bool ) ) ); + DelegateConfigWrapper* dialog = new DelegateConfigWrapper( account->configurationWidget(), QString("%1 Config" ).arg( account->accountFriendlyName() ), this, Qt::Sheet ); + dialog->setProperty( "accountplugin", QVariant::fromValue< QObject* >( account ) ); + connect( dialog, SIGNAL( finished( int ) ), this, SLOT( accountCreateConfigClosed( int ) ) ); + + if( account->configurationWidget()->metaObject()->indexOfSignal( "dataError(bool)" ) > -1 ) + connect( account->configurationWidget(), SIGNAL( dataError( bool ) ), dialog, SLOT( toggleOkButton( bool ) ), Qt::UniqueConnection ); dialog->show(); #else - DelegateConfigWrapper dialog( p->configWidget(), QString("%1 Config" ).arg( p->friendlyName() ), this ); + DelegateConfigWrapper dialog( account->configurationWidget(), QString("%1 Config" ).arg( account->accountFriendlyName() ), this ); QWeakPointer< DelegateConfigWrapper > watcher( &dialog ); - connect( p, SIGNAL( dataError( bool ) ), &dialog, SLOT( toggleOkButton( bool ) ) ); + + if( account->configurationWidget()->metaObject()->indexOfSignal( "dataError(bool)" ) > -1 ) + connect( account->configurationWidget(), SIGNAL( dataError( bool ) ), &dialog, SLOT( toggleOkButton( bool ) ), Qt::UniqueConnection ); + int ret = dialog.exec(); - if( !watcher.isNull() && ret == QDialog::Accepted ) - { - // send changed config to resolver - p->saveConfig(); - - // accepted, so add it to tomahawk - TomahawkSettings::instance()->addSipPlugin( p->pluginId() ); - SipHandler::instance()->addSipPlugin( p ); - + if( !watcher.isNull() && ret == QDialog::Accepted ) // send changed config to account added = true; - } - else - { - // canceled, delete it + else // canceled, delete it added = false; - } - handleSipPluginAdded( p, added ); + handleAccountAdded( account, added ); #endif } else { // no config, so just add it added = true; - TomahawkSettings::instance()->addSipPlugin( p->pluginId() ); - SipHandler::instance()->addSipPlugin( p ); - - handleSipPluginAdded( p, added ); + handleAccountAdded( account, added ); } } void -SettingsDialog::sipCreateConfigClosed( int finished ) +SettingsDialog::accountCreateConfigClosed( int finished ) { DelegateConfigWrapper* dialog = qobject_cast< DelegateConfigWrapper* >( sender() ); - SipPlugin* p = qobject_cast< SipPlugin* >( dialog->property( "sipplugin" ).value< QObject* >() ); - Q_ASSERT( p ); + Account* account = qobject_cast< Account* >( dialog->property( "accountplugin" ).value< QObject* >() ); + Q_ASSERT( account ); - bool added = false; - if( finished == QDialog::Accepted ) - { + bool added = ( finished == QDialog::Accepted ); - p->saveConfig(); - TomahawkSettings::instance()->addSipPlugin( p->pluginId() ); - SipHandler::instance()->addSipPlugin( p ); - - added = true; - } - - handleSipPluginAdded( p, added ); + handleAccountAdded( account, added ); } void -SettingsDialog::handleSipPluginAdded( SipPlugin* p, bool added ) +SettingsDialog::handleAccountAdded( Account* account, bool added ) { - SipPluginFactory* f = SipHandler::instance()->factoryFromPlugin( p ); - if( added && f && f->isUnique() ) + AccountFactory* f = AccountManager::instance()->factoryForAccount( account ); + if ( added ) { - // remove from actions list - QAction* toremove = 0; - foreach( QAction* a, ui->addSipButton->actions() ) + account->setEnabled( true ); + account->setAutoConnect( true ); + account->saveConfig(); + + TomahawkSettings::instance()->addAccount( account->accountId() ); + AccountManager::instance()->addAccount( account ); + AccountManager::instance()->hookupAndEnable( account ); + + if( f && f->isUnique() ) { - if( f == qobject_cast< SipPluginFactory* >( a->property( "factory" ).value< QObject* >() ) ) + // remove from actions list + QAction* toremove = 0; + foreach( QAction* a, ui->addSipButton->actions() ) { - toremove = a; - break; + if( f == qobject_cast< AccountFactory* >( a->property( "factory" ).value< QObject* >() ) ) + { + toremove = a; + break; + } } + if( toremove ) + ui->addSipButton->removeAction( toremove ); } - if( toremove ) - ui->addSipButton->removeAction( toremove ); } - else if( added == false ) + else { // user pressed cancel - delete p; + delete account; } } void -SettingsDialog::sipContextMenuRequest( const QPoint& p ) +SettingsDialog::accountContextMenuRequest( const QPoint& p ) { QModelIndex idx = ui->accountsView->indexAt( p ); // if it's an account, allow to delete - if( idx.isValid() && !idx.data( SipModel::FactoryRole ).toBool() && !idx.data( SipModel::FactoryItemRole ).toBool() ) + if( idx.isValid() ) { QList< QAction* > acts; acts << new QAction( tr( "Delete Account" ), this ); - acts.first()->setProperty( "sipplugin", idx.data( SipModel::SipPluginData ) ); - connect( acts.first(), SIGNAL( triggered( bool ) ), this, SLOT( sipPluginRowDeleted( bool ) ) ); + acts.first()->setProperty( "accountplugin", idx.data( AccountModel::AccountData ) ); + connect( acts.first(), SIGNAL( triggered( bool ) ), this, SLOT( onAccountRowDeleted( bool ) ) ); QMenu::exec( acts, ui->accountsView->mapToGlobal( p ) ); } } void -SettingsDialog::sipPluginRowDeleted( bool ) +SettingsDialog::onAccountRowDeleted( bool ) { - SipPlugin* p = qobject_cast< SipPlugin* >( qobject_cast< QAction* >( sender() )->property( "sipplugin" ).value< QObject* >() ); - SipHandler::instance()->removeSipPlugin( p ); + Account* account = qobject_cast< Account* >( qobject_cast< QAction* >( sender() )->property( "accountplugin" ).value< QObject* >() ); + + if( AccountFactory* f = AccountManager::instance()->factoryForAccount( account ) ) + { + if( f->isUnique() ) // just deleted a unique plugin->re-add to add menu + { + QAction* action = new QAction( f->icon(), f->prettyName(), ui->addSipButton ); + action->setProperty( "factory", QVariant::fromValue< QObject* >( f ) ); + ui->addSipButton->addAction( action ); + + connect( action, SIGNAL( triggered(bool) ), this, SLOT( factoryActionTriggered( bool ) ) ); + } + } + + AccountManager::instance()->removeAccount( account ); } void -SettingsDialog::sipPluginDeleted( bool ) +SettingsDialog::accountDeleted( bool ) { QModelIndexList indexes = ui->accountsView->selectionModel()->selectedIndexes(); // if it's an account, allow to delete foreach( const QModelIndex& idx, indexes ) { - if( idx.isValid() && !idx.data( SipModel::FactoryRole ).toBool() && !idx.data( SipModel::FactoryItemRole ).toBool() ) + if( idx.isValid() ) { - SipPlugin* p = qobject_cast< SipPlugin* >( idx.data( SipModel::SipPluginData ).value< QObject* >() ); + Account* account = qobject_cast< Account* >( idx.data( AccountModel::AccountData ).value< QObject* >() ); - if( SipPluginFactory* f = SipHandler::instance()->factoryFromPlugin( p ) ) + if( AccountFactory* f = AccountManager::instance()->factoryForAccount( account ) ) { if( f->isUnique() ) // just deleted a unique plugin->re-add to add menu { @@ -802,11 +794,11 @@ SettingsDialog::sipPluginDeleted( bool ) connect( action, SIGNAL( triggered(bool) ), this, SLOT( factoryActionTriggered( bool ) ) ); } } - SipHandler::instance()->removeSipPlugin( p ); + AccountManager::instance()->removeAccount( account ); } } } -*/ + ProxyDialog::ProxyDialog( QWidget *parent ) : QDialog( parent ) diff --git a/src/settingsdialog.h b/src/settingsdialog.h index a2fa1de90..bbc68d354 100644 --- a/src/settingsdialog.h +++ b/src/settingsdialog.h @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2010-2011, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -42,7 +43,9 @@ namespace Tomahawk namespace Accounts { class AccountModel; - } + class Account; + class AccountFactory; +} } class ProxyDialog : public QDialog @@ -95,21 +98,20 @@ private slots: #endif void openResolverConfig( const QString& ); - /* - void sipItemClicked ( const QModelIndex& ); - void openSipConfig( SipPlugin* ); + + void openAccountConfig( Tomahawk::Accounts::Account* ); void factoryActionTriggered ( bool ); - void sipFactoryClicked( SipPluginFactory* ); - void sipContextMenuRequest( const QPoint& ); - void sipPluginDeleted( bool ); - void sipPluginRowDeleted( bool ); - */ + void accountFactoryClicked( Tomahawk::Accounts::AccountFactory* ); + void accountContextMenuRequest( const QPoint& ); + void accountDeleted( bool ); + void onAccountRowDeleted( bool ); + // dialog slots void resolverConfigClosed( int value ); - /* - void sipConfigClosed( int value ); - void sipCreateConfigClosed( int value ); - */ + + void accountConfigClosed( int value ); + void accountCreateConfigClosed( int value ); + void updateScanOptionsView(); void changePage( QListWidgetItem*, QListWidgetItem* ); @@ -117,8 +119,8 @@ private slots: private: void createIcons(); - //void setupSipButtons(); - //void handleSipPluginAdded( SipPlugin* p, bool added ); + void setupAccountButtons(); + void handleAccountAdded( Tomahawk::Accounts::Account* p, bool added ); Ui_StackedSettingsDialog* ui; diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index a299c2579..7ea6c21d2 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -40,7 +40,6 @@ #include "database/databasecollection.h" #include "database/databasecommand_collectionstats.h" #include "database/databaseresolver.h" -#include "sip/SipHandler.h" #include "playlist/dynamic/GeneratorFactory.h" #include "playlist/dynamic/echonest/EchonestGenerator.h" #include "playlist/dynamic/database/DatabaseGenerator.h" @@ -297,7 +296,7 @@ TomahawkApp::~TomahawkApp() //FIXME: delete GeneratorFactory::registerFactory( "echonest", new EchonestFactory ); ? - delete SipHandler::instance(); + delete Tomahawk::Accounts::AccountManager::instance(); Pipeline::instance()->stop(); @@ -513,7 +512,7 @@ TomahawkApp::initSIP() #endif tDebug( LOGINFO ) << "Connecting SIP classes"; - Accounts::AccountManager::instance()->loadFromConfig(); + Accounts::AccountManager::instance()->initSIP(); } } From 3607d364e705469aed48c0210f793bdaf398e654 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 16 Dec 2011 17:31:54 -0500 Subject: [PATCH 024/104] port google wrapper over --- src/accounts/xmpp/CMakeLists.txt | 2 +- .../xmpp/googlewrapper/CMakeLists.txt | 31 ++++--- .../xmpp/googlewrapper/googlewrapper.cpp | 89 +++++++++++++------ .../xmpp/googlewrapper/googlewrapper.h | 51 ++++++++--- src/accounts/xmpp/xmppaccount.cpp | 4 +- src/accounts/xmpp/xmppaccount.h | 7 +- src/accounts/xmpp/xmppconfigwidget.h | 3 + 7 files changed, 127 insertions(+), 60 deletions(-) diff --git a/src/accounts/xmpp/CMakeLists.txt b/src/accounts/xmpp/CMakeLists.txt index 69fa87122..809ee5b03 100644 --- a/src/accounts/xmpp/CMakeLists.txt +++ b/src/accounts/xmpp/CMakeLists.txt @@ -60,5 +60,5 @@ ENDIF( APPLE ) install( TARGETS tomahawk_account_xmpp DESTINATION lib${LIB_SUFFIX} ) -#add_subdirectory(googlewrapper) +add_subdirectory(googlewrapper) diff --git a/src/accounts/xmpp/googlewrapper/CMakeLists.txt b/src/accounts/xmpp/googlewrapper/CMakeLists.txt index 8a3e47957..d8abd686f 100644 --- a/src/accounts/xmpp/googlewrapper/CMakeLists.txt +++ b/src/accounts/xmpp/googlewrapper/CMakeLists.txt @@ -2,31 +2,36 @@ # fake google plugin set( googleHeaders - ../jabber.h - ../avatarmanager.h - ../xmlconsole.h - googlewrapper.h ) + ../xmppaccount.h + ../xmppconfigwidget.h + ../sip/xmppsip.h + ../sip/avatarmanager.h + ../sip/xmlconsole.h + googlewrapper.h ) set( googleSources - ../jabber.cpp - ../tomahawkxmppmessage.cpp - ../tomahawkxmppmessagefactory.cpp - ../avatarmanager.cpp - ../xmlconsole.cpp - googlewrapper.cpp ) + ../xmppaccount.cpp + ../xmppconfigwidget.cpp + ../sip/xmppsip.cpp + ../sip/tomahawkxmppmessage.cpp + ../sip/tomahawkxmppmessagefactory.cpp + ../sip/avatarmanager.cpp + ../sip/xmlconsole.cpp + + googlewrapper.cpp ) add_definitions(-DGOOGLE_WRAPPER) qt4_add_resources( RCX_SRCS "resources.qrc" ) qt4_wrap_cpp( googleMoc ${googleHeaders} ) -add_library( tomahawk_sipgoogle SHARED ${googleSources} ${googleMoc} ${googleMoc} ${RCX_SRCS} ) +add_library( tomahawk_account_google SHARED ${googleSources} ${googleMoc} ${googleMoc} ${RCX_SRCS} ) -target_link_libraries( tomahawk_sipgoogle +target_link_libraries( tomahawk_account_google ${QT_LIBRARIES} ${LIBJREEN_LIBRARY} ${OS_SPECIFIC_LINK_LIBRARIES} tomahawklib ) -install( TARGETS tomahawk_sipgoogle DESTINATION lib${LIB_SUFFIX} ) +install( TARGETS tomahawk_account_google DESTINATION lib${LIB_SUFFIX} ) diff --git a/src/accounts/xmpp/googlewrapper/googlewrapper.cpp b/src/accounts/xmpp/googlewrapper/googlewrapper.cpp index 1e7c107f4..779aef58c 100644 --- a/src/accounts/xmpp/googlewrapper/googlewrapper.cpp +++ b/src/accounts/xmpp/googlewrapper/googlewrapper.cpp @@ -18,18 +18,21 @@ #include "googlewrapper.h" -#include "ui_configwidget.h" +#include "xmppconfigwidget.h" +#include "ui_xmppconfigwidget.h" #include "utils/tomahawkutils.h" #include #include +using namespace Tomahawk; +using namespace Accounts; -SipPlugin* -GoogleWrapperFactory::createPlugin( const QString& pluginId ) +Account* +GoogleWrapperFactory::createAccount( const QString& pluginId ) { - return new GoogleWrapper( pluginId.isEmpty() ? generateId() : pluginId ); + return new GoogleWrapper( pluginId.isEmpty() ? generateId( factoryId() ) : pluginId ); } @@ -39,36 +42,19 @@ GoogleWrapperFactory::icon() const return QIcon( ":/gmail-logo.png" ); } - -GoogleWrapper::GoogleWrapper ( const QString& pluginID ) - : JabberPlugin ( pluginID ) +GoogleWrapperSip::GoogleWrapperSip( Account* account ) + : XmppSipPlugin( account ) { - m_ui->headerLabel->setText( tr( "Configure this Google Account" ) ); - m_ui->emailLabel->setText( tr( "Google Address" ) ); - m_ui->jabberBlurb->setText( tr( "Enter your Google login to connect with your friends using Tomahawk!" ) ); - m_ui->logoLabel->setPixmap( QPixmap( ":/gmail-logo.png" ) ); - m_ui->jabberServer->setText( "talk.google.com" ); - m_ui->jabberPort->setValue( 5222 ); - m_ui->groupBoxJabberAdvanced->hide(); + } - -QIcon -GoogleWrapper::icon() const +GoogleWrapperSip::~GoogleWrapperSip() { - return QIcon( ":/gmail-logo.png" ); -} - - -QString -GoogleWrapper::defaultSuffix() const -{ - return "@gmail.com"; } void -GoogleWrapper::showAddFriendDialog() +GoogleWrapperSip::showAddFriendDialog() { bool ok; QString id = QInputDialog::getText( TomahawkUtils::tomahawkWindow(), tr( "Add Friend" ), @@ -81,6 +67,55 @@ GoogleWrapper::showAddFriendDialog() } +QString +GoogleWrapperSip::defaultSuffix() const +{ + return "@gmail.com"; +} + + +GoogleWrapper::GoogleWrapper ( const QString& pluginID ) + : XmppAccount ( pluginID ) +{ + XmppConfigWidget* config = static_cast< XmppConfigWidget* >( m_configWidget.data() ); + config->m_ui->headerLabel->setText( tr( "Configure this Google Account" ) ); + config->m_ui->emailLabel->setText( tr( "Google Address" ) ); + config->m_ui->xmppBlurb->setText( tr( "Enter your Google login to connect with your friends using Tomahawk!" ) ); + config->m_ui->logoLabel->setPixmap( QPixmap( ":/gmail-logo.png" ) ); + config->m_ui->xmppServer->setText( "talk.google.com" ); + config->m_ui->xmppPort->setValue( 5222 ); + config->m_ui->groupBoxXmppAdvanced->hide(); +} + +GoogleWrapper::~GoogleWrapper() +{ + delete m_sipPlugin.data(); +} + + +QIcon +GoogleWrapper::icon() const +{ + return QIcon( ":/gmail-logo.png" ); +} + + +SipPlugin* +GoogleWrapper::sipPlugin() +{ + if ( m_xmppSipPlugin.isNull() ) + { + m_xmppSipPlugin = QWeakPointer< XmppSipPlugin >( new GoogleWrapperSip( const_cast< GoogleWrapper* >( this ) ) ); + + connect( m_xmppSipPlugin.data(), SIGNAL( stateChanged( Tomahawk::Accounts::Account::ConnectionState ) ), this, SIGNAL( connectionStateChanged( Tomahawk::Accounts::Account::ConnectionState ) ) ); + connect( m_xmppSipPlugin.data(), SIGNAL( error( int, QString ) ), this, SIGNAL( error( int, QString ) ) ); + + return m_xmppSipPlugin.data(); + } + return m_xmppSipPlugin.data(); +} + + #ifdef GOOGLE_WRAPPER -Q_EXPORT_PLUGIN2( sipfactory, GoogleWrapperFactory ) +Q_EXPORT_PLUGIN2( Tomahawk::Accounts::AccountFactory, Tomahawk::Accounts::GoogleWrapperFactory ) #endif diff --git a/src/accounts/xmpp/googlewrapper/googlewrapper.h b/src/accounts/xmpp/googlewrapper/googlewrapper.h index f34238c6a..d765c67a9 100644 --- a/src/accounts/xmpp/googlewrapper/googlewrapper.h +++ b/src/accounts/xmpp/googlewrapper/googlewrapper.h @@ -19,12 +19,18 @@ #ifndef GOOGLEWRAPPER_H #define GOOGLEWRAPPER_H -#include "sip/jabber/jabber.h" +#include "xmppaccount.h" -class SIPDLLEXPORT GoogleWrapperFactory : public SipPluginFactory +namespace Tomahawk +{ + +namespace Accounts +{ + +class ACCOUNTDLLEXPORT GoogleWrapperFactory : public XmppAccountFactory { Q_OBJECT - Q_INTERFACES( SipPluginFactory ) + Q_INTERFACES( Tomahawk::Accounts::AccountFactory ) public: GoogleWrapperFactory() {} @@ -33,25 +39,42 @@ public: virtual QString prettyName() const { return "Google"; } virtual QString factoryId() const { return "sipgoogle"; } virtual QIcon icon() const; - virtual SipPlugin* createPlugin( const QString& pluginId ); + virtual Account* createAccount( const QString& pluginId ); }; -class SIPDLLEXPORT GoogleWrapper : public JabberPlugin +class ACCOUNTDLLEXPORT GoogleWrapperSip : public XmppSipPlugin { Q_OBJECT public: - GoogleWrapper( const QString& pluginID ); - virtual ~GoogleWrapper() {} - - virtual const QString name() const { return QString( "Google" ); } - virtual const QString friendlyName() const { return "Google"; } - virtual QIcon icon() const; - -protected: - QString defaultSuffix() const; + GoogleWrapperSip( Tomahawk::Accounts::Account* account ); + virtual ~GoogleWrapperSip(); public slots: void showAddFriendDialog(); + +protected: + QString defaultSuffix() const; }; +class ACCOUNTDLLEXPORT GoogleWrapper : public XmppAccount +{ + Q_OBJECT +public: + GoogleWrapper( const QString& pluginID ); + virtual ~GoogleWrapper(); + + virtual const QString name() const { return QString( "Google" ); } + virtual const QString friendlyName() const { return "Google"; } + virtual QIcon icon() const; + + virtual SipPlugin* sipPlugin(); + +private: + QWeakPointer< GoogleWrapperSip > m_sipPlugin; +}; + +} + +} + #endif // GOOGLEWRAPPER_H diff --git a/src/accounts/xmpp/xmppaccount.cpp b/src/accounts/xmpp/xmppaccount.cpp index b32aa2183..51a6dfc5b 100644 --- a/src/accounts/xmpp/xmppaccount.cpp +++ b/src/accounts/xmpp/xmppaccount.cpp @@ -83,8 +83,6 @@ XmppAccount::isAuthenticated() const Account::ConnectionState XmppAccount::connectionState() const { - // Ensure we exist - const_cast( this )->sipPlugin(); return m_xmppSipPlugin.data()->connectionState(); } @@ -116,4 +114,6 @@ XmppAccount::sipPlugin() } +#ifndef GOOGLE_WRAPPER Q_EXPORT_PLUGIN2( Tomahawk::Accounts::AccountFactory, Tomahawk::Accounts::XmppAccountFactory ) +#endif diff --git a/src/accounts/xmpp/xmppaccount.h b/src/accounts/xmpp/xmppaccount.h index 122d3171d..ff8961129 100644 --- a/src/accounts/xmpp/xmppaccount.h +++ b/src/accounts/xmpp/xmppaccount.h @@ -73,11 +73,12 @@ public: virtual Tomahawk::Accounts::Account::ConnectionState connectionState() const; -private: - Ui_XmppConfigWidget* m_ui; // so the google wrapper can change the config dialog a bit - QWeakPointer< QWidget > m_configWidget; +protected: + QWeakPointer< QWidget > m_configWidget; // so the google wrapper can change the config dialog a bit QWeakPointer< XmppSipPlugin > m_xmppSipPlugin; +private: + // for settings access friend class XmppConfigWidget; diff --git a/src/accounts/xmpp/xmppconfigwidget.h b/src/accounts/xmpp/xmppconfigwidget.h index ffe7e986b..d88e42631 100644 --- a/src/accounts/xmpp/xmppconfigwidget.h +++ b/src/accounts/xmpp/xmppconfigwidget.h @@ -35,6 +35,7 @@ namespace Accounts { class XmppAccount; +class GoogleWrapper; class DLLEXPORT XmppConfigWidget : public QWidget @@ -56,6 +57,8 @@ private slots: private: Ui::XmppConfigWidget *m_ui; XmppAccount *m_account; + + friend class GoogleWrapper; // So google wrapper can modify the labels and text }; } From 7783f48baed3fccad189afba038e9f82dd4d6773 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 16 Dec 2011 18:11:15 -0500 Subject: [PATCH 025/104] show account name in delegate properly --- src/libtomahawk/accounts/AccountModel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index f49d4a2a8..58d730f35 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -53,7 +53,7 @@ AccountModel::data( const QModelIndex& index, int role ) const { case Qt::DisplayRole: case AccountModel::AccountName: - return account->accountServiceName(); + return account->accountFriendlyName(); case AccountModel::ConnectionStateRole: return account->connectionState(); case AccountModel::HasConfig: From f74165424ff3000db380cabe3e112c681339120d Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sun, 18 Dec 2011 13:31:36 -0500 Subject: [PATCH 026/104] Port zeroconf plugin --- src/CMakeLists.txt | 2 +- src/accounts/CMakeLists.txt | 2 +- src/accounts/twitter/twitteraccount.cpp | 4 + src/accounts/twitter/twitteraccount.h | 3 +- src/{sip => accounts}/zeroconf/CMakeLists.txt | 8 +- .../zeroconf/configwidget.ui | 0 src/{sip => accounts}/zeroconf/resources.qrc | 0 .../zeroconf/tomahawkzeroconf.h | 6 +- .../zeroconf/zeroconf-icon.png | Bin src/{sip => accounts}/zeroconf/zeroconf.cpp | 41 ++---- src/{sip => accounts}/zeroconf/zeroconf.h | 38 +++--- src/accounts/zeroconf/zeroconfaccount.cpp | 126 ++++++++++++++++++ src/accounts/zeroconf/zeroconfaccount.h | 78 +++++++++++ src/sip/CMakeLists.txt | 0 .../jabber/googlewrapper/googlewrapper.cpp | 86 ------------ src/sip/xmpp/CMakeLists.txt | 86 ------------ 16 files changed, 248 insertions(+), 232 deletions(-) rename src/{sip => accounts}/zeroconf/CMakeLists.txt (74%) rename src/{sip => accounts}/zeroconf/configwidget.ui (100%) rename src/{sip => accounts}/zeroconf/resources.qrc (100%) rename src/{sip => accounts}/zeroconf/tomahawkzeroconf.h (97%) rename src/{sip => accounts}/zeroconf/zeroconf-icon.png (100%) rename src/{sip => accounts}/zeroconf/zeroconf.cpp (82%) rename src/{sip => accounts}/zeroconf/zeroconf.h (69%) create mode 100644 src/accounts/zeroconf/zeroconfaccount.cpp create mode 100644 src/accounts/zeroconf/zeroconfaccount.h delete mode 100644 src/sip/CMakeLists.txt delete mode 100644 src/sip/jabber/googlewrapper/googlewrapper.cpp delete mode 100644 src/sip/xmpp/CMakeLists.txt diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 66d305325..088236165 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -198,8 +198,8 @@ 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) INCLUDE_DIRECTORIES( ${QCA2_INCLUDE_DIR} ) diff --git a/src/accounts/CMakeLists.txt b/src/accounts/CMakeLists.txt index f345a75fc..8b61be457 100644 --- a/src/accounts/CMakeLists.txt +++ b/src/accounts/CMakeLists.txt @@ -7,4 +7,4 @@ IF( QTWEETLIB_FOUND AND BUILD_GUI ) #ADD_SUBDIRECTORY( twitter ) ENDIF() -#ADD_SUBDIRECTORY( zeroconf ) \ No newline at end of file +ADD_SUBDIRECTORY( zeroconf ) \ No newline at end of file diff --git a/src/accounts/twitter/twitteraccount.cpp b/src/accounts/twitter/twitteraccount.cpp index 74990e3b7..64eed5dcf 100644 --- a/src/accounts/twitter/twitteraccount.cpp +++ b/src/accounts/twitter/twitteraccount.cpp @@ -162,6 +162,10 @@ TwitterAccount::connectAuthVerifyReply( const QTweetUser &user ) emit nowAuthenticated( m_twitterAuth, user ); } } +QIcon +TwitterAccount::icon() const { + return QIcon( ":/twitter-icon.png" ); +} } diff --git a/src/accounts/twitter/twitteraccount.h b/src/accounts/twitter/twitteraccount.h index 0d45a893d..a0bfeae80 100644 --- a/src/accounts/twitter/twitteraccount.h +++ b/src/accounts/twitter/twitteraccount.h @@ -58,7 +58,7 @@ public: TwitterAccount( const QString &accountId ); virtual ~TwitterAccount(); - QIcon icon() const { return QIcon( ":/twitter-icon.png" ); } + QIcon icon() const; void authenticate(); void deauthenticate(); @@ -82,6 +82,7 @@ private slots: void connectAuthVerifyReply( const QTweetUser &user ); private: + QIcon m_icon; bool m_isAuthenticated; QWeakPointer< TomahawkOAuthTwitter > m_twitterAuth; QWeakPointer< TwitterConfigWidget > m_configWidget; diff --git a/src/sip/zeroconf/CMakeLists.txt b/src/accounts/zeroconf/CMakeLists.txt similarity index 74% rename from src/sip/zeroconf/CMakeLists.txt rename to src/accounts/zeroconf/CMakeLists.txt index c346cfa22..657a41b53 100644 --- a/src/sip/zeroconf/CMakeLists.txt +++ b/src/accounts/zeroconf/CMakeLists.txt @@ -8,11 +8,13 @@ add_definitions( -DSIPDLLEXPORT_PRO ) set( zeroconfSources zeroconf.cpp + zeroconfaccount.cpp ) set( zeroconfHeaders zeroconf.h tomahawkzeroconf.h + zeroconfaccount.h ) include_directories( . ${CMAKE_CURRENT_BINARY_DIR} .. @@ -22,7 +24,7 @@ include_directories( . ${CMAKE_CURRENT_BINARY_DIR} .. qt4_wrap_ui( UI_SRCS configwidget.ui ) qt4_add_resources( RC_SRCS "resources.qrc" ) qt4_wrap_cpp( zeroconfMoc ${zeroconfHeaders} ) -add_library( tomahawk_sipzeroconf SHARED ${zeroconfSources} ${zeroconfMoc} ${RC_SRCS} ${UI_SRCS} ) +add_library( tomahawk_account_zeroconf SHARED ${zeroconfSources} ${zeroconfMoc} ${RC_SRCS} ${UI_SRCS} ) IF( WIN32 ) SET( OS_SPECIFIC_LINK_LIBRARIES @@ -32,7 +34,7 @@ SET( OS_SPECIFIC_LINK_LIBRARIES ) ENDIF( WIN32 ) -target_link_libraries( tomahawk_sipzeroconf +target_link_libraries( tomahawk_account_zeroconf ${QT_LIBRARIES} ${OS_SPECIFIC_LINK_LIBRARIES} ${TOMAHAWK_LIBRARIES} @@ -42,4 +44,4 @@ IF( APPLE ) # SET( CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} "-undefined dynamic_lookup" ) ENDIF( APPLE ) -install( TARGETS tomahawk_sipzeroconf DESTINATION lib${LIB_SUFFIX} ) +install( TARGETS tomahawk_account_zeroconf DESTINATION lib${LIB_SUFFIX} ) diff --git a/src/sip/zeroconf/configwidget.ui b/src/accounts/zeroconf/configwidget.ui similarity index 100% rename from src/sip/zeroconf/configwidget.ui rename to src/accounts/zeroconf/configwidget.ui diff --git a/src/sip/zeroconf/resources.qrc b/src/accounts/zeroconf/resources.qrc similarity index 100% rename from src/sip/zeroconf/resources.qrc rename to src/accounts/zeroconf/resources.qrc diff --git a/src/sip/zeroconf/tomahawkzeroconf.h b/src/accounts/zeroconf/tomahawkzeroconf.h similarity index 97% rename from src/sip/zeroconf/tomahawkzeroconf.h rename to src/accounts/zeroconf/tomahawkzeroconf.h index 2eaf6ef10..efc309e51 100644 --- a/src/sip/zeroconf/tomahawkzeroconf.h +++ b/src/accounts/zeroconf/tomahawkzeroconf.h @@ -31,9 +31,7 @@ #include "database/database.h" #include "network/servent.h" -#include "../sipdllmacro.h" - -class SIPDLLEXPORT Node : public QObject +class Node : public QObject { Q_OBJECT @@ -71,7 +69,7 @@ private: }; -class SIPDLLEXPORT TomahawkZeroconf : public QObject +class TomahawkZeroconf : public QObject { Q_OBJECT diff --git a/src/sip/zeroconf/zeroconf-icon.png b/src/accounts/zeroconf/zeroconf-icon.png similarity index 100% rename from src/sip/zeroconf/zeroconf-icon.png rename to src/accounts/zeroconf/zeroconf-icon.png diff --git a/src/sip/zeroconf/zeroconf.cpp b/src/accounts/zeroconf/zeroconf.cpp similarity index 82% rename from src/sip/zeroconf/zeroconf.cpp rename to src/accounts/zeroconf/zeroconf.cpp index 1f88f4fe0..88fdf6016 100644 --- a/src/sip/zeroconf/zeroconf.cpp +++ b/src/accounts/zeroconf/zeroconf.cpp @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2011, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,20 +25,15 @@ #include "tomahawksettings.h" #include "utils/logger.h" +#include "zeroconfaccount.h" +using namespace Tomahawk; +using namespace Accounts; -SipPlugin* -ZeroconfFactory::createPlugin( const QString& pluginId ) -{ - return new ZeroconfPlugin( pluginId.isEmpty() ? generateId() : pluginId ); -} - -ZeroconfPlugin::ZeroconfPlugin() : SipPlugin( "") {} - -ZeroconfPlugin::ZeroconfPlugin ( const QString& pluginId ) - : SipPlugin( pluginId ) +ZeroconfPlugin::ZeroconfPlugin ( ZeroconfAccount* parent ) + : SipPlugin( parent ) , m_zeroconf( 0 ) - , m_state( Disconnected ) + , m_state( Account::Disconnected ) , m_cachedNodes() { qDebug() << Q_FUNC_INFO; @@ -66,21 +62,14 @@ ZeroconfPlugin::friendlyName() const return QString( MYNAME ); } -SipPlugin::ConnectionState +Account::ConnectionState ZeroconfPlugin::connectionState() const { return m_state; } -#ifndef ENABLE_HEADLESS -QIcon -ZeroconfFactory::icon() const -{ - return QIcon( ":/zeroconf-icon.png" ); -} -#endif -bool +void ZeroconfPlugin::connectPlugin() { delete m_zeroconf; @@ -89,7 +78,7 @@ ZeroconfPlugin::connectPlugin() SLOT( lanHostFound( QString, int, QString, QString ) ) ); advertise(); - m_state = Connected; + m_state = Account::Connected; foreach( const QStringList& nodeSet, m_cachedNodes ) { @@ -99,15 +88,13 @@ ZeroconfPlugin::connectPlugin() m_cachedNodes.clear(); m_advertisementTimer.start(); - - return true; } void ZeroconfPlugin::disconnectPlugin() { m_advertisementTimer.stop(); - m_state = Disconnected; + m_state = Account::Disconnected; delete m_zeroconf; m_zeroconf = 0; @@ -118,7 +105,7 @@ ZeroconfPlugin::disconnectPlugin() QIcon ZeroconfPlugin::icon() const { - return QIcon( ":/zeroconf-icon.png" ); + return account()->icon(); } #endif @@ -138,7 +125,7 @@ ZeroconfPlugin::lanHostFound( const QString& host, int port, const QString& name qDebug() << "Found LAN host:" << host << port << nodeid; - if ( m_state != Connected ) + if ( m_state != Account::Connected ) { qDebug() << "Not online, so not connecting."; QStringList nodeSet; @@ -153,5 +140,3 @@ ZeroconfPlugin::lanHostFound( const QString& host, int port, const QString& name qDebug() << "Already connected to" << host; } - -Q_EXPORT_PLUGIN2( sipfactory, ZeroconfFactory ) diff --git a/src/sip/zeroconf/zeroconf.h b/src/accounts/zeroconf/zeroconf.h similarity index 69% rename from src/sip/zeroconf/zeroconf.h rename to src/accounts/zeroconf/zeroconf.h index c9d33a7c3..98e8a865c 100644 --- a/src/sip/zeroconf/zeroconf.h +++ b/src/accounts/zeroconf/zeroconf.h @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2011, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,55 +21,45 @@ #define ZEROCONF_H #include "sip/SipPlugin.h" +#include "accounts/Account.h" #include "tomahawkzeroconf.h" -#include "../sipdllmacro.h" +#include "../accountdllmacro.h" #include #define MYNAME "Local Network" -class SIPDLLEXPORT ZeroconfFactory : public SipPluginFactory +namespace Tomahawk +{ +namespace Accounts { - Q_OBJECT - Q_INTERFACES( SipPluginFactory ) -public: - ZeroconfFactory() {} - virtual ~ZeroconfFactory() {} - virtual QString factoryId() const { return "sipzeroconf"; } - virtual QString prettyName() const { return "Local Network"; } - virtual bool isUnique() const { return true; } -#ifndef ENABLE_HEADLESS - virtual QIcon icon() const; -#endif +class ZeroconfAccount; - virtual SipPlugin* createPlugin ( const QString& pluginId = QString() ); -}; - -class SIPDLLEXPORT ZeroconfPlugin : public SipPlugin +class ACCOUNTDLLEXPORT ZeroconfPlugin : public SipPlugin { Q_OBJECT public: - ZeroconfPlugin(); - ZeroconfPlugin( const QString& pluginId ); + ZeroconfPlugin( ZeroconfAccount* acc ); virtual ~ZeroconfPlugin(); virtual const QString name() const; virtual const QString friendlyName() const; virtual const QString accountName() const; - virtual ConnectionState connectionState() const; + virtual Account::ConnectionState connectionState() const; virtual bool isValid() const { return true; } #ifndef ENABLE_HEADLESS virtual QIcon icon() const; #endif virtual void checkSettings() {} + virtual void configurationChanged() {} public slots: - virtual bool connectPlugin(); + void connectPlugin(); void disconnectPlugin(); void advertise(); @@ -82,9 +73,12 @@ private slots: private: TomahawkZeroconf* m_zeroconf; - ConnectionState m_state; + Account::ConnectionState m_state; QVector m_cachedNodes; QTimer m_advertisementTimer; }; +} +} + #endif diff --git a/src/accounts/zeroconf/zeroconfaccount.cpp b/src/accounts/zeroconf/zeroconfaccount.cpp new file mode 100644 index 000000000..06578f7ee --- /dev/null +++ b/src/accounts/zeroconf/zeroconfaccount.cpp @@ -0,0 +1,126 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2011, Leo Franchi + * + * 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 "zeroconfaccount.h" + +#include "sip/SipPlugin.h" +#include "zeroconf.h" + +#include + +using namespace Tomahawk; +using namespace Accounts; + +QIcon* s_icon = 0; + +ZeroconfFactory::ZeroconfFactory() +{ +#ifndef ENABLE_HEADLESS + if ( s_icon == 0 ) + s_icon = new QIcon( ":/zeroconf-icon.png" ); +#endif +} + + +ZeroconfFactory::~ZeroconfFactory() +{ + if ( s_icon ) + { + delete s_icon; + s_icon = 0; + } +} + + +Account* +ZeroconfFactory::createAccount( const QString& pluginId ) +{ + return new ZeroconfAccount( pluginId.isEmpty() ? generateId( factoryId() ) : pluginId ); +} + +QIcon +ZeroconfFactory::icon() const +{ + return *s_icon; +} + + +ZeroconfAccount::ZeroconfAccount( const QString& accountId ) + : Account( accountId ) +{ + setAccountServiceName( "Local Network" ); + setAccountFriendlyName( "Local Network" ); +} + +ZeroconfAccount::~ZeroconfAccount() +{ + +} + +QIcon +ZeroconfAccount::icon() const +{ + return *s_icon; +} + + +void +ZeroconfAccount::authenticate() +{ + if ( !isAuthenticated() ) + static_cast< ZeroconfPlugin* >( m_sipPlugin.data() )->connectPlugin(); +} + + +void +ZeroconfAccount::deauthenticate() +{ + if ( isAuthenticated() ) + static_cast< ZeroconfPlugin* >( m_sipPlugin.data() )->disconnectPlugin(); +} + + +bool +ZeroconfAccount::isAuthenticated() const +{ + return connectionState() == Connected; +} + + +Account::ConnectionState +ZeroconfAccount::connectionState() const +{ + if ( m_sipPlugin.isNull() ) + return Disconnected; + + // TODO can we get called before sipPlugin()? + return static_cast< ZeroconfPlugin* >( m_sipPlugin.data() )->connectionState(); +} + + +SipPlugin* +ZeroconfAccount::sipPlugin() +{ + if ( m_sipPlugin.isNull() ) + m_sipPlugin = QWeakPointer< SipPlugin >( new ZeroconfPlugin( this ) ); + + return m_sipPlugin.data(); +} + + +Q_EXPORT_PLUGIN2( Tomahawk::Accounts::AccountFactory, Tomahawk::Accounts::ZeroconfFactory ) \ No newline at end of file diff --git a/src/accounts/zeroconf/zeroconfaccount.h b/src/accounts/zeroconf/zeroconfaccount.h new file mode 100644 index 000000000..74d3afcad --- /dev/null +++ b/src/accounts/zeroconf/zeroconfaccount.h @@ -0,0 +1,78 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2011, Leo Franchi + * + * 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 ZEROCONF_ACCOUNTS_H +#define ZEROCONF_ACCOUNTS_H + +#include "accounts/Account.h" +#include "../accountdllmacro.h" + +class SipPlugin; + +namespace Tomahawk +{ +namespace Accounts +{ + +class ACCOUNTDLLEXPORT ZeroconfFactory : public AccountFactory +{ + Q_OBJECT + Q_INTERFACES( Tomahawk::Accounts::AccountFactory ) +public: + ZeroconfFactory(); + virtual ~ZeroconfFactory(); + + virtual QString factoryId() const { return "zeroconfaccount"; } + virtual QString prettyName() const { return "Local Network"; } + virtual bool isUnique() const { return true; } +#ifndef ENABLE_HEADLESS + virtual QIcon icon() const; +#endif + + + virtual Account* createAccount ( const QString& pluginId = QString() ); +}; + +class ACCOUNTDLLEXPORT ZeroconfAccount : public Account +{ + Q_OBJECT +public: + ZeroconfAccount( const QString &accountId ); + virtual ~ZeroconfAccount(); + + QIcon icon() const; + + void authenticate(); + void deauthenticate(); + bool isAuthenticated() const; + ConnectionState connectionState() const; + + Tomahawk::InfoSystem::InfoPlugin* infoPlugin() { return 0; } + SipPlugin* sipPlugin(); + + QWidget* configurationWidget() { return 0; } + QWidget* aclWidget() { return 0; } + +private: + QWeakPointer< SipPlugin > m_sipPlugin; +}; + +} +} + +#endif diff --git a/src/sip/CMakeLists.txt b/src/sip/CMakeLists.txt deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/sip/jabber/googlewrapper/googlewrapper.cpp b/src/sip/jabber/googlewrapper/googlewrapper.cpp deleted file mode 100644 index b04d80ad7..000000000 --- a/src/sip/jabber/googlewrapper/googlewrapper.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* - - Copyright (C) 2011 Leo Franchi - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - - -#include "googlewrapper.h" -#include "ui_configwidget.h" - -#include "utils/tomahawkutilsgui.h" - -#include -#include - - -SipPlugin* -GoogleWrapperFactory::createPlugin( const QString& pluginId ) -{ - return new GoogleWrapper( pluginId.isEmpty() ? generateId() : pluginId ); -} - - -QIcon -GoogleWrapperFactory::icon() const -{ - return QIcon( ":/gmail-logo.png" ); -} - - -GoogleWrapper::GoogleWrapper ( const QString& pluginID ) - : JabberPlugin ( pluginID ) -{ - m_ui->headerLabel->setText( tr( "Configure this Google Account" ) ); - m_ui->emailLabel->setText( tr( "Google Address" ) ); - m_ui->jabberBlurb->setText( tr( "Enter your Google login to connect with your friends using Tomahawk!" ) ); - m_ui->logoLabel->setPixmap( QPixmap( ":/gmail-logo.png" ) ); - m_ui->jabberServer->setText( "talk.google.com" ); - m_ui->jabberPort->setValue( 5222 ); - m_ui->groupBoxJabberAdvanced->hide(); -} - - -QIcon -GoogleWrapper::icon() const -{ - return QIcon( ":/gmail-logo.png" ); -} - - -QString -GoogleWrapper::defaultSuffix() const -{ - return "@gmail.com"; -} - - -void -GoogleWrapper::showAddFriendDialog() -{ - bool ok; - QString id = QInputDialog::getText( TomahawkUtils::tomahawkWindow(), tr( "Add Friend" ), - tr( "Enter Google Address:" ), QLineEdit::Normal, "", &ok ).trimmed(); - if ( !ok ) - return; - - qDebug() << "Attempting to add google contact to roster:" << id; - addContact( id ); -} - - -#ifdef GOOGLE_WRAPPER -Q_EXPORT_PLUGIN2( sipfactory, GoogleWrapperFactory ) -#endif diff --git a/src/sip/xmpp/CMakeLists.txt b/src/sip/xmpp/CMakeLists.txt deleted file mode 100644 index 6f4792bf9..000000000 --- a/src/sip/xmpp/CMakeLists.txt +++ /dev/null @@ -1,86 +0,0 @@ -project( tomahawk ) - -include( ${QT_USE_FILE} ) -add_definitions( ${QT_DEFINITIONS} ) -add_definitions( -DQT_PLUGIN ) -add_definitions( -DQT_SHARED ) -add_definitions( -DSIPDLLEXPORT_PRO ) - -<<<<<<< HEAD:src/sip/xmpp/CMakeLists.txt -set( xmppSipSources - xmppsip.cpp - tomahawkxmppmessage.cpp - tomahawkxmppmessagefactory.cpp -======= -set( jabberSources - jabber.cpp - tomahawksipmessage.cpp - tomahawksipmessagefactory.cpp -) -set( jabberSourcesGui ->>>>>>> origin/master:src/sip/jabber/CMakeLists.txt - avatarmanager.cpp - xmlconsole.cpp -) - -<<<<<<< HEAD:src/sip/xmpp/CMakeLists.txt -set( xmppSipHeaders - xmppsip.h -======= -set( jabberHeaders - jabber.h -) -set( jabberHeadersGui ->>>>>>> origin/master:src/sip/jabber/CMakeLists.txt - avatarmanager.h - xmlconsole.h -) - -set( xmppSipUI - xmlconsole.ui -) - -if(BUILD_GUI) - list(APPEND jabberSources ${jabberSourcesGui}) - list(APPEND jabberHeaders ${jabberHeadersGui}) -endif() - -include_directories( . ${CMAKE_CURRENT_BINARY_DIR} .. - ${QT_INCLUDE_DIR} - ${LIBJREEN_INCLUDE_DIR} -) - -qt4_wrap_ui( xmppSipUI_H ${xmppSipUI} ) -qt4_wrap_cpp( xmppSipMoc ${xmppSipHeaders} ) -add_library( tomahawk_sip_xmpp SHARED ${xmppSipSources} ${xmppSipMoc} ${xmppSipUI_H} ${RC_SRCS} ) - -IF( WIN32 ) -SET( OS_SPECIFIC_LINK_LIBRARIES - ${OS_SPECIFIC_LINK_LIBRARIES} - "secur32.dll" - "crypt32.dll" - ${TOMAHAWK_LIBRARIES} -) -ENDIF( WIN32 ) - -target_link_libraries( tomahawk_sip_xmpp - ${QT_LIBRARIES} - ${LIBJREEN_LIBRARY} - ${OS_SPECIFIC_LINK_LIBRARIES} - tomahawklib -) - -IF( APPLE ) -# SET( CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} "-undefined dynamic_lookup" ) -ENDIF( APPLE ) - -install( TARGETS tomahawk_sip_xmpp DESTINATION lib${LIB_SUFFIX} ) - -<<<<<<< HEAD:src/sip/xmpp/CMakeLists.txt - -#add_subdirectory(googlewrapper) -======= -if(BUILD_GUI) - add_subdirectory(googlewrapper) -endif() ->>>>>>> origin/master:src/sip/jabber/CMakeLists.txt From 2d66daec41acbda856f36270fdb729b37df2c988 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Thu, 22 Dec 2011 12:34:09 -0500 Subject: [PATCH 027/104] initial twitter fix --- src/accounts/CMakeLists.txt | 2 +- src/accounts/twitter/sip/twittersip.cpp | 4 ++-- src/accounts/twitter/sip/twittersip.h | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/accounts/CMakeLists.txt b/src/accounts/CMakeLists.txt index 8b61be457..c7d709337 100644 --- a/src/accounts/CMakeLists.txt +++ b/src/accounts/CMakeLists.txt @@ -4,7 +4,7 @@ IF( LIBJREEN_FOUND ) ENDIF() IF( QTWEETLIB_FOUND AND BUILD_GUI ) -#ADD_SUBDIRECTORY( twitter ) + ADD_SUBDIRECTORY( twitter ) ENDIF() ADD_SUBDIRECTORY( zeroconf ) \ No newline at end of file diff --git a/src/accounts/twitter/sip/twittersip.cpp b/src/accounts/twitter/sip/twittersip.cpp index 75027ab35..75472c8a0 100644 --- a/src/accounts/twitter/sip/twittersip.cpp +++ b/src/accounts/twitter/sip/twittersip.cpp @@ -53,7 +53,7 @@ TwitterSipPlugin::TwitterSipPlugin( Tomahawk::Accounts::Account* account ) , m_cachedDirectMessagesSinceId( 0 ) , m_cachedPeers() , m_keyCache() - , m_state( Disconnected ) + , m_state( Tomahawk::Accounts::Account::Disconnected ) { qDebug() << Q_FUNC_INFO; @@ -149,7 +149,7 @@ TwitterSipPlugin::disconnectPlugin() m_configuration[ "cachedpeers" ] = m_cachedPeers; syncConfig(); m_cachedPeers.empty(); - m_state = Disconnected; + m_state = Tomahawk::Accounts::Account::Disconnected; emit stateChanged( m_state ); } diff --git a/src/accounts/twitter/sip/twittersip.h b/src/accounts/twitter/sip/twittersip.h index 84963fe17..f8a5428cd 100644 --- a/src/accounts/twitter/sip/twittersip.h +++ b/src/accounts/twitter/sip/twittersip.h @@ -48,7 +48,7 @@ public: virtual ~TwitterSipPlugin() {} virtual bool isValid() const; - virtual ConnectionState connectionState() const; + virtual Tomahawk::Accounts::Account::ConnectionState connectionState() const; public slots: virtual void connectPlugin(); @@ -118,7 +118,7 @@ private: QVariantHash m_cachedPeers; QHash< QString, QPixmap > m_cachedAvatars; QSet m_keyCache; - ConnectionState m_state; + Tomahawk::Accounts::Account::ConnectionState m_state; }; #endif From aaf147a39a389ee4b49ed868a1c98c104a732f60 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 23 Dec 2011 11:13:30 -0600 Subject: [PATCH 028/104] make twitter compile --- src/accounts/twitter/sip/twittersip.cpp | 10 +++++----- src/accounts/twitter/sip/twittersip.h | 3 +++ src/accounts/twitter/twitteraccount.cpp | 16 ++++++++++++---- src/accounts/twitter/twitteraccount.h | 2 ++ 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/accounts/twitter/sip/twittersip.cpp b/src/accounts/twitter/sip/twittersip.cpp index 75472c8a0..123b7b43c 100644 --- a/src/accounts/twitter/sip/twittersip.cpp +++ b/src/accounts/twitter/sip/twittersip.cpp @@ -87,7 +87,7 @@ TwitterSipPlugin::isValid() const } -SipPlugin::ConnectionState +Tomahawk::Accounts::Account::ConnectionState TwitterSipPlugin::connectionState() const { return m_state; @@ -121,7 +121,7 @@ TwitterSipPlugin::connectPlugin() m_account->authenticate(); } - m_state = Connecting; + m_state = Tomahawk::Accounts::Account::Connecting; emit stateChanged( m_state ); } @@ -174,7 +174,7 @@ TwitterSipPlugin::accountAuthenticated( const QWeakPointer< TomahawkOAuthTwitter 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 = Connected; + m_state = Tomahawk::Accounts::Account::Connected; emit stateChanged( m_state ); QStringList peerList = m_cachedPeers.keys(); qStableSort( peerList.begin(), peerList.end() ); @@ -578,7 +578,7 @@ TwitterSipPlugin::registerOffer( const QString &screenName, const QVariantHash & syncConfig(); } - if ( m_state == Connected && _peerData.contains( "host" ) && _peerData.contains( "port" ) && _peerData.contains( "pkey" ) ) + 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 ) ); } @@ -698,7 +698,7 @@ void TwitterSipPlugin::configurationChanged() { tDebug() << Q_FUNC_INFO; - if ( m_state != Disconnected ) + if ( m_state != Tomahawk::Accounts::Account::Disconnected ) m_account->deauthenticate(); connectPlugin(); } diff --git a/src/accounts/twitter/sip/twittersip.h b/src/accounts/twitter/sip/twittersip.h index f8a5428cd..3ca600e31 100644 --- a/src/accounts/twitter/sip/twittersip.h +++ b/src/accounts/twitter/sip/twittersip.h @@ -50,6 +50,9 @@ public: virtual bool isValid() const; virtual Tomahawk::Accounts::Account::ConnectionState connectionState() const; +signals: + void stateChanged( Tomahawk::Accounts::Account::ConnectionState ); + public slots: virtual void connectPlugin(); void disconnectPlugin(); diff --git a/src/accounts/twitter/twitteraccount.cpp b/src/accounts/twitter/twitteraccount.cpp index 64eed5dcf..ff9b16feb 100644 --- a/src/accounts/twitter/twitteraccount.cpp +++ b/src/accounts/twitter/twitteraccount.cpp @@ -79,12 +79,20 @@ TwitterAccount::configDialogAuthedSignalSlot( bool authed ) } +Account::ConnectionState +TwitterAccount::connectionState() const +{ + return m_twitterSipPlugin.data()->connectionState(); +} + SipPlugin* TwitterAccount::sipPlugin() { if ( m_twitterSipPlugin.isNull() ) { m_twitterSipPlugin = QWeakPointer< 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(); @@ -96,7 +104,7 @@ TwitterAccount::authenticate() { tDebug() << Q_FUNC_INFO << "credentials: " << credentials().keys(); - if ( credentials[ "oauthtoken" ].toString().isEmpty() || credentials()[ "oauthtokensecret" ].toString().isEmpty() ) + if ( credentials()[ "oauthtoken" ].toString().isEmpty() || credentials()[ "oauthtokensecret" ].toString().isEmpty() ) { qDebug() << "TwitterSipPlugin has empty Twitter credentials; not connecting"; return; @@ -137,8 +145,8 @@ TwitterAccount::refreshTwitterAuth() if( m_twitterAuth.isNull() ) return false; - m_twitterAuth.data()->setOAuthToken( m_credentials[ "oauthtoken" ].toString().toLatin1() ); - m_twitterAuth.data()->setOAuthTokenSecret( m_credentials[ "oauthtokensecret" ].toString().toLatin1() ); + m_twitterAuth.data()->setOAuthToken( credentials()[ "oauthtoken" ].toString().toLatin1() ); + m_twitterAuth.data()->setOAuthTokenSecret( credentials()[ "oauthtokensecret" ].toString().toLatin1() ); return true; } @@ -172,4 +180,4 @@ TwitterAccount::icon() const { } -Q_EXPORT_PLUGIN2( Tomahawk::Accounts::AccountFactory, Tomahawk::Accounts::TwitterAccountFactory ) \ No newline at end of file +Q_EXPORT_PLUGIN2( Tomahawk::Accounts::AccountFactory, Tomahawk::Accounts::TwitterAccountFactory ) diff --git a/src/accounts/twitter/twitteraccount.h b/src/accounts/twitter/twitteraccount.h index a0bfeae80..f965beef6 100644 --- a/src/accounts/twitter/twitteraccount.h +++ b/src/accounts/twitter/twitteraccount.h @@ -64,6 +64,8 @@ public: void deauthenticate(); bool isAuthenticated() const { return m_isAuthenticated; } + ConnectionState connectionState() const; + Tomahawk::InfoSystem::InfoPlugin* infoPlugin() { return 0; } SipPlugin* sipPlugin(); From 801d7e5d896fc7e8e5728c663f5a764f07f10cdd Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sat, 31 Dec 2011 18:00:19 -0600 Subject: [PATCH 029/104] fix crash on closing account config dialog --- src/accounts/xmpp/xmppaccount.cpp | 1 - src/delegateconfigwrapper.h | 5 ++++- src/settingsdialog.cpp | 7 ++++--- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/accounts/xmpp/xmppaccount.cpp b/src/accounts/xmpp/xmppaccount.cpp index 51a6dfc5b..67aa4b6cf 100644 --- a/src/accounts/xmpp/xmppaccount.cpp +++ b/src/accounts/xmpp/xmppaccount.cpp @@ -53,7 +53,6 @@ XmppAccount::XmppAccount( const QString &accountId ) XmppAccount::~XmppAccount() { - delete m_configWidget.data(); delete m_xmppSipPlugin.data(); } diff --git a/src/delegateconfigwrapper.h b/src/delegateconfigwrapper.h index ef737b33b..4ab32671e 100644 --- a/src/delegateconfigwrapper.h +++ b/src/delegateconfigwrapper.h @@ -22,6 +22,7 @@ #include #include #include +#include class DelegateConfigWrapper : public QDialog { @@ -33,7 +34,6 @@ public: #ifdef Q_WS_MAC m_widget->setVisible( true ); #endif - setWindowTitle( title ); QVBoxLayout* v = new QVBoxLayout( this ); v->setContentsMargins( 0, 0, 0, 0 ); @@ -59,6 +59,9 @@ public: #endif } + + ~DelegateConfigWrapper() { delete m_widget; } + public slots: void toggleOkButton( bool dataError ) { diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index cbf184d58..e09194084 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -731,7 +731,7 @@ SettingsDialog::handleAccountAdded( Account* account, bool added ) AccountManager::instance()->addAccount( account ); AccountManager::instance()->hookupAndEnable( account ); - if( f && f->isUnique() ) + if ( f && f->isUnique() ) { // remove from actions list QAction* toremove = 0; @@ -743,12 +743,13 @@ SettingsDialog::handleAccountAdded( Account* account, bool added ) break; } } - if( toremove ) + if ( toremove ) ui->addSipButton->removeAction( toremove ); } } else - { // user pressed cancel + { + // user pressed cancel delete account; } } From a78ef004f019f04d9f63f516b3beaa30eb01aeab Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sat, 7 Jan 2012 12:49:37 -0500 Subject: [PATCH 030/104] Add migration from pre-accounts to accounts, and fix twitter in various places --- src/accounts/twitter/sip/twittersip.cpp | 12 ++- src/accounts/twitter/sip/twittersip.h | 3 +- src/accounts/twitter/twitteraccount.cpp | 10 +-- src/accounts/twitter/twitterconfigwidget.cpp | 6 +- src/accounts/twitter/twitterconfigwidget.h | 2 +- .../xmpp/googlewrapper/googlewrapper.h | 2 +- src/accounts/xmpp/xmppaccount.cpp | 2 - src/accounts/zeroconf/zeroconfaccount.cpp | 2 + src/libtomahawk/accounts/Account.cpp | 6 +- src/libtomahawk/playlistinterface.h | 2 +- src/libtomahawk/tomahawksettings.cpp | 74 ++++++++++++++++++- src/libtomahawk/tomahawksettings.h | 1 + 12 files changed, 102 insertions(+), 20 deletions(-) diff --git a/src/accounts/twitter/sip/twittersip.cpp b/src/accounts/twitter/sip/twittersip.cpp index 123b7b43c..446cc321d 100644 --- a/src/accounts/twitter/sip/twittersip.cpp +++ b/src/accounts/twitter/sip/twittersip.cpp @@ -59,7 +59,7 @@ TwitterSipPlugin::TwitterSipPlugin( Tomahawk::Accounts::Account* account ) connect( account, SIGNAL( nowAuthenticated( const QWeakPointer< TomahawkOAuthTwitter > &, const QTweetUser & ) ), SLOT( accountAuthenticated( const QWeakPointer< TomahawkOAuthTwitter > &, const QTweetUser & ) ) ); - if ( Database::instance()->dbid() != m_configuration[ "saveddbid" ].toString() ) + if ( Database::instance()->dbid() != m_account->configuration()[ "saveddbid" ].toString() ) { m_configuration[ "cachedpeers" ] = QVariantHash(); m_configuration[ "saveddbid" ] = Database::instance()->dbid(); @@ -158,7 +158,7 @@ TwitterSipPlugin::accountAuthenticated( const QWeakPointer< TomahawkOAuthTwitter { Q_UNUSED( user ); - if ( !isValid() ) + if ( !m_account->enabled() || !m_account->isAuthenticated() ) return; m_cachedTwitterAuth = twitterAuth; @@ -702,3 +702,11 @@ TwitterSipPlugin::configurationChanged() m_account->deauthenticate(); connectPlugin(); } + + +void +TwitterSipPlugin::syncConfig() +{ + m_account->setConfiguration( m_configuration ); + m_account->sync(); +} diff --git a/src/accounts/twitter/sip/twittersip.h b/src/accounts/twitter/sip/twittersip.h index 3ca600e31..09c18ac91 100644 --- a/src/accounts/twitter/sip/twittersip.h +++ b/src/accounts/twitter/sip/twittersip.h @@ -97,7 +97,7 @@ private slots: void profilePicReply(); private: - inline void syncConfig() { m_account->setCredentials( m_credentials ); m_account->setConfiguration( m_configuration ); m_account->sync(); } + void syncConfig(); bool refreshTwitterAuth(); void parseGotTomahawk( const QRegExp ®ex, const QString &screenName, const QString &text ); @@ -110,7 +110,6 @@ private: QWeakPointer< QTweetDirectMessageDestroy > m_directMessageDestroy; QVariantHash m_configuration; - QVariantHash m_credentials; QTimer m_checkTimer; QTimer m_connectTimer; diff --git a/src/accounts/twitter/twitteraccount.cpp b/src/accounts/twitter/twitteraccount.cpp index ff9b16feb..2ff007f61 100644 --- a/src/accounts/twitter/twitteraccount.cpp +++ b/src/accounts/twitter/twitteraccount.cpp @@ -47,12 +47,8 @@ TwitterAccount::TwitterAccount( const QString &accountId ) : Account( accountId ) , m_isAuthenticated( false ) { - loadFromConfig( accountId ); - setAccountServiceName( "Twitter" ); - QSet< AccountType > types; - types << InfoType << SipType; - setTypes( types ); + setTypes( QSet< AccountType >() << InfoType << SipType ); m_configWidget = QWeakPointer< TwitterConfigWidget >( new TwitterConfigWidget( this, 0 ) ); connect( m_configWidget.data(), SIGNAL( twitterAuthed( bool ) ), SLOT( configDialogAuthedSignalSlot( bool ) ) ); @@ -167,6 +163,10 @@ TwitterAccount::connectAuthVerifyReply( const QTweetUser &user ) config[ "screenname" ] = user.screenName(); setConfiguration( config ); sync(); + + sipPlugin()->connectPlugin(); + + m_isAuthenticated = true; emit nowAuthenticated( m_twitterAuth, user ); } } diff --git a/src/accounts/twitter/twitterconfigwidget.cpp b/src/accounts/twitter/twitterconfigwidget.cpp index efb8fc8ab..1603b4b82 100644 --- a/src/accounts/twitter/twitterconfigwidget.cpp +++ b/src/accounts/twitter/twitterconfigwidget.cpp @@ -57,7 +57,7 @@ TwitterConfigWidget::TwitterConfigWidget( TwitterAccount* account, QWidget *pare m_ui->twitterTweetGotTomahawkButton->setText( tr( "Tweet!" ) ); QVariantHash credentials = m_account->credentials(); - + if ( credentials[ "oauthtoken" ].toString().isEmpty() || credentials[ "oauthtokensecret" ].toString().isEmpty() || credentials[ "username" ].toString().isEmpty() ) @@ -131,7 +131,7 @@ TwitterConfigWidget::authenticateVerifyReply( const QTweetUser &user ) configuration[ "sipcachedfriendssinceid" ] = 0; configuration[ "sipcachedmentionssinceid" ] = 0; m_account->setConfiguration( configuration ); - + m_ui->twitterStatusLabel->setText( tr( "Status: Credentials saved for %1" ).arg( user.screenName() ) ); m_ui->twitterAuthenticateButton->setText( tr( "De-authenticate" ) ); m_ui->twitterSyncGroupBox->setVisible( true ); @@ -202,7 +202,7 @@ TwitterConfigWidget::startPostGotTomahawkStatus() qDebug() << "Posting Got Tomahawk status"; QVariantHash credentials = m_account->credentials(); - + if ( credentials[ "oauthtoken" ].toString().isEmpty() || credentials[ "oauthtokensecret" ].toString().isEmpty() || credentials[ "username" ].toString().isEmpty() ) diff --git a/src/accounts/twitter/twitterconfigwidget.h b/src/accounts/twitter/twitterconfigwidget.h index 7d223fe95..7b7b87bb8 100644 --- a/src/accounts/twitter/twitterconfigwidget.h +++ b/src/accounts/twitter/twitterconfigwidget.h @@ -54,7 +54,7 @@ signals: void twitterAuthed( bool authed ); void sizeHintChanged(); - + private slots: void authDeauthTwitter(); void startPostGotTomahawkStatus(); diff --git a/src/accounts/xmpp/googlewrapper/googlewrapper.h b/src/accounts/xmpp/googlewrapper/googlewrapper.h index d765c67a9..01a516e31 100644 --- a/src/accounts/xmpp/googlewrapper/googlewrapper.h +++ b/src/accounts/xmpp/googlewrapper/googlewrapper.h @@ -37,7 +37,7 @@ public: virtual ~GoogleWrapperFactory() {} virtual QString prettyName() const { return "Google"; } - virtual QString factoryId() const { return "sipgoogle"; } + virtual QString factoryId() const { return "googleaccount"; } virtual QIcon icon() const; virtual Account* createAccount( const QString& pluginId ); }; diff --git a/src/accounts/xmpp/xmppaccount.cpp b/src/accounts/xmpp/xmppaccount.cpp index 67aa4b6cf..a4af19f50 100644 --- a/src/accounts/xmpp/xmppaccount.cpp +++ b/src/accounts/xmpp/xmppaccount.cpp @@ -40,8 +40,6 @@ XmppAccountFactory::createAccount( const QString& accountId ) XmppAccount::XmppAccount( const QString &accountId ) : Account( accountId ) { - loadFromConfig( accountId ); - setAccountServiceName( "XMPP (Jabber)" ); QSet< AccountType > types; types << SipType; diff --git a/src/accounts/zeroconf/zeroconfaccount.cpp b/src/accounts/zeroconf/zeroconfaccount.cpp index 06578f7ee..f7bffb78b 100644 --- a/src/accounts/zeroconf/zeroconfaccount.cpp +++ b/src/accounts/zeroconf/zeroconfaccount.cpp @@ -65,6 +65,8 @@ ZeroconfAccount::ZeroconfAccount( const QString& accountId ) { setAccountServiceName( "Local Network" ); setAccountFriendlyName( "Local Network" ); + + setTypes( QSet< AccountType >() << SipType ); } ZeroconfAccount::~ZeroconfAccount() diff --git a/src/libtomahawk/accounts/Account.cpp b/src/libtomahawk/accounts/Account.cpp index b25ac0e61..9c6dffa7e 100644 --- a/src/libtomahawk/accounts/Account.cpp +++ b/src/libtomahawk/accounts/Account.cpp @@ -33,6 +33,8 @@ Account::Account( const QString& accountId ) { connect( this, SIGNAL( error( int, QString ) ), this, SLOT( onError( int,QString ) ) ); connect( this, SIGNAL( connectionStateChanged( Tomahawk::Accounts::Account::ConnectionState ) ) , this, SLOT( onConnectionStateChanged( Tomahawk::Accounts::Account::ConnectionState ) ) ); + + loadFromConfig( accountId ); } QWidget* @@ -77,8 +79,10 @@ Account::isAuthenticated() const void -Account::onError(int errorCode, const QString& error ) +Account::onError( int errorCode, const QString& error ) { + Q_UNUSED( errorCode ); + QMutexLocker locker( &m_mutex ); m_cachedError = error; } diff --git a/src/libtomahawk/playlistinterface.h b/src/libtomahawk/playlistinterface.h index 1632e5b66..b125d8ae9 100644 --- a/src/libtomahawk/playlistinterface.h +++ b/src/libtomahawk/playlistinterface.h @@ -78,7 +78,7 @@ public slots: virtual void setShuffled( bool enabled ) = 0; signals: - void repeatModeChanged( PlaylistInterface::RepeatMode mode ); + void repeatModeChanged( Tomahawk::PlaylistInterface::RepeatMode mode ); void shuffleModeChanged( bool enabled ); void trackCountChanged( unsigned int tracks ); void sourceTrackCountChanged( unsigned int tracks ); diff --git a/src/libtomahawk/tomahawksettings.cpp b/src/libtomahawk/tomahawksettings.cpp index 6eaa8fd24..029faf615 100644 --- a/src/libtomahawk/tomahawksettings.cpp +++ b/src/libtomahawk/tomahawksettings.cpp @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2010-2011 Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -29,7 +30,7 @@ #include "database/databasecommand_updatesearchindex.h" #include "database/database.h" -#define VERSION 5 +#define VERSION 6 using namespace Tomahawk; @@ -111,7 +112,7 @@ TomahawkSettings::doUpgrade( int oldVersion, int newVersion ) setValue( QString( "%1_legacy/username" ).arg( sipName ), value( "jabber/username" ) ); setValue( QString( "%1_legacy/password" ).arg( sipName ), value( "jabber/password" ) ); - setValue( QString( "%1r_legacy/autoconnect" ).arg( sipName ), value( "jabber/autoconnect" ) ); + setValue( QString( "%1_legacy/autoconnect" ).arg( sipName ), value( "jabber/autoconnect" ) ); setValue( QString( "%1_legacy/port" ).arg( sipName ), value( "jabber/port" ) ); setValue( QString( "%1_legacy/server" ).arg( sipName ), value( "jabber/server" ) ); @@ -187,6 +188,75 @@ TomahawkSettings::doUpgrade( int oldVersion, int newVersion ) { // 0.3.0 contained a bug which prevent indexing local files. Force a reindex. QTimer::singleShot( 0, this, SLOT( updateIndex() ) ); + } else if ( oldVersion == 5 ) + { + // Migrate to accounts from sipplugins. + // collect old connected and enabled sip plugins + const QStringList allSip = sipPlugins(); + const QStringList enabledSip = enabledSipPlugins(); + + QStringList accounts; + foreach ( const QString& sipPlugin, allSip ) + { + const QStringList parts = sipPlugin.split( "_" ); + Q_ASSERT( parts.size() == 2 ); + + const QString pluginName = parts[ 0 ]; + const QString pluginId = parts[ 1 ]; + + // new key, account_ + QString rawpluginname = pluginName; + rawpluginname.replace( "sip", "" ); + if ( rawpluginname.contains( "jabber" ) ) + rawpluginname.replace( "jabber", "xmpp" ); + + QString accountKey = QString( "%1account_%2" ).arg( rawpluginname ).arg( pluginId ); + accounts << accountKey; + + beginGroup( "accounts/" + accountKey ); + setValue( "enabled", enabledSip.contains( sipPlugin ) == true ); + setValue( "autoconnect", true ); + setValue( "configuration", QVariantHash() ); + setValue( "acl", QVariantMap() ); + setValue( "types", QStringList() << "SipType" ); + endGroup(); + if ( pluginName == "sipjabber" || pluginName == "sipgoogle" ) + { + QVariantHash credentials; + credentials[ "username" ] = value( sipPlugin + "/username" ); + credentials[ "password" ] = value( sipPlugin + "/password" ); + credentials[ "port" ] = value( sipPlugin + "/port" ); + credentials[ "server" ] = value( sipPlugin + "/server" ); + + setValue( QString( "accounts/%1/credentials" ).arg( accountKey ), credentials ); + setValue( QString( "accounts/%1/accountfriendlyname" ).arg( accountKey ), value( sipPlugin + "/username" ) ); + + } + else if ( pluginName == "siptwitter" ) + { + QVariantHash credentials; + credentials[ "cachedfriendssinceid" ] = value( sipPlugin + "/cachedfriendssinceid" ); + credentials[ "cacheddirectmessagessinceid" ] = value( sipPlugin + "/cacheddirectmessagessinceid" ); + credentials[ "cachedpeers" ] = value( sipPlugin + "/cachedpeers" ); + credentials[ "oauthtoken" ] = value( sipPlugin + "/oauthtoken" ); + credentials[ "oauthtokensecret" ] = value( sipPlugin + "/oauthtokensecret" ); + credentials[ "cachedmentionssinceid" ] = value( sipPlugin + "/cachedmentionssinceid" ); + credentials[ "username" ] = value( sipPlugin + "/screenname" ); + credentials[ "saveddbid" ] = value( sipPlugin + "/saveddbid" ); + + setValue( QString( "accounts/%1/credentials" ).arg( accountKey ), credentials ); + setValue( QString( "accounts/%1/accountfriendlyname" ).arg( accountKey ), "@" + value( sipPlugin + "/screenname" ).toString() ); + } + else if ( pluginName == "sipzeroconf" ) + { + setValue( QString( "accounts/%1/accountfriendlyname" ).arg( accountKey ), "Local Network" ); + } + + + remove( sipPlugin ); + } + setValue( "accounts/allaccounts", accounts ); + remove( "sip" ); } } diff --git a/src/libtomahawk/tomahawksettings.h b/src/libtomahawk/tomahawksettings.h index 8c2a4327b..de288dcfb 100644 --- a/src/libtomahawk/tomahawksettings.h +++ b/src/libtomahawk/tomahawksettings.h @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2010-2011 Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by From 8483e38f585ae327e50cbc6f213caad478900863 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sun, 8 Jan 2012 18:32:10 -0500 Subject: [PATCH 031/104] style --- .../infoplugins/generic/hypemPlugin.cpp | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/libtomahawk/infosystem/infoplugins/generic/hypemPlugin.cpp b/src/libtomahawk/infosystem/infoplugins/generic/hypemPlugin.cpp index 9eab12814..20220043b 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/hypemPlugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/generic/hypemPlugin.cpp @@ -323,12 +323,12 @@ hypemPlugin::chartReturned() QList< InfoStringHash > top_tracks; QStringList top_artists; - if( url.contains( "artists" ) ) + if ( url.contains( "artists" ) ) setChartType( Artist ); else setChartType( Track ); - foreach(QVariant result, res ) + foreach ( QVariant result, res ) { QString title, artist; QVariantMap chartMap = result.toMap(); @@ -339,28 +339,21 @@ hypemPlugin::chartReturned() title = chartMap.value( "title" ).toString(); artist = chartMap.value( "artist" ).toString(); - if( chartType() == Track ) + if ( chartType() == Track ) { InfoStringHash pair; pair["artist"] = artist; pair["track"] = title; top_tracks << pair; - - qDebug() << "HypemChart type is track"; } - if( chartType() == Artist ) - { - + if ( chartType() == Artist ) top_artists << artist; - qDebug() << "HypemChart type is artist"; - - } } } - if( chartType() == Track ) + if ( chartType() == Track ) { tDebug() << "HypemPlugin:" << "\tgot " << top_tracks.size() << " tracks"; returnedData["tracks"] = QVariant::fromValue( top_tracks ); @@ -369,7 +362,7 @@ hypemPlugin::chartReturned() - if( chartType() == Artist ) + if ( chartType() == Artist ) { tDebug() << "HypemPlugin:" << "\tgot " << top_artists.size() << " artists"; returnedData["artists"] = top_artists; From 0aa61b9fa80ea2cd45c41f8bf4790af7d65c6105 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sun, 8 Jan 2012 18:32:28 -0500 Subject: [PATCH 032/104] Reduce how fast we watch for other apps, reduce timer wakeups a bit --- .../kdsingleapplicationguard/kdsingleapplicationguard.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libtomahawk/thirdparty/kdsingleapplicationguard/kdsingleapplicationguard.cpp b/src/libtomahawk/thirdparty/kdsingleapplicationguard/kdsingleapplicationguard.cpp index 1319b6837..b7c04c2d6 100644 --- a/src/libtomahawk/thirdparty/kdsingleapplicationguard/kdsingleapplicationguard.cpp +++ b/src/libtomahawk/thirdparty/kdsingleapplicationguard/kdsingleapplicationguard.cpp @@ -341,7 +341,7 @@ d( new Private( this ) ) #endif // now listen for commands - startTimer( 250 ); + startTimer( 750 ); } /*! From 601bc7729a905bdae8fef300cb8bf0bbe4cfbb4f Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sun, 8 Jan 2012 18:33:13 -0500 Subject: [PATCH 033/104] Initial account UI update. Buttons needs styling and implementation --- src/AccountDelegate.cpp | 151 ++++++++++---------- src/AccountDelegate.h | 5 +- src/accounts/twitter/twitteraccount.cpp | 2 +- src/accounts/xmpp/xmppaccount.cpp | 4 +- src/accounts/zeroconf/zeroconfaccount.cpp | 2 +- src/configdelegatebase.cpp | 2 +- src/delegateconfigwrapper.h | 2 +- src/libtomahawk/accounts/Account.cpp | 40 +++--- src/libtomahawk/accounts/Account.h | 15 +- src/libtomahawk/accounts/AccountManager.cpp | 12 +- src/libtomahawk/accounts/AccountModel.cpp | 6 +- src/libtomahawk/accounts/AccountModel.h | 10 +- src/libtomahawk/widgets/welcomewidget.cpp | 2 +- src/libtomahawk/widgets/whatshotwidget.h | 1 + src/settingsdialog.cpp | 100 +++++++------ src/stackedsettingsdialog.ui | 129 ++++++++--------- src/tomahawkwindow.cpp | 3 +- 17 files changed, 238 insertions(+), 248 deletions(-) diff --git a/src/AccountDelegate.cpp b/src/AccountDelegate.cpp index 8062a2ef3..cee10ecb7 100644 --- a/src/AccountDelegate.cpp +++ b/src/AccountDelegate.cpp @@ -27,9 +27,9 @@ #include "utils/tomahawkutils.h" #include "utils/logger.h" -#define ICONSIZE 36 +#define ICONSIZE 34 #define WRENCH_SIZE 24 -#define STATUS_ICON_SIZE 18 +#define STATUS_ICON_SIZE 13 #define CHECK_LEFT_EDGE 8 using namespace Tomahawk; @@ -39,6 +39,10 @@ AccountDelegate::AccountDelegate( QObject* parent ) : ConfigDelegateBase ( parent ) { connect( this, SIGNAL( configPressed( QModelIndex ) ), this, SLOT( askedForEdit( QModelIndex ) ) ); + + m_cachedIcons[ "sipplugin-online" ] = QPixmap( RESPATH "images/sipplugin-online.png" ).scaled( STATUS_ICON_SIZE, STATUS_ICON_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation ); + m_cachedIcons[ "sipplugin-offline" ] = QPixmap( RESPATH "images/sipplugin-offline.png" ).scaled( STATUS_ICON_SIZE, STATUS_ICON_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation ); + } bool @@ -55,24 +59,25 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, const QRect itemRect = opt.rect; const int top = itemRect.top(); const int mid = itemRect.height() / 2; + const int quarter = mid - ( itemRect.height() / 4 ); // one line bold for account name - // space below it for account description - // checkbox, icon, name, online/offline status, config icon + // space below it for online/offline status + // checkbox, icon, name/status, features, config icon QFont name = opt.font; name.setPointSize( name.pointSize() + 2 ); name.setBold( true ); - QFont desc = opt.font; - desc.setItalic( true ); - desc.setPointSize( desc.pointSize() - 2 ); + QFont smallFont = opt.font; + smallFont.setPointSize( smallFont.pointSize() - 1 ); + QFontMetrics smallFontFM( smallFont ); // draw the background const QWidget* w = opt.widget; QStyle* style = w ? w->style() : QApplication::style(); style->drawPrimitive( QStyle::PE_PanelItemViewItem, &opt, painter, w ); - int iconLeftEdge = CHECK_LEFT_EDGE + ICONSIZE + PADDING; + int iconLeftEdge = CHECK_LEFT_EDGE + WRENCH_SIZE + PADDING; int textLeftEdge = iconLeftEdge + ICONSIZE + PADDING; // draw checkbox first @@ -91,6 +96,51 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, painter->restore(); } + // name + painter->save(); + painter->setFont( name ); + QFontMetrics namefm( name ); + // pos will the top-left point of the text rect + pos = quarter - ( namefm.height() / 2 ) + top; + const QString nameStr = index.data( AccountModel::AccountName ).toString(); + const int titleWidth = namefm.width( nameStr ); + const QRect nameRect( textLeftEdge, pos, titleWidth, namefm.height() ); + painter->drawText( nameRect, nameStr ); + painter->restore(); + + // draw the online/offline status + const int stateY = mid + quarter - ( smallFontFM.height() / 2 ) + top; + + QPixmap p; + QString statusText; + Account::ConnectionState state = static_cast< Account::ConnectionState >( index.data( AccountModel::ConnectionStateRole ).toInt() ); + if ( state == Account::Connected ) + { + p = m_cachedIcons[ "sipplugin-online" ]; + statusText = tr( "Online" ); + } + else if ( state == Account::Connecting ) + { + p = m_cachedIcons[ "sipplugin-offline" ]; + statusText = tr( "Connecting..." ); + } + else + { + p = m_cachedIcons[ "sipplugin-offline" ]; + statusText = tr( "Offline" ); + } + painter->drawPixmap( textLeftEdge, stateY, STATUS_ICON_SIZE, STATUS_ICON_SIZE, p ); + + int width = smallFontFM.width( statusText ); + int statusTextX = textLeftEdge + STATUS_ICON_SIZE + PADDING; + painter->save(); + painter->setFont( smallFont ); + painter->drawText( QRect( statusTextX, stateY, width, smallFontFM.height() ), statusText ); + painter->restore(); + + // right-most edge of text on left (name, desc) is the cutoff point for the rest of the delegate + width = qMax( statusTextX + width, textLeftEdge + titleWidth ); + // from the right edge--config status and online/offline QRect confRect = QRect( itemRect.width() - WRENCH_SIZE - 2 * PADDING, mid - WRENCH_SIZE / 2 + top, WRENCH_SIZE, WRENCH_SIZE ); if( index.data( AccountModel::HasConfig ).toBool() ) { @@ -102,81 +152,34 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, drawConfigWrench( painter, opt, topt ); } - - // draw the online/offline status - const bool hasCapability = ( static_cast< AccountModel::BasicCapabilities >( index.data( AccountModel::BasicCapabilityRole ).toInt() ) != AccountModel::NoCapabilities ); - const int quarter = mid - ( itemRect.height() / 4 ); - const int statusY = hasCapability ? quarter : mid; - const int statusX = confRect.left() - 2*PADDING - STATUS_ICON_SIZE; - - QFont statusF = opt.font; - statusF.setPointSize( statusF.pointSize() - 2 ); - QFontMetrics statusFM( statusF ); - - QPixmap p; - QString statusText; - Account::ConnectionState state = static_cast< Account::ConnectionState >( index.data( AccountModel::ConnectionStateRole ).toInt() ); - if( state == Account::Connected ) { - p = QPixmap( RESPATH "images/sipplugin-online.png" ); - statusText = tr( "Online" ); - } else if( state == Account::Connecting ) { - p = QPixmap( RESPATH "images/sipplugin-offline.png" ); - statusText = tr( "Connecting..." ); - } else { - p = QPixmap( RESPATH "images/sipplugin-offline.png" ); - statusText = tr( "Offline" ); - } - p = p.scaled( STATUS_ICON_SIZE, STATUS_ICON_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation ); - painter->drawPixmap( statusX, statusY - STATUS_ICON_SIZE / 2 + top, STATUS_ICON_SIZE, STATUS_ICON_SIZE, p ); - int width = statusFM.width( statusText ); - int statusTextX = statusX - PADDING - width; - painter->save(); - painter->setFont( statusF ); - painter->drawText( QRect( statusTextX, statusY - statusFM.height() / 2 + top, width, statusFM.height() ), statusText ); + const bool hasCapability = ( static_cast< Accounts::AccountTypes >( index.data( AccountModel::AccountTypeRole ).toInt() ) != Accounts::NoType ); // draw optional capability text if it exists if ( hasCapability ) { QString capString; - AccountModel::BasicCapabilities cap = static_cast< AccountModel::BasicCapabilities >( index.data( AccountModel::BasicCapabilityRole ).toInt() ); - if ( ( cap & AccountModel::SipCapability ) && ( cap & AccountModel::ResolverCapability ) ) - capString = tr( "Connect to and play from friends" ); - else if ( cap & AccountModel::SipCapability ) - capString = tr( "Connect to friends" ); - else if ( cap & AccountModel::ResolverCapability ) - capString = tr( "Find Music"); + AccountTypes types = AccountTypes( index.data( AccountModel::AccountTypeRole ).toInt() ); + if ( ( types & Accounts::SipType ) && ( types & Accounts::ResolverType ) ) + capString = tr( "Connects to, plays from friends" ); + else if ( types & Accounts::SipType ) + capString = tr( "Connects to friends" ); + else if ( types & Accounts::ResolverType ) + capString = tr( "Finds Music"); // checkbox for capability - const int capY = statusY + ( itemRect.height() / 2 ); - QRect capCheckRect( statusX, capY - STATUS_ICON_SIZE / 2 + top, STATUS_ICON_SIZE, STATUS_ICON_SIZE ); - opt.rect = capCheckRect; - drawCheckBox( opt, painter, w ); +// QRect capCheckRect( statusX, capY - STATUS_ICON_SIZE / 2 + top, STATUS_ICON_SIZE, STATUS_ICON_SIZE ); +// opt.rect = capCheckRect; +// drawCheckBox( opt, painter, w ); // text to accompany checkbox - const int capW = statusFM.width( capString ); - const int capTextX = statusX - PADDING - capW; - painter->drawText( QRect( capTextX, capY - statusFM.height() / 2 + top, capW, statusFM.height() ), capString ); - - if ( capTextX < statusTextX ) - statusTextX = capTextX; + const int capY = mid - ( smallFontFM.height() / 2 ) + top; + const int configLeftEdge = confRect.left() - PADDING; + const int capW = configLeftEdge - width; + // Right-align text + const int capTextX = qMax( width, configLeftEdge - smallFontFM.width( capString ) ); + painter->setFont( smallFont ); + painter->drawText( QRect( capTextX, capY, configLeftEdge - capTextX, smallFontFM.height() ), Qt::AlignRight, capString ); } - painter->restore(); - - // name - painter->save(); - painter->setFont( name ); - QFontMetrics namefm( name ); - // pos will the top-left point of the text rect - pos = mid - ( namefm.height() / 2 ) + top; - // TODO bound with config icon and offline/online status - width = itemRect.width() - statusTextX; - QRect nameRect( textLeftEdge, pos, width, namefm.height() ); - painter->drawText( nameRect, index.data( AccountModel::AccountName ).toString() ); - - nameRect.translate( mid, 0 ); // move down by half the hight - painter->drawText( nameRect, index.data( AccountModel::DescText ).toString() ); - painter->restore(); - } QRect @@ -192,7 +195,7 @@ AccountDelegate::checkRectForIndex( const QStyleOptionViewItem &option, const QM QRect checkRect( CHECK_LEFT_EDGE, pos + opt.rect.top(), ICONSIZE, ICONSIZE ); return checkRect; - } else if ( role == AccountModel::BasicCapabilityRole ) + } else if ( role == AccountModel::AccountTypeRole ) { // The capabilities checkbox QStyleOptionViewItemV4 opt = option; diff --git a/src/AccountDelegate.h b/src/AccountDelegate.h index 757cc3923..a15c82910 100644 --- a/src/AccountDelegate.h +++ b/src/AccountDelegate.h @@ -42,12 +42,15 @@ public: virtual QRect checkRectForIndex( const QStyleOptionViewItem &option, const QModelIndex &idx, int role ) const; virtual QRect configRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const; - virtual QList extraCheckRoles() const { return QList() << (int)AccountModel::BasicCapabilityRole; } + virtual QList extraCheckRoles() const { return QList() << (int)AccountModel::AccountTypeRole; } private slots: void askedForEdit( const QModelIndex& idx ); signals: void openConfig( Tomahawk::Accounts::Account* ); + +private: + QMap< QString, QPixmap > m_cachedIcons; }; } diff --git a/src/accounts/twitter/twitteraccount.cpp b/src/accounts/twitter/twitteraccount.cpp index 2ff007f61..b53487110 100644 --- a/src/accounts/twitter/twitteraccount.cpp +++ b/src/accounts/twitter/twitteraccount.cpp @@ -48,7 +48,7 @@ TwitterAccount::TwitterAccount( const QString &accountId ) , m_isAuthenticated( false ) { setAccountServiceName( "Twitter" ); - setTypes( QSet< AccountType >() << InfoType << SipType ); + setTypes( AccountTypes( InfoType | SipType ) ); m_configWidget = QWeakPointer< TwitterConfigWidget >( new TwitterConfigWidget( this, 0 ) ); connect( m_configWidget.data(), SIGNAL( twitterAuthed( bool ) ), SLOT( configDialogAuthedSignalSlot( bool ) ) ); diff --git a/src/accounts/xmpp/xmppaccount.cpp b/src/accounts/xmpp/xmppaccount.cpp index a4af19f50..1c23f45c3 100644 --- a/src/accounts/xmpp/xmppaccount.cpp +++ b/src/accounts/xmpp/xmppaccount.cpp @@ -41,9 +41,7 @@ XmppAccount::XmppAccount( const QString &accountId ) : Account( accountId ) { setAccountServiceName( "XMPP (Jabber)" ); - QSet< AccountType > types; - types << SipType; - setTypes( types ); + setTypes( SipType ); m_configWidget = QWeakPointer< QWidget >( new XmppConfigWidget( this, 0 ) ); } diff --git a/src/accounts/zeroconf/zeroconfaccount.cpp b/src/accounts/zeroconf/zeroconfaccount.cpp index f7bffb78b..7d239b14b 100644 --- a/src/accounts/zeroconf/zeroconfaccount.cpp +++ b/src/accounts/zeroconf/zeroconfaccount.cpp @@ -66,7 +66,7 @@ ZeroconfAccount::ZeroconfAccount( const QString& accountId ) setAccountServiceName( "Local Network" ); setAccountFriendlyName( "Local Network" ); - setTypes( QSet< AccountType >() << SipType ); + setTypes( SipType ); } ZeroconfAccount::~ZeroconfAccount() diff --git a/src/configdelegatebase.cpp b/src/configdelegatebase.cpp index bdf826bfc..6503ca223 100644 --- a/src/configdelegatebase.cpp +++ b/src/configdelegatebase.cpp @@ -25,7 +25,7 @@ #include "utils/tomahawkutils.h" #include "utils/logger.h" -#define ROW_HEIGHT 50 +#define ROW_HEIGHT 40 ConfigDelegateBase::ConfigDelegateBase ( QObject* parent ) : QStyledItemDelegate ( parent ) diff --git a/src/delegateconfigwrapper.h b/src/delegateconfigwrapper.h index 4ab32671e..5e71bdcac 100644 --- a/src/delegateconfigwrapper.h +++ b/src/delegateconfigwrapper.h @@ -60,7 +60,7 @@ public: } - ~DelegateConfigWrapper() { delete m_widget; } + ~DelegateConfigWrapper() {} public slots: void toggleOkButton( bool dataError ) diff --git a/src/libtomahawk/accounts/Account.cpp b/src/libtomahawk/accounts/Account.cpp index 9c6dffa7e..62387f1aa 100644 --- a/src/libtomahawk/accounts/Account.cpp +++ b/src/libtomahawk/accounts/Account.cpp @@ -147,39 +147,33 @@ Account::removeFromConfig() void -Account::setTypes( const QSet< AccountType > types ) +Account::setTypes( AccountTypes types ) { QMutexLocker locker( &m_mutex ); m_types = QStringList(); - foreach ( AccountType type, types ) - { - switch( type ) - { - case InfoType: - m_types << "InfoType"; - break; - case SipType: - m_types << "SipType"; - break; - } - } + if ( types & InfoType ) + m_types << "InfoType"; + if ( types & SipType ) + m_types << "SipType"; + if ( types & ResolverType ) + m_types << "ResolverType"; syncConfig(); } -QSet< AccountType > +AccountTypes Account::types() const { QMutexLocker locker( &m_mutex ); - QSet< AccountType > set; - foreach ( QString type, m_types ) - { - if ( type == "InfoType" ) - set << InfoType; - else if ( type == "SipType" ) - set << SipType; - } - return set; + AccountTypes types; + if ( m_types.contains( "InfoType" ) ) + types |= InfoType; + if ( m_types.contains( "SipType" ) ) + types |= SipType; + if ( m_types.contains( "ResolverType" ) ) + types |= ResolverType; + + return types; } diff --git a/src/libtomahawk/accounts/Account.h b/src/libtomahawk/accounts/Account.h index 97a0882f2..83b37aece 100644 --- a/src/libtomahawk/accounts/Account.h +++ b/src/libtomahawk/accounts/Account.h @@ -44,7 +44,16 @@ namespace InfoSystem namespace Accounts { -enum AccountType { InfoType, SipType }; +enum AccountType +{ + NoType = 0x00, + + InfoType = 0x01, + SipType = 0x02, + ResolverType = 0x04 +}; + +Q_DECLARE_FLAGS(AccountTypes, AccountType); inline QString generateId( const QString &factoryId ) { @@ -92,7 +101,7 @@ public: virtual Tomahawk::InfoSystem::InfoPlugin* infoPlugin() = 0; virtual SipPlugin* sipPlugin() = 0; - QSet< AccountType > types() const; + AccountTypes types() const; void setAccountServiceName( const QString &serviceName ) { QMutexLocker locker( &m_mutex ); m_accountServiceName = serviceName; } void setAccountFriendlyName( const QString &friendlyName ) { QMutexLocker locker( &m_mutex ); m_accountFriendlyName = friendlyName; } @@ -102,7 +111,7 @@ public: void setCredentials( const QVariantHash &credentialHash ) { QMutexLocker locker( &m_mutex ); m_credentials = credentialHash; } void setConfiguration( const QVariantHash &configuration ) { QMutexLocker locker( &m_mutex ); m_configuration = configuration; } void setAcl( const QVariantMap &acl ) { QMutexLocker locker( &m_mutex ); m_acl = acl; } - void setTypes( const QSet< AccountType > types ); + void setTypes( AccountTypes types ); virtual void sync() { QMutexLocker locker( &m_mutex ); syncConfig(); }; diff --git a/src/libtomahawk/accounts/AccountManager.cpp b/src/libtomahawk/accounts/AccountManager.cpp index d78119154..dd17b45ef 100644 --- a/src/libtomahawk/accounts/AccountManager.cpp +++ b/src/libtomahawk/accounts/AccountManager.cpp @@ -175,7 +175,7 @@ AccountManager::connectAll() { foreach( Account* acc, m_accounts ) { - if ( acc->types().contains( Accounts::SipType ) && acc->sipPlugin() ) + if ( acc->types() & Accounts::SipType && acc->sipPlugin() ) acc->sipPlugin()->connectPlugin(); } @@ -252,8 +252,12 @@ AccountManager::addAccount( Account* account ) tDebug() << Q_FUNC_INFO << "adding account plugin"; m_accounts.append( account ); - foreach( AccountType type, account->types() ) - m_accountsByAccountType[ type ].append( account ); + if ( account->types() & Accounts::SipType ) + m_accountsByAccountType[ Accounts::SipType ].append( account ); + if ( account->types() & Accounts::InfoType ) + m_accountsByAccountType[ Accounts::InfoType ].append( account ); + if ( account->types() & Accounts::ResolverType ) + m_accountsByAccountType[ Accounts::ResolverType ].append( account ); emit added( account ); } @@ -330,7 +334,7 @@ AccountManager::onSettingsChanged() { foreach( Account* account, m_accounts ) { - if ( account->types().contains( Accounts::SipType ) && account->sipPlugin() ) + if ( account->types() & Accounts::SipType && account->sipPlugin() ) account->sipPlugin()->checkSettings(); } } diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index 58d730f35..d5cd8b30c 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -58,6 +58,8 @@ AccountModel::data( const QModelIndex& index, int role ) const return account->connectionState(); case AccountModel::HasConfig: return ( account->configurationWidget() != 0 ); + case AccountModel::AccountTypeRole: + return (int)account->types(); case Qt::DecorationRole: return account->icon(); case AccountModel::AccountData: @@ -90,7 +92,7 @@ AccountModel::setData( const QModelIndex& index, const QVariant& value, int role return true; } - else if ( role == BasicCapabilityRole ) + else if ( role == AccountTypeRole ) { // TODO } @@ -115,7 +117,7 @@ AccountModel::accountAdded( Account* account ) { // TODO HACK we assume account plugins are added at the end of the list. Q_ASSERT( AccountManager::instance()->accounts().last() == account ); - if ( account->types().contains( SipType ) ) + if ( account->types() & SipType ) connect( account, SIGNAL( connectionStateChanged( Tomahawk::Accounts::Account::ConnectionState ) ), this, SLOT( accountStateChanged( Tomahawk::Accounts::Account::ConnectionState ) ) ); int size = AccountManager::instance()->accounts().count() - 1; diff --git a/src/libtomahawk/accounts/AccountModel.h b/src/libtomahawk/accounts/AccountModel.h index 96b23d2b3..5ad2c6402 100644 --- a/src/libtomahawk/accounts/AccountModel.h +++ b/src/libtomahawk/accounts/AccountModel.h @@ -37,19 +37,11 @@ class DLLEXPORT AccountModel : public QAbstractListModel { Q_OBJECT public: - enum BasicCapabilities - { - NoCapabilities = 0, - SipCapability = 0x1, - ResolverCapability = 0x2 - }; - enum Roles { AccountName = Qt::UserRole + 15, AccountIcon = Qt::UserRole + 16, HeadlineText = Qt::UserRole + 17, - DescText = Qt::UserRole + 18, - BasicCapabilityRole = Qt::UserRole + 19, + AccountTypeRole = Qt::UserRole + 19, ConnectionStateRole = Qt::UserRole + 20, HasConfig = Qt::UserRole + 21, ErrorString = Qt::UserRole + 22, diff --git a/src/libtomahawk/widgets/welcomewidget.cpp b/src/libtomahawk/widgets/welcomewidget.cpp index 2dd214e60..f0f22584f 100644 --- a/src/libtomahawk/widgets/welcomewidget.cpp +++ b/src/libtomahawk/widgets/welcomewidget.cpp @@ -318,7 +318,7 @@ PlaylistDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, painter->setFont( font ); QString author = index.data( RecentlyPlayedPlaylistsModel::PlaylistRole ).value< Tomahawk::playlist_ptr >()->author()->friendlyName(); - if ( author.contains( "@" ) ) + if ( author.indexOf( '@' ) > 0 ) author = author.mid( 0, author.indexOf( '@' ) ); const int w = painter->fontMetrics().width( author ) + 2; diff --git a/src/libtomahawk/widgets/whatshotwidget.h b/src/libtomahawk/widgets/whatshotwidget.h index 1cfcd0248..1ac2c6561 100644 --- a/src/libtomahawk/widgets/whatshotwidget.h +++ b/src/libtomahawk/widgets/whatshotwidget.h @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2011, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index e09194084..ca188dbbd 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -86,8 +86,6 @@ SettingsDialog::SettingsDialog( QWidget *parent ) TomahawkUtils::unmarginLayout( layout() ); ui->stackedWidget->setContentsMargins( 4, 4, 4, 0 ); - ui->addSipButton->setFixedWidth( 42 ); - ui->removeSipButton->setFixedWidth( ui->addSipButton->width() ); ui->addScript->setFixedWidth( 42 ); ui->removeScript->setFixedWidth( ui->addScript->width() ); @@ -133,8 +131,8 @@ SettingsDialog::SettingsDialog( QWidget *parent ) m_sipSpinner = new LoadingSpinner( ui->accountsView ); m_sipSpinner->fadeIn(); - ui->addSipButton->setEnabled( false ); - ui->removeSipButton->setEnabled( false ); + ui->addNewServiceBtn->setEnabled( false ); + ui->removeServiceBtn->setEnabled( false ); connect( Servent::instance(), SIGNAL( ready() ), this, SLOT( serventReady() ) ); } @@ -260,8 +258,8 @@ void SettingsDialog::serventReady() { m_sipSpinner->fadeOut(); - ui->addSipButton->setEnabled( true ); - ui->removeSipButton->setEnabled( true ); + ui->addNewServiceBtn->setEnabled( true ); + ui->removeScript->setEnabled( true ); } @@ -330,21 +328,21 @@ SettingsDialog::createIcons() void SettingsDialog::setupAccountButtons() { - foreach( AccountFactory* f, AccountManager::instance()->factories() ) - { - if( f->isUnique() && AccountManager::instance()->hasPluginWithFactory( f->factoryId() ) ) - { - continue; - } +// foreach( AccountFactory* f, AccountManager::instance()->factories() ) +// { +// if( f->isUnique() && AccountManager::instance()->hasPluginWithFactory( f->factoryId() ) ) +// { +// continue; +// } +// +// QAction* action = new QAction( f->icon(), f->prettyName(), ui->addSipButton ); +// action->setProperty( "factory", QVariant::fromValue< QObject* >( f ) ); +// ui->addSipButton->addAction( action ); +// +// connect( action, SIGNAL( triggered(bool) ), this, SLOT( factoryActionTriggered( bool ) ) ); +// } - QAction* action = new QAction( f->icon(), f->prettyName(), ui->addSipButton ); - action->setProperty( "factory", QVariant::fromValue< QObject* >( f ) ); - ui->addSipButton->addAction( action ); - - connect( action, SIGNAL( triggered(bool) ), this, SLOT( factoryActionTriggered( bool ) ) ); - } - - connect( ui->removeSipButton, SIGNAL( clicked( bool ) ), this, SLOT( accountDeleted( bool ) ) ); + connect( ui->removeServiceBtn, SIGNAL( clicked( bool ) ), this, SLOT( accountDeleted( bool ) ) ); } @@ -731,21 +729,21 @@ SettingsDialog::handleAccountAdded( Account* account, bool added ) AccountManager::instance()->addAccount( account ); AccountManager::instance()->hookupAndEnable( account ); - if ( f && f->isUnique() ) - { - // remove from actions list - QAction* toremove = 0; - foreach( QAction* a, ui->addSipButton->actions() ) - { - if( f == qobject_cast< AccountFactory* >( a->property( "factory" ).value< QObject* >() ) ) - { - toremove = a; - break; - } - } - if ( toremove ) - ui->addSipButton->removeAction( toremove ); - } +// if ( f && f->isUnique() ) +// { +// // remove from actions list +// QAction* toremove = 0; +// foreach( QAction* a, ui->addSipButton->actions() ) +// { +// if( f == qobject_cast< AccountFactory* >( a->property( "factory" ).value< QObject* >() ) ) +// { +// toremove = a; +// break; +// } +// } +// if ( toremove ) +// ui->addSipButton->removeAction( toremove ); +// } } else { @@ -778,14 +776,14 @@ SettingsDialog::onAccountRowDeleted( bool ) if( AccountFactory* f = AccountManager::instance()->factoryForAccount( account ) ) { - if( f->isUnique() ) // just deleted a unique plugin->re-add to add menu - { - QAction* action = new QAction( f->icon(), f->prettyName(), ui->addSipButton ); - action->setProperty( "factory", QVariant::fromValue< QObject* >( f ) ); - ui->addSipButton->addAction( action ); - - connect( action, SIGNAL( triggered(bool) ), this, SLOT( factoryActionTriggered( bool ) ) ); - } +// if( f->isUnique() ) // just deleted a unique plugin->re-add to add menu +// { +// QAction* action = new QAction( f->icon(), f->prettyName(), ui->addSipButton ); +// action->setProperty( "factory", QVariant::fromValue< QObject* >( f ) ); +// ui->addSipButton->addAction( action ); +// +// connect( action, SIGNAL( triggered(bool) ), this, SLOT( factoryActionTriggered( bool ) ) ); +// } } AccountManager::instance()->removeAccount( account ); @@ -805,14 +803,14 @@ SettingsDialog::accountDeleted( bool ) if( AccountFactory* f = AccountManager::instance()->factoryForAccount( account ) ) { - if( f->isUnique() ) // just deleted a unique plugin->re-add to add menu - { - QAction* action = new QAction( f->icon(), f->prettyName(), ui->addSipButton ); - action->setProperty( "factory", QVariant::fromValue< QObject* >( f ) ); - ui->addSipButton->addAction( action ); - - connect( action, SIGNAL( triggered(bool) ), this, SLOT( factoryActionTriggered( bool ) ) ); - } +// if( f->isUnique() ) // just deleted a unique plugin->re-add to add menu +// { +// QAction* action = new QAction( f->icon(), f->prettyName(), ui->addSipButton ); +// action->setProperty( "factory", QVariant::fromValue< QObject* >( f ) ); +// ui->addSipButton->addAction( action ); +// +// connect( action, SIGNAL( triggered(bool) ), this, SLOT( factoryActionTriggered( bool ) ) ); +// } } AccountManager::instance()->removeAccount( account ); } diff --git a/src/stackedsettingsdialog.ui b/src/stackedsettingsdialog.ui index 704c60c40..b26f638b5 100644 --- a/src/stackedsettingsdialog.ui +++ b/src/stackedsettingsdialog.ui @@ -6,8 +6,8 @@ 0 0 - 641 - 393 + 655 + 500 @@ -95,87 +95,74 @@ - Accounts + Internet Sources 2 - - - - Connect to your friends with Google Chat, Twitter, and more. - - - - - - 0 - - - false - - - false - - - true - - - true - - - false + + + Show music sources - - - - - ... - - - - :/data/images/sipplugin-add.png:/data/images/sipplugin-add.png - - - QToolButton::InstantPopup - - - - - - - ... - - - - :/data/images/sipplugin-remove.png:/data/images/sipplugin-remove.png - - - QToolButton::DelayedPopup - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - + + + Show friend sources + + + + + + + Show update services + + + + + + + + + 0 + + + false + + + false + + + true + + + true + + + false + + + + + + + + + Add new service... + + + + + + + Remove Service + + diff --git a/src/tomahawkwindow.cpp b/src/tomahawkwindow.cpp index 992bb3f04..55deb5c8d 100644 --- a/src/tomahawkwindow.cpp +++ b/src/tomahawkwindow.cpp @@ -690,8 +690,7 @@ TomahawkWindow::onAccountDisconnected() void TomahawkWindow::onAccountAdded( Account* acc ) { - if ( !acc->types().contains( SipType ) || - !acc->sipPlugin() ) + if ( !acc->types() & SipType || !acc->sipPlugin() ) return; connect( acc->sipPlugin(), SIGNAL( addMenu( QMenu* ) ), this, SLOT( pluginMenuAdded( QMenu* ) ) ); From cf9389a0deae1eb34bb26f6b76f84ac672fa0d37 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sun, 22 Jan 2012 20:08:32 -0500 Subject: [PATCH 034/104] work towards integrating resolvers in accounts refactor --- src/CMakeLists.txt | 4 - src/accounts/xmpp/xmppaccount.h | 8 +- src/libtomahawk/CMakeLists.txt | 2 + src/libtomahawk/ExternalResolver.h | 4 +- src/libtomahawk/accounts/Account.h | 2 +- src/libtomahawk/accounts/AccountManager.cpp | 49 +++- src/libtomahawk/accounts/AccountManager.h | 3 + src/libtomahawk/accounts/AccountModel.cpp | 6 +- src/libtomahawk/accounts/AccountModel.h | 1 - src/libtomahawk/pipeline.cpp | 31 +-- src/libtomahawk/pipeline.h | 4 +- src/libtomahawk/resolvers/scriptresolver.cpp | 2 + src/libtomahawk/tomahawksettings.cpp | 28 ++- src/libtomahawk/typedefs.h | 4 + src/resolverconfigdelegate.cpp | 2 +- src/resolversmodel.cpp | 251 ------------------- src/resolversmodel.h | 64 ----- src/settingsdialog.cpp | 40 ++- src/settingsdialog.h | 7 - 19 files changed, 123 insertions(+), 389 deletions(-) delete mode 100644 src/resolversmodel.cpp delete mode 100644 src/resolversmodel.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 48d6d4fec..31591e961 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -76,9 +76,7 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui} diagnosticsdialog.cpp configdelegatebase.cpp AccountDelegate.cpp - resolverconfigdelegate.cpp settingslistdelegate.cpp - resolversmodel.cpp tomahawkwindow.cpp LoadXSPFDialog.cpp ) @@ -127,10 +125,8 @@ SET( tomahawkHeadersGui ${tomahawkHeadersGui} settingsdialog.h diagnosticsdialog.h configdelegatebase.h - resolverconfigdelegate.h AccountDelegate.h settingslistdelegate.h - resolversmodel.h delegateconfigwrapper.h tomahawkwindow.h LoadXSPFDialog.h diff --git a/src/accounts/xmpp/xmppaccount.h b/src/accounts/xmpp/xmppaccount.h index ff8961129..7295df7c1 100644 --- a/src/accounts/xmpp/xmppaccount.h +++ b/src/accounts/xmpp/xmppaccount.h @@ -40,6 +40,8 @@ class ACCOUNTDLLEXPORT XmppAccountFactory : public AccountFactory Q_OBJECT Q_INTERFACES( Tomahawk::Accounts::AccountFactory ) + // for settings access + friend class XmppConfigWidget; public: XmppAccountFactory() {} virtual ~XmppAccountFactory() {} @@ -76,12 +78,6 @@ public: protected: QWeakPointer< QWidget > m_configWidget; // so the google wrapper can change the config dialog a bit QWeakPointer< XmppSipPlugin > m_xmppSipPlugin; - -private: - - - // for settings access - friend class XmppConfigWidget; }; }; diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index 9c92ee5c6..6444822d6 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -308,6 +308,7 @@ set( libSources accounts/AccountManager.cpp accounts/Account.cpp accounts/AccountModel.cpp + accounts/ResolverAccount.cpp sip/SipPlugin.cpp sip/SipHandler.cpp @@ -439,6 +440,7 @@ set( libHeaders accounts/Account.h accounts/AccountManager.h accounts/AccountModel.h + accounts/ResolverAccount.h EchonestCatalogSynchronizer.h diff --git a/src/libtomahawk/ExternalResolver.h b/src/libtomahawk/ExternalResolver.h index a63f42396..bf3a01082 100644 --- a/src/libtomahawk/ExternalResolver.h +++ b/src/libtomahawk/ExternalResolver.h @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2010-2011, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,6 +25,7 @@ #include "dllmacro.h" #include "resolver.h" +#include #include @@ -64,7 +66,7 @@ public slots: virtual void stop() = 0; signals: - void changed(); // if config widget was added/removed + void changed(); // if config widget was added/removed, name changed, etc protected: void setFilePath( const QString& path ) { m_filePath = path; } diff --git a/src/libtomahawk/accounts/Account.h b/src/libtomahawk/accounts/Account.h index 83b37aece..a46007b19 100644 --- a/src/libtomahawk/accounts/Account.h +++ b/src/libtomahawk/accounts/Account.h @@ -113,7 +113,7 @@ public: void setAcl( const QVariantMap &acl ) { QMutexLocker locker( &m_mutex ); m_acl = acl; } void setTypes( AccountTypes types ); - virtual void sync() { QMutexLocker locker( &m_mutex ); syncConfig(); }; + void sync() { QMutexLocker locker( &m_mutex ); syncConfig(); }; /** * Removes all the settings held in the config file for this account instance diff --git a/src/libtomahawk/accounts/AccountManager.cpp b/src/libtomahawk/accounts/AccountManager.cpp index dd17b45ef..a400353fc 100644 --- a/src/libtomahawk/accounts/AccountManager.cpp +++ b/src/libtomahawk/accounts/AccountManager.cpp @@ -20,6 +20,7 @@ #include "AccountManager.h" #include "config.h" #include "sourcelist.h" +#include "ResolverAccount.h" #include #include @@ -53,6 +54,10 @@ AccountManager::AccountManager( QObject *parent ) connect( TomahawkSettings::instance(), SIGNAL( changed() ), SLOT( onSettingsChanged() ) ); loadPluginFactories( findPluginFactories() ); + + // We include the resolver factory manually, not in a plugin + ResolverAccountFactory* f = new ResolverAccountFactory(); + m_accountFactories[ f->factoryId() ] = f; } @@ -170,13 +175,40 @@ AccountManager::loadPluginFactory( const QString& path ) +void +AccountManager::enableAccount( Account* account ) +{ + if ( account->isAuthenticated() ) + return; + + account->authenticate(); + + account->setEnabled( true ); + m_enabledAccounts << account; +} + + +void +AccountManager::disableAccount( Account* account ) +{ + if ( !account->isAuthenticated() ) + return; + + account->deauthenticate(); + account->setEnabled( false ); + m_enabledAccounts.removeAll( account ); +} + + void AccountManager::connectAll() { foreach( Account* acc, m_accounts ) { - if ( acc->types() & Accounts::SipType && acc->sipPlugin() ) - acc->sipPlugin()->connectPlugin(); + acc->authenticate(); + m_enabledAccounts << acc; +// if ( acc->types() & Accounts::SipType && acc->sipPlugin() ) +// acc->sipPlugin()->connectPlugin(); } m_connected = true; @@ -186,9 +218,10 @@ AccountManager::connectAll() void AccountManager::disconnectAll() { - foreach( Account* acc, m_connectedAccounts ) - acc->sipPlugin()->disconnectPlugin(); + foreach( Account* acc, m_enabledAccounts ) + acc->deauthenticate(); + m_enabledAccounts.clear(); SourceList::instance()->removeAllRemote(); m_connected = false; } @@ -224,9 +257,8 @@ void AccountManager::initSIP() { tDebug() << Q_FUNC_INFO; - foreach( Account* account, accounts( Tomahawk::Accounts::SipType ) ) + foreach( Account* account, accounts() ) { - tDebug() << Q_FUNC_INFO << "adding plugin " << account->accountId(); hookupAndEnable( account, true ); } } @@ -300,7 +332,8 @@ void AccountManager::hookupAndEnable( Account* account, bool startup ) { SipPlugin* p = account->sipPlugin(); - SipHandler::instance()->hookUpPlugin( p ); + if ( p ) + SipHandler::instance()->hookUpPlugin( p ); if ( account->enabled() && ( !startup || account->autoConnect() ) ) { @@ -363,4 +396,4 @@ AccountManager::onStateChanged( Account::ConnectionState state ) }; -}; +}; \ No newline at end of file diff --git a/src/libtomahawk/accounts/AccountManager.h b/src/libtomahawk/accounts/AccountManager.h index 2894dad6e..969edd27f 100644 --- a/src/libtomahawk/accounts/AccountManager.h +++ b/src/libtomahawk/accounts/AccountManager.h @@ -47,6 +47,9 @@ public: void loadFromConfig(); void initSIP(); + void enableAccount( Account* account ); + void disableAccount( Account* account ); + QList< AccountFactory* > factories() const { return m_accountFactories.values(); } bool hasPluginWithFactory( const QString& factory ) const; AccountFactory* factoryForAccount( Account* account ) const; diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index d5cd8b30c..80f04444b 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -84,10 +84,12 @@ AccountModel::setData( const QModelIndex& index, const QVariant& value, int role Account* account = accounts[ index.row() ]; if( state == Qt::Checked && !account->enabled() ) { - account->setEnabled( true ); + AccountManager::instance()->enableAccount( account ); } else if( state == Qt::Unchecked ) { - account->setEnabled( false ); + AccountManager::instance()->disableAccount( account ); } + + account->sync(); dataChanged( index, index ); return true; diff --git a/src/libtomahawk/accounts/AccountModel.h b/src/libtomahawk/accounts/AccountModel.h index 5ad2c6402..e905a7ca2 100644 --- a/src/libtomahawk/accounts/AccountModel.h +++ b/src/libtomahawk/accounts/AccountModel.h @@ -40,7 +40,6 @@ public: enum Roles { AccountName = Qt::UserRole + 15, AccountIcon = Qt::UserRole + 16, - HeadlineText = Qt::UserRole + 17, AccountTypeRole = Qt::UserRole + 19, ConnectionStateRole = Qt::UserRole + 20, HasConfig = Qt::UserRole + 21, diff --git a/src/libtomahawk/pipeline.cpp b/src/libtomahawk/pipeline.cpp index 73d14fce4..0fdc9c563 100644 --- a/src/libtomahawk/pipeline.cpp +++ b/src/libtomahawk/pipeline.cpp @@ -64,7 +64,10 @@ Pipeline::~Pipeline() m_running = false; // stop script resolvers - qDeleteAll( m_scriptResolvers ); + foreach ( QWeakPointer< ExternalResolver > r, m_scriptResolvers ) + if ( !r.isNull() ) + r.data()->deleteLater(); + m_scriptResolvers.clear(); } @@ -133,7 +136,7 @@ Pipeline::addScriptResolver( const QString& path, bool start ) if ( !res ) continue; - m_scriptResolvers << res; + m_scriptResolvers << QWeakPointer< ExternalResolver >( res ); if ( start ) res->start(); @@ -147,10 +150,10 @@ Pipeline::addScriptResolver( const QString& path, bool start ) void Pipeline::stopScriptResolver( const QString& path ) { - foreach ( ExternalResolver* res, m_scriptResolvers ) + foreach ( QWeakPointer< ExternalResolver > res, m_scriptResolvers ) { - if ( res->filePath() == path ) - res->stop(); + if ( res.data()->filePath() == path ) + res.data()->stop(); } } @@ -158,18 +161,18 @@ Pipeline::stopScriptResolver( const QString& path ) void Pipeline::removeScriptResolver( const QString& scriptPath ) { - ExternalResolver* r = 0; - foreach ( ExternalResolver* res, m_scriptResolvers ) + QWeakPointer< ExternalResolver > r; + foreach ( QWeakPointer< ExternalResolver > res, m_scriptResolvers ) { - if ( res->filePath() == scriptPath ) + if ( res.data()->filePath() == scriptPath ) r = res; } m_scriptResolvers.removeAll( r ); - if ( r ) + if ( !r.isNull() ) { - r->stop(); - r->deleteLater(); + r.data()->stop(); + r.data()->deleteLater(); } } @@ -177,10 +180,10 @@ Pipeline::removeScriptResolver( const QString& scriptPath ) ExternalResolver* Pipeline::resolverForPath( const QString& scriptPath ) { - foreach ( ExternalResolver* res, m_scriptResolvers ) + foreach ( QWeakPointer< ExternalResolver > res, m_scriptResolvers ) { - if ( res->filePath() == scriptPath ) - return res; + if ( res.data()->filePath() == scriptPath ) + return res.data(); } return 0; } diff --git a/src/libtomahawk/pipeline.h b/src/libtomahawk/pipeline.h index 8ef9a607b..5fa88a2d7 100644 --- a/src/libtomahawk/pipeline.h +++ b/src/libtomahawk/pipeline.h @@ -59,7 +59,7 @@ public: Tomahawk::ExternalResolver* addScriptResolver( const QString& scriptPath, bool start = true ); void stopScriptResolver( const QString& scriptPath ); void removeScriptResolver( const QString& scriptPath ); - QList< Tomahawk::ExternalResolver* > scriptResolvers() const { return m_scriptResolvers; } + QList< QWeakPointer< ExternalResolver > > scriptResolvers() const { return m_scriptResolvers; } Tomahawk::ExternalResolver* resolverForPath( const QString& scriptPath ); void addResolver( Resolver* r ); @@ -106,7 +106,7 @@ private: int decQIDState( const Tomahawk::query_ptr& query ); QList< Resolver* > m_resolvers; - QList< Tomahawk::ExternalResolver* > m_scriptResolvers; + QList< QWeakPointer > m_scriptResolvers; QList< ResolverFactoryFunc > m_resolverFactories; QMap< QID, bool > m_qidsTimeout; QMap< QID, unsigned int > m_qidsState; diff --git a/src/libtomahawk/resolvers/scriptresolver.cpp b/src/libtomahawk/resolvers/scriptresolver.cpp index 37fd4ec05..e03ac5d9f 100644 --- a/src/libtomahawk/resolvers/scriptresolver.cpp +++ b/src/libtomahawk/resolvers/scriptresolver.cpp @@ -342,6 +342,8 @@ ScriptResolver::doSetup( const QVariantMap& m ) if ( !m_stopped ) Tomahawk::Pipeline::instance()->addResolver( this ); + + emit changed(); } diff --git a/src/libtomahawk/tomahawksettings.cpp b/src/libtomahawk/tomahawksettings.cpp index 029faf615..63305d912 100644 --- a/src/libtomahawk/tomahawksettings.cpp +++ b/src/libtomahawk/tomahawksettings.cpp @@ -255,8 +255,34 @@ TomahawkSettings::doUpgrade( int oldVersion, int newVersion ) remove( sipPlugin ); } - setValue( "accounts/allaccounts", accounts ); remove( "sip" ); + + // Migrate all resolvers from old resolvers settings to new accounts system + const QStringList allResolvers = value( "script/resolvers" ).toStringList(); + const QStringList enabledResolvers = value( "script/loadedresolvers" ).toStringList(); + + foreach ( const QString& resolver, allResolvers ) + { + const QString accountKey = QString( "resolveraccount_%1" ).arg( QUuid::createUuid().toString().mid( 1, 8 ) ); + accounts << accountKey; + + beginGroup( "accounts/" + accountKey ); + setValue( "enabled", enabledResolvers.contains( resolver ) == true ); + setValue( "autoconnect", true ); + setValue( "types", QStringList() << "ResolverType" ); + + QVariantHash configuration; + configuration[ "path" ] = resolver; + setValue( "configuration", configuration ); + + endGroup(); + + } + + remove( "script/resolvers" ); + remove( "script/loadedresolvers" ); + + setValue( "accounts/allaccounts", accounts ); } } diff --git a/src/libtomahawk/typedefs.h b/src/libtomahawk/typedefs.h index b972009ba..ffe6b23ab 100644 --- a/src/libtomahawk/typedefs.h +++ b/src/libtomahawk/typedefs.h @@ -22,6 +22,7 @@ #include #include #include +#include //template class QSharedPointer; @@ -69,6 +70,9 @@ namespace Tomahawk InfoSystemMode }; + class ExternalResolver; + typedef boost::function ResolverFactoryFunc; + }; // ns typedef int AudioErrorCode; diff --git a/src/resolverconfigdelegate.cpp b/src/resolverconfigdelegate.cpp index 592d1a768..96f2274f2 100644 --- a/src/resolverconfigdelegate.cpp +++ b/src/resolverconfigdelegate.cpp @@ -18,7 +18,7 @@ #include "resolverconfigdelegate.h" -#include "resolversmodel.h" +// #include "resolversmodel.h" #include "ExternalResolverGui.h" #include diff --git a/src/resolversmodel.cpp b/src/resolversmodel.cpp deleted file mode 100644 index c38b02b44..000000000 --- a/src/resolversmodel.cpp +++ /dev/null @@ -1,251 +0,0 @@ -/* === This file is part of Tomahawk Player - === - * - * Copyright 2010-2011, Leo Franchi - * - * Tomahawk is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Tomahawk is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Tomahawk. If not, see . - */ - -#include "resolversmodel.h" - -#include - -#include "tomahawksettings.h" -#include "tomahawkapp.h" -#include "ExternalResolverGui.h" -#include "pipeline.h" -#include "config.h" -#include "AtticaManager.h" -#include "utils/logger.h" - -ResolversModel::ResolversModel( QObject* parent ) - : QAbstractListModel( parent ) -{ - addInstalledResolvers(); -} - - -ResolversModel::~ResolversModel() -{ - -} - - -QVariant -ResolversModel::data( const QModelIndex& index, int role ) const -{ - if( !index.isValid() || !hasIndex( index.row(), index.column(), QModelIndex() ) ) - return QVariant(); - - Tomahawk::ExternalResolver* r = Tomahawk::Pipeline::instance()->scriptResolvers().at( index.row() ); - Tomahawk::ExternalResolverGui* res = qobject_cast< Tomahawk::ExternalResolverGui* >( r ); - Q_ASSERT(res); // this is part of the gui, so there should be no non-gui resolvers - switch( role ) - { - case Qt::DisplayRole: - case ResolversModel::ResolverName: - return res->name(); - case ResolversModel::ResolverPath: - return res->filePath(); - case ResolversModel::HasConfig: - return res->configUI() != 0; - case ResolversModel::ErrorState: - return res->error(); - case Qt::CheckStateRole: - return res->running() ? Qt::Checked : Qt::Unchecked; - case Qt::ToolTipRole: - return res->filePath(); - default: - return QVariant(); - } -} - - -bool -ResolversModel::setData( const QModelIndex& index, const QVariant& value, int role ) -{ - if ( !hasIndex( index.row(), index.column(), QModelIndex() ) ) - return false; - - Tomahawk::ExternalResolver* r = Tomahawk::Pipeline::instance()->scriptResolvers().at( index.row() ); - if ( r && r->error() == Tomahawk::ExternalResolver::FileNotFound ) // give it a shot to see if the user manually fixed paths - { - r->reload(); - - if( r->error() == Tomahawk::ExternalResolver::FileNotFound ) // Nope, no luck. Doesn't exist on disk, don't let user mess with it - return false; - } - else if ( !r && !QFile::exists( r->filePath() ) ) - { - return false; - } - - if ( role == Qt::CheckStateRole ) - { - Qt::CheckState state = static_cast< Qt::CheckState >( value.toInt() ); - - if ( state == Qt::Checked && !r->running() ) { - r->start(); - } - else if ( state == Qt::Unchecked ) - { - r->stop(); - } - - emit dataChanged( index, index ); - return true; - } - return false; -} - - -int -ResolversModel::rowCount( const QModelIndex& parent ) const -{ - Q_UNUSED( parent ); - return Tomahawk::Pipeline::instance()->scriptResolvers().count(); -} - - -int -ResolversModel::columnCount(const QModelIndex& parent) const -{ - Q_UNUSED( parent ); - return 1; -} - - -Qt::ItemFlags -ResolversModel::flags( const QModelIndex& index ) const -{ - return QAbstractItemModel::flags(index) | Qt::ItemIsUserCheckable; -} - - -void -ResolversModel::addResolver( const QString& resolver, bool enable ) -{ - const int count = rowCount( QModelIndex() ); - beginInsertRows( QModelIndex(), count, count ); - Tomahawk::ExternalResolver* r = Tomahawk::Pipeline::instance()->addScriptResolver( resolver, enable ); - Tomahawk::ExternalResolverGui* res = qobject_cast< Tomahawk::ExternalResolverGui* >( r ); - Q_ASSERT(res); // this is part of the gui, so there should be no non-gui resolvers - connect( res, SIGNAL( changed() ), this, SLOT( resolverChanged() ) ); - endInsertRows(); - - if ( res->configUI() ) - emit openConfig( res->filePath() ); - else - m_waitingForLoad << resolver; -} - - -void -ResolversModel::atticaResolverInstalled( const QString& resolverId ) -{ -#ifdef LIBATTICA_FOUND - Tomahawk::ExternalResolver* r = Tomahawk::Pipeline::instance()->resolverForPath( AtticaManager::instance()->pathFromId( resolverId ) ); - if ( !r ) - return; - const int idx = Tomahawk::Pipeline::instance()->scriptResolvers().indexOf( r ); - if ( idx >= 0 ) - { - beginInsertRows( QModelIndex(), idx, idx ); - endInsertRows(); - } -#endif -} - - -void -ResolversModel::removeResolver( const QString& resolver ) -{ - const int idx = Tomahawk::Pipeline::instance()->scriptResolvers().indexOf( Tomahawk::Pipeline::instance()->resolverForPath( resolver ) ); - if ( idx < 0 ) - return; - - beginRemoveRows( QModelIndex(), idx, idx ); - Tomahawk::Pipeline::instance()->removeScriptResolver( resolver ); - endRemoveRows(); -} - - -void -ResolversModel::resolverChanged() -{ - Tomahawk::ExternalResolver* res = qobject_cast< Tomahawk::ExternalResolver* >( sender() ); - Q_ASSERT( res ); - - if ( Tomahawk::Pipeline::instance()->scriptResolvers().contains( res ) ) - { - qDebug() << "Got resolverChanged signal, does it have a config UI yet?" << qobject_cast< Tomahawk::ExternalResolverGui* >(res)->configUI(); - const QModelIndex idx = index( Tomahawk::Pipeline::instance()->scriptResolvers().indexOf( res ), 0, QModelIndex() ); - emit dataChanged( idx, idx ); - - if ( m_waitingForLoad.contains( res->filePath() ) ) - { - m_waitingForLoad.remove( res->filePath() ); - emit openConfig( res->filePath() ); - } - } -} - - -void -ResolversModel::addInstalledResolvers() -{ - QList< QDir > pluginDirs; - - QDir appDir( qApp->applicationDirPath() ); - QDir libDir( CMAKE_INSTALL_PREFIX "/lib" ); - QDir libexecDir( CMAKE_INSTALL_FULL_LIBEXECDIR ); - - QDir lib64Dir( appDir ); - lib64Dir.cdUp(); - lib64Dir.cd( "lib64" ); - - pluginDirs << appDir << libDir << lib64Dir << libexecDir; - foreach ( const QDir& pluginDir, pluginDirs ) - { - qDebug() << "Checking directory for resolvers:" << pluginDir; - foreach ( QString fileName, pluginDir.entryList( QStringList() << "*_tomahawkresolver*", QDir::Files ) ){ - if ( fileName.contains( "_tomahawkresolver" ) ) { - const QString path = pluginDir.absoluteFilePath( fileName ); - bool found = false; - foreach ( Tomahawk::ExternalResolver* res, Tomahawk::Pipeline::instance()->scriptResolvers() ) - { - if ( res->filePath() == path ) - found = true; - } - if ( !found ) { - Tomahawk::Pipeline::instance()->addScriptResolver( path, false ); - } - } - } - } -} - - -void -ResolversModel::saveScriptResolvers() -{ - QStringList enabled, all; - foreach ( Tomahawk::ExternalResolver* res, Tomahawk::Pipeline::instance()->scriptResolvers() ) - { - all << res->filePath(); - if ( res->running() ) - enabled << res->filePath(); - } - TomahawkSettings::instance()->setAllScriptResolvers( all ); - TomahawkSettings::instance()->setEnabledScriptResolvers( enabled ); -} diff --git a/src/resolversmodel.h b/src/resolversmodel.h deleted file mode 100644 index 9aee76f72..000000000 --- a/src/resolversmodel.h +++ /dev/null @@ -1,64 +0,0 @@ -/* === This file is part of Tomahawk Player - === - * - * Copyright 2010-2011, Leo Franchi - * - * Tomahawk is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Tomahawk is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Tomahawk. If not, see . - */ - - -#ifndef RESOLVERSMODEL_H -#define RESOLVERSMODEL_H - -#include -#include -#include - -class ResolversModel : public QAbstractListModel -{ - Q_OBJECT -public: - enum Roles { - ResolverName = Qt::UserRole + 15, - ResolverPath = Qt::UserRole + 16, - HasConfig = Qt::UserRole + 17, - ErrorState = Qt::UserRole + 18 - }; - - explicit ResolversModel( QObject* parent = 0 ); - virtual ~ResolversModel(); - - virtual QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const; - virtual int rowCount( const QModelIndex& parent = QModelIndex() ) const; - virtual int columnCount( const QModelIndex& parent ) const; - virtual Qt::ItemFlags flags(const QModelIndex& index) const; - virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole); - - void addResolver( const QString& resolver, bool enable = false ); - void atticaResolverInstalled ( const QString& resolverId ); - void removeResolver( const QString& resolver ); - - void saveScriptResolvers(); - -signals: - void openConfig( const QString& filePath ); - -private slots: - void resolverChanged(); - -private: - void addInstalledResolvers(); - QSet m_waitingForLoad; -}; - -#endif // RESOLVERSMODEL_H diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index ca188dbbd..2785971dd 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -44,8 +44,6 @@ #include "pipeline.h" #include "resolver.h" #include "ExternalResolverGui.h" -#include "resolverconfigdelegate.h" -#include "resolversmodel.h" #include "scanmanager.h" #include "settingslistdelegate.h" #include "AccountDelegate.h" @@ -77,7 +75,6 @@ SettingsDialog::SettingsDialog( QWidget *parent ) , m_proxySettings( this ) , m_rejected( false ) , m_accountModel( 0 ) - , m_resolversModel( 0 ) , m_sipSpinner( 0 ) { ui->setupUi( this ); @@ -183,13 +180,7 @@ SettingsDialog::SettingsDialog( QWidget *parent ) // SCRIPT RESOLVER ui->removeScript->setEnabled( false ); - ResolverConfigDelegate* del = new ResolverConfigDelegate( this ); - connect( del, SIGNAL( openConfig( QString ) ), SLOT( openResolverConfig( QString ) ) ); - ui->scriptList->setItemDelegate( del ); - m_resolversModel = new ResolversModel( this ); - ui->scriptList->setModel( m_resolversModel ); ui->scriptList->setVerticalScrollMode( QAbstractItemView::ScrollPerPixel ); - connect( m_resolversModel, SIGNAL( openConfig( QString ) ), SLOT( openResolverConfig( QString ) ) ); #ifdef LIBATTICA_FOUND connect( ui->getMoreResolvers, SIGNAL( clicked() ), this, SLOT( getMoreResolvers() ) ); @@ -242,8 +233,6 @@ SettingsDialog::~SettingsDialog() s->setLastFmUsername( ui->lineEditLastfmUsername->text() ); s->setLastFmPassword( ui->lineEditLastfmPassword->text() ); - m_resolversModel->saveScriptResolvers(); - s->applyChanges(); s->sync(); } @@ -485,14 +474,13 @@ SettingsDialog::onLastFmFinished() #endif } - +/* void SettingsDialog::addScriptResolver() { QString resolver = QFileDialog::getOpenFileName( this, tr( "Load script resolver file" ), TomahawkSettings::instance()->scriptDefaultPath() ); if( !resolver.isEmpty() ) { - m_resolversModel->addResolver( resolver, true ); QFileInfo resolverAbsoluteFilePath = resolver; TomahawkSettings::instance()->setScriptDefaultPath( resolverAbsoluteFilePath.absolutePath() ); @@ -512,7 +500,7 @@ SettingsDialog::removeScriptResolver() #endif m_resolversModel->removeResolver( resolver ); } -} +}*/ void @@ -532,18 +520,18 @@ SettingsDialog::getMoreResolvers() #ifdef LIBATTICA_FOUND -void -SettingsDialog::atticaResolverInstalled( const QString& resolverId ) -{ - m_resolversModel->atticaResolverInstalled( resolverId ); -} - - -void -SettingsDialog::atticaResolverUninstalled ( const QString& resolverId ) -{ - m_resolversModel->removeResolver( AtticaManager::instance()->pathFromId( resolverId ) ); -} +// void +// SettingsDialog::atticaResolverInstalled( const QString& resolverId ) +// { +// m_resolversModel->atticaResolverInstalled( resolverId ); +// } +// +// +// void +// SettingsDialog::atticaResolverUninstalled ( const QString& resolverId ) +// { +// m_resolversModel->removeResolver( AtticaManager::instance()->pathFromId( resolverId ) ); +// } #endif diff --git a/src/settingsdialog.h b/src/settingsdialog.h index 995f5fffd..b0a26a482 100644 --- a/src/settingsdialog.h +++ b/src/settingsdialog.h @@ -87,15 +87,9 @@ private slots: void testLastFmLogin(); void onLastFmFinished(); - void addScriptResolver(); void scriptSelectionChanged(); - void removeScriptResolver(); void getMoreResolvers(); void getMoreResolversFinished( int ); -#ifdef LIBATTICA_FOUND - void atticaResolverInstalled( const QString& ); - void atticaResolverUninstalled( const QString& ); -#endif void openResolverConfig( const QString& ); @@ -129,7 +123,6 @@ private: ProxyDialog m_proxySettings; bool m_rejected; Tomahawk::Accounts::AccountModel* m_accountModel; - ResolversModel* m_resolversModel; LoadingSpinner* m_sipSpinner; }; From 22def2c617222fda58b5f914f93b45d0dea98f77 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Mon, 23 Jan 2012 23:28:49 -0500 Subject: [PATCH 035/104] Add resolver account wrapper and attica flag --- src/libtomahawk/accounts/Account.cpp | 2 +- src/libtomahawk/accounts/ResolverAccount.cpp | 172 +++++++++++++++++++ src/libtomahawk/accounts/ResolverAccount.h | 99 +++++++++++ src/libtomahawk/tomahawksettings.cpp | 4 + 4 files changed, 276 insertions(+), 1 deletion(-) create mode 100644 src/libtomahawk/accounts/ResolverAccount.cpp create mode 100644 src/libtomahawk/accounts/ResolverAccount.h diff --git a/src/libtomahawk/accounts/Account.cpp b/src/libtomahawk/accounts/Account.cpp index 62387f1aa..bc1501947 100644 --- a/src/libtomahawk/accounts/Account.cpp +++ b/src/libtomahawk/accounts/Account.cpp @@ -54,7 +54,7 @@ Account::aclWidget() QIcon Account::icon() const { - return QIcon(); + return QPixmap(); } void diff --git a/src/libtomahawk/accounts/ResolverAccount.cpp b/src/libtomahawk/accounts/ResolverAccount.cpp new file mode 100644 index 000000000..f7dcf4a62 --- /dev/null +++ b/src/libtomahawk/accounts/ResolverAccount.cpp @@ -0,0 +1,172 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Leo Franchi + * + * 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 "ResolverAccount.h" + +#include "ExternalResolver.h" +#include "ExternalResolverGui.h" +#include "AccountManager.h" +#include +#include +#include +#include + +using namespace Tomahawk; +using namespace Accounts; + +Account* +ResolverAccountFactory::createAccount( const QString& accountId ) +{ + // Can't use this to create new accounts. Needs to be able to find account in config + // to load proper resolver account type. Creation is done from AtticaManager when path is known + Q_ASSERT( !accountId.isEmpty() ); + + // If it's an attica resolver, return it instead so we get an icon + const bool isFromAttica = TomahawkSettings::instance()->value( QString( "accounts/%1/atticaresolver" ).arg( accountId ), false ).toBool(); + if ( isFromAttica ) + return new AtticaResolverAccount( accountId ); + else + return new ResolverAccount( accountId ); +} + + +ResolverAccount::ResolverAccount( const QString& accountId ) + : Account( accountId ) +{ + + const QString path = configuration()[ "path" ].toString(); + + // We should have a valid saved path + Q_ASSERT( !path.isEmpty() ); + + m_resolver = qobject_cast< ExternalResolverGui* >( Pipeline::instance()->addScriptResolver( path, enabled() ) ); + connect( m_resolver, SIGNAL( changed() ), this, SLOT( resolverChanged() ) ); + + // What resolver do we have here? Should only be types that are 'real' resolvers + Q_ASSERT ( m_resolver ); + + setAccountFriendlyName( m_resolver->name() ); + setTypes( AccountType( ResolverType ) ); +} + + +ResolverAccount::~ResolverAccount() +{ + delete m_resolver; +} + + + +void +ResolverAccount::authenticate() +{ + if ( !m_resolver->running() ) + m_resolver->start(); + + emit connectionStateChanged( connectionState() ); +} + + +bool +ResolverAccount::isAuthenticated() const +{ + return m_resolver->running(); +} + + +void +ResolverAccount::deauthenticate() +{ + if ( m_resolver->running() ) + m_resolver->stop(); + + emit connectionStateChanged( connectionState() ); + +} + + +Account::ConnectionState +ResolverAccount::connectionState() const +{ + if ( m_resolver->running() ) + return Connected; + else + return Disconnected; +} + + +QWidget* +ResolverAccount::configurationWidget() +{ + return m_resolver->configUI(); +} + + +QString +ResolverAccount::errorMessage() const +{ + // TODO +// return m_resolver->error(); + return QString(); +} + + +void +ResolverAccount::removeFromConfig() +{ + // TODO +} + + +void ResolverAccount::saveConfig() +{ + m_resolver->saveConfig(); +} + + +void +ResolverAccount::resolverChanged() +{ + setAccountFriendlyName( m_resolver->name() ); + emit connectionStateChanged( connectionState() ); +} + + +/// AtticaResolverAccount + +AtticaResolverAccount::AtticaResolverAccount( const QString& accountId ) + : ResolverAccount( accountId ) +{ + const QFileInfo fi( m_resolver->filePath() ); + QDir codeDir = fi.absoluteDir(); + codeDir.cd( "../images" ); + + if ( codeDir.exists() && codeDir.exists( "icon.png" ) ) + m_icon.addFile( codeDir.absoluteFilePath( "icon.png" ) ); +} + +AtticaResolverAccount::~AtticaResolverAccount() +{ + +} + +QIcon +AtticaResolverAccount::icon() const +{ + return QPixmap; +} diff --git a/src/libtomahawk/accounts/ResolverAccount.h b/src/libtomahawk/accounts/ResolverAccount.h new file mode 100644 index 000000000..4aeb159ce --- /dev/null +++ b/src/libtomahawk/accounts/ResolverAccount.h @@ -0,0 +1,99 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Leo Franchi + * + * 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 RESOLVERACCOUNT_H +#define RESOLVERACCOUNT_H + +#include "accounts/Account.h" + +namespace Tomahawk { + +class ExternalResolverGui; + +namespace Accounts { + +class ResolverAccountFactory : public AccountFactory +{ + Q_OBJECT +public: + ResolverAccountFactory() {} + virtual ~ResolverAccountFactory() {} + + virtual Account* createAccount(const QString& accountId = QString()); + virtual QString factoryId() const { return "resolveraccount"; } + virtual QString prettyName() const { return QString(); } // Internal, not displayed +}; + +/** + * Helper wrapper class that is a resolver-only account. + * + * Contains the resolver* that is it wrapping + */ +class ResolverAccount : public Account +{ + Q_OBJECT +public: + explicit ResolverAccount( const QString& accountId ); + virtual ~ResolverAccount(); + + virtual void authenticate(); + virtual void deauthenticate(); + virtual bool isAuthenticated() const; + virtual Tomahawk::Accounts::Account::ConnectionState connectionState() const; + + virtual QWidget* configurationWidget(); + virtual QString errorMessage() const; + + virtual void saveConfig(); + virtual void removeFromConfig(); + + // Not relevant + virtual QIcon icon() const { return QIcon(); } + virtual SipPlugin* sipPlugin() { return 0; } + virtual Tomahawk::InfoSystem::InfoPlugin* infoPlugin() { return 0; } + virtual QWidget* aclWidget() { return 0; } + +private slots: + void resolverChanged(); + +protected: + ExternalResolverGui* m_resolver; +}; + + +/** + * Extends ResolverAccount with what attica additionally provides---e.g. icon + * Assumes certain file layout on disk. + */ +class AtticaResolverAccount : public ResolverAccount +{ + Q_OBJECT +public: + explicit AtticaResolverAccount(const QString& accountId); + virtual ~AtticaResolverAccount(); + + virtual QIcon icon() const; + +private: + QIcon m_icon; +}; + +} +} + +#endif // RESOLVERACCOUNT_H diff --git a/src/libtomahawk/tomahawksettings.cpp b/src/libtomahawk/tomahawksettings.cpp index 63305d912..455ea29ff 100644 --- a/src/libtomahawk/tomahawksettings.cpp +++ b/src/libtomahawk/tomahawksettings.cpp @@ -275,6 +275,10 @@ TomahawkSettings::doUpgrade( int oldVersion, int newVersion ) configuration[ "path" ] = resolver; setValue( "configuration", configuration ); + // reasonably ugly check for attica resolvers + if ( resolver.contains( "atticaresolvers" ) && resolver.contains( "code" ) ) + setValue( "atticaresolver", true ); + endGroup(); } From 4334840dad8c2b1ae7c71142f9ea6b1c5336e9ca Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 27 Jan 2012 12:49:29 -0500 Subject: [PATCH 036/104] QIcon->QPixmap for account icon. QIcon doesn't make sense in this case, as it is designed to store multiple sizes/active states for icons that are associated with e.g. toolbuttons. Account icons are just an image that represents the logo of the account, so only one pixmap is needed. --- src/AccountDelegate.cpp | 4 ++-- src/accounts/twitter/twitteraccount.cpp | 4 ++-- src/accounts/twitter/twitteraccount.h | 4 ++-- src/accounts/xmpp/googlewrapper/googlewrapper.cpp | 8 ++++---- src/accounts/xmpp/googlewrapper/googlewrapper.h | 4 ++-- src/accounts/xmpp/xmppaccount.h | 4 ++-- src/accounts/zeroconf/zeroconfaccount.cpp | 8 ++++---- src/accounts/zeroconf/zeroconfaccount.h | 4 ++-- src/libtomahawk/accounts/Account.cpp | 2 +- src/libtomahawk/accounts/Account.h | 4 ++-- src/libtomahawk/accounts/ResolverAccount.cpp | 6 +++--- src/libtomahawk/accounts/ResolverAccount.h | 6 +++--- 12 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/AccountDelegate.cpp b/src/AccountDelegate.cpp index cee10ecb7..a371e8a87 100644 --- a/src/AccountDelegate.cpp +++ b/src/AccountDelegate.cpp @@ -88,11 +88,11 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, // draw the icon if it exists pos = mid - ( ICONSIZE / 2 ); - if( !index.data( Qt::DecorationRole ).value< QIcon >().isNull() ) { + if( !index.data( Qt::DecorationRole ).value< QPixmap >().isNull() ) { QRect prect = QRect( iconLeftEdge, pos + top, ICONSIZE, ICONSIZE ); painter->save(); - painter->drawPixmap( prect, index.data( Qt::DecorationRole ).value< QIcon >().pixmap( prect.size() ) ); + painter->drawPixmap( prect, index.data( Qt::DecorationRole ).value< QPixmap >().scaled( prect.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation ) ); painter->restore(); } diff --git a/src/accounts/twitter/twitteraccount.cpp b/src/accounts/twitter/twitteraccount.cpp index b53487110..390bf55e4 100644 --- a/src/accounts/twitter/twitteraccount.cpp +++ b/src/accounts/twitter/twitteraccount.cpp @@ -170,9 +170,9 @@ TwitterAccount::connectAuthVerifyReply( const QTweetUser &user ) emit nowAuthenticated( m_twitterAuth, user ); } } -QIcon +QPixmap TwitterAccount::icon() const { - return QIcon( ":/twitter-icon.png" ); + return QPixmap( ":/twitter-icon.png" ); } diff --git a/src/accounts/twitter/twitteraccount.h b/src/accounts/twitter/twitteraccount.h index f965beef6..4746f9aae 100644 --- a/src/accounts/twitter/twitteraccount.h +++ b/src/accounts/twitter/twitteraccount.h @@ -46,7 +46,7 @@ public: QString prettyName() const { return "Twitter"; } QString factoryId() const { return "twitteraccount"; } - QIcon icon() const { return QIcon( ":/twitter-icon.png" ); } + QPixmap icon() const { return QPixmap( ":/twitter-icon.png" ); } Account* createAccount( const QString& pluginId = QString() ); }; @@ -58,7 +58,7 @@ public: TwitterAccount( const QString &accountId ); virtual ~TwitterAccount(); - QIcon icon() const; + QPixmap icon() const; void authenticate(); void deauthenticate(); diff --git a/src/accounts/xmpp/googlewrapper/googlewrapper.cpp b/src/accounts/xmpp/googlewrapper/googlewrapper.cpp index a341b91f9..d60a91740 100644 --- a/src/accounts/xmpp/googlewrapper/googlewrapper.cpp +++ b/src/accounts/xmpp/googlewrapper/googlewrapper.cpp @@ -36,10 +36,10 @@ GoogleWrapperFactory::createAccount( const QString& pluginId ) } -QIcon +QPixmap GoogleWrapperFactory::icon() const { - return QIcon( ":/gmail-logo.png" ); + return QPixmap( ":/gmail-logo.png" ); } GoogleWrapperSip::GoogleWrapperSip( Account* account ) @@ -93,10 +93,10 @@ GoogleWrapper::~GoogleWrapper() } -QIcon +QPixmap GoogleWrapper::icon() const { - return QIcon( ":/gmail-logo.png" ); + return QPixmap( ":/gmail-logo.png" ); } diff --git a/src/accounts/xmpp/googlewrapper/googlewrapper.h b/src/accounts/xmpp/googlewrapper/googlewrapper.h index 01a516e31..fdb8fb0a0 100644 --- a/src/accounts/xmpp/googlewrapper/googlewrapper.h +++ b/src/accounts/xmpp/googlewrapper/googlewrapper.h @@ -38,7 +38,7 @@ public: virtual QString prettyName() const { return "Google"; } virtual QString factoryId() const { return "googleaccount"; } - virtual QIcon icon() const; + virtual QPixmap icon() const; virtual Account* createAccount( const QString& pluginId ); }; @@ -65,7 +65,7 @@ public: virtual const QString name() const { return QString( "Google" ); } virtual const QString friendlyName() const { return "Google"; } - virtual QIcon icon() const; + virtual QPixmap icon() const; virtual SipPlugin* sipPlugin(); diff --git a/src/accounts/xmpp/xmppaccount.h b/src/accounts/xmpp/xmppaccount.h index 7295df7c1..905a869ff 100644 --- a/src/accounts/xmpp/xmppaccount.h +++ b/src/accounts/xmpp/xmppaccount.h @@ -48,7 +48,7 @@ public: QString prettyName() const { return "XMPP (Jabber)"; } QString factoryId() const { return "xmppaccount"; } - QIcon icon() const { return QIcon( ":/xmpp-icon.png" ); } + QPixmap icon() const { return QPixmap( ":/xmpp-icon.png" ); } Account* createAccount( const QString& pluginId = QString() ); }; @@ -60,7 +60,7 @@ public: XmppAccount( const QString &accountId ); virtual ~XmppAccount(); - QIcon icon() const { return QIcon( ":/xmpp-icon.png" ); } + QPixmap icon() const { return QPixmap( ":/xmpp-icon.png" ); } void authenticate(); void deauthenticate(); diff --git a/src/accounts/zeroconf/zeroconfaccount.cpp b/src/accounts/zeroconf/zeroconfaccount.cpp index 7d239b14b..97548ecbc 100644 --- a/src/accounts/zeroconf/zeroconfaccount.cpp +++ b/src/accounts/zeroconf/zeroconfaccount.cpp @@ -26,13 +26,13 @@ using namespace Tomahawk; using namespace Accounts; -QIcon* s_icon = 0; +QPixmap* s_icon = 0; ZeroconfFactory::ZeroconfFactory() { #ifndef ENABLE_HEADLESS if ( s_icon == 0 ) - s_icon = new QIcon( ":/zeroconf-icon.png" ); + s_icon = new QPixmap( ":/zeroconf-icon.png" ); #endif } @@ -53,7 +53,7 @@ ZeroconfFactory::createAccount( const QString& pluginId ) return new ZeroconfAccount( pluginId.isEmpty() ? generateId( factoryId() ) : pluginId ); } -QIcon +QPixmap ZeroconfFactory::icon() const { return *s_icon; @@ -74,7 +74,7 @@ ZeroconfAccount::~ZeroconfAccount() } -QIcon +QPixmap ZeroconfAccount::icon() const { return *s_icon; diff --git a/src/accounts/zeroconf/zeroconfaccount.h b/src/accounts/zeroconf/zeroconfaccount.h index 74d3afcad..5f926a12a 100644 --- a/src/accounts/zeroconf/zeroconfaccount.h +++ b/src/accounts/zeroconf/zeroconfaccount.h @@ -41,7 +41,7 @@ public: virtual QString prettyName() const { return "Local Network"; } virtual bool isUnique() const { return true; } #ifndef ENABLE_HEADLESS - virtual QIcon icon() const; +virtual QPixmap icon() const; #endif @@ -55,7 +55,7 @@ public: ZeroconfAccount( const QString &accountId ); virtual ~ZeroconfAccount(); - QIcon icon() const; + QPixmap icon() const; void authenticate(); void deauthenticate(); diff --git a/src/libtomahawk/accounts/Account.cpp b/src/libtomahawk/accounts/Account.cpp index bc1501947..9227c7f5c 100644 --- a/src/libtomahawk/accounts/Account.cpp +++ b/src/libtomahawk/accounts/Account.cpp @@ -51,7 +51,7 @@ Account::aclWidget() } -QIcon +QPixmap Account::icon() const { return QPixmap(); diff --git a/src/libtomahawk/accounts/Account.h b/src/libtomahawk/accounts/Account.h index a46007b19..7a92f30e8 100644 --- a/src/libtomahawk/accounts/Account.h +++ b/src/libtomahawk/accounts/Account.h @@ -91,7 +91,7 @@ public: QVariantMap acl() const { QMutexLocker locker( &m_mutex ); return m_acl; } virtual QWidget* aclWidget() = 0; - virtual QIcon icon() const = 0; + virtual QPixmap icon() const = 0; virtual ConnectionState connectionState() const = 0; virtual bool isAuthenticated() const = 0; @@ -166,7 +166,7 @@ public: // internal name virtual QString factoryId() const = 0; // if the user can create multiple - virtual QIcon icon() const { return QIcon(); } + virtual QPixmap icon() const { return QPixmap(); } virtual bool isUnique() const { return false; } virtual Account* createAccount( const QString& accountId = QString() ) = 0; diff --git a/src/libtomahawk/accounts/ResolverAccount.cpp b/src/libtomahawk/accounts/ResolverAccount.cpp index f7dcf4a62..c2408f10d 100644 --- a/src/libtomahawk/accounts/ResolverAccount.cpp +++ b/src/libtomahawk/accounts/ResolverAccount.cpp @@ -157,7 +157,7 @@ AtticaResolverAccount::AtticaResolverAccount( const QString& accountId ) codeDir.cd( "../images" ); if ( codeDir.exists() && codeDir.exists( "icon.png" ) ) - m_icon.addFile( codeDir.absoluteFilePath( "icon.png" ) ); + m_icon.load( codeDir.absoluteFilePath( "icon.png" ) ); } AtticaResolverAccount::~AtticaResolverAccount() @@ -165,8 +165,8 @@ AtticaResolverAccount::~AtticaResolverAccount() } -QIcon +QPixmap AtticaResolverAccount::icon() const { - return QPixmap; + return m_icon; } diff --git a/src/libtomahawk/accounts/ResolverAccount.h b/src/libtomahawk/accounts/ResolverAccount.h index 4aeb159ce..8d77a83e0 100644 --- a/src/libtomahawk/accounts/ResolverAccount.h +++ b/src/libtomahawk/accounts/ResolverAccount.h @@ -63,7 +63,7 @@ public: virtual void removeFromConfig(); // Not relevant - virtual QIcon icon() const { return QIcon(); } + virtual QPixmap icon() const { return QPixmap(); } virtual SipPlugin* sipPlugin() { return 0; } virtual Tomahawk::InfoSystem::InfoPlugin* infoPlugin() { return 0; } virtual QWidget* aclWidget() { return 0; } @@ -87,10 +87,10 @@ public: explicit AtticaResolverAccount(const QString& accountId); virtual ~AtticaResolverAccount(); - virtual QIcon icon() const; + virtual QPixmap icon() const; private: - QIcon m_icon; + QPixmap m_icon; }; } From 39c7af6262206ed5d329189fcd6493cbfd2493ae Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 27 Jan 2012 13:50:29 -0500 Subject: [PATCH 037/104] Remove ifdef of libattica --- CMakeLists.txt | 4 ++-- src/config.h.in | 1 - src/libtomahawk/AtticaManager.h | 12 ------------ src/settingsdialog.cpp | 12 ++---------- src/tomahawkapp.cpp | 4 ---- 5 files changed, 4 insertions(+), 29 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9693d6962..5ff9d2629 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -109,10 +109,10 @@ macro_optional_find_package(QCA2) macro_log_feature(QCA2_FOUND "QCA2" "Provides encryption and signing functions required for Grooveshark resolver" "http://delta.affinix.com/qca/" FALSE "" "") macro_optional_find_package(LibAttica) -macro_log_feature(LIBATTICA_FOUND "libattica" "Provides support for automatic fetching and managing of resolvers from the tomahawk website" "https://projects.kde.org/projects/kdesupport/attica" FALSE "" "") +macro_log_feature(LIBATTICA_FOUND "libattica" "Provides support for automatic fetching and managing of resolvers from the tomahawk website" "https://projects.kde.org/projects/kdesupport/attica" TRUE "" "") macro_optional_find_package(QuaZip) -macro_log_feature(QuaZip_FOUND "QuaZip" "Provides support for extracting downloaded resolvers automatically." "http://quazip.sourceforge.net/" FALSE "" "") +macro_log_feature(QuaZip_FOUND "QuaZip" "Provides support for extracting downloaded resolvers automatically." "http://quazip.sourceforge.net/" TRUE "" "") macro_optional_find_package(Jreen) macro_log_feature(LIBJREEN_FOUND "Jreen" "Qt XMPP Library" "https://github.com/euroelessar/jreen" FALSE "" "Jreen is needed for the Jabber SIP plugin.\n") diff --git a/src/config.h.in b/src/config.h.in index 42e6a346b..0cdbb948e 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -20,6 +20,5 @@ #cmakedefine LIBLASTFM_FOUND #cmakedefine GLOOX_FOUND #cmakedefine QCA2_FOUND -#cmakedefine LIBATTICA_FOUND #endif // CONFIG_H_IN diff --git a/src/libtomahawk/AtticaManager.h b/src/libtomahawk/AtticaManager.h index bff352df9..d4fced92f 100644 --- a/src/libtomahawk/AtticaManager.h +++ b/src/libtomahawk/AtticaManager.h @@ -27,11 +27,9 @@ #include "dllmacro.h" -#ifdef LIBATTICA_FOUND #include #include #include -#endif class DLLEXPORT AtticaManager : public QObject { @@ -68,14 +66,7 @@ public: } explicit AtticaManager ( QObject* parent = 0 ); -#ifdef LIBATTICA_FOUND - virtual ~AtticaManager(); -#else - virtual ~AtticaManager() {} -#endif - -#ifdef LIBATTICA_FOUND bool resolversLoaded() const; @@ -122,13 +113,10 @@ private: Attica::Provider m_resolverProvider; Attica::Content::List m_resolvers; StateHash m_resolverStates; -#endif static AtticaManager* s_instance; }; -#ifdef LIBATTICA_FOUND Q_DECLARE_METATYPE( Attica::Content ); -#endif #endif // ATTICAMANAGER_H diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index 2785971dd..2000df4e0 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -182,14 +182,10 @@ SettingsDialog::SettingsDialog( QWidget *parent ) ui->removeScript->setEnabled( false ); ui->scriptList->setVerticalScrollMode( QAbstractItemView::ScrollPerPixel ); -#ifdef LIBATTICA_FOUND connect( ui->getMoreResolvers, SIGNAL( clicked() ), this, SLOT( getMoreResolvers() ) ); connect( AtticaManager::instance(), SIGNAL( resolverInstalled( QString ) ), this, SLOT( atticaResolverInstalled( QString ) ) ); connect( AtticaManager::instance(), SIGNAL( resolverUninstalled( QString ) ), this, SLOT( atticaResolverUninstalled( QString ) ) ); -#else - ui->getMoreResolvers->hide(); -#endif connect( ui->scriptList->selectionModel(), SIGNAL( selectionChanged( QItemSelection,QItemSelection ) ), this, SLOT( scriptSelectionChanged() ) ); connect( ui->addScript, SIGNAL( clicked( bool ) ), this, SLOT( addScriptResolver() ) ); @@ -495,9 +491,7 @@ SettingsDialog::removeScriptResolver() if( !ui->scriptList->selectionModel()->selectedIndexes().isEmpty() ) { QString resolver = ui->scriptList->selectionModel()->selectedIndexes().first().data( ResolversModel::ResolverPath ).toString(); -#ifdef LIBATTICA_FOUND AtticaManager::instance()->uninstallResolver( resolver ); -#endif m_resolversModel->removeResolver( resolver ); } }*/ @@ -506,11 +500,11 @@ SettingsDialog::removeScriptResolver() void SettingsDialog::getMoreResolvers() { -#if defined(Q_WS_MAC) && defined(LIBATTICA_FOUND) +#if defined(Q_WS_MAC) GetNewStuffDialog* diag = new GetNewStuffDialog( this, Qt::Sheet ); connect( diag, SIGNAL( finished( int ) ), this, SLOT( getMoreResolversFinished( int ) ) ); diag->show(); -#elif defined(LIBATTICA_FOUND) +#else GetNewStuffDialog diag( this ); int ret = diag.exec(); Q_UNUSED( ret ); @@ -519,7 +513,6 @@ SettingsDialog::getMoreResolvers() } -#ifdef LIBATTICA_FOUND // void // SettingsDialog::atticaResolverInstalled( const QString& resolverId ) // { @@ -532,7 +525,6 @@ SettingsDialog::getMoreResolvers() // { // m_resolversModel->removeResolver( AtticaManager::instance()->pathFromId( resolverId ) ); // } -#endif void diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index 4f63d79fc..350b4cdc5 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -248,11 +248,9 @@ TomahawkApp::init() tDebug() << "Init Pipeline."; initPipeline(); -#ifdef LIBATTICA_FOUND #ifndef ENABLE_HEADLESS // load remote list of resolvers able to be installed AtticaManager::instance(); -#endif #endif if ( arguments().contains( "--http" ) || TomahawkSettings::instance()->value( "network/http", true ).toBool() ) @@ -324,9 +322,7 @@ TomahawkApp::~TomahawkApp() #ifndef ENABLE_HEADLESS delete m_mainwindow; - #ifdef LIBATTICA_FOUND delete AtticaManager::instance(); - #endif #endif From e319aa248c1a2d00e982cfcc3ebe2b3dcc5ec8fe Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 27 Jan 2012 18:31:11 -0500 Subject: [PATCH 038/104] Initial work towards merging accounts into GetNewStuffModel --- src/GetNewStuffDelegate.cpp | 17 +- src/GetNewStuffDialog.cpp | 35 ++- src/GetNewStuffDialog.h | 3 + src/GetNewStuffDialog.ui | 44 ++- src/GetNewStuffModel.cpp | 266 +++++++++++++----- src/GetNewStuffModel.h | 33 ++- src/accounts/twitter/twitteraccount.h | 1 + .../xmpp/googlewrapper/googlewrapper.h | 1 + src/accounts/xmpp/xmppaccount.h | 1 + src/accounts/zeroconf/zeroconfaccount.h | 1 + src/libtomahawk/accounts/Account.h | 6 +- src/libtomahawk/accounts/ResolverAccount.h | 2 + src/settingsdialog.cpp | 211 ++------------ src/settingsdialog.h | 19 +- src/stackedsettingsdialog.ui | 101 ------- 15 files changed, 351 insertions(+), 390 deletions(-) diff --git a/src/GetNewStuffDelegate.cpp b/src/GetNewStuffDelegate.cpp index 1e1c5d381..a1a3409bd 100644 --- a/src/GetNewStuffDelegate.cpp +++ b/src/GetNewStuffDelegate.cpp @@ -111,28 +111,31 @@ GetNewStuffDelegate::paint( QPainter* painter, const QStyleOptionViewItem& optio // Go from right edge now, stars, install button, and downloaded info // install / status button - AtticaManager::ResolverState state = static_cast< AtticaManager::ResolverState >( index.data( GetNewStuffModel::StateRole ).toInt() ); + GetNewStuffModel::ItemState state = static_cast< GetNewStuffModel::ItemState >( index.data( GetNewStuffModel::StateRole ).toInt() ); QString actionText; switch( state ) { - case AtticaManager::Uninstalled: + case GetNewStuffModel::Uninstalled: actionText = tr( "Install" ); break; - case AtticaManager::Installing: + case GetNewStuffModel::Installing: actionText = tr( "Installing" ); break; - case AtticaManager::Upgrading: + case GetNewStuffModel::Upgrading: actionText = tr( "Upgrading" ); break; - case AtticaManager::Failed: + case GetNewStuffModel::Failed: actionText = tr( "Failed" ); break; - case AtticaManager::Installed: + case GetNewStuffModel::Installed: actionText = tr( "Uninstall" ); break; - case AtticaManager::NeedsUpgrade: + case GetNewStuffModel::NeedsUpgrade: actionText = tr( "Upgrade" ); break; + case GetNewStuffModel::CanInstallMore: + actionText = tr( "Install Another" ); + break; } const int btnWidth = m_widestTextWidth + 7; diff --git a/src/GetNewStuffDialog.cpp b/src/GetNewStuffDialog.cpp index da3f0891f..b188a2f38 100644 --- a/src/GetNewStuffDialog.cpp +++ b/src/GetNewStuffDialog.cpp @@ -21,6 +21,9 @@ #include "ui_GetNewStuffDialog.h" #include "GetNewStuffDelegate.h" #include "GetNewStuffModel.h" +#include "tomahawksettings.h" + +#include GetNewStuffDialog::GetNewStuffDialog( QWidget* parent, Qt::WindowFlags f ) : QDialog( parent, f ) @@ -29,13 +32,13 @@ GetNewStuffDialog::GetNewStuffDialog( QWidget* parent, Qt::WindowFlags f ) { ui->setupUi( this ); - ui->listView->setModel( m_model ); - GetNewStuffDelegate* del = new GetNewStuffDelegate( ui->listView ); - connect( del, SIGNAL( update( QModelIndex ) ), ui->listView, SLOT( update( QModelIndex ) ) ); - ui->listView->setItemDelegate( del ); - ui->listView->setVerticalScrollMode( QAbstractItemView::ScrollPerPixel ); + ui->accountsList->setModel( m_model ); + GetNewStuffDelegate* del = new GetNewStuffDelegate( ui->accountsList ); + connect( del, SIGNAL( update( QModelIndex ) ), ui->accountsList, SLOT( update( QModelIndex ) ) ); + ui->accountsList->setItemDelegate( del ); + ui->accountsList->setVerticalScrollMode( QAbstractItemView::ScrollPerPixel ); - ui->listView->setMouseTracking( true ); + ui->accountsList->setMouseTracking( true ); setMinimumSize( 560, 350 ); @@ -43,8 +46,10 @@ GetNewStuffDialog::GetNewStuffDialog( QWidget* parent, Qt::WindowFlags f ) setMaximumSize( 560, 350 ); setSizeGripEnabled( false ); - ui->listView->setAttribute( Qt::WA_MacShowFocusRect, false ); + ui->accountsList->setAttribute( Qt::WA_MacShowFocusRect, false ); #endif + + connect( ui->installFromFileBtn, SIGNAL( clicked( bool ) ), this, SLOT( installFromFile() ) ); } @@ -52,3 +57,19 @@ GetNewStuffDialog::~GetNewStuffDialog() { delete ui; } + + +void +GetNewStuffDialog::installFromFile() +{ + QString resolver = QFileDialog::getOpenFileName( this, tr( "Load script resolver file" ), TomahawkSettings::instance()->scriptDefaultPath() ); + +// m_resolversModel->addResolver( resolver, true ); + // TODO + if( !resolver.isEmpty() ) + { + + QFileInfo resolverAbsoluteFilePath = resolver; + TomahawkSettings::instance()->setScriptDefaultPath( resolverAbsoluteFilePath.absolutePath() ); + } +} diff --git a/src/GetNewStuffDialog.h b/src/GetNewStuffDialog.h index a0e195a8d..3e63a66c1 100644 --- a/src/GetNewStuffDialog.h +++ b/src/GetNewStuffDialog.h @@ -33,6 +33,9 @@ public: explicit GetNewStuffDialog( QWidget *parent = 0, Qt::WindowFlags f = 0 ); ~GetNewStuffDialog(); +private slots: + void installFromFile(); + private: Ui::GetNewStuffDialog *ui; GetNewStuffModel* m_model; diff --git a/src/GetNewStuffDialog.ui b/src/GetNewStuffDialog.ui index 1686a8200..f844f82f4 100644 --- a/src/GetNewStuffDialog.ui +++ b/src/GetNewStuffDialog.ui @@ -7,7 +7,7 @@ 0 0 449 - 282 + 327 @@ -15,17 +15,41 @@ - + - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - + + + + + Install from file... + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + diff --git a/src/GetNewStuffModel.cpp b/src/GetNewStuffModel.cpp index 405ca968b..e80093cdf 100644 --- a/src/GetNewStuffModel.cpp +++ b/src/GetNewStuffModel.cpp @@ -20,32 +20,73 @@ #include "utils/tomahawkutils.h" #include "utils/logger.h" +#include "AtticaManager.h" +#include "accounts/AccountManager.h" #include #include -#include "AtticaManager.h" + +using namespace Tomahawk; +using namespace Accounts; GetNewStuffModel::GetNewStuffModel( QObject* parent ) : QAbstractListModel ( parent ) { - - if ( AtticaManager::instance()->resolversLoaded() ) - m_contentList = AtticaManager::instance()->resolvers(); - connect( AtticaManager::instance(), SIGNAL( resolversReloaded( Attica::Content::List ) ), this, SLOT( resolversReloaded( Attica::Content::List ) ) ); connect( AtticaManager::instance(), SIGNAL( resolverStateChanged( QString ) ), this, SLOT( resolverStateChanged( QString ) ) ); + loadData(); } GetNewStuffModel::~GetNewStuffModel() { } +void +GetNewStuffModel::loadData() +{ + foreach ( const QVariant& content, m_contentList ) + { + if ( !isAttica( content ) ) + { + AccountItem* item = content.value< GetNewStuffModel::AccountItem* >(); + delete item; + } + } + m_contentList.clear(); + + Attica::Content::List fromAttica = AtticaManager::instance()->resolvers(); + foreach ( const Attica::Content& content, fromAttica ) + m_contentList.append( QVariant::fromValue< Attica::Content >( content ) ); + + QList< AccountFactory* > factories = AccountManager::instance()->factories(); + QList< Account* > allAccounts = AccountManager::instance()->accounts(); + foreach ( AccountFactory* fac, factories ) + { + if ( !fac->allowUserCreation() ) + continue; + + AccountItem* item = new AccountItem; + item->factory = fac; + + foreach ( Account* acct, allAccounts ) + { + if ( AccountManager::instance()->factoryForAccount( acct ) == fac ) + item->alreadyExists = true; + else + item->alreadyExists = false; + } + + m_contentList.append( QVariant::fromValue< GetNewStuffModel::AccountItem* >( item ) ); + } +} + + void GetNewStuffModel::resolversReloaded( const Attica::Content::List& resolvers ) { beginResetModel(); - m_contentList = resolvers; + loadData(); endResetModel(); } @@ -54,7 +95,10 @@ GetNewStuffModel::resolverStateChanged( const QString& resolverId ) { for ( int i = 0; i < m_contentList.count(); i++ ) { - const Attica::Content resolver = m_contentList[ i ]; + if ( !isAttica( m_contentList.at( i ) ) ) + continue; + + const Attica::Content resolver = atticaFromItem( m_contentList.at( i ) ); if ( resolver.id() == resolverId ) { QModelIndex idx = index( i, 0, QModelIndex() ); @@ -70,33 +114,82 @@ GetNewStuffModel::data( const QModelIndex& index, int role ) const if ( !index.isValid() || !hasIndex( index.row(), index.column(), index.parent() ) ) return QVariant(); - Attica::Content resolver = m_contentList[ index.row() ]; - switch ( role ) + if ( isAttica( m_contentList.at( index.row() ) ) ) { - case Qt::DisplayRole: - return resolver.name(); - case Qt::DecorationRole: - return QVariant::fromValue< QPixmap >( AtticaManager::instance()->iconForResolver( resolver ) ); - case DownloadUrlRole: - // TODO - return QUrl(); - case RatingRole: - return resolver.rating() / 20; // rating is out of 100 - case DownloadCounterRole: - return resolver.downloads(); - case VersionRole: - return resolver.version(); - case DescriptionRole: - return resolver.description(); - case TypeRole: - return ResolverType; - case AuthorRole: - return resolver.author(); - case StateRole: - return (int)AtticaManager::instance()->resolverState( resolver ); - case UserHasRatedRole: - return AtticaManager::instance()->userHasRated( resolver ); + const Attica::Content resolver = atticaFromItem( m_contentList.at( index.row() ) ); + switch ( role ) + { + case Qt::DisplayRole: + return resolver.name(); + case Qt::DecorationRole: + return QVariant::fromValue< QPixmap >( AtticaManager::instance()->iconForResolver( resolver ) ); + case DownloadUrlRole: + // TODO + return QUrl(); + case RatingRole: + return resolver.rating() / 20; // rating is out of 100 + case DownloadCounterRole: + return resolver.downloads(); + case VersionRole: + return resolver.version(); + case DescriptionRole: + return resolver.description(); + case TypeRole: + return AtticaType; + case AuthorRole: + return resolver.author(); + case StateRole: + return (int)AtticaManager::instance()->resolverState( resolver ); + case UserHasRatedRole: + return AtticaManager::instance()->userHasRated( resolver ); + } } + else + { + // Account, not from Attica + AccountItem* item = accountFromItem( m_contentList.at( index.row() ) ); + Q_ASSERT( item ); + switch ( role ) + { + case Qt::DisplayRole: + return item->factory->prettyName(); + case Qt::DecorationRole: + return QVariant::fromValue< QPixmap >( item->factory->icon() ); + case RatingRole: + // TODO + return 3; +// return resolver.rating() / 20; // rating is out of 100 + case DownloadCounterRole: + // TODO + return 10; +// return resolver.downloads(); + case VersionRole: + return "1.0"; +// return resolver.version(); + case DescriptionRole: + return item->factory->description(); + case TypeRole: + return AccountType; + case AuthorRole: + return "Tomahawk Developers"; + case StateRole: + { + GetNewStuffModel::ItemState state = Uninstalled; + if ( item->factory->isUnique() && item->alreadyExists ) + state = Installed; + else if ( !item->factory->isUnique() && item->alreadyExists ) + state = CanInstallMore; + else if ( !item->alreadyExists ) + state = Uninstalled; + return (int)state; + } + case UserHasRatedRole: + // TODO + return true; +// return AtticaManager::instance()->userHasRated( resolver ); + } + } + return QVariant(); } @@ -114,43 +207,84 @@ GetNewStuffModel::setData( const QModelIndex &index, const QVariant &value, int if ( !hasIndex( index.row(), index.column(), index.parent() ) ) return false; - - Attica::Content resolver = m_contentList[ index.row() ]; - AtticaManager::ResolverState state = AtticaManager::instance()->resolverState( resolver ); - if ( role == Qt::EditRole ) + if ( isAttica( m_contentList.at( index.row() ) ) ) { - switch( state ) + Attica::Content resolver = atticaFromItem( m_contentList.at( index.row() ) ); + AtticaManager::ResolverState state = AtticaManager::instance()->resolverState( resolver ); + if ( role == Qt::EditRole ) { - case AtticaManager::Uninstalled: - // install - AtticaManager::instance()->installResolver( resolver ); - break; - case AtticaManager::Installing: - case AtticaManager::Upgrading: - // Do nothing, busy - break; - case AtticaManager::Installed: - // Uninstall - AtticaManager::instance()->uninstallResolver( resolver ); - break; - case AtticaManager::NeedsUpgrade: - AtticaManager::instance()->upgradeResolver( resolver ); - break; - default: - //FIXME -- this handles e.g. Failed - break; - }; - } else if ( role == RatingRole ) - { - // For now only allow rating if a resolver is installed! - if ( state != AtticaManager::Installed && state != AtticaManager::NeedsUpgrade ) - return false; - if ( AtticaManager::instance()->userHasRated( resolver ) ) - return false; - m_contentList[ index.row() ].setRating( value.toInt() * 20 ); - AtticaManager::instance()->uploadRating( m_contentList[ index.row() ] ); + switch( state ) + { + case AtticaManager::Uninstalled: + // install + AtticaManager::instance()->installResolver( resolver ); + break; + case AtticaManager::Installing: + case AtticaManager::Upgrading: + // Do nothing, busy + break; + case AtticaManager::Installed: + // Uninstall + AtticaManager::instance()->uninstallResolver( resolver ); + break; + case AtticaManager::NeedsUpgrade: + AtticaManager::instance()->upgradeResolver( resolver ); + break; + default: + //FIXME -- this handles e.g. Failed + break; + }; + } else if ( role == RatingRole ) + { + // For now only allow rating if a resolver is installed! + if ( state != AtticaManager::Installed && state != AtticaManager::NeedsUpgrade ) + return false; + if ( AtticaManager::instance()->userHasRated( resolver ) ) + return false; + resolver.setRating( value.toInt() * 20 ); + m_contentList[ index.row() ] = QVariant::fromValue< Attica::Content >( resolver ); + AtticaManager::instance()->uploadRating( resolver ); + } + emit dataChanged( index, index ); + } + else + { + AccountItem* item = accountFromItem( m_contentList.at( index.row() ) ); + if ( role == Qt::EditRole ) + { + // TODO + } + else if ( role == RatingRole ) + { + // TODO + } } - emit dataChanged( index, index ); return true; } + + +bool +GetNewStuffModel::isAttica( const QVariant& item ) const +{ + return qstrcmp( item.typeName(),"Attica::Content" ) == 0; +} + + +GetNewStuffModel::AccountItem* +GetNewStuffModel::accountFromItem( const QVariant& item ) const +{ + Q_ASSERT( !isAttica( item ) ); + + return item.value< GetNewStuffModel::AccountItem* >(); +} + + +Attica::Content +GetNewStuffModel::atticaFromItem( const QVariant& item ) const +{ + Q_ASSERT( isAttica( item ) ); + + return item.value< Attica::Content >(); + +} diff --git a/src/GetNewStuffModel.h b/src/GetNewStuffModel.h index 378057e1e..c2e21afba 100644 --- a/src/GetNewStuffModel.h +++ b/src/GetNewStuffModel.h @@ -19,14 +19,17 @@ #ifndef GETNEWSTUFFMODEL_H #define GETNEWSTUFFMODEL_H -#include +#include "accounts/Account.h" #include + +#include #include class GetNewStuffModel: public QAbstractListModel { Q_OBJECT + public: enum NewStuffRoles { // DisplayRole is title @@ -43,9 +46,26 @@ public: }; enum Types { - ResolverType = 0, + AtticaType = 0, + AccountType = 1 }; + enum ItemState { + Uninstalled = 0, + Installing, + Installed, + NeedsUpgrade, + Upgrading, + Failed, + CanInstallMore, // accounts that are not unique + }; + + // plz don't use me kthxbbq + typedef struct { + Tomahawk::Accounts::AccountFactory* factory; + bool alreadyExists; + } AccountItem; + explicit GetNewStuffModel( QObject* parent = 0 ); virtual ~GetNewStuffModel(); @@ -58,7 +78,14 @@ private slots: void resolverStateChanged( const QString& resolverId ); private: - Attica::Content::List m_contentList; + void loadData(); + bool isAttica( const QVariant& item ) const; + Attica::Content atticaFromItem( const QVariant& item ) const; + AccountItem* accountFromItem( const QVariant& item ) const; + + QVariantList m_contentList; }; +Q_DECLARE_METATYPE( GetNewStuffModel::AccountItem* ); + #endif // GETNEWSTUFFMODEL_H diff --git a/src/accounts/twitter/twitteraccount.h b/src/accounts/twitter/twitteraccount.h index 4746f9aae..d943b2591 100644 --- a/src/accounts/twitter/twitteraccount.h +++ b/src/accounts/twitter/twitteraccount.h @@ -46,6 +46,7 @@ public: QString prettyName() const { return "Twitter"; } QString factoryId() const { return "twitteraccount"; } + QString description() const { return tr( "Connect to your Twitter followers." ); } QPixmap icon() const { return QPixmap( ":/twitter-icon.png" ); } Account* createAccount( const QString& pluginId = QString() ); }; diff --git a/src/accounts/xmpp/googlewrapper/googlewrapper.h b/src/accounts/xmpp/googlewrapper/googlewrapper.h index fdb8fb0a0..833cf3be2 100644 --- a/src/accounts/xmpp/googlewrapper/googlewrapper.h +++ b/src/accounts/xmpp/googlewrapper/googlewrapper.h @@ -38,6 +38,7 @@ public: virtual QString prettyName() const { return "Google"; } virtual QString factoryId() const { return "googleaccount"; } + QString description() const { return tr( "Connect to GChat to find your friends" ); } virtual QPixmap icon() const; virtual Account* createAccount( const QString& pluginId ); }; diff --git a/src/accounts/xmpp/xmppaccount.h b/src/accounts/xmpp/xmppaccount.h index 905a869ff..77ba97904 100644 --- a/src/accounts/xmpp/xmppaccount.h +++ b/src/accounts/xmpp/xmppaccount.h @@ -47,6 +47,7 @@ public: virtual ~XmppAccountFactory() {} QString prettyName() const { return "XMPP (Jabber)"; } + 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-icon.png" ); } Account* createAccount( const QString& pluginId = QString() ); diff --git a/src/accounts/zeroconf/zeroconfaccount.h b/src/accounts/zeroconf/zeroconfaccount.h index 5f926a12a..726e5c5a2 100644 --- a/src/accounts/zeroconf/zeroconfaccount.h +++ b/src/accounts/zeroconf/zeroconfaccount.h @@ -39,6 +39,7 @@ public: virtual QString factoryId() const { return "zeroconfaccount"; } virtual QString prettyName() const { return "Local Network"; } + QString description() const { return tr( "Automatically connect to Tomahawks on the local network" ); } virtual bool isUnique() const { return true; } #ifndef ENABLE_HEADLESS virtual QPixmap icon() const; diff --git a/src/libtomahawk/accounts/Account.h b/src/libtomahawk/accounts/Account.h index 7a92f30e8..9513b4839 100644 --- a/src/libtomahawk/accounts/Account.h +++ b/src/libtomahawk/accounts/Account.h @@ -165,10 +165,14 @@ public: virtual QString prettyName() const = 0; // internal name virtual QString factoryId() const = 0; + // description to be shown when user views a list of account types + virtual QString description() const = 0; // if the user can create multiple - virtual QPixmap icon() const { return QPixmap(); } virtual bool isUnique() const { return false; } + virtual QPixmap icon() const { return QPixmap(); } + virtual bool allowUserCreation() const { return true; } + virtual Account* createAccount( const QString& accountId = QString() ) = 0; }; diff --git a/src/libtomahawk/accounts/ResolverAccount.h b/src/libtomahawk/accounts/ResolverAccount.h index 8d77a83e0..228479de6 100644 --- a/src/libtomahawk/accounts/ResolverAccount.h +++ b/src/libtomahawk/accounts/ResolverAccount.h @@ -36,7 +36,9 @@ public: virtual Account* createAccount(const QString& accountId = QString()); virtual QString factoryId() const { return "resolveraccount"; } + virtual QString description() const { return QString(); } virtual QString prettyName() const { return QString(); } // Internal, not displayed + virtual bool allowUserCreation() const { return false; } }; /** diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index 2000df4e0..2e26b7a43 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -61,14 +61,6 @@ using namespace Tomahawk; using namespace Accounts; -static QString -md5( const QByteArray& src ) -{ - QByteArray const digest = QCryptographicHash::hash( src, QCryptographicHash::Md5 ); - return QString::fromLatin1( digest.toHex() ).rightJustified( 32, '0' ); -} - - SettingsDialog::SettingsDialog( QWidget *parent ) : QDialog( parent ) , ui( new Ui_StackedSettingsDialog ) @@ -83,9 +75,6 @@ SettingsDialog::SettingsDialog( QWidget *parent ) TomahawkUtils::unmarginLayout( layout() ); ui->stackedWidget->setContentsMargins( 4, 4, 4, 0 ); - ui->addScript->setFixedWidth( 42 ); - ui->removeScript->setFixedWidth( ui->addScript->width() ); - ui->checkBoxReporter->setChecked( s->crashReporterEnabled() ); ui->checkBoxHttp->setChecked( s->httpEnabled() ); ui->checkBoxStaticPreferred->setChecked( s->preferStaticHostPort() ); @@ -123,6 +112,14 @@ SettingsDialog::SettingsDialog( QWidget *parent ) m_accountModel = new AccountModel( this ); ui->accountsView->setModel( m_accountModel ); + connect( ui->addNewServiceBtn, SIGNAL( clicked( bool ) ), this, SLOT( getMoreResolvers() ) ); + connect( ui->removeServiceBtn, SIGNAL( clicked( bool ) ), this, SLOT( accountDeleted( bool ) ) ); + + connect( AtticaManager::instance(), SIGNAL( resolverInstalled( QString ) ), this, SLOT( accountAdded( Tomahawk::Accounts::Account* ) ) ); + connect( AtticaManager::instance(), SIGNAL( resolverUninstalled( QString ) ), this, SLOT( accountUninstalled( QString ) ) ); + + connect( ui->accountsView->selectionModel(), SIGNAL( selectionChanged( QItemSelection,QItemSelection ) ), this, SLOT( accountsSelectionChanged() ) ); + if ( !Servent::instance()->isReady() ) { m_sipSpinner = new LoadingSpinner( ui->accountsView ); @@ -132,9 +129,6 @@ SettingsDialog::SettingsDialog( QWidget *parent ) ui->removeServiceBtn->setEnabled( false ); connect( Servent::instance(), SIGNAL( ready() ), this, SLOT( serventReady() ) ); } - - setupAccountButtons(); - ui->staticHostName->setText( s->externalHostname() ); ui->staticPort->setValue( s->externalPort() ); ui->proxyButton->setVisible( true ); @@ -178,18 +172,6 @@ SettingsDialog::SettingsDialog( QWidget *parent ) ui->pushButtonTestLastfmLogin->setVisible( false ); #endif - // SCRIPT RESOLVER - ui->removeScript->setEnabled( false ); - ui->scriptList->setVerticalScrollMode( QAbstractItemView::ScrollPerPixel ); - - connect( ui->getMoreResolvers, SIGNAL( clicked() ), this, SLOT( getMoreResolvers() ) ); - - connect( AtticaManager::instance(), SIGNAL( resolverInstalled( QString ) ), this, SLOT( atticaResolverInstalled( QString ) ) ); - connect( AtticaManager::instance(), SIGNAL( resolverUninstalled( QString ) ), this, SLOT( atticaResolverUninstalled( QString ) ) ); - - connect( ui->scriptList->selectionModel(), SIGNAL( selectionChanged( QItemSelection,QItemSelection ) ), this, SLOT( scriptSelectionChanged() ) ); - connect( ui->addScript, SIGNAL( clicked( bool ) ), this, SLOT( addScriptResolver() ) ); - connect( ui->removeScript, SIGNAL( clicked( bool ) ), this, SLOT( removeScriptResolver() ) ); connect( ui->proxyButton, SIGNAL( clicked() ), SLOT( showProxySettings() ) ); connect( ui->checkBoxStaticPreferred, SIGNAL( toggled(bool) ), SLOT( toggleUpnp(bool) ) ); connect( ui->checkBoxStaticPreferred, SIGNAL( toggled(bool) ), SLOT( requiresRestart() ) ); @@ -244,7 +226,7 @@ SettingsDialog::serventReady() { m_sipSpinner->fadeOut(); ui->addNewServiceBtn->setEnabled( true ); - ui->removeScript->setEnabled( true ); + ui->removeServiceBtn->setEnabled( true ); } @@ -310,27 +292,6 @@ SettingsDialog::createIcons() } -void -SettingsDialog::setupAccountButtons() -{ -// foreach( AccountFactory* f, AccountManager::instance()->factories() ) -// { -// if( f->isUnique() && AccountManager::instance()->hasPluginWithFactory( f->factoryId() ) ) -// { -// continue; -// } -// -// QAction* action = new QAction( f->icon(), f->prettyName(), ui->addSipButton ); -// action->setProperty( "factory", QVariant::fromValue< QObject* >( f ) ); -// ui->addSipButton->addAction( action ); -// -// connect( action, SIGNAL( triggered(bool) ), this, SLOT( factoryActionTriggered( bool ) ) ); -// } - - connect( ui->removeServiceBtn, SIGNAL( clicked( bool ) ), this, SLOT( accountDeleted( bool ) ) ); -} - - void SettingsDialog::changePage( QListWidgetItem* current, QListWidgetItem* previous ) { @@ -470,32 +431,6 @@ SettingsDialog::onLastFmFinished() #endif } -/* -void -SettingsDialog::addScriptResolver() -{ - QString resolver = QFileDialog::getOpenFileName( this, tr( "Load script resolver file" ), TomahawkSettings::instance()->scriptDefaultPath() ); - if( !resolver.isEmpty() ) - { - - QFileInfo resolverAbsoluteFilePath = resolver; - TomahawkSettings::instance()->setScriptDefaultPath( resolverAbsoluteFilePath.absolutePath() ); - } -} - - -void -SettingsDialog::removeScriptResolver() -{ - // only one selection - if( !ui->scriptList->selectionModel()->selectedIndexes().isEmpty() ) - { - QString resolver = ui->scriptList->selectionModel()->selectedIndexes().first().data( ResolversModel::ResolverPath ).toString(); - AtticaManager::instance()->uninstallResolver( resolver ); - m_resolversModel->removeResolver( resolver ); - } -}*/ - void SettingsDialog::getMoreResolvers() @@ -513,30 +448,30 @@ SettingsDialog::getMoreResolvers() } -// void -// SettingsDialog::atticaResolverInstalled( const QString& resolverId ) -// { +void +SettingsDialog::accountInstalled(Account* account) +{ // m_resolversModel->atticaResolverInstalled( resolverId ); -// } -// -// -// void -// SettingsDialog::atticaResolverUninstalled ( const QString& resolverId ) -// { -// m_resolversModel->removeResolver( AtticaManager::instance()->pathFromId( resolverId ) ); -// } +} void -SettingsDialog::scriptSelectionChanged() +SettingsDialog::accountUninstalled(const QString& acct) { - if( !ui->scriptList->selectionModel()->selectedIndexes().isEmpty() ) +// m_resolversModel->removeResolver( AtticaManager::instance()->pathFromId( resolverId ) ); +} + + +void +SettingsDialog::accountsSelectionChanged() +{ + if( !ui->accountsView->selectionModel()->selectedIndexes().isEmpty() ) { - ui->removeScript->setEnabled( true ); + ui->removeServiceBtn->setEnabled( true ); } else { - ui->removeScript->setEnabled( false ); + ui->addNewServiceBtn->setEnabled( false ); } } @@ -545,46 +480,7 @@ void SettingsDialog::getMoreResolversFinished( int ret ) { Q_UNUSED( ret ); -} - - -void -SettingsDialog::openResolverConfig( const QString& resolver ) -{ - Tomahawk::ExternalResolver* r = Tomahawk::Pipeline::instance()->resolverForPath( resolver ); - Tomahawk::ExternalResolverGui* res = qobject_cast< Tomahawk::ExternalResolverGui* >( r ); - if( res && res->configUI() ) - { -#ifndef Q_WS_MAC - DelegateConfigWrapper dialog( res->configUI(), "Resolver Configuration", this ); - QWeakPointer< DelegateConfigWrapper > watcher( &dialog ); - int ret = dialog.exec(); - if( !watcher.isNull() && ret == QDialog::Accepted ) - { - // send changed config to resolver - r->saveConfig(); - } -#else - // on osx a sheet needs to be non-modal - DelegateConfigWrapper* dialog = new DelegateConfigWrapper( res->configUI(), "Resolver Configuration", this, Qt::Sheet ); - dialog->setProperty( "resolver", QVariant::fromValue< QObject* >( res ) ); - connect( dialog, SIGNAL( finished( int ) ), this, SLOT( resolverConfigClosed( int ) ) ); - - dialog->show(); -#endif - } -} - - -void -SettingsDialog::resolverConfigClosed( int value ) -{ - if( value == QDialog::Accepted ) - { - DelegateConfigWrapper* dialog = qobject_cast< DelegateConfigWrapper* >( sender() ); - Tomahawk::ExternalResolver* r = qobject_cast< Tomahawk::ExternalResolver* >( dialog->property( "resolver" ).value< QObject* >() ); - r->saveConfig(); - } + sender()->deleteLater(); } @@ -627,20 +523,7 @@ SettingsDialog::accountConfigClosed( int value ) void -SettingsDialog::factoryActionTriggered( bool ) -{ - Q_ASSERT( sender() && qobject_cast< QAction* >( sender() ) ); - - QAction* a = qobject_cast< QAction* >( sender() ); - Q_ASSERT( qobject_cast< AccountFactory* >( a->property( "factory" ).value< QObject* >() ) ); - - AccountFactory* f = qobject_cast< AccountFactory* >( a->property( "factory" ).value< QObject* >() ); - accountFactoryClicked( f ); -} - - -void -SettingsDialog::accountFactoryClicked( AccountFactory* factory ) +SettingsDialog::createAccountFromFactory( AccountFactory* factory ) { //if exited with OK, create it, if not, delete it immediately! Account* account = factory->createAccount(); @@ -708,22 +591,6 @@ SettingsDialog::handleAccountAdded( Account* account, bool added ) TomahawkSettings::instance()->addAccount( account->accountId() ); AccountManager::instance()->addAccount( account ); AccountManager::instance()->hookupAndEnable( account ); - -// if ( f && f->isUnique() ) -// { -// // remove from actions list -// QAction* toremove = 0; -// foreach( QAction* a, ui->addSipButton->actions() ) -// { -// if( f == qobject_cast< AccountFactory* >( a->property( "factory" ).value< QObject* >() ) ) -// { -// toremove = a; -// break; -// } -// } -// if ( toremove ) -// ui->addSipButton->removeAction( toremove ); -// } } else { @@ -741,7 +608,7 @@ SettingsDialog::accountContextMenuRequest( const QPoint& p ) if( idx.isValid() ) { QList< QAction* > acts; - acts << new QAction( tr( "Delete Account" ), this ); + acts << new QAction( tr( "Delete Service" ), this ); acts.first()->setProperty( "accountplugin", idx.data( AccountModel::AccountData ) ); connect( acts.first(), SIGNAL( triggered( bool ) ), this, SLOT( onAccountRowDeleted( bool ) ) ); QMenu::exec( acts, ui->accountsView->mapToGlobal( p ) ); @@ -754,18 +621,6 @@ SettingsDialog::onAccountRowDeleted( bool ) { Account* account = qobject_cast< Account* >( qobject_cast< QAction* >( sender() )->property( "accountplugin" ).value< QObject* >() ); - if( AccountFactory* f = AccountManager::instance()->factoryForAccount( account ) ) - { -// if( f->isUnique() ) // just deleted a unique plugin->re-add to add menu -// { -// QAction* action = new QAction( f->icon(), f->prettyName(), ui->addSipButton ); -// action->setProperty( "factory", QVariant::fromValue< QObject* >( f ) ); -// ui->addSipButton->addAction( action ); -// -// connect( action, SIGNAL( triggered(bool) ), this, SLOT( factoryActionTriggered( bool ) ) ); -// } - } - AccountManager::instance()->removeAccount( account ); } @@ -780,18 +635,6 @@ SettingsDialog::accountDeleted( bool ) if( idx.isValid() ) { Account* account = qobject_cast< Account* >( idx.data( AccountModel::AccountData ).value< QObject* >() ); - - if( AccountFactory* f = AccountManager::instance()->factoryForAccount( account ) ) - { -// if( f->isUnique() ) // just deleted a unique plugin->re-add to add menu -// { -// QAction* action = new QAction( f->icon(), f->prettyName(), ui->addSipButton ); -// action->setProperty( "factory", QVariant::fromValue< QObject* >( f ) ); -// ui->addSipButton->addAction( action ); -// -// connect( action, SIGNAL( triggered(bool) ), this, SLOT( factoryActionTriggered( bool ) ) ); -// } - } AccountManager::instance()->removeAccount( account ); } } diff --git a/src/settingsdialog.h b/src/settingsdialog.h index b0a26a482..de2e948e1 100644 --- a/src/settingsdialog.h +++ b/src/settingsdialog.h @@ -45,6 +45,7 @@ namespace Tomahawk class AccountModel; class Account; class AccountFactory; +class Account; } } @@ -87,21 +88,18 @@ private slots: void testLastFmLogin(); void onLastFmFinished(); - void scriptSelectionChanged(); - void getMoreResolvers(); - void getMoreResolversFinished( int ); - - void openResolverConfig( const QString& ); - void openAccountConfig( Tomahawk::Accounts::Account* ); - void factoryActionTriggered ( bool ); - void accountFactoryClicked( Tomahawk::Accounts::AccountFactory* ); + void createAccountFromFactory( Tomahawk::Accounts::AccountFactory* ); void accountContextMenuRequest( const QPoint& ); void accountDeleted( bool ); void onAccountRowDeleted( bool ); - // dialog slots - void resolverConfigClosed( int value ); + void accountsSelectionChanged(); + void getMoreResolvers(); + void getMoreResolversFinished( int ); + + void accountInstalled( Tomahawk::Accounts::Account* account ); + void accountUninstalled( const QString& acct ); void accountConfigClosed( int value ); void accountCreateConfigClosed( int value ); @@ -115,7 +113,6 @@ private slots: private: void createIcons(); - void setupAccountButtons(); void handleAccountAdded( Tomahawk::Accounts::Account* p, bool added ); Ui_StackedSettingsDialog* ui; diff --git a/src/stackedsettingsdialog.ui b/src/stackedsettingsdialog.ui index b26f638b5..e0e1620f0 100644 --- a/src/stackedsettingsdialog.ui +++ b/src/stackedsettingsdialog.ui @@ -365,107 +365,6 @@ - - - - 0 - - - - - Script Resolvers - - - - 2 - - - - - Script resolvers search for a given track to make it playable. - - - - - - - Get more resolvers... - - - - - - - - - true - - - QAbstractItemView::SingleSelection - - - false - - - true - - - false - - - true - - - true - - - - - - - - - - - - - :/data/images/list-add.png:/data/images/list-add.png - - - - - - - - - - - :/data/images/list-remove.png:/data/images/list-remove.png - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - From b300279e30abc09f30fd9d3def6a3ed2fb7bc3a3 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 27 Jan 2012 18:32:25 -0500 Subject: [PATCH 039/104] remove Resolver from settings list --- src/settingsdialog.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index 2e26b7a43..40a362f3f 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -262,13 +262,6 @@ SettingsDialog::createIcons() lastfmButton->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled ); maxlen = qMax( fm.width( lastfmButton->text() ), maxlen ); - QListWidgetItem *resolversButton = new QListWidgetItem( ui->listWidget ); - resolversButton->setIcon( QIcon( RESPATH "images/resolvers-settings.png" ) ); - resolversButton->setText( tr( "Resolvers" ) ); - resolversButton->setTextAlignment( Qt::AlignHCenter ); - resolversButton->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled ); - maxlen = qMax( fm.width( resolversButton->text() ), maxlen ); - QListWidgetItem *advancedButton = new QListWidgetItem( ui->listWidget ); advancedButton->setIcon( QIcon( RESPATH "images/advanced-settings.png" ) ); advancedButton->setText( tr( "Advanced" ) ); @@ -280,7 +273,6 @@ SettingsDialog::createIcons() accountsButton->setSizeHint( QSize( maxlen, 60 ) ); musicButton->setSizeHint( QSize( maxlen, 60 ) ); lastfmButton->setSizeHint( QSize( maxlen, 60 ) ); - resolversButton->setSizeHint( QSize( maxlen, 60 ) ); advancedButton->setSizeHint( QSize( maxlen, 60 ) ); #ifndef Q_WS_MAC From 4e450b36ee4147f83c1ff77df2c1fa036b67998b Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 27 Jan 2012 19:10:11 -0500 Subject: [PATCH 040/104] implement adding in getnewstuffmodel for attica resolvers --- src/libtomahawk/AtticaManager.cpp | 5 ++ src/libtomahawk/accounts/ResolverAccount.cpp | 56 +++++++++++++++++--- src/libtomahawk/accounts/ResolverAccount.h | 13 +++++ 3 files changed, 68 insertions(+), 6 deletions(-) diff --git a/src/libtomahawk/AtticaManager.cpp b/src/libtomahawk/AtticaManager.cpp index 26a4838d4..eeab67066 100644 --- a/src/libtomahawk/AtticaManager.cpp +++ b/src/libtomahawk/AtticaManager.cpp @@ -32,6 +32,8 @@ #include #include "utils/logger.h" +#include "accounts/ResolverAccount.h" +#include "accounts/AccountManager.h" using namespace Attica; @@ -374,6 +376,9 @@ AtticaManager::payloadFetched() // Do the install / add to tomahawk Tomahawk::Pipeline::instance()->addScriptResolver( resolverPath, true ); + Tomahawk::Accounts::Account* resolver = Tomahawk::Accounts::ResolverAccountFactory::createFromPath( resolverPath, true ); + Tomahawk::Accounts::AccountManager::instance()->addAccount( resolver ); + m_resolverStates[ resolverId ].state = Installed; TomahawkSettingsGui::instanceGui()->setAtticaResolverStates( m_resolverStates ); emit resolverInstalled( resolverId ); diff --git a/src/libtomahawk/accounts/ResolverAccount.cpp b/src/libtomahawk/accounts/ResolverAccount.cpp index c2408f10d..72c1dc575 100644 --- a/src/libtomahawk/accounts/ResolverAccount.cpp +++ b/src/libtomahawk/accounts/ResolverAccount.cpp @@ -45,6 +45,16 @@ ResolverAccountFactory::createAccount( const QString& accountId ) } +Account* +ResolverAccountFactory::createFromPath( const QString& path, bool isAttica ) +{ + if ( isAttica ) + return new AtticaResolverAccount( generateId( "resolveraccount" ), path ); + else + return new ResolverAccount( generateId( "resolveraccount" ), path ); +} + + ResolverAccount::ResolverAccount( const QString& accountId ) : Account( accountId ) { @@ -65,6 +75,25 @@ ResolverAccount::ResolverAccount( const QString& accountId ) } +ResolverAccount::ResolverAccount( const QString& accountId, const QString& path ) + : Account( accountId ) +{ + QVariantHash configuration; + configuration[ "path" ] = path; + setConfiguration( configuration ); + setEnabled( true ); + + m_resolver = qobject_cast< ExternalResolverGui* >( Pipeline::instance()->addScriptResolver( path, true ) ); + connect( m_resolver, SIGNAL( changed() ), this, SLOT( resolverChanged() ) ); + + // What resolver do we have here? Should only be types that are 'real' resolvers + Q_ASSERT ( m_resolver ); + + setAccountFriendlyName( m_resolver->name() ); + setTypes( AccountType( ResolverType ) ); +} + + ResolverAccount::~ResolverAccount() { delete m_resolver; @@ -152,19 +181,34 @@ ResolverAccount::resolverChanged() AtticaResolverAccount::AtticaResolverAccount( const QString& accountId ) : ResolverAccount( accountId ) { - const QFileInfo fi( m_resolver->filePath() ); - QDir codeDir = fi.absoluteDir(); - codeDir.cd( "../images" ); - - if ( codeDir.exists() && codeDir.exists( "icon.png" ) ) - m_icon.load( codeDir.absoluteFilePath( "icon.png" ) ); + loadIcon(); } +AtticaResolverAccount::AtticaResolverAccount( const QString& accountId, const QString& path ) + : ResolverAccount( accountId, path ) +{ + loadIcon(); +} + + AtticaResolverAccount::~AtticaResolverAccount() { } +void +AtticaResolverAccount::loadIcon() +{ + const QFileInfo fi( m_resolver->filePath() ); + QDir codeDir = fi.absoluteDir(); + codeDir.cd( "../images" ); + + if ( codeDir.exists() && codeDir.exists( "icon.png" ) ) + m_icon.load( codeDir.absoluteFilePath( "icon.png" ) ); + +} + + QPixmap AtticaResolverAccount::icon() const { diff --git a/src/libtomahawk/accounts/ResolverAccount.h b/src/libtomahawk/accounts/ResolverAccount.h index 228479de6..88cf0c7e3 100644 --- a/src/libtomahawk/accounts/ResolverAccount.h +++ b/src/libtomahawk/accounts/ResolverAccount.h @@ -39,6 +39,10 @@ public: virtual QString description() const { return QString(); } virtual QString prettyName() const { return QString(); } // Internal, not displayed virtual bool allowUserCreation() const { return false; } + + // Used to create a new resolver from a script on disk, either chosen by + // the user, or installed from synchrotron + static Account* createFromPath( const QString& path, bool isAttica ); }; /** @@ -74,7 +78,10 @@ private slots: void resolverChanged(); protected: + ResolverAccount( const QString& accountId, const QString& path ); ExternalResolverGui* m_resolver; + + friend class ResolverAccountFactory; }; @@ -92,7 +99,13 @@ public: virtual QPixmap icon() const; private: + AtticaResolverAccount( const QString& accountId, const QString& path ); + + void loadIcon(); + QPixmap m_icon; + + friend class ResolverAccountFactory; }; } From b78a34871206020664dbca4423cf100a8ba3bcff Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sat, 28 Jan 2012 12:15:51 -0500 Subject: [PATCH 041/104] small work --- src/libtomahawk/accounts/ResolverAccount.cpp | 7 +++++++ src/libtomahawk/accounts/ResolverAccount.h | 2 ++ 2 files changed, 9 insertions(+) diff --git a/src/libtomahawk/accounts/ResolverAccount.cpp b/src/libtomahawk/accounts/ResolverAccount.cpp index 72c1dc575..fd4723dc9 100644 --- a/src/libtomahawk/accounts/ResolverAccount.cpp +++ b/src/libtomahawk/accounts/ResolverAccount.cpp @@ -168,6 +168,13 @@ void ResolverAccount::saveConfig() } +QString +ResolverAccount::path() const +{ + return m_resolver->filePath(); +} + + void ResolverAccount::resolverChanged() { diff --git a/src/libtomahawk/accounts/ResolverAccount.h b/src/libtomahawk/accounts/ResolverAccount.h index 88cf0c7e3..28755bc46 100644 --- a/src/libtomahawk/accounts/ResolverAccount.h +++ b/src/libtomahawk/accounts/ResolverAccount.h @@ -68,6 +68,8 @@ public: virtual void saveConfig(); virtual void removeFromConfig(); + QString path() const; + // Not relevant virtual QPixmap icon() const { return QPixmap(); } virtual SipPlugin* sipPlugin() { return 0; } From 7e13f1ae62cc22e4c9baedf71d046470483f780e Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sun, 29 Jan 2012 10:04:20 -0500 Subject: [PATCH 042/104] Hook up some removing --- src/libtomahawk/AtticaManager.cpp | 16 ++++++++++++++++ src/libtomahawk/accounts/ResolverAccount.cpp | 15 +++++++++++++-- src/libtomahawk/accounts/ResolverAccount.h | 10 ++++++++-- src/libtomahawk/tomahawksettings.cpp | 7 ++++++- src/settingsdialog.cpp | 1 - 5 files changed, 43 insertions(+), 6 deletions(-) diff --git a/src/libtomahawk/AtticaManager.cpp b/src/libtomahawk/AtticaManager.cpp index eeab67066..54f8fcd87 100644 --- a/src/libtomahawk/AtticaManager.cpp +++ b/src/libtomahawk/AtticaManager.cpp @@ -464,6 +464,9 @@ AtticaManager::extractPayload( const QString& filename, const QString& resolverI void AtticaManager::uninstallResolver( const QString& pathToResolver ) { + // when is this used? find and fix + Q_ASSERT(false); + // User manually removed a resolver not through attica dialog, simple remove QRegExp r( ".*([^/]*)/contents/code/main.js" ); r.indexIn( pathToResolver ); @@ -495,6 +498,19 @@ AtticaManager::uninstallResolver( const Content& resolver ) m_resolverStates[ resolver.id() ].state = Uninstalled; TomahawkSettingsGui::instanceGui()->setAtticaResolverState( resolver.id(), Uninstalled ); + + // remove account as well + QList< Tomahawk::Accounts::Account* > accounts = Tomahawk::Accounts::AccountManager::instance()->accounts( Tomahawk::Accounts::ResolverType ); + foreach ( Tomahawk::Accounts::Account* account, accounts ) + { + if ( Tomahawk::Accounts::AtticaResolverAccount* atticaAccount = qobject_cast< Tomahawk::Accounts::AtticaResolverAccount* >( account ) ) + { + if ( atticaAccount->atticaId() == resolver.id() ) // this is the account we want to remove + { + Tomahawk::Accounts::AccountManager::instance()->removeAccount( atticaAccount ); + } + } + } } Tomahawk::Pipeline::instance()->removeScriptResolver( pathFromId( resolver.id() ) ); diff --git a/src/libtomahawk/accounts/ResolverAccount.cpp b/src/libtomahawk/accounts/ResolverAccount.cpp index fd4723dc9..cb33caf09 100644 --- a/src/libtomahawk/accounts/ResolverAccount.cpp +++ b/src/libtomahawk/accounts/ResolverAccount.cpp @@ -49,7 +49,10 @@ Account* ResolverAccountFactory::createFromPath( const QString& path, bool isAttica ) { if ( isAttica ) - return new AtticaResolverAccount( generateId( "resolveraccount" ), path ); + { + QFileInfo info( path ); + return new AtticaResolverAccount( generateId( "resolveraccount" ), path, info.baseName() ); + } else return new ResolverAccount( generateId( "resolveraccount" ), path ); } @@ -159,11 +162,13 @@ void ResolverAccount::removeFromConfig() { // TODO + Account::removeFromConfig(); } void ResolverAccount::saveConfig() { + Account::saveConfig(); m_resolver->saveConfig(); } @@ -188,12 +193,18 @@ ResolverAccount::resolverChanged() AtticaResolverAccount::AtticaResolverAccount( const QString& accountId ) : ResolverAccount( accountId ) { + m_atticaId = configuration().value( "atticaId" ).toString(); loadIcon(); } -AtticaResolverAccount::AtticaResolverAccount( const QString& accountId, const QString& path ) +AtticaResolverAccount::AtticaResolverAccount( const QString& accountId, const QString& path, const QString& atticaId ) : ResolverAccount( accountId, path ) + , m_atticaId( atticaId ) { + QVariantHash conf = configuration(); + conf[ "atticaid" ] = atticaId; + setConfiguration( conf ); + loadIcon(); } diff --git a/src/libtomahawk/accounts/ResolverAccount.h b/src/libtomahawk/accounts/ResolverAccount.h index 28755bc46..9ee94bee4 100644 --- a/src/libtomahawk/accounts/ResolverAccount.h +++ b/src/libtomahawk/accounts/ResolverAccount.h @@ -54,6 +54,7 @@ class ResolverAccount : public Account { Q_OBJECT public: + // Loads from config. Must already exist. explicit ResolverAccount( const QString& accountId ); virtual ~ResolverAccount(); @@ -80,6 +81,7 @@ private slots: void resolverChanged(); protected: + // Created by factory, when user installs a new resolver ResolverAccount( const QString& accountId, const QString& path ); ExternalResolverGui* m_resolver; @@ -95,17 +97,21 @@ class AtticaResolverAccount : public ResolverAccount { Q_OBJECT public: - explicit AtticaResolverAccount(const QString& accountId); + // Loads from config + explicit AtticaResolverAccount( const QString& accountId ); virtual ~AtticaResolverAccount(); virtual QPixmap icon() const; + QString atticaId() const { return m_atticaId; } private: - AtticaResolverAccount( const QString& accountId, const QString& path ); + // Created by factory, when user installs a new resolver + AtticaResolverAccount( const QString& accountId, const QString& path, const QString& atticaId ); void loadIcon(); QPixmap m_icon; + QString m_atticaId; friend class ResolverAccountFactory; }; diff --git a/src/libtomahawk/tomahawksettings.cpp b/src/libtomahawk/tomahawksettings.cpp index 455ea29ff..b07564cd3 100644 --- a/src/libtomahawk/tomahawksettings.cpp +++ b/src/libtomahawk/tomahawksettings.cpp @@ -273,12 +273,17 @@ TomahawkSettings::doUpgrade( int oldVersion, int newVersion ) QVariantHash configuration; configuration[ "path" ] = resolver; - setValue( "configuration", configuration ); // reasonably ugly check for attica resolvers if ( resolver.contains( "atticaresolvers" ) && resolver.contains( "code" ) ) + { setValue( "atticaresolver", true ); + QFileInfo info( resolver ); + configuration[ "atticaId" ] = info.baseName(); + } + + setValue( "configuration", configuration ); endGroup(); } diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index 40a362f3f..4c254525f 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -573,7 +573,6 @@ SettingsDialog::accountCreateConfigClosed( int finished ) void SettingsDialog::handleAccountAdded( Account* account, bool added ) { - AccountFactory* f = AccountManager::instance()->factoryForAccount( account ); if ( added ) { account->setEnabled( true ); From ddb4bd4563c0ed1f297efa8bd976eb98a5d17a8e Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sun, 29 Jan 2012 13:38:22 -0500 Subject: [PATCH 043/104] Move qdatastream registration to before settings init --- src/libtomahawk/TomahawkSettingsGui.cpp | 36 ------------------------- src/main.cpp | 36 +++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/libtomahawk/TomahawkSettingsGui.cpp b/src/libtomahawk/TomahawkSettingsGui.cpp index b9b95bfc1..4337d030b 100644 --- a/src/libtomahawk/TomahawkSettingsGui.cpp +++ b/src/libtomahawk/TomahawkSettingsGui.cpp @@ -32,42 +32,8 @@ // #include "database/databasecommand_updatesearchindex.h" // #include "database/database.h" -#define VERSION 5 - using namespace Tomahawk; -inline QDataStream& operator<<(QDataStream& out, const AtticaManager::StateHash& states) -{ - out << VERSION; - out << (quint32)states.count(); - foreach( const QString& key, states.keys() ) - { - AtticaManager::Resolver resolver = states[ key ]; - out << key << resolver.version << resolver.scriptPath << (qint32)resolver.state << resolver.userRating; - } - return out; -} - - -inline QDataStream& operator>>(QDataStream& in, AtticaManager::StateHash& states) -{ - quint32 count = 0, version = 0; - in >> version; - in >> count; - for ( uint i = 0; i < count; i++ ) - { - QString key, version, scriptPath; - qint32 state, userRating; - in >> key; - in >> version; - in >> scriptPath; - in >> state; - in >> userRating; - states[ key ] = AtticaManager::Resolver( version, scriptPath, userRating, (AtticaManager::ResolverState)state ); - } - return in; -} - TomahawkSettingsGui* TomahawkSettingsGui::instanceGui() { @@ -78,8 +44,6 @@ TomahawkSettingsGui::instanceGui() TomahawkSettingsGui::TomahawkSettingsGui( QObject* parent ) : TomahawkSettings( parent ) { - qRegisterMetaType< AtticaManager::StateHash >( "AtticaManager::StateHash" ); - qRegisterMetaTypeStreamOperators("AtticaManager::StateHash"); } diff --git a/src/main.cpp b/src/main.cpp index b561d21f8..7d8516b9a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -36,6 +36,38 @@ #include "breakpad/BreakPad.h" #endif +inline QDataStream& operator<<(QDataStream& out, const AtticaManager::StateHash& states) +{ + out << TOMAHAWK_SETTINGS_VERSION; + out << (quint32)states.count(); + foreach( const QString& key, states.keys() ) + { + AtticaManager::Resolver resolver = states[ key ]; + out << key << resolver.version << resolver.scriptPath << (qint32)resolver.state << resolver.userRating; + } + return out; +} + + +inline QDataStream& operator>>(QDataStream& in, AtticaManager::StateHash& states) +{ + quint32 count = 0, version = 0; + in >> version; + in >> count; + for ( uint i = 0; i < count; i++ ) + { + QString key, version, scriptPath; + qint32 state, userRating; + in >> key; + in >> version; + in >> scriptPath; + in >> state; + in >> userRating; + states[ key ] = AtticaManager::Resolver( version, scriptPath, userRating, (AtticaManager::ResolverState)state ); + } + return in; +} + int main( int argc, char *argv[] ) { @@ -60,6 +92,10 @@ main( int argc, char *argv[] ) TomahawkApp a( argc, argv ); + // MUST register StateHash ****before*** initing TomahawkSettingsGui as constructor of settings does upgrade before Gui subclass registers type + qRegisterMetaType< AtticaManager::StateHash >( "AtticaManager::StateHash" ); + qRegisterMetaTypeStreamOperators("AtticaManager::StateHash"); + #ifdef ENABLE_HEADLESS new TomahawkSettings( &a ); #else From 9607d6be003be36698e661d1e6b37e749e3b9bd7 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sun, 29 Jan 2012 13:38:43 -0500 Subject: [PATCH 044/104] remove duplicated signal --- src/sourcetree/items/categoryitems.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/sourcetree/items/categoryitems.h b/src/sourcetree/items/categoryitems.h index c1e3dcadd..0b9697955 100644 --- a/src/sourcetree/items/categoryitems.h +++ b/src/sourcetree/items/categoryitems.h @@ -75,9 +75,6 @@ public: SourcesModel::CategoryType categoryType() { return m_category; } -signals: - void toggleExpandRequest( SourceTreeItem* ); - private: SourcesModel::CategoryType m_category; CategoryAddItem* m_addItem; From e8eb7300fc40f79bdce0175115fae30051c858cb Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sun, 29 Jan 2012 13:43:21 -0500 Subject: [PATCH 045/104] i = iniMap.constFind(sections.at(j)); Q_ASSERT(i != iniMap.constEnd()); Consolidate version macro... --- src/libtomahawk/tomahawksettings.cpp | 12 +++++------- src/libtomahawk/tomahawksettings.h | 3 +++ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/libtomahawk/tomahawksettings.cpp b/src/libtomahawk/tomahawksettings.cpp index b07564cd3..d456b1879 100644 --- a/src/libtomahawk/tomahawksettings.cpp +++ b/src/libtomahawk/tomahawksettings.cpp @@ -30,8 +30,6 @@ #include "database/databasecommand_updatesearchindex.h" #include "database/database.h" -#define VERSION 6 - using namespace Tomahawk; TomahawkSettings* TomahawkSettings::s_instance = 0; @@ -50,24 +48,24 @@ TomahawkSettings::TomahawkSettings( QObject* parent ) if( !contains( "configversion") ) { - setValue( "configversion", VERSION ); + setValue( "configversion", TOMAHAWK_SETTINGS_VERSION ); doInitialSetup(); } - else if( value( "configversion" ).toUInt() != VERSION ) + else if( value( "configversion" ).toUInt() != TOMAHAWK_SETTINGS_VERSION ) { qDebug() << "Config version outdated, old:" << value( "configversion" ).toUInt() - << "new:" << VERSION + << "new:" << TOMAHAWK_SETTINGS_VERSION << "Doing upgrade, if any..."; int current = value( "configversion" ).toUInt(); - while( current < VERSION ) + while( current < TOMAHAWK_SETTINGS_VERSION ) { doUpgrade( current, current + 1 ); current++; } // insert upgrade code here as required - setValue( "configversion", VERSION ); + setValue( "configversion", TOMAHAWK_SETTINGS_VERSION ); } } diff --git a/src/libtomahawk/tomahawksettings.h b/src/libtomahawk/tomahawksettings.h index de288dcfb..184e5ffcb 100644 --- a/src/libtomahawk/tomahawksettings.h +++ b/src/libtomahawk/tomahawksettings.h @@ -26,6 +26,9 @@ #include #include "dllmacro.h" + +#define TOMAHAWK_SETTINGS_VERSION 6 + /** * Convenience wrapper around QSettings for tomahawk-specific config */ From f2b1cc6ae3ac53b04a64a36e63a026ac881865cf Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sun, 29 Jan 2012 15:02:21 -0500 Subject: [PATCH 046/104] fix looping over account existing --- src/GetNewStuffModel.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/GetNewStuffModel.cpp b/src/GetNewStuffModel.cpp index e80093cdf..412e6d7da 100644 --- a/src/GetNewStuffModel.cpp +++ b/src/GetNewStuffModel.cpp @@ -72,7 +72,10 @@ GetNewStuffModel::loadData() foreach ( Account* acct, allAccounts ) { if ( AccountManager::instance()->factoryForAccount( acct ) == fac ) + { item->alreadyExists = true; + break; + } else item->alreadyExists = false; } From 8eba4c171f630100f97a976e16dff9d2b5ac2032 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sun, 29 Jan 2012 19:33:12 -0500 Subject: [PATCH 047/104] Begin work on overhauled account UI, again --- src/AccountDelegate.h | 2 +- src/CMakeLists.txt | 4 +- src/libtomahawk/TomahawkSettingsGui.cpp | 11 - src/libtomahawk/accounts/AccountModel.cpp | 374 +++++++++++++------- src/libtomahawk/accounts/AccountModel.h | 114 +++--- src/libtomahawk/accounts/AccountModelNode.h | 145 ++++++++ src/settingsdialog.cpp | 20 +- src/stackedsettingsdialog.ui | 4 +- 8 files changed, 483 insertions(+), 191 deletions(-) create mode 100644 src/libtomahawk/accounts/AccountModelNode.h diff --git a/src/AccountDelegate.h b/src/AccountDelegate.h index a15c82910..bd1f9b638 100644 --- a/src/AccountDelegate.h +++ b/src/AccountDelegate.h @@ -42,7 +42,7 @@ public: virtual QRect checkRectForIndex( const QStyleOptionViewItem &option, const QModelIndex &idx, int role ) const; virtual QRect configRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const; - virtual QList extraCheckRoles() const { return QList() << (int)AccountModel::AccountTypeRole; } +// virtual QList extraCheckRoles() const { return QList() << (int)AccountModel::AccountTypeRole; } private slots: void askedForEdit( const QModelIndex& idx ); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 31591e961..a2d75f978 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -75,7 +75,7 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui} settingsdialog.cpp diagnosticsdialog.cpp configdelegatebase.cpp - AccountDelegate.cpp +# AccountDelegate.cpp settingslistdelegate.cpp tomahawkwindow.cpp LoadXSPFDialog.cpp @@ -125,7 +125,7 @@ SET( tomahawkHeadersGui ${tomahawkHeadersGui} settingsdialog.h diagnosticsdialog.h configdelegatebase.h - AccountDelegate.h +# AccountDelegate.h settingslistdelegate.h delegateconfigwrapper.h tomahawkwindow.h diff --git a/src/libtomahawk/TomahawkSettingsGui.cpp b/src/libtomahawk/TomahawkSettingsGui.cpp index 4337d030b..32f70a4b8 100644 --- a/src/libtomahawk/TomahawkSettingsGui.cpp +++ b/src/libtomahawk/TomahawkSettingsGui.cpp @@ -21,17 +21,6 @@ #include #include "settingsdialog.h" -// #include -// -// #include "sip/SipHandler.h" -// #include "playlistinterface.h" -// -// #include "utils/logger.h" -// #include "utils/tomahawkutils.h" -// -// #include "database/databasecommand_updatesearchindex.h" -// #include "database/database.h" - using namespace Tomahawk; TomahawkSettingsGui* diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index 80f04444b..322a57222 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -1,156 +1,288 @@ - /* - Copyright (C) 2011 Leo Franchi - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Leo Franchi + * + * 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 "AccountModel.h" -#include "tomahawksettings.h" -#include "accounts/AccountManager.h" -#include "accounts/Account.h" +#include "Account.h" +#include "AccountModelNode.h" +#include "AccountManager.h" +#include "AtticaManager.h" +#include "ResolverAccount.h" -#include "utils/logger.h" +#include using namespace Tomahawk; using namespace Accounts; AccountModel::AccountModel( QObject* parent ) - : QAbstractListModel( parent ) + : QAbstractItemModel( parent ) + , m_rootItem( 0 ) { - connect( AccountManager::instance(), SIGNAL( added( Tomahawk::Accounts::Account* ) ), this, SLOT( accountAdded( Tomahawk::Accounts::Account* ) ) ); - connect( AccountManager::instance(), SIGNAL( removed( Tomahawk::Accounts::Account* ) ), this, SLOT( accountRemoved( Tomahawk::Accounts::Account* ) ) ); + loadData(); } - -AccountModel::~AccountModel() +void +AccountModel::loadData() { + beginResetModel(); + + delete m_rootItem; + + m_rootItem = new AccountModelNode(); + // Add all factories + QList< AccountFactory* > factories = AccountManager::instance()->factories(); + QList< Account* > allAccounts = AccountManager::instance()->accounts(); + foreach ( AccountFactory* fac, factories ) + { + if ( !fac->allowUserCreation() ) + continue; + + qDebug() << "Creating factory node:" << fac->prettyName(); + new AccountModelNode( m_rootItem, fac ); + } + + // add all attica resolvers (installed or uninstalled) + Attica::Content::List fromAttica = AtticaManager::instance()->resolvers(); + foreach ( const Attica::Content& content, fromAttica ) + new AccountModelNode( m_rootItem, content ); + + // Add all non-attica manually installed resolvers + foreach ( Account* acct, allAccounts ) + { + if ( qobject_cast< ResolverAccount* >( acct ) && !qobject_cast< AtticaResolverAccount* >( acct ) ) + { + new AccountModelNode( m_rootItem, qobject_cast< ResolverAccount* >( acct ) ); + } + } + } QVariant AccountModel::data( const QModelIndex& index, int role ) const { - if( !index.isValid() ) + if ( !index.isValid() ) return QVariant(); - QList< Account* > accounts = AccountManager::instance()->accounts(); - Q_ASSERT( index.row() <= accounts.size() ); - Account* account = accounts[ index.row() ]; - switch( role ) - { - case Qt::DisplayRole: - case AccountModel::AccountName: - return account->accountFriendlyName(); - case AccountModel::ConnectionStateRole: - return account->connectionState(); - case AccountModel::HasConfig: - return ( account->configurationWidget() != 0 ); - case AccountModel::AccountTypeRole: - return (int)account->types(); - case Qt::DecorationRole: - return account->icon(); - case AccountModel::AccountData: - return QVariant::fromValue< QObject* >( account ); - case Qt::CheckStateRole: - return account->enabled() ? Qt::Checked : Qt::Unchecked; - default: + if ( !hasIndex( index.row(), index.column(), index.parent() ) ) return QVariant(); + + AccountModelNode* node = nodeFromIndex( index ); + if ( node->parent == m_rootItem ) { + // This is a top-level item. 3 cases + Q_ASSERT( node->type != AccountModelNode::AccountType ); // must not be of this type, these should be children (other branch of if) + + switch ( node->type ) + { + case AccountModelNode::FactoryType: + { + AccountFactory* fac = node->factory; + Q_ASSERT( fac ); + + switch ( role ) + { + case Qt::DisplayRole: + return fac->prettyName(); + case Qt::DecorationRole: + return fac->icon(); + case StateRole: + return ShippedWithTomahawk; + case AccountDescription: + return fac->description(); + case AuthorRole: + return "Tomahawk Team"; + case RowType: + return TopLevelFactory; + default: + return QVariant(); + } + } + case AccountModelNode::AtticaType: + { + Attica::Content c = node->atticaContent; + Q_ASSERT( !c.id().isNull() ); + + switch( role ) + { + case Qt::DisplayRole: + return c.name(); + case Qt::DecorationRole: + return QVariant::fromValue< QPixmap >( AtticaManager::instance()->iconForResolver( c ) ); + case StateRole: + return (int)AtticaManager::instance()->resolverState( c ); + case AccountDescription: + return c.description(); + case AuthorRole: + return c.author(); + case RatingRole: + return c.rating() / 20; // rating is out of 100 + case DownloadCounterRole: + return c.downloads(); + case VersionRole: + return c.version(); + case UserHasRatedRole: + return AtticaManager::instance()->userHasRated( c ); + default: + ; + } + + AtticaResolverAccount* atticaAcct = node->atticaAccount; + if ( atticaAcct ) + { + // If the resolver is installed or on disk, we expose some additional data + switch ( role ) + { + case HasConfig: + return atticaAcct->configurationWidget() != 0; + case Qt::CheckStateRole: + return atticaAcct->enabled() ? Qt::Checked : Qt::Unchecked; + case AccountData: + return QVariant::fromValue< QObject* >( atticaAcct ); + case RowType: + return TopLevelAccount; + case ConnectionStateRole: + return atticaAcct->connectionState(); + default: + ; + } + } + return QVariant(); + } + case AccountModelNode::ManualResolverType: + { + ResolverAccount* resolver = node->resolverAccount; + Q_ASSERT( resolver ); + + switch ( role ) + { + case Qt::DisplayRole: + return resolver->accountFriendlyName(); + case Qt::DecorationRole: + return resolver->icon(); + case AccountDescription: + return QString(); + case Qt::CheckStateRole: + return resolver->enabled() ? Qt::Checked : Qt::Unchecked; + case AccountData: + return QVariant::fromValue< QObject* >( resolver ); + case RowType: + return TopLevelAccount; + case ConnectionStateRole: + return resolver->connectionState(); + default: + return QVariant(); + } + } + } } + else + { + // This is a child account* of an accountfactory* + Q_ASSERT( node->type == AccountModelNode::AccountType ); + Q_ASSERT( node->children.isEmpty() ); + Q_ASSERT( node->account ); + + Account* acc = node->account; + switch ( role ) + { + case RowType: + return ChildAccount; + case Qt::DisplayRole: + return acc->accountFriendlyName(); + case ConnectionStateRole: + return acc->connectionState(); + case HasConfig: + return ( acc->configurationWidget() != 0 ); + case ErrorString: + return acc->errorMessage(); + case Qt::CheckStateRole: + return acc->enabled() ? Qt::Checked : Qt::Unchecked; + case AccountData: + return QVariant::fromValue< QObject* >( acc ); + default: + return QVariant(); + } + } + return QVariant(); } - -bool -AccountModel::setData( const QModelIndex& index, const QVariant& value, int role ) +int +AccountModel::columnCount( const QModelIndex& parent ) const { - Q_ASSERT( index.isValid() && index.row() <= AccountManager::instance()->accounts().count() ); - - if ( role == Qt::CheckStateRole ) { - Qt::CheckState state = static_cast< Qt::CheckState >( value.toInt() ); - QList< Account* > accounts = AccountManager::instance()->accounts(); - Account* account = accounts[ index.row() ]; - - if( state == Qt::Checked && !account->enabled() ) { - AccountManager::instance()->enableAccount( account ); - } else if( state == Qt::Unchecked ) { - AccountManager::instance()->disableAccount( account ); - } - - account->sync(); - dataChanged( index, index ); - - return true; - } - else if ( role == AccountTypeRole ) - { - // TODO - } - return false; + return 1; } int -AccountModel::rowCount( const QModelIndex& ) const +AccountModel::rowCount( const QModelIndex& parent ) const { - return AccountManager::instance()->accounts().size(); -} - -Qt::ItemFlags -AccountModel::flags( const QModelIndex& index ) const -{ - return QAbstractListModel::flags( index ) | Qt::ItemIsUserCheckable; -} - - -void -AccountModel::accountAdded( Account* account ) -{ - // TODO HACK we assume account plugins are added at the end of the list. - Q_ASSERT( AccountManager::instance()->accounts().last() == account ); - if ( account->types() & SipType ) - connect( account, SIGNAL( connectionStateChanged( Tomahawk::Accounts::Account::ConnectionState ) ), this, SLOT( accountStateChanged( Tomahawk::Accounts::Account::ConnectionState ) ) ); - - int size = AccountManager::instance()->accounts().count() - 1; - beginInsertRows( QModelIndex(), size, size ); - endInsertRows(); -} - - -void -AccountModel::accountRemoved( Account* account ) -{ - int idx = AccountManager::instance()->accounts().indexOf( account ); - beginRemoveRows( QModelIndex(), idx, idx ); - endRemoveRows(); -} - - -void -AccountModel::accountStateChanged( Tomahawk::Accounts::Account::ConnectionState ) -{ - Account* account = qobject_cast< Account* >( sender() ); - Q_ASSERT( account ); - - for ( int i = 0; i < AccountManager::instance()->accounts().size(); i++ ) + if ( !parent.isValid() ) { - if ( AccountManager::instance()->accounts()[i] == account ) - { - QModelIndex idx = index( i, 0, QModelIndex() ); - emit dataChanged( idx, idx ); - return; - } + return m_rootItem->children.count(); } + + // If it's a top-level item, return child count. Only factories will have any. + return nodeFromIndex( parent )->children.count(); } +QModelIndex +AccountModel::parent( const QModelIndex& child ) const +{ + if ( !child.isValid() ) + { + return QModelIndex(); + } + + AccountModelNode* node = nodeFromIndex( child ); + AccountModelNode* parent = node->parent; + + // top level, none + if( parent == m_rootItem ) + return QModelIndex(); + + // child Account* of an AccountFactory* + Q_ASSERT( m_rootItem->children.contains( parent ) ); + return createIndex( m_rootItem->children.indexOf( parent ), 0, parent ); +} + +QModelIndex +AccountModel::index( int row, int column, const QModelIndex& parent ) const +{ + if( row < 0 || column < 0 ) + return QModelIndex(); + + if( hasIndex( row, column, parent ) ) + { + AccountModelNode *parentNode = nodeFromIndex( parent ); + AccountModelNode *childNode = parentNode->children.at( row ); + return createIndex( row, column, childNode ); + } + + return QModelIndex(); +} + +AccountModelNode* +AccountModel::nodeFromIndex( const QModelIndex& idx ) const +{ + if( !idx.isValid() ) + return m_rootItem; + + Q_ASSERT( idx.internalPointer() ); + + return reinterpret_cast< AccountModelNode* >( idx.internalPointer() ); +} diff --git a/src/libtomahawk/accounts/AccountModel.h b/src/libtomahawk/accounts/AccountModel.h index e905a7ca2..7338980e4 100644 --- a/src/libtomahawk/accounts/AccountModel.h +++ b/src/libtomahawk/accounts/AccountModel.h @@ -1,68 +1,94 @@ -/* - Copyright (C) 2011 Leo Franchi +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Leo Franchi + * + * 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 . + */ - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - - -#ifndef SIPMODEL_H -#define SIPMODEL_H +#ifndef TOMAHAWK_ACCOUNTS_ACCOUNTMODEL_H +#define TOMAHAWK_ACCOUNTS_ACCOUNTMODEL_H #include "dllmacro.h" -#include "sip/SipPlugin.h" -#include -#include -#include +#include -namespace Tomahawk -{ -namespace Accounts -{ -class Account; +namespace Tomahawk { -class DLLEXPORT AccountModel : public QAbstractListModel +namespace Accounts { + +class AccountModelNode; + +class DLLEXPORT AccountModel : public QAbstractItemModel { Q_OBJECT + public: enum Roles { - AccountName = Qt::UserRole + 15, - AccountIcon = Qt::UserRole + 16, - AccountTypeRole = Qt::UserRole + 19, - ConnectionStateRole = Qt::UserRole + 20, - HasConfig = Qt::UserRole + 21, - ErrorString = Qt::UserRole + 22, - AccountData = Qt::UserRole + 23 // raw plugin + RowType = Qt::UserRole + 1, // RowType enum + + // Used by top-level accounts + AccountDescription = Qt::UserRole + 17, + StateRole = Qt::UserRole + 18, // ItemState, + RatingRole = Qt::UserRole + 19, + DownloadCounterRole = Qt::UserRole + 20, + VersionRole = Qt::UserRole + 21, + AuthorRole = Qt::UserRole + 22, + UserHasRatedRole = Qt::UserRole + 24, + + // used by both + ConnectionStateRole = Qt::UserRole + 25, + HasConfig = Qt::UserRole + 26, + ErrorString = Qt::UserRole + 27, + + // used by individual accounts, needed still? + AccountData = Qt::UserRole + 28 // raw plugin + }; + + enum RowType { + TopLevelFactory, + TopLevelAccount, + ChildAccount + }; + + enum ItemState { + Uninstalled = 0, + Installing, + Installed, + NeedsUpgrade, + Upgrading, + Failed, + ShippedWithTomahawk // Can't uninstall or uninstall, just enable/disable }; explicit AccountModel( QObject* parent = 0 ); - virtual ~AccountModel(); virtual QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const; + virtual int columnCount( const QModelIndex& parent = QModelIndex() ) const; virtual int rowCount( const QModelIndex& parent = QModelIndex() ) const; - virtual Qt::ItemFlags flags(const QModelIndex& index) const; - virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole); + virtual QModelIndex parent( const QModelIndex& child ) const; + virtual QModelIndex index( int row, int column, const QModelIndex& parent = QModelIndex() ) const; -private slots: - void accountAdded( Tomahawk::Accounts::Account* p ); - void accountRemoved( Tomahawk::Accounts::Account* p ); - void accountStateChanged( Tomahawk::Accounts::Account::ConnectionState ); +private: + AccountModelNode* nodeFromIndex( const QModelIndex& index ) const; + void loadData(); + + AccountModelNode* m_rootItem; }; } } -#endif // SIPMODEL_H +#endif // TOMAHAWK_ACCOUNTS_ACCOUNTMODEL_H diff --git a/src/libtomahawk/accounts/AccountModelNode.h b/src/libtomahawk/accounts/AccountModelNode.h new file mode 100644 index 000000000..35405d057 --- /dev/null +++ b/src/libtomahawk/accounts/AccountModelNode.h @@ -0,0 +1,145 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Leo Franchi + * + * 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 TOMAHAWK_ACCOUNTS_ACCOUNTMODELNODE_H +#define TOMAHAWK_ACCOUNTS_ACCOUNTMODELNODE_H + +#include "Account.h" +#include "AccountManager.h" +#include "ResolverAccount.h" + +#include + +namespace Tomahawk { + +namespace Accounts { + +/** + * Node for account tree. + * + * Basically a union with possible types: + * 1) AccountFactory* for accounts that are not unique (jabber, google, twitter) + * 2) Account* for accounts that are associated with an AccountFactory (children of AccountFactory) + * 3) Attica::Content for AtticaResolverAccounts (with associated AtticaResolverAccount*) (all synchroton resolvers) + * 4) ResolverAccount* for manually added resolvers (from file). + * + * These are the top-level items in tree. + * + * Top level nodes all look the same to the user. The only difference is that services that have login (and thus + * can have multiple logins at once) allow a user to create multiple children with specific login information. + * All other top level accounts (Account*, Attica::Content, ResolverAccount*) behave the same to the user, they can + * simply click "Install" or toggle on/off. + * + */ + +struct AccountModelNode { + enum NodeType { + FactoryType, + AccountType, + AtticaType, + ManualResolverType + }; + AccountModelNode* parent; + NodeType type; + QList< AccountModelNode* > children; // list of children accounts (actually existing and configured accounts) + + /// 1. + AccountFactory* factory; + + /// 2. + Account* account; + + /// 3. + Attica::Content atticaContent; + AtticaResolverAccount* atticaAccount; + + /// 4. + ResolverAccount* resolverAccount; + + // Construct in one of four ways. Then access the corresponding members + explicit AccountModelNode( AccountModelNode* p, AccountFactory* fac ) : parent( p ), type( FactoryType ) + { + init(); + factory = fac; + // Initialize factory nodes with their children + foreach ( Account* acct, AccountManager::instance()->accounts() ) + { + if ( AccountManager::instance()->factoryForAccount( acct ) == fac ) + { + qDebug() << "Found account for factory:" << acct->accountFriendlyName(); + new AccountModelNode( this, acct ); + } + } + } + + AccountModelNode( AccountModelNode* p, Account* acct ) : parent( p ), type( AccountType ) + { + init(); + account = acct; + } + + explicit AccountModelNode( AccountModelNode* p, Attica::Content cnt ) : parent( p ), type( AtticaType ) + { + init(); + atticaContent = cnt; + + qDebug() << "Creating attica model node for resolver:" << cnt.id(); + + foreach ( Account* acct, AccountManager::instance()->accounts( Accounts::ResolverType ) ) + { + if ( AtticaResolverAccount* resolver = qobject_cast< AtticaResolverAccount* >( acct ) ) + { + if ( resolver->atticaId() == atticaContent.id() ) + { + qDebug() << "found atticaaccount :" << resolver->accountFriendlyName(); + atticaAccount = resolver; + break; + } + } + } + } + + explicit AccountModelNode( AccountModelNode* p, ResolverAccount* ra ) : parent( p ), type( ManualResolverType ) + { + init(); + resolverAccount = ra; + } + + AccountModelNode() : parent( 0 ) {} + + ~AccountModelNode() + { + qDeleteAll( children ); + } + + + void init() + { + parent->children.append( this ); + + factory = 0; + account = 0; + atticaAccount = 0; + resolverAccount = 0; + } +}; + +} + +} +#endif // TOMAHAWK_ACCOUNTS_ACCOUNTMODELNODE_H diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index 4c254525f..2f4ad8df7 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -102,12 +102,12 @@ SettingsDialog::SettingsDialog( QWidget *parent ) #endif // SIP PLUGINS - AccountDelegate* sipdel = new AccountDelegate( this ); - ui->accountsView->setItemDelegate( sipdel ); +// AccountDelegate* sipdel = new AccountDelegate( this ); +// ui->accountsView->setItemDelegate( sipdel ); ui->accountsView->setContextMenuPolicy( Qt::CustomContextMenu ); ui->accountsView->setVerticalScrollMode( QAbstractItemView::ScrollPerPixel ); - connect( sipdel, SIGNAL( openConfig( Tomahawk::Accounts::Account* ) ), this, SLOT( openAccountConfig( Tomahawk::Accounts::Account* ) ) ); +// connect( sipdel, SIGNAL( openConfig( Tomahawk::Accounts::Account* ) ), this, SLOT( openAccountConfig( Tomahawk::Accounts::Account* ) ) ); connect( ui->accountsView, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( accountContextMenuRequest( QPoint ) ) ); m_accountModel = new AccountModel( this ); ui->accountsView->setModel( m_accountModel ); @@ -598,11 +598,11 @@ SettingsDialog::accountContextMenuRequest( const QPoint& p ) // if it's an account, allow to delete if( idx.isValid() ) { - QList< QAction* > acts; - acts << new QAction( tr( "Delete Service" ), this ); - acts.first()->setProperty( "accountplugin", idx.data( AccountModel::AccountData ) ); - connect( acts.first(), SIGNAL( triggered( bool ) ), this, SLOT( onAccountRowDeleted( bool ) ) ); - QMenu::exec( acts, ui->accountsView->mapToGlobal( p ) ); +// QList< QAction* > acts; +// acts << new QAction( tr( "Delete Service" ), this ); +// acts.first()->setProperty( "accountplugin", idx.data( AccountModel::AccountData ) ); +// connect( acts.first(), SIGNAL( triggered( bool ) ), this, SLOT( onAccountRowDeleted( bool ) ) ); +// QMenu::exec( acts, ui->accountsView->mapToGlobal( p ) ); } } @@ -625,8 +625,8 @@ SettingsDialog::accountDeleted( bool ) { if( idx.isValid() ) { - Account* account = qobject_cast< Account* >( idx.data( AccountModel::AccountData ).value< QObject* >() ); - AccountManager::instance()->removeAccount( account ); +// Account* account = qobject_cast< Account* >( idx.data( AccountModel::AccountData ).value< QObject* >() ); +// AccountManager::instance()->removeAccount( account ); } } } diff --git a/src/stackedsettingsdialog.ui b/src/stackedsettingsdialog.ui index e0e1620f0..f823b6e8c 100644 --- a/src/stackedsettingsdialog.ui +++ b/src/stackedsettingsdialog.ui @@ -129,10 +129,10 @@ - 0 + 6 - false + true false From f17bba773df3a456cc0dec992c604a29cac6854f Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Tue, 31 Jan 2012 18:25:34 -0500 Subject: [PATCH 048/104] initial delegate work --- src/AccountDelegate.h | 2 +- src/CMakeLists.txt | 4 ++-- src/libtomahawk/accounts/AccountModel.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/AccountDelegate.h b/src/AccountDelegate.h index bd1f9b638..a15c82910 100644 --- a/src/AccountDelegate.h +++ b/src/AccountDelegate.h @@ -42,7 +42,7 @@ public: virtual QRect checkRectForIndex( const QStyleOptionViewItem &option, const QModelIndex &idx, int role ) const; virtual QRect configRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const; -// virtual QList extraCheckRoles() const { return QList() << (int)AccountModel::AccountTypeRole; } + virtual QList extraCheckRoles() const { return QList() << (int)AccountModel::AccountTypeRole; } private slots: void askedForEdit( const QModelIndex& idx ); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a2d75f978..31591e961 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -75,7 +75,7 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui} settingsdialog.cpp diagnosticsdialog.cpp configdelegatebase.cpp -# AccountDelegate.cpp + AccountDelegate.cpp settingslistdelegate.cpp tomahawkwindow.cpp LoadXSPFDialog.cpp @@ -125,7 +125,7 @@ SET( tomahawkHeadersGui ${tomahawkHeadersGui} settingsdialog.h diagnosticsdialog.h configdelegatebase.h -# AccountDelegate.h + AccountDelegate.h settingslistdelegate.h delegateconfigwrapper.h tomahawkwindow.h diff --git a/src/libtomahawk/accounts/AccountModel.h b/src/libtomahawk/accounts/AccountModel.h index 7338980e4..f594b1025 100644 --- a/src/libtomahawk/accounts/AccountModel.h +++ b/src/libtomahawk/accounts/AccountModel.h @@ -52,7 +52,7 @@ public: HasConfig = Qt::UserRole + 26, ErrorString = Qt::UserRole + 27, - // used by individual accounts, needed still? + // used by individual accounts AccountData = Qt::UserRole + 28 // raw plugin }; From 96eb48090c34e0cd62a521597ad89066fb6974c9 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Tue, 31 Jan 2012 23:05:50 -0500 Subject: [PATCH 049/104] Initialwork on new accounts delegate --- src/AccountDelegate.cpp | 440 +++++++++++++++++++--- src/AccountDelegate.h | 13 +- src/libtomahawk/accounts/AccountModel.cpp | 16 +- src/libtomahawk/accounts/AccountModel.h | 6 +- src/libtomahawk/utils/xspfloader.cpp | 1 + src/libtomahawk/utils/xspfloader.h | 1 + src/settingsdialog.cpp | 5 +- src/stackedsettingsdialog.ui | 2 +- 8 files changed, 425 insertions(+), 59 deletions(-) diff --git a/src/AccountDelegate.cpp b/src/AccountDelegate.cpp index a371e8a87..e0042a9cf 100644 --- a/src/AccountDelegate.cpp +++ b/src/AccountDelegate.cpp @@ -27,7 +27,19 @@ #include "utils/tomahawkutils.h" #include "utils/logger.h" -#define ICONSIZE 34 +#define CHILD_ACCOUNT_HEIGHT 24 + +#define PADDING 4 +#define PADDING_BETWEEN_STARS 2 +#define STAR_SIZE 12 + +#ifdef Q_WS_MAC +#define TOPLEVEL_ACCOUNT_HEIGHT 70 +#else +#define TOPLEVEL_ACCOUNT_HEIGHT 60 +#endif + +#define ICONSIZE 40 #define WRENCH_SIZE 24 #define STATUS_ICON_SIZE 13 #define CHECK_LEFT_EDGE 8 @@ -38,11 +50,36 @@ using namespace Accounts; AccountDelegate::AccountDelegate( QObject* parent ) : ConfigDelegateBase ( parent ) { - connect( this, SIGNAL( configPressed( QModelIndex ) ), this, SLOT( askedForEdit( QModelIndex ) ) ); + + m_defaultCover.load( RESPATH "images/sipplugin-online.png" ); + m_ratingStarPositive.load( RESPATH "images/starred.png" ); + m_ratingStarNegative.load( RESPATH "images/star-unstarred.png" ); + m_onHoverStar.load( RESPATH "images/star-hover.png" ); + m_onlineIcon.load( RESPATH "images/sipplugin-online.png" ); + m_offlineIcon.load( RESPATH "images/sipplugin-offline.png" ); + + m_ratingStarPositive = m_ratingStarPositive.scaled( STAR_SIZE, STAR_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation ); + m_ratingStarNegative = m_ratingStarNegative.scaled( STAR_SIZE, STAR_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation ); + m_onlineIcon = m_onlineIcon.scaled( STATUS_ICON_SIZE, STATUS_ICON_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation ); + m_offlineIcon = m_offlineIcon.scaled( STATUS_ICON_SIZE, STATUS_ICON_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation ); + m_onHoverStar = m_onHoverStar.scaled( STAR_SIZE, STAR_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation ); + + const int w = TOPLEVEL_ACCOUNT_HEIGHT - 2*PADDING; + m_defaultCover = m_defaultCover.scaled( w, w, Qt::KeepAspectRatio, Qt::SmoothTransformation ); m_cachedIcons[ "sipplugin-online" ] = QPixmap( RESPATH "images/sipplugin-online.png" ).scaled( STATUS_ICON_SIZE, STATUS_ICON_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation ); m_cachedIcons[ "sipplugin-offline" ] = QPixmap( RESPATH "images/sipplugin-offline.png" ).scaled( STATUS_ICON_SIZE, STATUS_ICON_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation ); + // save the widest width + QFont f( QApplication::font() ); + f.setPointSize( f.pointSize() - 1 ); + QFontMetrics fm( f ); + QStringList l = QStringList() << tr( "Installed" ) << tr( "Installing" ) << tr( "Failed" ) << tr( "Uninstalling" ) << tr( "Create" ); + foreach ( const QString& str, l ) + { + if ( fm.width( str ) > m_widestTextWidth ) + m_widestTextWidth = fm.width( str ); + } } bool @@ -51,32 +88,60 @@ AccountDelegate::editorEvent ( QEvent* event, QAbstractItemModel* model, const Q return ConfigDelegateBase::editorEvent( event, model, option, index ); } + +QSize +AccountDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const +{ + AccountModel::RowType rowType = static_cast< AccountModel::RowType >( index.data( AccountModel::RowTypeRole ).toInt() ); + if ( rowType == AccountModel::TopLevelAccount || rowType == AccountModel::TopLevelFactory ) + return QSize( 200, TOPLEVEL_ACCOUNT_HEIGHT ); + else // individual child account + return QSize( 200, CHILD_ACCOUNT_HEIGHT ); +} + + void AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const { QStyleOptionViewItemV4 opt = option; initStyleOption( &opt, index ); - const QRect itemRect = opt.rect; - const int top = itemRect.top(); - const int mid = itemRect.height() / 2; - const int quarter = mid - ( itemRect.height() / 4 ); - - // one line bold for account name - // space below it for online/offline status - // checkbox, icon, name/status, features, config icon - QFont name = opt.font; - name.setPointSize( name.pointSize() + 2 ); - name.setBold( true ); - - QFont smallFont = opt.font; - smallFont.setPointSize( smallFont.pointSize() - 1 ); - QFontMetrics smallFontFM( smallFont ); // draw the background const QWidget* w = opt.widget; QStyle* style = w ? w->style() : QApplication::style(); style->drawPrimitive( QStyle::PE_PanelItemViewItem, &opt, painter, w ); + painter->setRenderHint( QPainter::Antialiasing ); + + AccountModel::RowType rowType = static_cast< AccountModel::RowType >( index.data( AccountModel::RowTypeRole ).toInt() ); + if ( rowType == AccountModel::TopLevelAccount || rowType == AccountModel::TopLevelFactory ) + paintTopLevel( painter, opt, index ); + else // individual child account + paintChild( painter, opt, index ); + + return; + +// const QRect itemRect = opt.rect; +// const int top = itemRect.top(); +// const int mid = itemRect.height() / 2; +// const int quarter = mid - ( itemRect.height() / 4 ); +// +// // one line bold for account name +// // space below it for online/offline status +// // checkbox, icon, name/status, features, config icon +// QFont name = opt.font; +// name.setPointSize( name.pointSize() + 2 ); +// name.setBold( true ); +// +// QFont smallFont = opt.font; +// smallFont.setPointSize( smallFont.pointSize() - 1 ); +// QFontMetrics smallFontFM( smallFont ); +// +// // draw the background +// const QWidget* w = opt.widget; +// QStyle* style = w ? w->style() : QApplication::style(); +// style->drawPrimitive( QStyle::PE_PanelItemViewItem, &opt, painter, w ); +/* int iconLeftEdge = CHECK_LEFT_EDGE + WRENCH_SIZE + PADDING; int textLeftEdge = iconLeftEdge + ICONSIZE + PADDING; @@ -179,32 +244,326 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, const int capTextX = qMax( width, configLeftEdge - smallFontFM.width( capString ) ); painter->setFont( smallFont ); painter->drawText( QRect( capTextX, capY, configLeftEdge - capTextX, smallFontFM.height() ), Qt::AlignRight, capString ); + }*/ +} + + +void +AccountDelegate::paintTopLevel( QPainter* painter, const QStyleOptionViewItemV4& option, const QModelIndex& index ) const +{ + QStyleOptionViewItemV4 opt = option; + + QFont titleFont = opt.font; + titleFont.setBold( true ); + titleFont.setPointSize( titleFont.pointSize() + 2 ); + const QFontMetrics titleMetrics( titleFont ); + + QFont authorFont = opt.font; + authorFont.setItalic( true ); + authorFont.setPointSize( authorFont.pointSize() - 1 ); + const QFontMetrics authorMetrics( authorFont ); + + QFont descFont = authorFont; + descFont.setItalic( false ); + const QFontMetrics descMetrics( descFont ); + + QFont installFont = opt.font; + installFont.setPointSize( installFont.pointSize() - 1 ); + const QFontMetrics installMetrics( descFont ); + + const int height = opt.rect.height(); + const int center = height / 2 + opt.rect.top(); + + // Left account enable/disable checkbox if this is not a factory + const AccountModel::RowType rowType = static_cast< AccountModel::RowType >( index.data( AccountModel::RowTypeRole ).toInt() ); + int leftEdge = PADDING; + if ( rowType != AccountModel::TopLevelFactory ) + { + // draw checkbox first + int ypos = ( center ) - ( WRENCH_SIZE / 2 ); + QRect checkRect = QRect( leftEdge, ypos, WRENCH_SIZE, WRENCH_SIZE ); + QStyleOptionViewItemV4 opt2 = opt; + opt2.rect = checkRect; + const AccountModel::ItemState state = static_cast< AccountModel::ItemState >( index.data( AccountModel::StateRole ).toInt() ); + const bool canCheck = ( state == AccountModel::Installed || state == AccountModel::ShippedWithTomahawk ); + opt2.state = canCheck ? QStyle::State_On : QStyle::State_Off; + drawCheckBox( opt2, painter, opt.widget ); } + leftEdge += WRENCH_SIZE + PADDING / 2; + + // Pixmap + QPixmap p = index.data( Qt::DecorationRole ).value< QPixmap >(); + const int pixmapWidth = height - 2*PADDING; + QRect pixmapRect( leftEdge + PADDING, PADDING + opt.rect.top(), pixmapWidth, pixmapWidth ); + if ( p.isNull() ) // default image... TODO + p = m_defaultCover; + else + p = p.scaled( pixmapRect.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation ); + + painter->drawPixmap( pixmapRect, p ); + + + // Go from right edge now, stars, install/create button, downloaded info, config wrench and status etc + + // install / status button + const AccountModel::ItemState state = static_cast< AccountModel::ItemState >( index.data( AccountModel::StateRole ).toInt() ); + QString actionText; + switch( state ) + { + case AccountModel::Uninstalled: + actionText = tr( "Install" ); + break; + case AccountModel::Installing: + actionText = tr( "Installing" ); + break; + case AccountModel::Upgrading: + actionText = tr( "Upgrading" ); + break; + case AccountModel::Failed: + actionText = tr( "Failed" ); + break; + case AccountModel::Installed: + actionText = tr( "Uninstall" ); + break; + case AccountModel::NeedsUpgrade: + actionText = tr( "Upgrade" ); + break; + case AccountModel::ShippedWithTomahawk: + actionText = tr( "Create" ); + break; + } + + // title and description + const int btnWidth = m_widestTextWidth + 7; + leftEdge = opt.rect.width() - PADDING - btnWidth - 3; + const QRect btnRect( leftEdge, center - ( installMetrics.height() + 4 ) / 2, btnWidth, installMetrics.height() + 4 ); + m_cachedButtonRects[ index ] = btnRect; + + const QPen saved = painter->pen(); + painter->setPen( opt.palette.color( QPalette::Active, QPalette::AlternateBase ) ); + + drawRoundedButton( painter, btnRect ); + + painter->setFont( installFont ); + painter->drawText( btnRect, Qt::AlignCenter, actionText ); + + painter->setPen( saved ); + + + // rating stars + const int rating = index.data( AccountModel::RatingRole ).toInt(); + const int ratingWidth = 5 * ( m_ratingStarPositive.width() + PADDING_BETWEEN_STARS ); + int runningEdge = ( btnRect.right() - btnRect.width() / 2 ) - ratingWidth / 2; + for ( int i = 1; i < 6; i++ ) + { + QRect r( runningEdge, btnRect.top() - m_ratingStarPositive.height() - PADDING, m_ratingStarPositive.width(), m_ratingStarPositive.height() ); + if ( i == 1 ) + m_cachedStarRects[ index ] = r; + + const bool userHasRated = index.data( AccountModel::UserHasRatedRole ).toBool(); + if ( !userHasRated && // Show on-hover animation if the user hasn't rated it yet, and is hovering over it + m_hoveringOver > -1 && + m_hoveringItem == index ) + { + if ( i <= m_hoveringOver ) // positive star + painter->drawPixmap( r, m_onHoverStar ); + else + painter->drawPixmap( r, m_ratingStarNegative ); + } + else + { + if ( i <= rating ) // positive or rated star + { + if ( userHasRated ) + painter->drawPixmap( r, m_onHoverStar ); + else + painter->drawPixmap( r, m_ratingStarPositive ); + } + else + painter->drawPixmap( r, m_ratingStarNegative ); + } + runningEdge += m_ratingStarPositive.width() + PADDING_BETWEEN_STARS; + } + + + // downloaded num times, underneath button + QString count = tr( "%1 downloads" ).arg( index.data( AccountModel::DownloadCounterRole ).toInt() ); + const QRect countRect( btnRect.left(), btnRect.bottom() + PADDING, btnRect.width(), opt.rect.bottom() - PADDING - btnRect.bottom() ); + QFont countFont = descFont; + countFont.setPointSize( countFont.pointSize() - 2 ); + countFont.setBold( true ); + painter->setFont( countFont ); + painter->drawText( countRect, Qt::AlignCenter | Qt::TextWordWrap, count ); + + // author and version + QString author = index.data( AccountModel::AuthorRole ).toString(); + const int authorWidth = authorMetrics.width( author ); + const int topTextLine = opt.rect.top() + PADDING; + const QRect authorRect( btnRect.x() - 3*PADDING - authorWidth, topTextLine, authorWidth + 6, authorMetrics.height() ); + painter->setFont( authorFont ); + painter->drawText( authorRect, Qt::AlignCenter, author ); + + // Disable version for now, that space is used +// const QRect versionRect = authorRect.translated( 0, authorRect.height() ); +// QString version = index.data( AccountModel::VersionRole ).toString(); +// painter->drawText( versionRect, Qt::AlignCenter, version ); + + // if this is a real resolver, show config wrench, state/status, and string + int edgeOfRightExtras = btnRect.x(); + if ( rowType == AccountModel::TopLevelAccount ) + { + const QRect confRect = QRect( btnRect.x() - 2*PADDING - WRENCH_SIZE, center - WRENCH_SIZE / 2, WRENCH_SIZE, WRENCH_SIZE ); + if( index.data( AccountModel::HasConfig ).toBool() ) { + + QStyleOptionToolButton topt; + topt.rect = confRect; + topt.pos = confRect.topLeft(); + + drawConfigWrench( painter, opt, topt ); + } + + const int stateY = center - ( authorMetrics.height() / 2 ); + + QPixmap p; + QString statusText; + Account::ConnectionState state = static_cast< Account::ConnectionState >( index.data( AccountModel::ConnectionStateRole ).toInt() ); + if ( state == Account::Connected ) + { + p = m_onlineIcon; + statusText = tr( "Online" ); + } + else if ( state == Account::Connecting ) + { + p = m_offlineIcon; + statusText = tr( "Connecting..." ); + } + else + { + p = m_offlineIcon; + statusText = tr( "Offline" ); + } + const QRect connectIconRect( confRect.x() - PADDING - STATUS_ICON_SIZE, stateY, STATUS_ICON_SIZE, STATUS_ICON_SIZE ); + painter->drawPixmap( connectIconRect, p ); + + int width = installMetrics.width( statusText ); + int statusTextX = connectIconRect.x() - PADDING - width; + painter->save(); + painter->setFont( installFont ); + painter->drawText( QRect( statusTextX, stateY, width, installMetrics.height() ), statusText ); + painter->restore(); + + edgeOfRightExtras = statusTextX; + } + + // Title and description! + // title + QString title = index.data( Qt::DisplayRole ).toString(); + const int rightTitleEdge = authorRect.x() - PADDING; + const int leftTitleEdge = pixmapRect.right() + PADDING; + const QRect textRect( leftTitleEdge, topTextLine, rightTitleEdge - leftTitleEdge, center - opt.rect.top() - PADDING ); + painter->setFont( titleFont ); + painter->drawText( textRect, Qt::AlignVCenter | Qt::AlignLeft, title ); + + // description + QString desc = index.data( AccountModel::DescriptionRole ).toString(); + const int descWidth = edgeOfRightExtras - leftTitleEdge - PADDING; + const QRect descRect( leftTitleEdge, center, descWidth, opt.rect.bottom() - center + PADDING ); + painter->setFont( descFont ); + painter->drawText( descRect, Qt::AlignLeft | Qt::TextWordWrap, desc ); +} + + +void +AccountDelegate::paintChild( QPainter* painter, const QStyleOptionViewItemV4& option, const QModelIndex& index ) const +{ + const int radius = 6; + const int top = option.rect.top(); + QPainterPath outline; + outline.moveTo( option.rect.topLeft() ); + + outline.lineTo( option.rect.left(), option.rect.bottom() - radius ); + outline.quadTo( option.rect.bottomLeft(), QPointF( option.rect.left() + radius, option.rect.bottom() ) ); + outline.lineTo( option.rect.right() - radius, option.rect.bottom() ); + outline.quadTo( option.rect.bottomRight(), QPointF( option.rect.right() - 1, top ) ); + outline.lineTo( option.rect.right(), top ); + + painter->drawPath( outline ); + + // draw checkbox first + const int smallWrenchSize = option.rect.height() - PADDING; + int ypos = ( option.rect.center().y() ) - ( smallWrenchSize / 2 ); + QRect checkRect = QRect( option.rect.left() + PADDING, ypos, smallWrenchSize, smallWrenchSize ); + QStyleOptionViewItemV4 opt2 = option; + opt2.rect = checkRect; + drawCheckBox( opt2, painter, opt2.widget ); + + const QString username = index.data( Qt::DisplayRole ).toString(); + QFont f = option.font; + f.setPointSize( 9 ); + painter->setFont( f ); + painter->drawText( option.rect.adjusted( PADDING + checkRect.right(), 0, 0, 0 ), Qt::AlignVCenter | Qt::AlignLeft, username ); +} + + +void +AccountDelegate::drawRoundedButton( QPainter* painter, const QRect& btnRect ) const +{ + QPainterPath btnPath; + const int radius = 3; + // draw top half gradient + const int btnCenter = btnRect.bottom() - ( btnRect.height() / 2 ); + btnPath.moveTo( btnRect.left(), btnCenter ); + btnPath.lineTo( btnRect.left(), btnRect.top() + radius ); + btnPath.quadTo( QPoint( btnRect.topLeft() ), QPoint( btnRect.left() + radius, btnRect.top() ) ); + btnPath.lineTo( btnRect.right() - radius, btnRect.top() ); + btnPath.quadTo( QPoint( btnRect.topRight() ), QPoint( btnRect.right(), btnRect.top() + radius ) ); + btnPath.lineTo( btnRect.right(),btnCenter ); + btnPath.lineTo( btnRect.left(), btnCenter ); + + QLinearGradient g; + g.setColorAt( 0, QColor(54, 127, 211) ); + g.setColorAt( 0.5, QColor(43, 104, 182) ); + //painter->setPen( bg.darker() ); + painter->fillPath( btnPath, g ); + //painter->drawPath( btnPath ); + + btnPath = QPainterPath(); + btnPath.moveTo( btnRect.left(), btnCenter ); + btnPath.lineTo( btnRect.left(), btnRect.bottom() - radius ); + btnPath.quadTo( QPoint( btnRect.bottomLeft() ), QPoint( btnRect.left() + radius, btnRect.bottom() ) ); + btnPath.lineTo( btnRect.right() - radius, btnRect.bottom() ); + btnPath.quadTo( QPoint( btnRect.bottomRight() ), QPoint( btnRect.right(), btnRect.bottom() - radius ) ); + btnPath.lineTo( btnRect.right(), btnCenter ); + btnPath.lineTo( btnRect.left(), btnCenter ); + + g.setColorAt( 0, QColor(34, 85, 159) ); + g.setColorAt( 0.5, QColor(35, 79, 147) ); + painter->fillPath( btnPath, g ); } QRect AccountDelegate::checkRectForIndex( const QStyleOptionViewItem &option, const QModelIndex &idx, int role ) const { - if ( role == Qt::CheckStateRole ) - { - // the whole resolver checkbox - QStyleOptionViewItemV4 opt = option; - initStyleOption( &opt, idx ); - const int mid = opt.rect.height() / 2; - const int pos = mid - ( ICONSIZE / 2 ); - QRect checkRect( CHECK_LEFT_EDGE, pos + opt.rect.top(), ICONSIZE, ICONSIZE ); - - return checkRect; - } else if ( role == AccountModel::AccountTypeRole ) - { - // The capabilities checkbox - QStyleOptionViewItemV4 opt = option; - initStyleOption( &opt, idx ); - const int quarter = opt.rect.height() / 4 + opt.rect.height() / 2; - const int leftEdge = opt.rect.width() - PADDING - WRENCH_SIZE - PADDING - WRENCH_SIZE; - QRect checkRect( leftEdge, quarter, WRENCH_SIZE, WRENCH_SIZE ); - return checkRect; - } +// if ( role == Qt::CheckStateRole ) +// { +// // the whole resolver checkbox +// QStyleOptionViewItemV4 opt = option; +// initStyleOption( &opt, idx ); +// const int mid = opt.rect.height() / 2; +// const int pos = mid - ( ICONSIZE / 2 ); +// QRect checkRect( CHECK_LEFT_EDGE, pos + opt.rect.top(), ICONSIZE, ICONSIZE ); +// +// return checkRect; +// } else if ( role == AccountModel::AccountTypeRole ) +// { +// // The capabilities checkbox +// QStyleOptionViewItemV4 opt = option; +// initStyleOption( &opt, idx ); +// const int quarter = opt.rect.height() / 4 + opt.rect.height() / 2; +// const int leftEdge = opt.rect.width() - PADDING - WRENCH_SIZE - PADDING - WRENCH_SIZE; +// QRect checkRect( leftEdge, quarter, WRENCH_SIZE, WRENCH_SIZE ); +// return checkRect; +// } return QRect(); } @@ -218,13 +577,6 @@ AccountDelegate::configRectForIndex( const QStyleOptionViewItem& option, const Q return confRect; } - -QSize -AccountDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const -{ - return ConfigDelegateBase::sizeHint( option, index ); -} - void AccountDelegate::askedForEdit( const QModelIndex& idx ) { diff --git a/src/AccountDelegate.h b/src/AccountDelegate.h index a15c82910..dd1250a10 100644 --- a/src/AccountDelegate.h +++ b/src/AccountDelegate.h @@ -42,15 +42,26 @@ public: virtual QRect checkRectForIndex( const QStyleOptionViewItem &option, const QModelIndex &idx, int role ) const; virtual QRect configRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const; - virtual QList extraCheckRoles() const { return QList() << (int)AccountModel::AccountTypeRole; } private slots: void askedForEdit( const QModelIndex& idx ); signals: + void update( const QModelIndex& idx ); void openConfig( Tomahawk::Accounts::Account* ); private: + void paintTopLevel( QPainter* painter, const QStyleOptionViewItemV4& option, const QModelIndex& index ) const; + void paintChild( QPainter* painter, const QStyleOptionViewItemV4& option, const QModelIndex& index ) const; + void drawRoundedButton( QPainter* painter, const QRect& buttonRect ) const; + QMap< QString, QPixmap > m_cachedIcons; + QPixmap m_offlineIcon, m_onlineIcon, m_defaultCover, m_onHoverStar, m_ratingStarPositive, m_ratingStarNegative; + + int m_widestTextWidth; + int m_hoveringOver; + QPersistentModelIndex m_hoveringItem; + mutable QHash< QPersistentModelIndex, QRect > m_cachedButtonRects; + mutable QHash< QPersistentModelIndex, QRect > m_cachedStarRects; }; } diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index 322a57222..195af49b7 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -102,11 +102,11 @@ AccountModel::data( const QModelIndex& index, int role ) const return fac->icon(); case StateRole: return ShippedWithTomahawk; - case AccountDescription: + case DescriptionRole: return fac->description(); case AuthorRole: return "Tomahawk Team"; - case RowType: + case RowTypeRole: return TopLevelFactory; default: return QVariant(); @@ -125,10 +125,12 @@ AccountModel::data( const QModelIndex& index, int role ) const return QVariant::fromValue< QPixmap >( AtticaManager::instance()->iconForResolver( c ) ); case StateRole: return (int)AtticaManager::instance()->resolverState( c ); - case AccountDescription: + case DescriptionRole: return c.description(); case AuthorRole: return c.author(); + case RowTypeRole: + return TopLevelAccount; case RatingRole: return c.rating() / 20; // rating is out of 100 case DownloadCounterRole: @@ -153,8 +155,6 @@ AccountModel::data( const QModelIndex& index, int role ) const return atticaAcct->enabled() ? Qt::Checked : Qt::Unchecked; case AccountData: return QVariant::fromValue< QObject* >( atticaAcct ); - case RowType: - return TopLevelAccount; case ConnectionStateRole: return atticaAcct->connectionState(); default: @@ -174,13 +174,13 @@ AccountModel::data( const QModelIndex& index, int role ) const return resolver->accountFriendlyName(); case Qt::DecorationRole: return resolver->icon(); - case AccountDescription: + case DescriptionRole: return QString(); case Qt::CheckStateRole: return resolver->enabled() ? Qt::Checked : Qt::Unchecked; case AccountData: return QVariant::fromValue< QObject* >( resolver ); - case RowType: + case RowTypeRole: return TopLevelAccount; case ConnectionStateRole: return resolver->connectionState(); @@ -200,7 +200,7 @@ AccountModel::data( const QModelIndex& index, int role ) const Account* acc = node->account; switch ( role ) { - case RowType: + case RowTypeRole: return ChildAccount; case Qt::DisplayRole: return acc->accountFriendlyName(); diff --git a/src/libtomahawk/accounts/AccountModel.h b/src/libtomahawk/accounts/AccountModel.h index f594b1025..354f31539 100644 --- a/src/libtomahawk/accounts/AccountModel.h +++ b/src/libtomahawk/accounts/AccountModel.h @@ -36,10 +36,10 @@ class DLLEXPORT AccountModel : public QAbstractItemModel public: enum Roles { - RowType = Qt::UserRole + 1, // RowType enum + RowTypeRole = Qt::UserRole + 1, // RowType enum // Used by top-level accounts - AccountDescription = Qt::UserRole + 17, + DescriptionRole = Qt::UserRole + 17, StateRole = Qt::UserRole + 18, // ItemState, RatingRole = Qt::UserRole + 19, DownloadCounterRole = Qt::UserRole + 20, @@ -69,7 +69,7 @@ public: NeedsUpgrade, Upgrading, Failed, - ShippedWithTomahawk // Can't uninstall or uninstall, just enable/disable + ShippedWithTomahawk // Can't uninstall or uninstall, just create }; explicit AccountModel( QObject* parent = 0 ); diff --git a/src/libtomahawk/utils/xspfloader.cpp b/src/libtomahawk/utils/xspfloader.cpp index 77dba6a26..570213c41 100644 --- a/src/libtomahawk/utils/xspfloader.cpp +++ b/src/libtomahawk/utils/xspfloader.cpp @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2010-2011, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/libtomahawk/utils/xspfloader.h b/src/libtomahawk/utils/xspfloader.h index fa9a27194..055e76dbf 100644 --- a/src/libtomahawk/utils/xspfloader.h +++ b/src/libtomahawk/utils/xspfloader.h @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2010-2011, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index 2f4ad8df7..41d94a131 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -102,8 +102,8 @@ SettingsDialog::SettingsDialog( QWidget *parent ) #endif // SIP PLUGINS -// AccountDelegate* sipdel = new AccountDelegate( this ); -// ui->accountsView->setItemDelegate( sipdel ); + AccountDelegate* sipdel = new AccountDelegate( this ); + ui->accountsView->setItemDelegate( sipdel ); ui->accountsView->setContextMenuPolicy( Qt::CustomContextMenu ); ui->accountsView->setVerticalScrollMode( QAbstractItemView::ScrollPerPixel ); @@ -111,6 +111,7 @@ SettingsDialog::SettingsDialog( QWidget *parent ) connect( ui->accountsView, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( accountContextMenuRequest( QPoint ) ) ); m_accountModel = new AccountModel( this ); ui->accountsView->setModel( m_accountModel ); + ui->accountsView->expandAll(); connect( ui->addNewServiceBtn, SIGNAL( clicked( bool ) ), this, SLOT( getMoreResolvers() ) ); connect( ui->removeServiceBtn, SIGNAL( clicked( bool ) ), this, SLOT( accountDeleted( bool ) ) ); diff --git a/src/stackedsettingsdialog.ui b/src/stackedsettingsdialog.ui index f823b6e8c..82edf4921 100644 --- a/src/stackedsettingsdialog.ui +++ b/src/stackedsettingsdialog.ui @@ -132,7 +132,7 @@ 6 - true + false false From 21cfb96b1ef7955763d873b6bc2729e28d2933ba Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Wed, 1 Feb 2012 18:24:39 -0500 Subject: [PATCH 050/104] more work --- src/AccountDelegate.cpp | 72 +++++++++++++-------- src/AccountDelegate.h | 2 + src/libtomahawk/accounts/AccountModel.cpp | 26 ++++++-- src/libtomahawk/accounts/AccountModel.h | 5 +- src/libtomahawk/accounts/AccountModelNode.h | 16 ++++- 5 files changed, 83 insertions(+), 38 deletions(-) diff --git a/src/AccountDelegate.cpp b/src/AccountDelegate.cpp index e0042a9cf..80491258f 100644 --- a/src/AccountDelegate.cpp +++ b/src/AccountDelegate.cpp @@ -49,6 +49,7 @@ using namespace Accounts; AccountDelegate::AccountDelegate( QObject* parent ) : ConfigDelegateBase ( parent ) + , m_widestTextWidth( 0 ) { m_defaultCover.load( RESPATH "images/sipplugin-online.png" ); @@ -331,6 +332,9 @@ AccountDelegate::paintTopLevel( QPainter* painter, const QStyleOptionViewItemV4& case AccountModel::ShippedWithTomahawk: actionText = tr( "Create" ); break; + case AccountModel::UniqueFactory: + actionText = tr( "Installed" ); + break; } // title and description @@ -422,37 +426,10 @@ AccountDelegate::paintTopLevel( QPainter* painter, const QStyleOptionViewItemV4& drawConfigWrench( painter, opt, topt ); } - const int stateY = center - ( authorMetrics.height() / 2 ); - - QPixmap p; - QString statusText; - Account::ConnectionState state = static_cast< Account::ConnectionState >( index.data( AccountModel::ConnectionStateRole ).toInt() ); - if ( state == Account::Connected ) - { - p = m_onlineIcon; - statusText = tr( "Online" ); - } - else if ( state == Account::Connecting ) - { - p = m_offlineIcon; - statusText = tr( "Connecting..." ); - } - else - { - p = m_offlineIcon; - statusText = tr( "Offline" ); - } - const QRect connectIconRect( confRect.x() - PADDING - STATUS_ICON_SIZE, stateY, STATUS_ICON_SIZE, STATUS_ICON_SIZE ); - painter->drawPixmap( connectIconRect, p ); - - int width = installMetrics.width( statusText ); - int statusTextX = connectIconRect.x() - PADDING - width; painter->save(); painter->setFont( installFont ); - painter->drawText( QRect( statusTextX, stateY, width, installMetrics.height() ), statusText ); + edgeOfRightExtras = drawStatus( painter, QPointF( confRect.x() - PADDING, center ), index ); painter->restore(); - - edgeOfRightExtras = statusTextX; } // Title and description! @@ -470,6 +447,8 @@ AccountDelegate::paintTopLevel( QPainter* painter, const QStyleOptionViewItemV4& const QRect descRect( leftTitleEdge, center, descWidth, opt.rect.bottom() - center + PADDING ); painter->setFont( descFont ); painter->drawText( descRect, Qt::AlignLeft | Qt::TextWordWrap, desc ); + + painter->drawLine( opt.rect.bottomLeft(), opt.rect.bottomRight() ); } @@ -502,6 +481,8 @@ AccountDelegate::paintChild( QPainter* painter, const QStyleOptionViewItemV4& op f.setPointSize( 9 ); painter->setFont( f ); painter->drawText( option.rect.adjusted( PADDING + checkRect.right(), 0, 0, 0 ), Qt::AlignVCenter | Qt::AlignLeft, username ); + + } @@ -541,6 +522,41 @@ AccountDelegate::drawRoundedButton( QPainter* painter, const QRect& btnRect ) co painter->fillPath( btnPath, g ); } + +int +AccountDelegate::drawStatus( QPainter* painter, const QPointF& rightCenterEdge, const QModelIndex& index ) const +{ + QPixmap p; + QString statusText; + Account::ConnectionState state = static_cast< Account::ConnectionState >( index.data( AccountModel::ConnectionStateRole ).toInt() ); + if ( state == Account::Connected ) + { + p = m_onlineIcon; + statusText = tr( "Online" ); + } + else if ( state == Account::Connecting ) + { + p = m_offlineIcon; + statusText = tr( "Connecting..." ); + } + else + { + p = m_offlineIcon; + statusText = tr( "Offline" ); + } + + const int yPos = rightCenterEdge.y() - painter->fontMetrics().height() / 2; + const QRect connectIconRect( rightCenterEdge.x() - STATUS_ICON_SIZE, yPos, STATUS_ICON_SIZE, STATUS_ICON_SIZE ); + painter->drawPixmap( connectIconRect, p ); + + int width = painter->fontMetrics().width( statusText ); + int statusTextX = connectIconRect.x() - PADDING - width; + painter->drawText( QRect( statusTextX, yPos, width, painter->fontMetrics().height() ), statusText ); + + return statusTextX; +} + + QRect AccountDelegate::checkRectForIndex( const QStyleOptionViewItem &option, const QModelIndex &idx, int role ) const { diff --git a/src/AccountDelegate.h b/src/AccountDelegate.h index dd1250a10..69c4257e2 100644 --- a/src/AccountDelegate.h +++ b/src/AccountDelegate.h @@ -53,6 +53,8 @@ private: void paintTopLevel( QPainter* painter, const QStyleOptionViewItemV4& option, const QModelIndex& index ) const; void paintChild( QPainter* painter, const QStyleOptionViewItemV4& option, const QModelIndex& index ) const; void drawRoundedButton( QPainter* painter, const QRect& buttonRect ) const; + // Returns new left edge + int drawStatus( QPainter* painter, const QPointF& rightCenterEdge, const QModelIndex& index ) const; QMap< QString, QPixmap > m_cachedIcons; QPixmap m_offlineIcon, m_onlineIcon, m_defaultCover, m_onHoverStar, m_ratingStarPositive, m_ratingStarNegative; diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index 195af49b7..8765ddda0 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -164,30 +164,42 @@ AccountModel::data( const QModelIndex& index, int role ) const return QVariant(); } case AccountModelNode::ManualResolverType: + case AccountModelNode::UniqueFactoryType: { - ResolverAccount* resolver = node->resolverAccount; - Q_ASSERT( resolver ); + Account* acct = 0; + if ( node->type == AccountModelNode::ManualResolverType ) + acct = node->resolverAccount; + else if ( node->type == AccountModelNode::UniqueFactoryType ) + acct = node->account; + + Q_ASSERT( acct ); switch ( role ) { case Qt::DisplayRole: - return resolver->accountFriendlyName(); + return acct->accountFriendlyName(); case Qt::DecorationRole: - return resolver->icon(); + return acct->icon(); case DescriptionRole: return QString(); case Qt::CheckStateRole: - return resolver->enabled() ? Qt::Checked : Qt::Unchecked; + return acct->enabled() ? Qt::Checked : Qt::Unchecked; case AccountData: - return QVariant::fromValue< QObject* >( resolver ); + return QVariant::fromValue< QObject* >( acct ); case RowTypeRole: return TopLevelAccount; case ConnectionStateRole: - return resolver->connectionState(); + return acct->connectionState(); + case HasConfig: + return acct->configurationWidget() != 0; + case StateRole: + return node->type == AccountModelNode::ManualResolverType ? Installed : UniqueFactory; default: return QVariant(); } } + case AccountModelNode::AccountType: + Q_ASSERT( false ); // Should not be here---all account nodes should be children of top level nodes } } else diff --git a/src/libtomahawk/accounts/AccountModel.h b/src/libtomahawk/accounts/AccountModel.h index 354f31539..a5aca2fed 100644 --- a/src/libtomahawk/accounts/AccountModel.h +++ b/src/libtomahawk/accounts/AccountModel.h @@ -63,13 +63,14 @@ public: }; enum ItemState { - Uninstalled = 0, + Uninstalled = 0, // Attica resolver states Installing, Installed, NeedsUpgrade, Upgrading, Failed, - ShippedWithTomahawk // Can't uninstall or uninstall, just create + ShippedWithTomahawk, // Built-in account/factory state: Can't uninstall or uninstall, just create + UniqueFactory // Shipped with tomahawk but is a unique account }; explicit AccountModel( QObject* parent = 0 ); diff --git a/src/libtomahawk/accounts/AccountModelNode.h b/src/libtomahawk/accounts/AccountModelNode.h index 35405d057..7f0708d0a 100644 --- a/src/libtomahawk/accounts/AccountModelNode.h +++ b/src/libtomahawk/accounts/AccountModelNode.h @@ -37,6 +37,7 @@ namespace Accounts { * 2) Account* for accounts that are associated with an AccountFactory (children of AccountFactory) * 3) Attica::Content for AtticaResolverAccounts (with associated AtticaResolverAccount*) (all synchroton resolvers) * 4) ResolverAccount* for manually added resolvers (from file). + * 5) AccountFactory* + Account* for factories that are unique * * These are the top-level items in tree. * @@ -50,6 +51,7 @@ namespace Accounts { struct AccountModelNode { enum NodeType { FactoryType, + UniqueFactoryType, AccountType, AtticaType, ManualResolverType @@ -76,13 +78,25 @@ struct AccountModelNode { { init(); factory = fac; + + if ( fac->isUnique() ) + type = UniqueFactoryType; + // Initialize factory nodes with their children foreach ( Account* acct, AccountManager::instance()->accounts() ) { if ( AccountManager::instance()->factoryForAccount( acct ) == fac ) { qDebug() << "Found account for factory:" << acct->accountFriendlyName(); - new AccountModelNode( this, acct ); + if ( fac->isUnique() ) + { + account = acct; + break; + } + else + { + new AccountModelNode( this, acct ); + } } } } From daa6b7b841f776a55692284d17ee447c7df5cb33 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Thu, 2 Feb 2012 10:54:13 -0500 Subject: [PATCH 051/104] more work --- src/AccountDelegate.cpp | 151 ++++++++++++++-------- src/AccountDelegate.h | 3 +- src/libtomahawk/accounts/AccountModel.cpp | 35 ++++- src/main.cpp | 2 +- 4 files changed, 126 insertions(+), 65 deletions(-) diff --git a/src/AccountDelegate.cpp b/src/AccountDelegate.cpp index 80491258f..6f4efb1ce 100644 --- a/src/AccountDelegate.cpp +++ b/src/AccountDelegate.cpp @@ -41,8 +41,10 @@ #define ICONSIZE 40 #define WRENCH_SIZE 24 +#define SMALL_WRENCH_SIZE 16 #define STATUS_ICON_SIZE 13 #define CHECK_LEFT_EDGE 8 +#define REMOVE_ICON_SIZE 12 using namespace Tomahawk; using namespace Accounts; @@ -58,12 +60,14 @@ AccountDelegate::AccountDelegate( QObject* parent ) m_onHoverStar.load( RESPATH "images/star-hover.png" ); m_onlineIcon.load( RESPATH "images/sipplugin-online.png" ); m_offlineIcon.load( RESPATH "images/sipplugin-offline.png" ); + m_removeIcon.load( RESPATH "images/list-remove.png" ); m_ratingStarPositive = m_ratingStarPositive.scaled( STAR_SIZE, STAR_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation ); m_ratingStarNegative = m_ratingStarNegative.scaled( STAR_SIZE, STAR_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation ); m_onlineIcon = m_onlineIcon.scaled( STATUS_ICON_SIZE, STATUS_ICON_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation ); m_offlineIcon = m_offlineIcon.scaled( STATUS_ICON_SIZE, STATUS_ICON_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation ); m_onHoverStar = m_onHoverStar.scaled( STAR_SIZE, STAR_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation ); + m_removeIcon = m_removeIcon.scaled( REMOVE_ICON_SIZE, REMOVE_ICON_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation ); const int w = TOPLEVEL_ACCOUNT_HEIGHT - 2*PADDING; m_defaultCover = m_defaultCover.scaled( w, w, Qt::KeepAspectRatio, Qt::SmoothTransformation ); @@ -262,6 +266,9 @@ AccountDelegate::paintTopLevel( QPainter* painter, const QStyleOptionViewItemV4& QFont authorFont = opt.font; authorFont.setItalic( true ); authorFont.setPointSize( authorFont.pointSize() - 1 ); +#ifdef Q_OS_MAC + authorFont.setPointSize( authorFont.pointSize() - 1 ); +#endif const QFontMetrics authorMetrics( authorFont ); QFont descFont = authorFont; @@ -354,66 +361,71 @@ AccountDelegate::paintTopLevel( QPainter* painter, const QStyleOptionViewItemV4& painter->setPen( saved ); - // rating stars - const int rating = index.data( AccountModel::RatingRole ).toInt(); - const int ratingWidth = 5 * ( m_ratingStarPositive.width() + PADDING_BETWEEN_STARS ); - int runningEdge = ( btnRect.right() - btnRect.width() / 2 ) - ratingWidth / 2; - for ( int i = 1; i < 6; i++ ) + int edgeOfRightExtras = btnRect.x(); + if ( rowType == AccountModel::TopLevelAccount ) { - QRect r( runningEdge, btnRect.top() - m_ratingStarPositive.height() - PADDING, m_ratingStarPositive.width(), m_ratingStarPositive.height() ); - if ( i == 1 ) - m_cachedStarRects[ index ] = r; + // rating stars + const int rating = index.data( AccountModel::RatingRole ).toInt(); + const int ratingWidth = 5 * ( m_ratingStarPositive.width() + PADDING_BETWEEN_STARS ); + int runningEdge = ( btnRect.right() - btnRect.width() / 2 ) - ratingWidth / 2; + for ( int i = 1; i < 6; i++ ) + { + QRect r( runningEdge, btnRect.top() - m_ratingStarPositive.height() - PADDING, m_ratingStarPositive.width(), m_ratingStarPositive.height() ); + if ( i == 1 ) + m_cachedStarRects[ index ] = r; - const bool userHasRated = index.data( AccountModel::UserHasRatedRole ).toBool(); - if ( !userHasRated && // Show on-hover animation if the user hasn't rated it yet, and is hovering over it - m_hoveringOver > -1 && - m_hoveringItem == index ) - { - if ( i <= m_hoveringOver ) // positive star - painter->drawPixmap( r, m_onHoverStar ); - else - painter->drawPixmap( r, m_ratingStarNegative ); - } - else - { - if ( i <= rating ) // positive or rated star + const bool userHasRated = index.data( AccountModel::UserHasRatedRole ).toBool(); + if ( !userHasRated && // Show on-hover animation if the user hasn't rated it yet, and is hovering over it + m_hoveringOver > -1 && + m_hoveringItem == index ) { - if ( userHasRated ) + if ( i <= m_hoveringOver ) // positive star painter->drawPixmap( r, m_onHoverStar ); else - painter->drawPixmap( r, m_ratingStarPositive ); + painter->drawPixmap( r, m_ratingStarNegative ); } else - painter->drawPixmap( r, m_ratingStarNegative ); + { + if ( i <= rating ) // positive or rated star + { + if ( userHasRated ) + painter->drawPixmap( r, m_onHoverStar ); + else + painter->drawPixmap( r, m_ratingStarPositive ); + } + else + painter->drawPixmap( r, m_ratingStarNegative ); + } + runningEdge += m_ratingStarPositive.width() + PADDING_BETWEEN_STARS; } - runningEdge += m_ratingStarPositive.width() + PADDING_BETWEEN_STARS; + + // downloaded num times, underneath button + QString count = tr( "%1 downloads" ).arg( index.data( AccountModel::DownloadCounterRole ).toInt() ); + const QRect countRect( btnRect.left(), btnRect.bottom() + PADDING, btnRect.width(), opt.rect.bottom() - PADDING - btnRect.bottom() ); + QFont countFont = descFont; + countFont.setPointSize( countFont.pointSize() - 2 ); + countFont.setBold( true ); + painter->setFont( countFont ); + painter->drawText( countRect, Qt::AlignCenter | Qt::TextWordWrap, count ); + + // author and version + QString author = index.data( AccountModel::AuthorRole ).toString(); + const int authorWidth = authorMetrics.width( author ); + const int topTextLine = opt.rect.top() + PADDING; + const QRect authorRect( btnRect.x() - 3*PADDING - authorWidth, topTextLine, authorWidth + 6, authorMetrics.height() ); + painter->setFont( authorFont ); + painter->drawText( authorRect, Qt::AlignCenter, author ); + + // Disable version for now, that space is used + // const QRect versionRect = authorRect.translated( 0, authorRect.height() ); + // QString version = index.data( AccountModel::VersionRole ).toString(); + // painter->drawText( versionRect, Qt::AlignCenter, version ); + + edgeOfRightExtras = authorRect.x(); } - - // downloaded num times, underneath button - QString count = tr( "%1 downloads" ).arg( index.data( AccountModel::DownloadCounterRole ).toInt() ); - const QRect countRect( btnRect.left(), btnRect.bottom() + PADDING, btnRect.width(), opt.rect.bottom() - PADDING - btnRect.bottom() ); - QFont countFont = descFont; - countFont.setPointSize( countFont.pointSize() - 2 ); - countFont.setBold( true ); - painter->setFont( countFont ); - painter->drawText( countRect, Qt::AlignCenter | Qt::TextWordWrap, count ); - - // author and version - QString author = index.data( AccountModel::AuthorRole ).toString(); - const int authorWidth = authorMetrics.width( author ); - const int topTextLine = opt.rect.top() + PADDING; - const QRect authorRect( btnRect.x() - 3*PADDING - authorWidth, topTextLine, authorWidth + 6, authorMetrics.height() ); - painter->setFont( authorFont ); - painter->drawText( authorRect, Qt::AlignCenter, author ); - - // Disable version for now, that space is used -// const QRect versionRect = authorRect.translated( 0, authorRect.height() ); -// QString version = index.data( AccountModel::VersionRole ).toString(); -// painter->drawText( versionRect, Qt::AlignCenter, version ); - // if this is a real resolver, show config wrench, state/status, and string - int edgeOfRightExtras = btnRect.x(); + edgeOfRightExtras = btnRect.x(); if ( rowType == AccountModel::TopLevelAccount ) { const QRect confRect = QRect( btnRect.x() - 2*PADDING - WRENCH_SIZE, center - WRENCH_SIZE / 2, WRENCH_SIZE, WRENCH_SIZE ); @@ -424,20 +436,21 @@ AccountDelegate::paintTopLevel( QPainter* painter, const QStyleOptionViewItemV4& topt.pos = confRect.topLeft(); drawConfigWrench( painter, opt, topt ); + edgeOfRightExtras = confRect.left(); } painter->save(); painter->setFont( installFont ); - edgeOfRightExtras = drawStatus( painter, QPointF( confRect.x() - PADDING, center ), index ); + edgeOfRightExtras = drawStatus( painter, QPointF( edgeOfRightExtras - PADDING, center ), index ); painter->restore(); } // Title and description! // title QString title = index.data( Qt::DisplayRole ).toString(); - const int rightTitleEdge = authorRect.x() - PADDING; + const int rightTitleEdge = edgeOfRightExtras - PADDING; const int leftTitleEdge = pixmapRect.right() + PADDING; - const QRect textRect( leftTitleEdge, topTextLine, rightTitleEdge - leftTitleEdge, center - opt.rect.top() - PADDING ); + const QRect textRect( leftTitleEdge, opt.rect.top() + PADDING, rightTitleEdge - leftTitleEdge, center - opt.rect.top() - PADDING ); painter->setFont( titleFont ); painter->drawText( textRect, Qt::AlignVCenter | Qt::AlignLeft, title ); @@ -448,6 +461,7 @@ AccountDelegate::paintTopLevel( QPainter* painter, const QStyleOptionViewItemV4& painter->setFont( descFont ); painter->drawText( descRect, Qt::AlignLeft | Qt::TextWordWrap, desc ); + painter->setRenderHints( QPainter::RenderHints() ); painter->drawLine( opt.rect.bottomLeft(), opt.rect.bottomRight() ); } @@ -457,14 +471,16 @@ AccountDelegate::paintChild( QPainter* painter, const QStyleOptionViewItemV4& op { const int radius = 6; const int top = option.rect.top(); + const int center = top + option.rect.height() / 2; QPainterPath outline; outline.moveTo( option.rect.topLeft() ); + const int rightPadding = 2; outline.lineTo( option.rect.left(), option.rect.bottom() - radius ); outline.quadTo( option.rect.bottomLeft(), QPointF( option.rect.left() + radius, option.rect.bottom() ) ); - outline.lineTo( option.rect.right() - radius, option.rect.bottom() ); - outline.quadTo( option.rect.bottomRight(), QPointF( option.rect.right() - 1, top ) ); - outline.lineTo( option.rect.right(), top ); + outline.lineTo( option.rect.right() - radius - rightPadding, option.rect.bottom() ); + outline.quadTo( QPointF( option.rect.right() - rightPadding, option.rect.bottom() ), QPointF( option.rect.right() - rightPadding, option.rect.bottom() - radius ) ); + outline.lineTo( option.rect.right() - 2, top ); painter->drawPath( outline ); @@ -482,7 +498,32 @@ AccountDelegate::paintChild( QPainter* painter, const QStyleOptionViewItemV4& op painter->setFont( f ); painter->drawText( option.rect.adjusted( PADDING + checkRect.right(), 0, 0, 0 ), Qt::AlignVCenter | Qt::AlignLeft, username ); + // draw remove icon, config wrench, and then status from right edge + const QRect removeRect( option.rect.right() - rightPadding - PADDING - REMOVE_ICON_SIZE, center - REMOVE_ICON_SIZE/2, REMOVE_ICON_SIZE, REMOVE_ICON_SIZE ); + painter->drawPixmap( removeRect, m_removeIcon ); + int edgeOfRightExtras = removeRect.left(); + + if ( index.data( AccountModel::HasConfig ).toBool() ) + { + const QRect confRect = QRect( removeRect.x() - PADDING - SMALL_WRENCH_SIZE, center - SMALL_WRENCH_SIZE / 2, SMALL_WRENCH_SIZE, SMALL_WRENCH_SIZE ); + + QStyleOptionToolButton topt; + topt.rect = confRect; + topt.pos = confRect.topLeft(); + + QStyleOptionViewItemV4 opt3 = option; + drawConfigWrench( painter, opt3, topt ); + + edgeOfRightExtras = confRect.left(); + } + + painter->save(); + QFont smallFont = option.font; + smallFont.setPointSize( smallFont.pointSize() - 2 ); + painter->setFont( smallFont ); + drawStatus( painter, QPointF( edgeOfRightExtras - PADDING, center ), index ); + painter->restore(); } diff --git a/src/AccountDelegate.h b/src/AccountDelegate.h index 69c4257e2..a12c21e73 100644 --- a/src/AccountDelegate.h +++ b/src/AccountDelegate.h @@ -57,8 +57,7 @@ private: int drawStatus( QPainter* painter, const QPointF& rightCenterEdge, const QModelIndex& index ) const; QMap< QString, QPixmap > m_cachedIcons; - QPixmap m_offlineIcon, m_onlineIcon, m_defaultCover, m_onHoverStar, m_ratingStarPositive, m_ratingStarNegative; - + QPixmap m_offlineIcon, m_onlineIcon, m_defaultCover, m_onHoverStar, m_ratingStarPositive, m_ratingStarNegative, m_removeIcon; int m_widestTextWidth; int m_hoveringOver; QPersistentModelIndex m_hoveringItem; diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index 8765ddda0..8522a1cf7 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -104,8 +104,6 @@ AccountModel::data( const QModelIndex& index, int role ) const return ShippedWithTomahawk; case DescriptionRole: return fac->description(); - case AuthorRole: - return "Tomahawk Team"; case RowTypeRole: return TopLevelFactory; default: @@ -172,16 +170,38 @@ AccountModel::data( const QModelIndex& index, int role ) const else if ( node->type == AccountModelNode::UniqueFactoryType ) acct = node->account; - Q_ASSERT( acct ); - - switch ( role ) + // If there's no account*, then it means it's a unique factory that hasn't been created + if ( !acct ) { + Q_ASSERT( node->type == AccountModelNode::UniqueFactoryType ); + Q_ASSERT( node->factory ); + + switch( role ) + { + case Qt::DisplayRole: + return node->factory->prettyName(); + case Qt::DecorationRole: + return node->factory->icon(); + case DescriptionRole: + return node->factory->description(); + case RowTypeRole: + return TopLevelFactory; + case StateRole: + return Uninstalled; + default: + return QVariant(); + } + } + else + { + switch ( role ) + { case Qt::DisplayRole: return acct->accountFriendlyName(); case Qt::DecorationRole: return acct->icon(); case DescriptionRole: - return QString(); + return node->type == AccountModelNode::ManualResolverType ? QString() : node->factory->description(); case Qt::CheckStateRole: return acct->enabled() ? Qt::Checked : Qt::Unchecked; case AccountData: @@ -193,9 +213,10 @@ AccountModel::data( const QModelIndex& index, int role ) const case HasConfig: return acct->configurationWidget() != 0; case StateRole: - return node->type == AccountModelNode::ManualResolverType ? Installed : UniqueFactory; + return Installed; default: return QVariant(); + } } } case AccountModelNode::AccountType: diff --git a/src/main.cpp b/src/main.cpp index 7d8516b9a..f326cca78 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -103,7 +103,7 @@ main( int argc, char *argv[] ) #endif #ifndef ENABLE_HEADLESS - new BreakPad( QDir::tempPath(), TomahawkSettings::instance()->crashReporterEnabled() ); + // new BreakPad( QDir::tempPath(), TomahawkSettings::instance()->crashReporterEnabled() ); #endif KDSingleApplicationGuard guard( &a, KDSingleApplicationGuard::AutoKillOtherInstances ); From 34dbc50b3a6777f25f886ebb5cea1c00409688c6 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 3 Feb 2012 17:19:04 -0500 Subject: [PATCH 052/104] Work to add setData to the model, and hook up model to some signals --- src/AccountDelegate.cpp | 452 ++++++++++---------- src/AccountDelegate.h | 20 +- src/CMakeLists.txt | 11 +- src/GetNewStuffDelegate.cpp | 326 -------------- src/GetNewStuffDelegate.h | 50 --- src/GetNewStuffDialog.cpp | 75 ---- src/GetNewStuffDialog.h | 44 -- src/GetNewStuffDialog.ui | 91 ---- src/GetNewStuffModel.cpp | 293 ------------- src/GetNewStuffModel.h | 91 ---- src/configdelegatebase.cpp | 113 ----- src/configdelegatebase.h | 2 - src/libtomahawk/AtticaManager.cpp | 18 + src/libtomahawk/accounts/AccountModel.cpp | 264 +++++++++++- src/libtomahawk/accounts/AccountModel.h | 16 +- src/libtomahawk/accounts/AccountModelNode.h | 2 +- src/settingsdialog.cpp | 37 +- src/settingsdialog.h | 3 - 18 files changed, 543 insertions(+), 1365 deletions(-) delete mode 100644 src/GetNewStuffDelegate.cpp delete mode 100644 src/GetNewStuffDelegate.h delete mode 100644 src/GetNewStuffDialog.cpp delete mode 100644 src/GetNewStuffDialog.h delete mode 100644 src/GetNewStuffDialog.ui delete mode 100644 src/GetNewStuffModel.cpp delete mode 100644 src/GetNewStuffModel.h delete mode 100644 src/configdelegatebase.cpp diff --git a/src/AccountDelegate.cpp b/src/AccountDelegate.cpp index 6f4efb1ce..020a0e89a 100644 --- a/src/AccountDelegate.cpp +++ b/src/AccountDelegate.cpp @@ -20,6 +20,7 @@ #include #include +#include #include "accounts/AccountModel.h" #include "accounts/Account.h" @@ -50,7 +51,7 @@ using namespace Tomahawk; using namespace Accounts; AccountDelegate::AccountDelegate( QObject* parent ) - : ConfigDelegateBase ( parent ) + : QStyledItemDelegate ( parent ) , m_widestTextWidth( 0 ) { @@ -87,12 +88,6 @@ AccountDelegate::AccountDelegate( QObject* parent ) } } -bool -AccountDelegate::editorEvent ( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index ) -{ - return ConfigDelegateBase::editorEvent( event, model, option, index ); -} - QSize AccountDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const @@ -125,131 +120,6 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, paintChild( painter, opt, index ); return; - -// const QRect itemRect = opt.rect; -// const int top = itemRect.top(); -// const int mid = itemRect.height() / 2; -// const int quarter = mid - ( itemRect.height() / 4 ); -// -// // one line bold for account name -// // space below it for online/offline status -// // checkbox, icon, name/status, features, config icon -// QFont name = opt.font; -// name.setPointSize( name.pointSize() + 2 ); -// name.setBold( true ); -// -// QFont smallFont = opt.font; -// smallFont.setPointSize( smallFont.pointSize() - 1 ); -// QFontMetrics smallFontFM( smallFont ); -// -// // draw the background -// const QWidget* w = opt.widget; -// QStyle* style = w ? w->style() : QApplication::style(); -// style->drawPrimitive( QStyle::PE_PanelItemViewItem, &opt, painter, w ); -/* - int iconLeftEdge = CHECK_LEFT_EDGE + WRENCH_SIZE + PADDING; - int textLeftEdge = iconLeftEdge + ICONSIZE + PADDING; - - // draw checkbox first - int pos = ( mid ) - ( WRENCH_SIZE / 2 ); - QRect checkRect = QRect( CHECK_LEFT_EDGE, pos + top, WRENCH_SIZE, WRENCH_SIZE ); - opt.rect = checkRect; - drawCheckBox( opt, painter, w ); - - // draw the icon if it exists - pos = mid - ( ICONSIZE / 2 ); - if( !index.data( Qt::DecorationRole ).value< QPixmap >().isNull() ) { - QRect prect = QRect( iconLeftEdge, pos + top, ICONSIZE, ICONSIZE ); - - painter->save(); - painter->drawPixmap( prect, index.data( Qt::DecorationRole ).value< QPixmap >().scaled( prect.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation ) ); - painter->restore(); - } - - // name - painter->save(); - painter->setFont( name ); - QFontMetrics namefm( name ); - // pos will the top-left point of the text rect - pos = quarter - ( namefm.height() / 2 ) + top; - const QString nameStr = index.data( AccountModel::AccountName ).toString(); - const int titleWidth = namefm.width( nameStr ); - const QRect nameRect( textLeftEdge, pos, titleWidth, namefm.height() ); - painter->drawText( nameRect, nameStr ); - painter->restore(); - - // draw the online/offline status - const int stateY = mid + quarter - ( smallFontFM.height() / 2 ) + top; - - QPixmap p; - QString statusText; - Account::ConnectionState state = static_cast< Account::ConnectionState >( index.data( AccountModel::ConnectionStateRole ).toInt() ); - if ( state == Account::Connected ) - { - p = m_cachedIcons[ "sipplugin-online" ]; - statusText = tr( "Online" ); - } - else if ( state == Account::Connecting ) - { - p = m_cachedIcons[ "sipplugin-offline" ]; - statusText = tr( "Connecting..." ); - } - else - { - p = m_cachedIcons[ "sipplugin-offline" ]; - statusText = tr( "Offline" ); - } - painter->drawPixmap( textLeftEdge, stateY, STATUS_ICON_SIZE, STATUS_ICON_SIZE, p ); - - int width = smallFontFM.width( statusText ); - int statusTextX = textLeftEdge + STATUS_ICON_SIZE + PADDING; - painter->save(); - painter->setFont( smallFont ); - painter->drawText( QRect( statusTextX, stateY, width, smallFontFM.height() ), statusText ); - painter->restore(); - - // right-most edge of text on left (name, desc) is the cutoff point for the rest of the delegate - width = qMax( statusTextX + width, textLeftEdge + titleWidth ); - - // from the right edge--config status and online/offline - QRect confRect = QRect( itemRect.width() - WRENCH_SIZE - 2 * PADDING, mid - WRENCH_SIZE / 2 + top, WRENCH_SIZE, WRENCH_SIZE ); - if( index.data( AccountModel::HasConfig ).toBool() ) { - - QStyleOptionToolButton topt; - topt.rect = confRect; - topt.pos = confRect.topLeft(); - - drawConfigWrench( painter, opt, topt ); - } - - const bool hasCapability = ( static_cast< Accounts::AccountTypes >( index.data( AccountModel::AccountTypeRole ).toInt() ) != Accounts::NoType ); - - // draw optional capability text if it exists - if ( hasCapability ) - { - QString capString; - AccountTypes types = AccountTypes( index.data( AccountModel::AccountTypeRole ).toInt() ); - if ( ( types & Accounts::SipType ) && ( types & Accounts::ResolverType ) ) - capString = tr( "Connects to, plays from friends" ); - else if ( types & Accounts::SipType ) - capString = tr( "Connects to friends" ); - else if ( types & Accounts::ResolverType ) - capString = tr( "Finds Music"); - - // checkbox for capability -// QRect capCheckRect( statusX, capY - STATUS_ICON_SIZE / 2 + top, STATUS_ICON_SIZE, STATUS_ICON_SIZE ); -// opt.rect = capCheckRect; -// drawCheckBox( opt, painter, w ); - - // text to accompany checkbox - const int capY = mid - ( smallFontFM.height() / 2 ) + top; - const int configLeftEdge = confRect.left() - PADDING; - const int capW = configLeftEdge - width; - // Right-align text - const int capTextX = qMax( width, configLeftEdge - smallFontFM.width( capString ) ); - painter->setFont( smallFont ); - painter->drawText( QRect( capTextX, capY, configLeftEdge - capTextX, smallFontFM.height() ), Qt::AlignRight, capString ); - }*/ } @@ -294,7 +164,8 @@ AccountDelegate::paintTopLevel( QPainter* painter, const QStyleOptionViewItemV4& opt2.rect = checkRect; const AccountModel::ItemState state = static_cast< AccountModel::ItemState >( index.data( AccountModel::StateRole ).toInt() ); const bool canCheck = ( state == AccountModel::Installed || state == AccountModel::ShippedWithTomahawk ); - opt2.state = canCheck ? QStyle::State_On : QStyle::State_Off; + if ( !canCheck ) + opt2.state &= ~QStyle::State_Enabled; drawCheckBox( opt2, painter, opt.widget ); } leftEdge += WRENCH_SIZE + PADDING / 2; @@ -315,62 +186,69 @@ AccountDelegate::paintTopLevel( QPainter* painter, const QStyleOptionViewItemV4& // install / status button const AccountModel::ItemState state = static_cast< AccountModel::ItemState >( index.data( AccountModel::StateRole ).toInt() ); - QString actionText; - switch( state ) + int edgeOfRightExtras = opt.rect.right(); + if ( rowType == Tomahawk::Accounts::AccountModel::TopLevelFactory ) { - case AccountModel::Uninstalled: - actionText = tr( "Install" ); - break; - case AccountModel::Installing: - actionText = tr( "Installing" ); - break; - case AccountModel::Upgrading: - actionText = tr( "Upgrading" ); - break; - case AccountModel::Failed: - actionText = tr( "Failed" ); - break; - case AccountModel::Installed: - actionText = tr( "Uninstall" ); - break; - case AccountModel::NeedsUpgrade: - actionText = tr( "Upgrade" ); - break; - case AccountModel::ShippedWithTomahawk: - actionText = tr( "Create" ); - break; - case AccountModel::UniqueFactory: - actionText = tr( "Installed" ); - break; + QString actionText; + switch( state ) + { + case AccountModel::Uninstalled: + actionText = tr( "Install" ); + break; + case AccountModel::Installing: + actionText = tr( "Installing" ); + break; + case AccountModel::Upgrading: + actionText = tr( "Upgrading" ); + break; + case AccountModel::Failed: + actionText = tr( "Failed" ); + break; + case AccountModel::Installed: + actionText = tr( "Uninstall" ); + break; + case AccountModel::NeedsUpgrade: + actionText = tr( "Upgrade" ); + break; + case AccountModel::ShippedWithTomahawk: + actionText = tr( "Create" ); + break; + case AccountModel::UniqueFactory: + actionText = tr( "Installed" ); + break; + } + // title and description + const int btnWidth = m_widestTextWidth + 7; + leftEdge = opt.rect.width() - PADDING - btnWidth - 3; + const QRect btnRect( leftEdge, center - ( installMetrics.height() + 4 ) / 2, btnWidth, installMetrics.height() + 4 ); + m_cachedButtonRects[ index ] = btnRect; + + + painter->save(); + painter->setPen( opt.palette.color( QPalette::Active, QPalette::AlternateBase ) ); + + drawRoundedButton( painter, btnRect ); + + painter->setFont( installFont ); + painter->drawText( btnRect, Qt::AlignCenter, actionText ); + painter->restore(); + + edgeOfRightExtras = btnRect.left(); } - // title and description - const int btnWidth = m_widestTextWidth + 7; - leftEdge = opt.rect.width() - PADDING - btnWidth - 3; - const QRect btnRect( leftEdge, center - ( installMetrics.height() + 4 ) / 2, btnWidth, installMetrics.height() + 4 ); - m_cachedButtonRects[ index ] = btnRect; - const QPen saved = painter->pen(); - painter->setPen( opt.palette.color( QPalette::Active, QPalette::AlternateBase ) ); - - drawRoundedButton( painter, btnRect ); - - painter->setFont( installFont ); - painter->drawText( btnRect, Qt::AlignCenter, actionText ); - - painter->setPen( saved ); - - - int edgeOfRightExtras = btnRect.x(); if ( rowType == AccountModel::TopLevelAccount ) { // rating stars const int rating = index.data( AccountModel::RatingRole ).toInt(); const int ratingWidth = 5 * ( m_ratingStarPositive.width() + PADDING_BETWEEN_STARS ); - int runningEdge = ( btnRect.right() - btnRect.width() / 2 ) - ratingWidth / 2; + +// int runningEdge = ( btnRect.right() - btnRect.width() / 2 ) - ratingWidth / 2; + int runningEdge = opt.rect.right() - PADDING - ratingWidth; + edgeOfRightExtras = runningEdge; for ( int i = 1; i < 6; i++ ) { - QRect r( runningEdge, btnRect.top() - m_ratingStarPositive.height() - PADDING, m_ratingStarPositive.width(), m_ratingStarPositive.height() ); + QRect r( runningEdge, opt.rect.top() + PADDING, m_ratingStarPositive.width(), m_ratingStarPositive.height() ); if ( i == 1 ) m_cachedStarRects[ index ] = r; @@ -401,19 +279,23 @@ AccountDelegate::paintTopLevel( QPainter* painter, const QStyleOptionViewItemV4& // downloaded num times, underneath button QString count = tr( "%1 downloads" ).arg( index.data( AccountModel::DownloadCounterRole ).toInt() ); - const QRect countRect( btnRect.left(), btnRect.bottom() + PADDING, btnRect.width(), opt.rect.bottom() - PADDING - btnRect.bottom() ); + QFont countFont = descFont; countFont.setPointSize( countFont.pointSize() - 2 ); countFont.setBold( true ); painter->setFont( countFont ); + const int countW = painter->fontMetrics().width( count ); + + const QRect countRect( opt.rect.right() - PADDING - countW, opt.rect.bottom() - PADDING - painter->fontMetrics().height(), countW, painter->fontMetrics().height() ); + painter->setFont( countFont ); painter->drawText( countRect, Qt::AlignCenter | Qt::TextWordWrap, count ); // author and version QString author = index.data( AccountModel::AuthorRole ).toString(); + painter->setFont( authorFont ); const int authorWidth = authorMetrics.width( author ); const int topTextLine = opt.rect.top() + PADDING; - const QRect authorRect( btnRect.x() - 3*PADDING - authorWidth, topTextLine, authorWidth + 6, authorMetrics.height() ); - painter->setFont( authorFont ); + const QRect authorRect( edgeOfRightExtras - 2*PADDING - authorWidth, topTextLine, authorWidth + 6, authorMetrics.height() ); painter->drawText( authorRect, Qt::AlignCenter, author ); // Disable version for now, that space is used @@ -425,10 +307,10 @@ AccountDelegate::paintTopLevel( QPainter* painter, const QStyleOptionViewItemV4& } // if this is a real resolver, show config wrench, state/status, and string - edgeOfRightExtras = btnRect.x(); + m_cachedConfigRects.remove( index ); if ( rowType == AccountModel::TopLevelAccount ) { - const QRect confRect = QRect( btnRect.x() - 2*PADDING - WRENCH_SIZE, center - WRENCH_SIZE / 2, WRENCH_SIZE, WRENCH_SIZE ); + const QRect confRect = QRect( edgeOfRightExtras - 2*PADDING - WRENCH_SIZE, center - WRENCH_SIZE / 2, WRENCH_SIZE, WRENCH_SIZE ); if( index.data( AccountModel::HasConfig ).toBool() ) { QStyleOptionToolButton topt; @@ -436,13 +318,17 @@ AccountDelegate::paintTopLevel( QPainter* painter, const QStyleOptionViewItemV4& topt.pos = confRect.topLeft(); drawConfigWrench( painter, opt, topt ); + m_cachedConfigRects[ index ] = confRect; edgeOfRightExtras = confRect.left(); } - painter->save(); - painter->setFont( installFont ); - edgeOfRightExtras = drawStatus( painter, QPointF( edgeOfRightExtras - PADDING, center ), index ); - painter->restore(); + if ( state == AccountModel::Installed || state == AccountModel::ShippedWithTomahawk || state == AccountModel::NeedsUpgrade ) + { + painter->save(); + painter->setFont( installFont ); + edgeOfRightExtras = drawStatus( painter, QPointF( edgeOfRightExtras - PADDING, center ), index ); + painter->restore(); + } } // Title and description! @@ -500,10 +386,12 @@ AccountDelegate::paintChild( QPainter* painter, const QStyleOptionViewItemV4& op // draw remove icon, config wrench, and then status from right edge const QRect removeRect( option.rect.right() - rightPadding - PADDING - REMOVE_ICON_SIZE, center - REMOVE_ICON_SIZE/2, REMOVE_ICON_SIZE, REMOVE_ICON_SIZE ); + m_cachedButtonRects[ index ] = removeRect; painter->drawPixmap( removeRect, m_removeIcon ); int edgeOfRightExtras = removeRect.left(); + m_cachedConfigRects.remove( index ); if ( index.data( AccountModel::HasConfig ).toBool() ) { const QRect confRect = QRect( removeRect.x() - PADDING - SMALL_WRENCH_SIZE, center - SMALL_WRENCH_SIZE / 2, SMALL_WRENCH_SIZE, SMALL_WRENCH_SIZE ); @@ -514,6 +402,7 @@ AccountDelegate::paintChild( QPainter* painter, const QStyleOptionViewItemV4& op QStyleOptionViewItemV4 opt3 = option; drawConfigWrench( painter, opt3, topt ); + m_cachedConfigRects[ index ] = confRect; edgeOfRightExtras = confRect.left(); } @@ -527,6 +416,103 @@ AccountDelegate::paintChild( QPainter* painter, const QStyleOptionViewItemV4& op } +bool +AccountDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index ) +{ + if ( event->type() != QEvent::MouseButtonPress && + event->type() != QEvent::MouseButtonRelease && + event->type() != QEvent::MouseButtonDblClick && + event->type() != QEvent::MouseMove ) + return false; + + if ( event->type() == QEvent::MouseButtonPress ) + { + // Show the config wrench as depressed on click + QMouseEvent* me = static_cast< QMouseEvent* >( event ); + if ( me->button() == Qt::LeftButton && m_cachedConfigRects.contains( index ) && m_cachedConfigRects[ index ].contains( me->pos() ) ) + { + m_configPressed = index; + + Account* acct = qobject_cast< Account* >( index.data( AccountModel::AccountData ).value< QObject* >() ); + Q_ASSERT( acct ); // Should not be showing a config wrench if there is no account! + emit openConfig( acct ); + return true; + } + } else if ( event->type() == QEvent::MouseButtonRelease || event->type() == QEvent::MouseButtonDblClick ) + { + QMouseEvent* me = static_cast< QMouseEvent* >( event ); + if ( m_configPressed.isValid() ) + emit update( m_configPressed ); + + m_configPressed = QModelIndex(); + + const AccountModel::ItemState state = static_cast< AccountModel::ItemState >( index.data( AccountModel::StateRole ).toInt() ); + const bool canCheck = ( state == AccountModel::Installed || state == AccountModel::ShippedWithTomahawk ); + if ( !canCheck ) + return false; + + // A few options. First, could be the checkbox on/off. + // second, could be the install/uninstall/create button + // third could be the config button + if ( checkRectForIndex( option, index ).contains( me->pos() ) ) + { + // Check box for this row + + // eat the double click events inside the check rect + if( event->type() == QEvent::MouseButtonDblClick ) { + return true; + } + + Qt::CheckState curState = static_cast< Qt::CheckState >( index.data( Qt::CheckStateRole ).toInt() ); + Qt::CheckState newState = curState == Qt::Checked ? Qt::Unchecked : Qt::Checked; + return model->setData( index, newState, AccountModel::CheckboxClickedRole ); + } + else if ( m_cachedButtonRects.contains( index ) && m_cachedButtonRects[ index ].contains( me->pos() ) ) + { + // Install/create/etc button for this row + model->setData( index, true, AccountModel::ButtonClickedRole ); + } + } + + if ( m_cachedStarRects.contains( index ) ) + { + QRect fullStars = m_cachedStarRects[ index ]; + const int starsWidth = 5 * ( m_ratingStarPositive.width() + PADDING_BETWEEN_STARS ); + fullStars.setWidth( starsWidth ); + + QMouseEvent* me = static_cast< QMouseEvent* >( event ); + + if ( fullStars.contains( me->pos() ) ) + { + const int eachStar = starsWidth / 5; + const int clickOffset = me->pos().x() - fullStars.x(); + const int whichStar = (clickOffset / eachStar) + 1; + + if ( event->type() == QEvent::MouseButtonRelease ) + { + model->setData( index, whichStar, AccountModel::RatingRole ); + } + else if ( event->type() == QEvent::MouseMove ) + { + // 0-indexed + m_hoveringOver = whichStar; + m_hoveringItem = index; + } + + return true; + } + } + + if ( m_hoveringOver > -1 ) + { + emit update( m_hoveringItem ); + m_hoveringOver = -1; + m_hoveringItem = QPersistentModelIndex(); + } + return false; +} + + void AccountDelegate::drawRoundedButton( QPainter* painter, const QRect& btnRect ) const { @@ -598,46 +584,62 @@ AccountDelegate::drawStatus( QPainter* painter, const QPointF& rightCenterEdge, } -QRect -AccountDelegate::checkRectForIndex( const QStyleOptionViewItem &option, const QModelIndex &idx, int role ) const +void +AccountDelegate::drawCheckBox( QStyleOptionViewItemV4& opt, QPainter* p, const QWidget* w ) const { -// if ( role == Qt::CheckStateRole ) -// { -// // the whole resolver checkbox -// QStyleOptionViewItemV4 opt = option; -// initStyleOption( &opt, idx ); -// const int mid = opt.rect.height() / 2; -// const int pos = mid - ( ICONSIZE / 2 ); -// QRect checkRect( CHECK_LEFT_EDGE, pos + opt.rect.top(), ICONSIZE, ICONSIZE ); -// -// return checkRect; -// } else if ( role == AccountModel::AccountTypeRole ) -// { -// // The capabilities checkbox -// QStyleOptionViewItemV4 opt = option; -// initStyleOption( &opt, idx ); -// const int quarter = opt.rect.height() / 4 + opt.rect.height() / 2; -// const int leftEdge = opt.rect.width() - PADDING - WRENCH_SIZE - PADDING - WRENCH_SIZE; -// QRect checkRect( leftEdge, quarter, WRENCH_SIZE, WRENCH_SIZE ); -// return checkRect; -// } + QStyle* style = w ? w->style() : QApplication::style(); + opt.checkState == Qt::Checked ? opt.state |= QStyle::State_On : opt.state |= QStyle::State_Off; + style->drawPrimitive( QStyle::PE_IndicatorViewItemCheck, &opt, p, w ); +} + + +void +AccountDelegate::drawConfigWrench ( QPainter* painter, QStyleOptionViewItemV4& opt, QStyleOptionToolButton& topt ) const +{ + const QWidget* w = opt.widget; + QStyle* style = w ? w->style() : QApplication::style(); + + // draw it the same size as the check belox + topt.font = opt.font; + topt.icon = QIcon( RESPATH "images/configure.png" ); + topt.iconSize = QSize( 16, 16 ); + topt.subControls = QStyle::SC_ToolButton; + topt.activeSubControls = QStyle::SC_None; + topt.features = QStyleOptionToolButton::None; + bool pressed = ( m_configPressed == opt.index ); + topt.state = pressed ? QStyle::State_On : QStyle::State_Raised; + if( opt.state & QStyle::State_MouseOver || pressed ) + topt.state |= QStyle::State_HasFocus; + style->drawComplexControl( QStyle::CC_ToolButton, &topt, painter, w ); +} + + + +QRect +AccountDelegate::checkRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const +{ + // the checkbox for this row was hit + const AccountModel::RowType rowType = static_cast< AccountModel::RowType >( idx.data( AccountModel::RowTypeRole ).toInt() ); + + QStyleOptionViewItemV4 opt = option; + initStyleOption( &opt, idx ); + + if ( rowType == AccountModel::TopLevelAccount || rowType == AccountModel::TopLevelFactory ) + { + // Top level item, return the corresponding rect + const int ypos = ( opt.rect.top() + opt.rect.height() / 2 ) - ( WRENCH_SIZE / 2 ); + QRect checkRect = QRect( PADDING, ypos, WRENCH_SIZE, WRENCH_SIZE ); + return checkRect; + } else if ( rowType == AccountModel::ChildAccount ) + { + // Return smaller rect of individual child account + const int smallWrenchSize = opt.rect.height() - PADDING; + int ypos = ( opt.rect.center().y() ) - ( smallWrenchSize / 2 ); + QRect checkRect = QRect( opt.rect.left() + PADDING, ypos, smallWrenchSize, smallWrenchSize ); + return checkRect; + } + return QRect(); } -QRect -AccountDelegate::configRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const -{ - QStyleOptionViewItemV4 opt = option; - initStyleOption( &opt, idx ); - QRect itemRect = opt.rect; - QRect confRect = QRect( itemRect.width() - ICONSIZE - 2 * PADDING, (opt.rect.height() / 2) - ICONSIZE / 2 + opt.rect.top(), ICONSIZE, ICONSIZE ); - return confRect; -} - -void -AccountDelegate::askedForEdit( const QModelIndex& idx ) -{ - emit openConfig( qobject_cast< Account* >( idx.data( AccountModel::AccountData ).value< QObject* >() ) ); -} - diff --git a/src/AccountDelegate.h b/src/AccountDelegate.h index a12c21e73..f9b565d79 100644 --- a/src/AccountDelegate.h +++ b/src/AccountDelegate.h @@ -19,7 +19,7 @@ #ifndef ACCOUNTDELEGATE_H #define ACCOUNTDELEGATE_H -#include "configdelegatebase.h" +#include #include "accounts/AccountModel.h" namespace Tomahawk @@ -29,21 +29,17 @@ namespace Accounts class Account; -class AccountDelegate : public ConfigDelegateBase +class AccountDelegate : public QStyledItemDelegate { Q_OBJECT public: AccountDelegate( QObject* parent = 0); virtual void paint ( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const; - virtual bool editorEvent ( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index ); virtual QSize sizeHint ( const QStyleOptionViewItem& option, const QModelIndex& index ) const; - virtual QRect checkRectForIndex( const QStyleOptionViewItem &option, const QModelIndex &idx, int role ) const; - virtual QRect configRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const; - -private slots: - void askedForEdit( const QModelIndex& idx ); +protected: + virtual bool editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index ); signals: void update( const QModelIndex& idx ); @@ -52,17 +48,23 @@ signals: private: void paintTopLevel( QPainter* painter, const QStyleOptionViewItemV4& option, const QModelIndex& index ) const; void paintChild( QPainter* painter, const QStyleOptionViewItemV4& option, const QModelIndex& index ) const; + void drawRoundedButton( QPainter* painter, const QRect& buttonRect ) const; // Returns new left edge int drawStatus( QPainter* painter, const QPointF& rightCenterEdge, const QModelIndex& index ) const; + void drawCheckBox( QStyleOptionViewItemV4& opt, QPainter* p, const QWidget* w ) const; + void drawConfigWrench( QPainter* painter, QStyleOptionViewItemV4& option, QStyleOptionToolButton& topt ) const; + + QRect checkRectForIndex( const QStyleOptionViewItem &option, const QModelIndex &idx ) const; QMap< QString, QPixmap > m_cachedIcons; QPixmap m_offlineIcon, m_onlineIcon, m_defaultCover, m_onHoverStar, m_ratingStarPositive, m_ratingStarNegative, m_removeIcon; int m_widestTextWidth; int m_hoveringOver; - QPersistentModelIndex m_hoveringItem; + QPersistentModelIndex m_hoveringItem, m_configPressed; mutable QHash< QPersistentModelIndex, QRect > m_cachedButtonRects; mutable QHash< QPersistentModelIndex, QRect > m_cachedStarRects; + mutable QHash< QPersistentModelIndex, QRect > m_cachedConfigRects; }; } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 31591e961..72de137ed 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -74,7 +74,6 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui} audiocontrols.cpp settingsdialog.cpp diagnosticsdialog.cpp - configdelegatebase.cpp AccountDelegate.cpp settingslistdelegate.cpp tomahawkwindow.cpp @@ -98,13 +97,6 @@ IF(LIBLASTFM_FOUND) ) ENDIF(LIBLASTFM_FOUND) -IF(LIBATTICA_FOUND) - SET( tomahawkSourcesGui ${tomahawkSourcesGui} GetNewStuffDialog.cpp GetNewStuffDelegate.cpp GetNewStuffModel.cpp ) - SET( tomahawkHeadersGui ${tomahawkHeadersGui} GetNewStuffDialog.h GetNewStuffDelegate.h GetNewStuffModel.h ) - INCLUDE_DIRECTORIES( ${LIBATTICA_INCLUDE_DIR} ) -ENDIF(LIBATTICA_FOUND) - - SET( tomahawkHeadersGui ${tomahawkHeadersGui} sourcetree/sourcesmodel.h sourcetree/sourcesproxymodel.h @@ -124,7 +116,6 @@ SET( tomahawkHeadersGui ${tomahawkHeadersGui} audiocontrols.h settingsdialog.h diagnosticsdialog.h - configdelegatebase.h AccountDelegate.h settingslistdelegate.h delegateconfigwrapper.h @@ -140,7 +131,6 @@ SET( tomahawkUI ${tomahawkUI} audiocontrols.ui - GetNewStuffDialog.ui LoadXSPFDialog.ui ) @@ -167,6 +157,7 @@ INCLUDE_DIRECTORIES( ${TAGLIB_INCLUDES} ${PHONON_INCLUDES} ${QJSON_INCLUDE_DIR} + ${LIBATTICA_INCLUDE_DIR} ${LIBECHONEST_INCLUDE_DIR} ${LIBECHONEST_INCLUDE_DIR}/.. ) diff --git a/src/GetNewStuffDelegate.cpp b/src/GetNewStuffDelegate.cpp deleted file mode 100644 index a1a3409bd..000000000 --- a/src/GetNewStuffDelegate.cpp +++ /dev/null @@ -1,326 +0,0 @@ -/* === This file is part of Tomahawk Player - === - * - * Copyright 2010-2011, Leo Franchi - * - * 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 "GetNewStuffDelegate.h" - -#include "GetNewStuffModel.h" -#include "utils/tomahawkutils.h" -#include "utils/logger.h" - -#include -#include -#include -#include "AtticaManager.h" - -#define PADDING 4 -#define PADDING_BETWEEN_STARS 2 -#define STAR_SIZE 12 - -#ifdef Q_WS_MAC -#define SIZEHINT_HEIGHT 70 -#else -#define SIZEHINT_HEIGHT 60 -#endif - -GetNewStuffDelegate::GetNewStuffDelegate( QObject* parent ) - : QStyledItemDelegate ( parent ) - , m_widestTextWidth( 0 ) - , m_hoveringOver( -1 ) -{ - m_defaultCover.load( RESPATH "images/sipplugin-online.png" ); - m_ratingStarPositive.load( RESPATH "images/starred.png" ); - m_ratingStarNegative.load( RESPATH "images/star-unstarred.png" ); - m_onHoverStar.load( RESPATH "images/star-hover.png" ); - - m_ratingStarPositive = m_ratingStarPositive.scaled( STAR_SIZE, STAR_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation ); - m_ratingStarNegative = m_ratingStarNegative.scaled( STAR_SIZE, STAR_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation ); - m_onHoverStar = m_onHoverStar.scaled( STAR_SIZE, STAR_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation ); - - const int w = SIZEHINT_HEIGHT - 2*PADDING; - m_defaultCover = m_defaultCover.scaled( w, w, Qt::KeepAspectRatio, Qt::SmoothTransformation ); - - // save the widest wifth - QFont f( QApplication::font() ); - f.setPointSize( f.pointSize() - 1 ); - QFontMetrics fm( f ); - QStringList l = QStringList() << tr( "Installed" ) << tr( "Installing" ) << tr( "Failed" ) << tr( "Uninstalling" ); - foreach ( const QString& str, l ) - { - if ( fm.width( str ) > m_widestTextWidth ) - m_widestTextWidth = fm.width( str ); - } -} - -void -GetNewStuffDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const -{ - QStyleOptionViewItemV4 opt = option; - initStyleOption( &opt, index ); - - QApplication::style()->drawPrimitive( QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget ); - - painter->setRenderHint( QPainter::Antialiasing ); - - QFont titleFont = opt.font; - titleFont.setBold( true ); - titleFont.setPointSize( titleFont.pointSize() + 2 ); - QFontMetrics titleMetrics( titleFont ); - - QFont authorFont = opt.font; - authorFont.setItalic( true ); - authorFont.setPointSize( authorFont.pointSize() - 1 ); - QFontMetrics authorMetrics( authorFont ); - - QFont descFont = authorFont; - descFont.setItalic( false ); - QFontMetrics descMetrics( descFont ); - - QFont installFont = opt.font; - installFont.setPointSize( installFont.pointSize() - 1 ); - QFontMetrics installMetrics( descFont ); - - const int height = opt.rect.height(); - const int center = height / 2 + opt.rect.top(); - - // Pixmap - QPixmap p = index.data( Qt::DecorationRole ).value< QPixmap >(); - const int pixmapWidth = height - 2*PADDING; - QRect pixmapRect( PADDING, PADDING + opt.rect.top(), pixmapWidth, pixmapWidth ); - if ( p.isNull() ) // default image... TODO - p = m_defaultCover; - else - p = p.scaled( pixmapRect.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation ); - - painter->drawPixmap( pixmapRect, p ); - - // Go from right edge now, stars, install button, and downloaded info - - // install / status button - GetNewStuffModel::ItemState state = static_cast< GetNewStuffModel::ItemState >( index.data( GetNewStuffModel::StateRole ).toInt() ); - QString actionText; - switch( state ) - { - case GetNewStuffModel::Uninstalled: - actionText = tr( "Install" ); - break; - case GetNewStuffModel::Installing: - actionText = tr( "Installing" ); - break; - case GetNewStuffModel::Upgrading: - actionText = tr( "Upgrading" ); - break; - case GetNewStuffModel::Failed: - actionText = tr( "Failed" ); - break; - case GetNewStuffModel::Installed: - actionText = tr( "Uninstall" ); - break; - case GetNewStuffModel::NeedsUpgrade: - actionText = tr( "Upgrade" ); - break; - case GetNewStuffModel::CanInstallMore: - actionText = tr( "Install Another" ); - break; - } - - const int btnWidth = m_widestTextWidth + 7; - const int leftEdge = opt.rect.width() - PADDING - btnWidth - 3; - const QRect btnRect( leftEdge, center - ( installMetrics.height() + 4 ) / 2, btnWidth, installMetrics.height() + 4 ); - m_cachedButtonRects[ QPair(index.row(), index.column()) ] = btnRect; - - QPen saved = painter->pen(); - painter->setPen( opt.palette.color( QPalette::Active, QPalette::AlternateBase ) ); - - QPainterPath btnPath; - const int radius = 3; - //btnPath.addRoundedRect( btnRect, 3, 3 ); - // draw top half gradient - const int btnCenter = btnRect.bottom() - ( btnRect.height() / 2 ); - btnPath.moveTo( btnRect.left(), btnCenter ); - btnPath.lineTo( btnRect.left(), btnRect.top() + radius ); - btnPath.quadTo( QPoint( btnRect.topLeft() ), QPoint( btnRect.left() + radius, btnRect.top() ) ); - btnPath.lineTo( btnRect.right() - radius, btnRect.top() ); - btnPath.quadTo( QPoint( btnRect.topRight() ), QPoint( btnRect.right(), btnRect.top() + radius ) ); - btnPath.lineTo( btnRect.right(),btnCenter ); - btnPath.lineTo( btnRect.left(), btnCenter ); - - QLinearGradient g; - g.setColorAt( 0, QColor(54, 127, 211) ); - g.setColorAt( 0.5, QColor(43, 104, 182) ); - //painter->setPen( bg.darker() ); - painter->fillPath( btnPath, g ); - //painter->drawPath( btnPath ); - - btnPath = QPainterPath(); - btnPath.moveTo( btnRect.left(), btnCenter ); - btnPath.lineTo( btnRect.left(), btnRect.bottom() - radius ); - btnPath.quadTo( QPoint( btnRect.bottomLeft() ), QPoint( btnRect.left() + radius, btnRect.bottom() ) ); - btnPath.lineTo( btnRect.right() - radius, btnRect.bottom() ); - btnPath.quadTo( QPoint( btnRect.bottomRight() ), QPoint( btnRect.right(), btnRect.bottom() - radius ) ); - btnPath.lineTo( btnRect.right(), btnCenter ); - btnPath.lineTo( btnRect.left(), btnCenter ); - - g.setColorAt( 0, QColor(34, 85, 159) ); - g.setColorAt( 0.5, QColor(35, 79, 147) ); - painter->fillPath( btnPath, g ); - - painter->setFont( installFont ); - painter->drawText( btnRect, Qt::AlignCenter, actionText ); - - painter->setPen( saved ); - - // rating stars - int rating = index.data( GetNewStuffModel::RatingRole ).toInt(); - const int ratingWidth = 5 * ( m_ratingStarPositive.width() + PADDING_BETWEEN_STARS ); - int runningEdge = ( btnRect.right() - btnRect.width() / 2 ) - ratingWidth / 2; - for ( int i = 1; i < 6; i++ ) - { - QRect r( runningEdge, btnRect.top() - m_ratingStarPositive.height() - PADDING, m_ratingStarPositive.width(), m_ratingStarPositive.height() ); - if ( i == 1 ) - m_cachedStarRects[ QPair(index.row(), index.column()) ] = r; - - const bool userHasRated = index.data( GetNewStuffModel::UserHasRatedRole ).toBool(); - if ( !userHasRated && // Show on-hover animation if the user hasn't rated it yet, and is hovering over it - m_hoveringOver > -1 && - m_hoveringItem == index ) - { - if ( i <= m_hoveringOver ) // positive star - painter->drawPixmap( r, m_onHoverStar ); - else - painter->drawPixmap( r, m_ratingStarNegative ); - } - else - { - if ( i <= rating ) // positive or rated star - { - if ( userHasRated ) - painter->drawPixmap( r, m_onHoverStar ); - else - painter->drawPixmap( r, m_ratingStarPositive ); - } - else - painter->drawPixmap( r, m_ratingStarNegative ); - } - runningEdge += m_ratingStarPositive.width() + PADDING_BETWEEN_STARS; - } - - // downloaded num times, underneath button - QString count = tr( "%1 downloads" ).arg( index.data( GetNewStuffModel::DownloadCounterRole ).toInt() ); - const QRect countRect( btnRect.left(), btnRect.bottom() + PADDING, btnRect.width(), opt.rect.bottom() - PADDING - btnRect.bottom() ); - QFont countFont = descFont; - countFont.setPointSize( countFont.pointSize() - 2 ); - countFont.setBold( true ); - painter->setFont( countFont ); - painter->drawText( countRect, Qt::AlignCenter | Qt::TextWordWrap, count ); - - // author and version - QString author = index.data( GetNewStuffModel::AuthorRole ).toString(); - const int authorWidth = authorMetrics.width( author ); - const int topTextLine = opt.rect.top() + PADDING; - const QRect authorRect( btnRect.x() - 3*PADDING - authorWidth, topTextLine, authorWidth + 6, authorMetrics.height() ); - painter->setFont( authorFont ); - painter->drawText( authorRect, Qt::AlignCenter, author ); - - const QRect versionRect = authorRect.translated( 0, authorRect.height() ); - QString version = index.data( GetNewStuffModel::VersionRole ).toString(); - painter->drawText( versionRect, Qt::AlignCenter, version ); - - // title - QString title = index.data( Qt::DisplayRole ).toString(); - const int rightTitleEdge = authorRect.left() - PADDING; - const int leftTitleEdge = pixmapRect.right() + PADDING; - const QRect textRect( leftTitleEdge, topTextLine, rightTitleEdge - leftTitleEdge, versionRect.bottom() - opt.rect.top() - PADDING ); - painter->setFont( titleFont ); - painter->drawText( textRect, Qt::AlignVCenter | Qt::AlignLeft, title ); - - // description - QString desc = index.data( GetNewStuffModel::DescriptionRole ).toString(); - const int descWidth = btnRect.left() - leftTitleEdge - PADDING; - const QRect descRect( leftTitleEdge, versionRect.bottom(), descWidth, opt.rect.bottom() - versionRect.bottom() + PADDING ); - painter->setFont( descFont ); - painter->drawText( descRect, Qt::AlignLeft | Qt::TextWordWrap, desc ); -} - - -QSize -GetNewStuffDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const -{ - Q_UNUSED( option ); - Q_UNUSED( index ); - return QSize( 200, SIZEHINT_HEIGHT ); -} - -bool -GetNewStuffDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index ) -{ - Q_UNUSED( option ); - - if ( event->type() != QEvent::MouseButtonRelease && - event->type() != QEvent::MouseMove ) - return false; - - if ( event->type() == QEvent::MouseButtonRelease && m_cachedButtonRects.contains( QPair( index.row(), index.column() ) ) ) - { - QRect rect = m_cachedButtonRects[ QPair( index.row(), index.column() ) ]; - QMouseEvent* me = static_cast< QMouseEvent* >( event ); - - if ( rect.contains( me->pos() ) ) - { - model->setData( index, true ); - - return true; - } - } - - if ( m_cachedStarRects.contains( QPair( index.row(), index.column() ) ) ) - { - QRect fullStars = m_cachedStarRects[ QPair( index.row(), index.column() ) ]; - const int starsWidth = 5 * ( m_ratingStarPositive.width() + PADDING_BETWEEN_STARS ); - fullStars.setWidth( starsWidth ); - - QMouseEvent* me = static_cast< QMouseEvent* >( event ); - - if ( fullStars.contains( me->pos() ) ) - { - const int eachStar = starsWidth / 5; - const int clickOffset = me->pos().x() - fullStars.x(); - const int whichStar = (clickOffset / eachStar) + 1; - - if ( event->type() == QEvent::MouseButtonRelease ) - { - model->setData( index, whichStar, GetNewStuffModel::RatingRole ); - } - else if ( event->type() == QEvent::MouseMove ) - { - // 0-indexed - m_hoveringOver = whichStar; - m_hoveringItem = index; - } - - return true; - } - } - - if ( m_hoveringOver > -1 ) - { - emit update( m_hoveringItem ); - m_hoveringOver = -1; - m_hoveringItem = QPersistentModelIndex(); - } - return false; -} diff --git a/src/GetNewStuffDelegate.h b/src/GetNewStuffDelegate.h deleted file mode 100644 index 570210226..000000000 --- a/src/GetNewStuffDelegate.h +++ /dev/null @@ -1,50 +0,0 @@ -/* === This file is part of Tomahawk Player - === - * - * Copyright 2010-2011, Leo Franchi - * - * 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 GETNEWSTUFFDELEGATE_H -#define GETNEWSTUFFDELEGATE_H - -#include - - -class -GetNewStuffDelegate : public QStyledItemDelegate -{ - Q_OBJECT -public: - explicit GetNewStuffDelegate( QObject* parent = 0 ); - virtual void paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const; - virtual QSize sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const; - -signals: - void update( const QModelIndex& idx ); - -protected: - virtual bool editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index ); - -private: - QPixmap m_defaultCover, m_onHoverStar, m_ratingStarPositive, m_ratingStarNegative; - - int m_widestTextWidth; - int m_hoveringOver; - QPersistentModelIndex m_hoveringItem; - mutable QHash< QPair, QRect > m_cachedButtonRects; - mutable QHash< QPair, QRect > m_cachedStarRects; -}; - -#endif // GETNEWSTUFFDELEGATE_H diff --git a/src/GetNewStuffDialog.cpp b/src/GetNewStuffDialog.cpp deleted file mode 100644 index b188a2f38..000000000 --- a/src/GetNewStuffDialog.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* === This file is part of Tomahawk Player - === - * - * Copyright 2011, Leo Franchi - * - * 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 "GetNewStuffDialog.h" - -#include "ui_GetNewStuffDialog.h" -#include "GetNewStuffDelegate.h" -#include "GetNewStuffModel.h" -#include "tomahawksettings.h" - -#include - -GetNewStuffDialog::GetNewStuffDialog( QWidget* parent, Qt::WindowFlags f ) - : QDialog( parent, f ) - , ui( new Ui::GetNewStuffDialog ) - , m_model( new GetNewStuffModel( this ) ) -{ - ui->setupUi( this ); - - ui->accountsList->setModel( m_model ); - GetNewStuffDelegate* del = new GetNewStuffDelegate( ui->accountsList ); - connect( del, SIGNAL( update( QModelIndex ) ), ui->accountsList, SLOT( update( QModelIndex ) ) ); - ui->accountsList->setItemDelegate( del ); - ui->accountsList->setVerticalScrollMode( QAbstractItemView::ScrollPerPixel ); - - ui->accountsList->setMouseTracking( true ); - - setMinimumSize( 560, 350 ); - -#ifdef Q_WS_MAC - setMaximumSize( 560, 350 ); - setSizeGripEnabled( false ); - - ui->accountsList->setAttribute( Qt::WA_MacShowFocusRect, false ); -#endif - - connect( ui->installFromFileBtn, SIGNAL( clicked( bool ) ), this, SLOT( installFromFile() ) ); -} - - -GetNewStuffDialog::~GetNewStuffDialog() -{ - delete ui; -} - - -void -GetNewStuffDialog::installFromFile() -{ - QString resolver = QFileDialog::getOpenFileName( this, tr( "Load script resolver file" ), TomahawkSettings::instance()->scriptDefaultPath() ); - -// m_resolversModel->addResolver( resolver, true ); - // TODO - if( !resolver.isEmpty() ) - { - - QFileInfo resolverAbsoluteFilePath = resolver; - TomahawkSettings::instance()->setScriptDefaultPath( resolverAbsoluteFilePath.absolutePath() ); - } -} diff --git a/src/GetNewStuffDialog.h b/src/GetNewStuffDialog.h deleted file mode 100644 index 3e63a66c1..000000000 --- a/src/GetNewStuffDialog.h +++ /dev/null @@ -1,44 +0,0 @@ -/* === This file is part of Tomahawk Player - === - * - * Copyright 2011, Leo Franchi - * - * 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 GETNEWSTUFFDIALOG_H -#define GETNEWSTUFFDIALOG_H - -#include - -class GetNewStuffModel; -namespace Ui { - class GetNewStuffDialog; -} - -class GetNewStuffDialog : public QDialog -{ - Q_OBJECT -public: - explicit GetNewStuffDialog( QWidget *parent = 0, Qt::WindowFlags f = 0 ); - ~GetNewStuffDialog(); - -private slots: - void installFromFile(); - -private: - Ui::GetNewStuffDialog *ui; - GetNewStuffModel* m_model; -}; - -#endif // GETNEWSTUFFDIALOG_H diff --git a/src/GetNewStuffDialog.ui b/src/GetNewStuffDialog.ui deleted file mode 100644 index f844f82f4..000000000 --- a/src/GetNewStuffDialog.ui +++ /dev/null @@ -1,91 +0,0 @@ - - - GetNewStuffDialog - - - - 0 - 0 - 449 - 327 - - - - Download New Resolvers - - - - - - - - - - - Install from file... - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - - - buttonBox - accepted() - GetNewStuffDialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - GetNewStuffDialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff --git a/src/GetNewStuffModel.cpp b/src/GetNewStuffModel.cpp deleted file mode 100644 index 412e6d7da..000000000 --- a/src/GetNewStuffModel.cpp +++ /dev/null @@ -1,293 +0,0 @@ -/* === This file is part of Tomahawk Player - === - * - * Copyright 2010-2011, Leo Franchi - * - * 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 "GetNewStuffModel.h" - -#include "utils/tomahawkutils.h" -#include "utils/logger.h" -#include "AtticaManager.h" -#include "accounts/AccountManager.h" - -#include -#include - -using namespace Tomahawk; -using namespace Accounts; - -GetNewStuffModel::GetNewStuffModel( QObject* parent ) - : QAbstractListModel ( parent ) -{ - connect( AtticaManager::instance(), SIGNAL( resolversReloaded( Attica::Content::List ) ), this, SLOT( resolversReloaded( Attica::Content::List ) ) ); - connect( AtticaManager::instance(), SIGNAL( resolverStateChanged( QString ) ), this, SLOT( resolverStateChanged( QString ) ) ); - - loadData(); -} - -GetNewStuffModel::~GetNewStuffModel() -{ -} - -void -GetNewStuffModel::loadData() -{ - foreach ( const QVariant& content, m_contentList ) - { - if ( !isAttica( content ) ) - { - AccountItem* item = content.value< GetNewStuffModel::AccountItem* >(); - delete item; - } - } - m_contentList.clear(); - - Attica::Content::List fromAttica = AtticaManager::instance()->resolvers(); - foreach ( const Attica::Content& content, fromAttica ) - m_contentList.append( QVariant::fromValue< Attica::Content >( content ) ); - - QList< AccountFactory* > factories = AccountManager::instance()->factories(); - QList< Account* > allAccounts = AccountManager::instance()->accounts(); - foreach ( AccountFactory* fac, factories ) - { - if ( !fac->allowUserCreation() ) - continue; - - AccountItem* item = new AccountItem; - item->factory = fac; - - foreach ( Account* acct, allAccounts ) - { - if ( AccountManager::instance()->factoryForAccount( acct ) == fac ) - { - item->alreadyExists = true; - break; - } - else - item->alreadyExists = false; - } - - m_contentList.append( QVariant::fromValue< GetNewStuffModel::AccountItem* >( item ) ); - } -} - - -void -GetNewStuffModel::resolversReloaded( const Attica::Content::List& resolvers ) -{ - beginResetModel(); - loadData(); - endResetModel(); -} - -void -GetNewStuffModel::resolverStateChanged( const QString& resolverId ) -{ - for ( int i = 0; i < m_contentList.count(); i++ ) - { - if ( !isAttica( m_contentList.at( i ) ) ) - continue; - - const Attica::Content resolver = atticaFromItem( m_contentList.at( i ) ); - if ( resolver.id() == resolverId ) - { - QModelIndex idx = index( i, 0, QModelIndex() ); - emit dataChanged( idx, idx ); - } - } -} - - -QVariant -GetNewStuffModel::data( const QModelIndex& index, int role ) const -{ - if ( !index.isValid() || !hasIndex( index.row(), index.column(), index.parent() ) ) - return QVariant(); - - if ( isAttica( m_contentList.at( index.row() ) ) ) - { - const Attica::Content resolver = atticaFromItem( m_contentList.at( index.row() ) ); - switch ( role ) - { - case Qt::DisplayRole: - return resolver.name(); - case Qt::DecorationRole: - return QVariant::fromValue< QPixmap >( AtticaManager::instance()->iconForResolver( resolver ) ); - case DownloadUrlRole: - // TODO - return QUrl(); - case RatingRole: - return resolver.rating() / 20; // rating is out of 100 - case DownloadCounterRole: - return resolver.downloads(); - case VersionRole: - return resolver.version(); - case DescriptionRole: - return resolver.description(); - case TypeRole: - return AtticaType; - case AuthorRole: - return resolver.author(); - case StateRole: - return (int)AtticaManager::instance()->resolverState( resolver ); - case UserHasRatedRole: - return AtticaManager::instance()->userHasRated( resolver ); - } - } - else - { - // Account, not from Attica - AccountItem* item = accountFromItem( m_contentList.at( index.row() ) ); - Q_ASSERT( item ); - switch ( role ) - { - case Qt::DisplayRole: - return item->factory->prettyName(); - case Qt::DecorationRole: - return QVariant::fromValue< QPixmap >( item->factory->icon() ); - case RatingRole: - // TODO - return 3; -// return resolver.rating() / 20; // rating is out of 100 - case DownloadCounterRole: - // TODO - return 10; -// return resolver.downloads(); - case VersionRole: - return "1.0"; -// return resolver.version(); - case DescriptionRole: - return item->factory->description(); - case TypeRole: - return AccountType; - case AuthorRole: - return "Tomahawk Developers"; - case StateRole: - { - GetNewStuffModel::ItemState state = Uninstalled; - if ( item->factory->isUnique() && item->alreadyExists ) - state = Installed; - else if ( !item->factory->isUnique() && item->alreadyExists ) - state = CanInstallMore; - else if ( !item->alreadyExists ) - state = Uninstalled; - return (int)state; - } - case UserHasRatedRole: - // TODO - return true; -// return AtticaManager::instance()->userHasRated( resolver ); - } - } - - return QVariant(); -} - -int -GetNewStuffModel::rowCount( const QModelIndex& parent ) const -{ - Q_UNUSED( parent ); - return m_contentList.count(); -} - -bool -GetNewStuffModel::setData( const QModelIndex &index, const QVariant &value, int role ) -{ - Q_UNUSED( value ); - if ( !hasIndex( index.row(), index.column(), index.parent() ) ) - return false; - - if ( isAttica( m_contentList.at( index.row() ) ) ) - { - Attica::Content resolver = atticaFromItem( m_contentList.at( index.row() ) ); - AtticaManager::ResolverState state = AtticaManager::instance()->resolverState( resolver ); - if ( role == Qt::EditRole ) - { - switch( state ) - { - case AtticaManager::Uninstalled: - // install - AtticaManager::instance()->installResolver( resolver ); - break; - case AtticaManager::Installing: - case AtticaManager::Upgrading: - // Do nothing, busy - break; - case AtticaManager::Installed: - // Uninstall - AtticaManager::instance()->uninstallResolver( resolver ); - break; - case AtticaManager::NeedsUpgrade: - AtticaManager::instance()->upgradeResolver( resolver ); - break; - default: - //FIXME -- this handles e.g. Failed - break; - }; - } else if ( role == RatingRole ) - { - // For now only allow rating if a resolver is installed! - if ( state != AtticaManager::Installed && state != AtticaManager::NeedsUpgrade ) - return false; - if ( AtticaManager::instance()->userHasRated( resolver ) ) - return false; - resolver.setRating( value.toInt() * 20 ); - m_contentList[ index.row() ] = QVariant::fromValue< Attica::Content >( resolver ); - AtticaManager::instance()->uploadRating( resolver ); - } - emit dataChanged( index, index ); - } - else - { - AccountItem* item = accountFromItem( m_contentList.at( index.row() ) ); - if ( role == Qt::EditRole ) - { - // TODO - } - else if ( role == RatingRole ) - { - // TODO - } - } - - return true; -} - - -bool -GetNewStuffModel::isAttica( const QVariant& item ) const -{ - return qstrcmp( item.typeName(),"Attica::Content" ) == 0; -} - - -GetNewStuffModel::AccountItem* -GetNewStuffModel::accountFromItem( const QVariant& item ) const -{ - Q_ASSERT( !isAttica( item ) ); - - return item.value< GetNewStuffModel::AccountItem* >(); -} - - -Attica::Content -GetNewStuffModel::atticaFromItem( const QVariant& item ) const -{ - Q_ASSERT( isAttica( item ) ); - - return item.value< Attica::Content >(); - -} diff --git a/src/GetNewStuffModel.h b/src/GetNewStuffModel.h deleted file mode 100644 index c2e21afba..000000000 --- a/src/GetNewStuffModel.h +++ /dev/null @@ -1,91 +0,0 @@ -/* === This file is part of Tomahawk Player - === - * - * Copyright 2010-2011, Leo Franchi - * - * 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 GETNEWSTUFFMODEL_H -#define GETNEWSTUFFMODEL_H - -#include "accounts/Account.h" - -#include - -#include -#include - -class GetNewStuffModel: public QAbstractListModel -{ - Q_OBJECT - -public: - enum NewStuffRoles { - // DisplayRole is title - // DecorationRole is qicon for item - DownloadUrlRole = Qt::UserRole + 1, - RatingRole = Qt::UserRole + 2, - DownloadCounterRole = Qt::UserRole + 3, - VersionRole = Qt::UserRole + 4, - DescriptionRole = Qt::UserRole + 5, - TypeRole = Qt::UserRole + 6, // Category in attica-speak. What sort of item this is (resolver, etc). - AuthorRole = Qt::UserRole + 7, - StateRole = Qt::UserRole + 8, - UserHasRatedRole = Qt::UserRole + 9 - }; - - enum Types { - AtticaType = 0, - AccountType = 1 - }; - - enum ItemState { - Uninstalled = 0, - Installing, - Installed, - NeedsUpgrade, - Upgrading, - Failed, - CanInstallMore, // accounts that are not unique - }; - - // plz don't use me kthxbbq - typedef struct { - Tomahawk::Accounts::AccountFactory* factory; - bool alreadyExists; - } AccountItem; - - explicit GetNewStuffModel( QObject* parent = 0 ); - virtual ~GetNewStuffModel(); - - virtual QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const; - virtual int rowCount( const QModelIndex& parent = QModelIndex() ) const; - virtual bool setData( const QModelIndex &index, const QVariant &value, int role ); - -private slots: - void resolversReloaded( const Attica::Content::List& ); - void resolverStateChanged( const QString& resolverId ); - -private: - void loadData(); - bool isAttica( const QVariant& item ) const; - Attica::Content atticaFromItem( const QVariant& item ) const; - AccountItem* accountFromItem( const QVariant& item ) const; - - QVariantList m_contentList; -}; - -Q_DECLARE_METATYPE( GetNewStuffModel::AccountItem* ); - -#endif // GETNEWSTUFFMODEL_H diff --git a/src/configdelegatebase.cpp b/src/configdelegatebase.cpp deleted file mode 100644 index 6503ca223..000000000 --- a/src/configdelegatebase.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/* - Copyright (C) 2011 Leo Franchi - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - - -#include "configdelegatebase.h" - -#include -#include -#include - -#include "utils/tomahawkutils.h" -#include "utils/logger.h" - -#define ROW_HEIGHT 40 - -ConfigDelegateBase::ConfigDelegateBase ( QObject* parent ) - : QStyledItemDelegate ( parent ) -{ - -} - - -QSize -ConfigDelegateBase::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const -{ - int width = QStyledItemDelegate::sizeHint( option, index ).width(); - return QSize( width, ROW_HEIGHT ); -} - -void -ConfigDelegateBase::drawCheckBox( QStyleOptionViewItemV4& opt, QPainter* p, const QWidget* w ) const -{ - QStyle* style = w ? w->style() : QApplication::style(); - opt.checkState == Qt::Checked ? opt.state |= QStyle::State_On : opt.state |= QStyle::State_Off; - style->drawPrimitive( QStyle::PE_IndicatorViewItemCheck, &opt, p, w ); -} - - -void -ConfigDelegateBase::drawConfigWrench ( QPainter* painter, QStyleOptionViewItemV4& opt, QStyleOptionToolButton& topt ) const -{ - const QWidget* w = opt.widget; - QStyle* style = w ? w->style() : QApplication::style(); - - // draw it the same size as the check belox - topt.font = opt.font; - topt.icon = QIcon( RESPATH "images/configure.png" ); - topt.iconSize = QSize( 16, 16 ); - topt.subControls = QStyle::SC_ToolButton; - topt.activeSubControls = QStyle::SC_None; - topt.features = QStyleOptionToolButton::None; - bool pressed = ( m_configPressed == opt.index ); - topt.state = pressed ? QStyle::State_On : QStyle::State_Raised; - if( opt.state & QStyle::State_MouseOver || pressed ) - topt.state |= QStyle::State_HasFocus; - style->drawComplexControl( QStyle::CC_ToolButton, &topt, painter, w ); -} - -bool -ConfigDelegateBase::editorEvent ( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index ) -{ - QStyleOptionViewItemV4 viewOpt( option ); - initStyleOption( &viewOpt, index ); - - if( event->type() == QEvent::MouseButtonRelease || event->type() == QEvent::MouseButtonDblClick ) { - m_configPressed = QModelIndex(); - - QMouseEvent* me = static_cast< QMouseEvent* >( event ); - QList roles = QList() << (int)Qt::CheckStateRole; - roles.append( extraCheckRoles() ); - - foreach ( int role, roles ) - { - if( me->button() != Qt::LeftButton || !checkRectForIndex( option, index, role ).contains( me->pos() ) ) - return false; - - // eat the double click events inside the check rect - if( event->type() == QEvent::MouseButtonDblClick ) { - return true; - } - - Qt::CheckState curState = static_cast< Qt::CheckState >( index.data( role ).toInt() ); - Qt::CheckState newState = curState == Qt::Checked ? Qt::Unchecked : Qt::Checked; - return model->setData( index, newState, role ); - } - - - } else if( event->type() == QEvent::MouseButtonPress ) { - QMouseEvent* me = static_cast< QMouseEvent* >( event ); - if( me->button() == Qt::LeftButton && configRectForIndex( option, index ).contains( me->pos() ) ) { - m_configPressed = index; - - emit configPressed( index ); - return true; - } - } - - return QStyledItemDelegate::editorEvent( event, model, option, index ); -} diff --git a/src/configdelegatebase.h b/src/configdelegatebase.h index 929467a00..bce0581c9 100644 --- a/src/configdelegatebase.h +++ b/src/configdelegatebase.h @@ -45,8 +45,6 @@ signals: void configPressed( const QModelIndex& idx ); protected: - void drawCheckBox( QStyleOptionViewItemV4& opt, QPainter* p, const QWidget* w ) const; - void drawConfigWrench( QPainter* painter, QStyleOptionViewItemV4& option, QStyleOptionToolButton& topt ) const; private: QModelIndex m_configPressed; diff --git a/src/libtomahawk/AtticaManager.cpp b/src/libtomahawk/AtticaManager.cpp index 54f8fcd87..160fc5cd0 100644 --- a/src/libtomahawk/AtticaManager.cpp +++ b/src/libtomahawk/AtticaManager.cpp @@ -210,6 +210,24 @@ AtticaManager::resolversList( BaseJob* j ) m_resolvers = job->itemList(); m_resolverStates = TomahawkSettingsGui::instanceGui()->atticaResolverStates(); + // Sanity check. if any resolvers are installed that don't exist on the hd, remove them. + foreach ( const QString& rId, m_resolverStates.keys() ) + { + if ( m_resolverStates[ rId ].state == Installed || + m_resolverStates[ rId ].state == NeedsUpgrade ) + { + // Guess location on disk + QDir dir( QString( "%1/atticaresolvers/%2" ).arg( TomahawkUtils::appDataDir().absolutePath() ).arg( rId ) ); + if ( !dir.exists() ) + { + // Uh oh + qWarning() << "Found attica resolver marked as installed that didn't exist on disk! Setting to uninstalled: " << rId << dir.absolutePath(); + m_resolverStates[ rId ].state = Uninstalled; + TomahawkSettingsGui::instanceGui()->setAtticaResolverState( rId, Uninstalled ); + } + } + } + // load icon cache from disk, and fetch any we are missing loadPixmapsFromCache(); diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index 8522a1cf7..4ddc4df80 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -70,6 +70,10 @@ AccountModel::loadData() } } + connect ( AccountManager::instance(), SIGNAL( added( Tomahawk::Accounts::Account* ) ), this, SLOT( accountAdded( Tomahawk::Accounts::Account* ) ) ); + connect ( AccountManager::instance(), SIGNAL( removed( Tomahawk::Accounts::Account* ) ), this, SLOT( accountRemoved( Tomahawk::Accounts::Account* ) ) ); + connect ( AccountManager::instance(), SIGNAL( stateChanged( Account* ,Accounts::Account::ConnectionState ) ), this, SLOT( accountStateChanged( Account*, Accounts::Account::ConnectionState ) ) ); + } @@ -82,7 +86,7 @@ AccountModel::data( const QModelIndex& index, int role ) const if ( !hasIndex( index.row(), index.column(), index.parent() ) ) return QVariant(); - AccountModelNode* node = nodeFromIndex( index ); + const AccountModelNode* node = nodeFromIndex( index ); if ( node->parent == m_rootItem ) { // This is a top-level item. 3 cases Q_ASSERT( node->type != AccountModelNode::AccountType ); // must not be of this type, these should be children (other branch of if) @@ -255,12 +259,267 @@ AccountModel::data( const QModelIndex& index, int role ) const return QVariant(); } + + +bool +AccountModel::setData( const QModelIndex& index, const QVariant& value, int role ) +{ + if ( !index.isValid() || !hasIndex( index.row(), index.column(), index.parent() ) ) + return false; + + AccountModelNode* node = nodeFromIndex( index ); + + if ( role == CheckboxClickedRole ) + { + // All checkboxes are for turning on/off an account. So we can just do that + Q_ASSERT( node->account || node->resolverAccount || node->atticaAccount ); + Q_ASSERT( node->type != AccountModelNode::FactoryType ); + + Account* acct = 0; + switch ( node->type ) + { + case AccountModelNode::AccountType: + case AccountModelNode::UniqueFactoryType: + acct = node->account; + break; + case AccountModelNode::AtticaType: + acct = node->atticaAccount; + break; + case AccountModelNode::ManualResolverType: + acct = node->resolverAccount; + break; + default: + ; + }; + Q_ASSERT( acct ); + + Qt::CheckState state = static_cast< Qt::CheckState >( value.toInt() ); + + if ( state == Qt::Checked && !acct->enabled() ) + AccountManager::instance()->enableAccount( acct ); + else if( state == Qt::Unchecked ) + AccountManager::instance()->disableAccount( acct ); + + acct->sync(); + emit dataChanged( index, index ); + + return true; + } + + // The install/create/remove/etc button was clicked. Handle it properly depending on this item + if ( role == ButtonClickedRole ) + { + switch ( node->type ) + { + case AccountModelNode::FactoryType: + case AccountModelNode::UniqueFactoryType: + { + Q_ASSERT( node->factory ); + + // Make a new account of this factory type + emit createAccount( node->factory ); + break; + } + case AccountModelNode::AccountType: + case AccountModelNode::ManualResolverType: + { + Q_ASSERT( node->account || node->resolverAccount ); + Account* acct = node->type == AccountModelNode::AccountType ? node->account : node->resolverAccount; + + // This is a child account, and the remove button was just hit. Remove it! + // OR this is a manually added resolver, and + // the only thing we can do with a manual resolver is remove it completely from the list + AccountManager::instance()->removeAccount( acct ); + + break; + } + case AccountModelNode::AtticaType: + { + // This is an attica resolver, may be installed or not. Handle it properly + Q_ASSERT( node->atticaContent.isValid() ); + + Attica::Content resolver = node->atticaContent; + AtticaManager::ResolverState state = AtticaManager::instance()->resolverState( resolver ); + if ( role == Qt::EditRole ) + { + switch( state ) + { + case AtticaManager::Uninstalled: + // install + AtticaManager::instance()->installResolver( resolver ); + break; + case AtticaManager::Installing: + case AtticaManager::Upgrading: + // Do nothing, busy + break; + case AtticaManager::Installed: + // Uninstall + AtticaManager::instance()->uninstallResolver( resolver ); + break; + case AtticaManager::NeedsUpgrade: + AtticaManager::instance()->upgradeResolver( resolver ); + break; + default: + //FIXME -- this handles e.g. Failed + break; + }; + } + emit dataChanged( index, index ); + } + } + + return true; + } + if ( role == RatingRole ) + { + // We only support rating Attica resolvers for the moment. + Q_ASSERT( node->type == AccountModelNode::AtticaType ); + + AtticaManager::ResolverState state = AtticaManager::instance()->resolverState( node->atticaContent ); + // For now only allow rating if a resolver is installed! + if ( state != AtticaManager::Installed && state != AtticaManager::NeedsUpgrade ) + return false; + if ( AtticaManager::instance()->userHasRated( node->atticaContent ) ) + return false; + node->atticaContent.setRating( value.toInt() * 20 ); + AtticaManager::instance()->uploadRating( node->atticaContent ); + + emit dataChanged( index, index ); + + return true; + } + + return false; +} + + +void +AccountModel::accountAdded( Account* account ) +{ + // Find the factory this belongs up, and update + AccountFactory* factory = AccountManager::instance()->factoryForAccount( account ); + for ( int i = 0; i < m_rootItem->children.size(); i++ ) + { + AccountModelNode* n = m_rootItem->children.at( i ); + if ( n->factory == factory ) + { + if ( factory->isUnique() ) + { + Q_ASSERT( n->type == AccountModelNode::UniqueFactoryType ); + n->account = account; + const QModelIndex idx = index( i, 0, QModelIndex() ); + emit dataChanged( idx, idx ); + + return; + } + else + { + Q_ASSERT( n->type == AccountModelNode::FactoryType ); + // This is our parent + beginInsertRows( index( i, 0, QModelIndex() ), n->children.size(), n->children.size() ); + new AccountModelNode( n, account ); + endInsertRows(); + + return; + } + } + } + + // Not matched with a factory. Then just add it at the end + if ( AtticaResolverAccount* attica = qobject_cast< AtticaResolverAccount* >( account ) ) + { + Attica::Content::List allAtticaContent = AtticaManager::instance()->resolvers(); + foreach ( const Attica::Content& c, allAtticaContent ) + { + if ( attica->atticaId() == c.id() ) + { + // This is us. Create the row +// const int count = m_rootItem->children.size() +// beginInsertRows( QModelIndex(), ); +// new AccountModelNode( ); + } + } + } +} + + +void +AccountModel::accountStateChanged( Account* account , Account::ConnectionState ) +{ + // Find the factory this belongs up, and update + AccountFactory* factory = AccountManager::instance()->factoryForAccount( account ); + for ( int i = 0; i < m_rootItem->children.size(); i++ ) + { + AccountModelNode* n = m_rootItem->children.at( i ); + if ( n->type != AccountModelNode::FactoryType ) + { + // If this is not a non-unique factory, it has as top-level account, so find that and update it + // For each type that this node could be, check the corresponding data + if ( ( n->type == AccountModelNode::UniqueFactoryType && n->account && n->account == account ) || + ( n->type == AccountModelNode::AccountType && n->account == account ) || + ( n->type == AccountModelNode::AtticaType && n->atticaAccount && n->atticaAccount == account ) || + ( n->type == AccountModelNode::ManualResolverType && n->resolverAccount && n->resolverAccount == account ) ) + { + const QModelIndex idx = index( i, 0, QModelIndex() ); + emit dataChanged( idx, idx ); + } + } + else + { + for ( int k = 0; k < n->children.size(); k++ ) + { + AccountModelNode* childAccount = n->children.at( k ); + Q_ASSERT( childAccount->type == AccountModelNode::AccountType ); + if ( childAccount->account == account ) + { + const QModelIndex parent = index( i, 0, QModelIndex() ); + const QModelIndex idx = index( k, 0, parent ); + emit dataChanged( idx, idx ); + } + } + } + + } +} + + +void +AccountModel::accountRemoved( Account* account ) +{ + // Find the factory this belongs up, and update + AccountFactory* factory = AccountManager::instance()->factoryForAccount( account ); + for ( int i = 0; i < m_rootItem->children.size(); i++ ) + { + AccountModelNode* n = m_rootItem->children.at( i ); + if ( n->factory == factory ) + { + if ( factory->isUnique() ) + { + Q_ASSERT( n->type == AccountModelNode::UniqueFactoryType ); + n->account = account; + const QModelIndex idx = index( i, 0, QModelIndex() ); + emit dataChanged( idx, idx ); + } + else + { + Q_ASSERT( n->type == AccountModelNode::FactoryType ); + // This is our parent + beginInsertRows( index( i, 0, QModelIndex() ), n->children.size(), n->children.size() ); + new AccountModelNode( n, account ); + endInsertRows(); + } + } + } +} + + int AccountModel::columnCount( const QModelIndex& parent ) const { return 1; } + int AccountModel::rowCount( const QModelIndex& parent ) const { @@ -273,6 +532,7 @@ AccountModel::rowCount( const QModelIndex& parent ) const return nodeFromIndex( parent )->children.count(); } + QModelIndex AccountModel::parent( const QModelIndex& child ) const { @@ -293,6 +553,7 @@ AccountModel::parent( const QModelIndex& child ) const return createIndex( m_rootItem->children.indexOf( parent ), 0, parent ); } + QModelIndex AccountModel::index( int row, int column, const QModelIndex& parent ) const { @@ -309,6 +570,7 @@ AccountModel::index( int row, int column, const QModelIndex& parent ) const return QModelIndex(); } + AccountModelNode* AccountModel::nodeFromIndex( const QModelIndex& idx ) const { diff --git a/src/libtomahawk/accounts/AccountModel.h b/src/libtomahawk/accounts/AccountModel.h index a5aca2fed..ad16c4add 100644 --- a/src/libtomahawk/accounts/AccountModel.h +++ b/src/libtomahawk/accounts/AccountModel.h @@ -21,6 +21,8 @@ #include "dllmacro.h" +#include "Account.h" + #include @@ -53,7 +55,10 @@ public: ErrorString = Qt::UserRole + 27, // used by individual accounts - AccountData = Qt::UserRole + 28 // raw plugin + AccountData = Qt::UserRole + 28, // raw plugin + + CheckboxClickedRole = Qt::UserRole + 29, // the checkbox for this row was toggled + ButtonClickedRole = Qt::UserRole + 30, // the generic install/create/remove/etc/ button was clicked }; enum RowType { @@ -80,6 +85,15 @@ public: virtual int rowCount( const QModelIndex& parent = QModelIndex() ) const; virtual QModelIndex parent( const QModelIndex& child ) const; virtual QModelIndex index( int row, int column, const QModelIndex& parent = QModelIndex() ) const; + virtual bool setData( const QModelIndex& index, const QVariant& value, int role = Qt::EditRole ); + +signals: + void createAccount( Tomahawk::Accounts::AccountFactory* factory ); + +private slots: + void accountAdded( Tomahawk::Accounts::Account* ); + void accountRemoved( Tomahawk::Accounts::Account* ); + void accountStateChanged( Account*, Accounts::Account::ConnectionState ); private: AccountModelNode* nodeFromIndex( const QModelIndex& index ) const; diff --git a/src/libtomahawk/accounts/AccountModelNode.h b/src/libtomahawk/accounts/AccountModelNode.h index 7f0708d0a..5c8396ba2 100644 --- a/src/libtomahawk/accounts/AccountModelNode.h +++ b/src/libtomahawk/accounts/AccountModelNode.h @@ -35,7 +35,7 @@ namespace Accounts { * Basically a union with possible types: * 1) AccountFactory* for accounts that are not unique (jabber, google, twitter) * 2) Account* for accounts that are associated with an AccountFactory (children of AccountFactory) - * 3) Attica::Content for AtticaResolverAccounts (with associated AtticaResolverAccount*) (all synchroton resolvers) + * 3) Attica::Content for AtticaResolverAccounts (with associated AtticaResolverAccount*) (all synchrotron resolvers) * 4) ResolverAccount* for manually added resolvers (from file). * 5) AccountFactory* + Account* for factories that are unique * diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index 41d94a131..cbd83833a 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -39,7 +39,6 @@ #include "tomahawkapp.h" #include "tomahawksettings.h" #include "delegateconfigwrapper.h" -#include "GetNewStuffDialog.h" #include "musicscanner.h" #include "pipeline.h" #include "resolver.h" @@ -102,19 +101,21 @@ SettingsDialog::SettingsDialog( QWidget *parent ) #endif // SIP PLUGINS - AccountDelegate* sipdel = new AccountDelegate( this ); - ui->accountsView->setItemDelegate( sipdel ); + AccountDelegate* accountDelegate = new AccountDelegate( this ); + ui->accountsView->setItemDelegate( accountDelegate ); ui->accountsView->setContextMenuPolicy( Qt::CustomContextMenu ); ui->accountsView->setVerticalScrollMode( QAbstractItemView::ScrollPerPixel ); -// connect( sipdel, SIGNAL( openConfig( Tomahawk::Accounts::Account* ) ), this, SLOT( openAccountConfig( Tomahawk::Accounts::Account* ) ) ); + connect( accountDelegate, SIGNAL( openConfig( Tomahawk::Accounts::Account* ) ), this, SLOT( openAccountConfig( Tomahawk::Accounts::Account* ) ) ); + connect( accountDelegate, SIGNAL( update( QModelIndex ) ), ui->accountsView, SLOT( update( QModelIndex ) ) ); + connect( ui->accountsView, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( accountContextMenuRequest( QPoint ) ) ); m_accountModel = new AccountModel( this ); + ui->accountsView->setModel( m_accountModel ); ui->accountsView->expandAll(); - connect( ui->addNewServiceBtn, SIGNAL( clicked( bool ) ), this, SLOT( getMoreResolvers() ) ); - connect( ui->removeServiceBtn, SIGNAL( clicked( bool ) ), this, SLOT( accountDeleted( bool ) ) ); + connect( m_accountModel, SIGNAL( createAccount( Tomahawk::Accounts::AccountFactory* ) ), this, SLOT( createAccountFromFactory( Tomahawk::Accounts::AccountFactory* ) ) ); connect( AtticaManager::instance(), SIGNAL( resolverInstalled( QString ) ), this, SLOT( accountAdded( Tomahawk::Accounts::Account* ) ) ); connect( AtticaManager::instance(), SIGNAL( resolverUninstalled( QString ) ), this, SLOT( accountUninstalled( QString ) ) ); @@ -425,22 +426,6 @@ SettingsDialog::onLastFmFinished() } -void -SettingsDialog::getMoreResolvers() -{ -#if defined(Q_WS_MAC) - GetNewStuffDialog* diag = new GetNewStuffDialog( this, Qt::Sheet ); - connect( diag, SIGNAL( finished( int ) ), this, SLOT( getMoreResolversFinished( int ) ) ); - diag->show(); -#else - GetNewStuffDialog diag( this ); - int ret = diag.exec(); - Q_UNUSED( ret ); -#endif - -} - - void SettingsDialog::accountInstalled(Account* account) { @@ -469,14 +454,6 @@ SettingsDialog::accountsSelectionChanged() } -void -SettingsDialog::getMoreResolversFinished( int ret ) -{ - Q_UNUSED( ret ); - sender()->deleteLater(); -} - - void SettingsDialog::openAccountConfig( Account* account ) { diff --git a/src/settingsdialog.h b/src/settingsdialog.h index de2e948e1..5f8300171 100644 --- a/src/settingsdialog.h +++ b/src/settingsdialog.h @@ -95,8 +95,6 @@ private slots: void onAccountRowDeleted( bool ); void accountsSelectionChanged(); - void getMoreResolvers(); - void getMoreResolversFinished( int ); void accountInstalled( Tomahawk::Accounts::Account* account ); void accountUninstalled( const QString& acct ); @@ -125,4 +123,3 @@ private: #endif // SETTINGSDIALOG_H -struct A; From 8f1fa9b7288027d47ae72d1cbddd3bb159d9f386 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 3 Feb 2012 18:34:46 -0500 Subject: [PATCH 053/104] Step one in the pivot --- src/AccountDelegate.cpp | 2 +- src/libtomahawk/accounts/AccountModel.cpp | 565 ++++++++------------ src/libtomahawk/accounts/AccountModel.h | 16 +- src/libtomahawk/accounts/AccountModelNode.h | 51 +- src/settingsdialog.cpp | 1 - src/stackedsettingsdialog.ui | 21 +- 6 files changed, 240 insertions(+), 416 deletions(-) diff --git a/src/AccountDelegate.cpp b/src/AccountDelegate.cpp index 020a0e89a..5a4896bc1 100644 --- a/src/AccountDelegate.cpp +++ b/src/AccountDelegate.cpp @@ -470,7 +470,7 @@ AccountDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const QS else if ( m_cachedButtonRects.contains( index ) && m_cachedButtonRects[ index ].contains( me->pos() ) ) { // Install/create/etc button for this row - model->setData( index, true, AccountModel::ButtonClickedRole ); + model->setData( index, true, AccountModel::AddAccountButtonRole ); } } diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index 4ddc4df80..7a2c06660 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -30,8 +30,7 @@ using namespace Tomahawk; using namespace Accounts; AccountModel::AccountModel( QObject* parent ) - : QAbstractItemModel( parent ) - , m_rootItem( 0 ) + : QAbstractListModel( parent ) { loadData(); } @@ -41,9 +40,8 @@ AccountModel::loadData() { beginResetModel(); - delete m_rootItem; + qDeleteAll( m_accounts ); - m_rootItem = new AccountModelNode(); // Add all factories QList< AccountFactory* > factories = AccountManager::instance()->factories(); QList< Account* > allAccounts = AccountManager::instance()->accounts(); @@ -53,20 +51,20 @@ AccountModel::loadData() continue; qDebug() << "Creating factory node:" << fac->prettyName(); - new AccountModelNode( m_rootItem, fac ); + m_accounts << new AccountModelNode( fac ); } // add all attica resolvers (installed or uninstalled) Attica::Content::List fromAttica = AtticaManager::instance()->resolvers(); foreach ( const Attica::Content& content, fromAttica ) - new AccountModelNode( m_rootItem, content ); + m_accounts << new AccountModelNode( content ); // Add all non-attica manually installed resolvers foreach ( Account* acct, allAccounts ) { if ( qobject_cast< ResolverAccount* >( acct ) && !qobject_cast< AtticaResolverAccount* >( acct ) ) { - new AccountModelNode( m_rootItem, qobject_cast< ResolverAccount* >( acct ) ); + m_accounts << new AccountModelNode( qobject_cast< ResolverAccount* >( acct ) ); } } @@ -86,173 +84,140 @@ AccountModel::data( const QModelIndex& index, int role ) const if ( !hasIndex( index.row(), index.column(), index.parent() ) ) return QVariant(); - const AccountModelNode* node = nodeFromIndex( index ); - if ( node->parent == m_rootItem ) { - // This is a top-level item. 3 cases - Q_ASSERT( node->type != AccountModelNode::AccountType ); // must not be of this type, these should be children (other branch of if) + const AccountModelNode* node = m_accounts.at( index.row() ); + // This is a top-level item. 3 cases - switch ( node->type ) + switch ( node->type ) + { + case AccountModelNode::FactoryType: { - case AccountModelNode::FactoryType: - { - AccountFactory* fac = node->factory; - Q_ASSERT( fac ); + AccountFactory* fac = node->factory; + Q_ASSERT( fac ); + switch ( role ) + { + case Qt::DisplayRole: + return fac->prettyName(); + case Qt::DecorationRole: + return fac->icon(); + case StateRole: + return ShippedWithTomahawk; + case DescriptionRole: + return fac->description(); + case RowTypeRole: + return TopLevelFactory; + default: + return QVariant(); + } + } + case AccountModelNode::AtticaType: + { + Attica::Content c = node->atticaContent; + Q_ASSERT( !c.id().isNull() ); + + switch( role ) + { + case Qt::DisplayRole: + return c.name(); + case Qt::DecorationRole: + return QVariant::fromValue< QPixmap >( AtticaManager::instance()->iconForResolver( c ) ); + case StateRole: + return (int)AtticaManager::instance()->resolverState( c ); + case DescriptionRole: + return c.description(); + case AuthorRole: + return c.author(); + case RowTypeRole: + return TopLevelAccount; + case RatingRole: + return c.rating() / 20; // rating is out of 100 + case DownloadCounterRole: + return c.downloads(); + case VersionRole: + return c.version(); + case UserHasRatedRole: + return AtticaManager::instance()->userHasRated( c ); + default: + ; + } + + AtticaResolverAccount* atticaAcct = node->atticaAccount; + if ( atticaAcct ) + { + // If the resolver is installed or on disk, we expose some additional data switch ( role ) { - case Qt::DisplayRole: - return fac->prettyName(); - case Qt::DecorationRole: - return fac->icon(); - case StateRole: - return ShippedWithTomahawk; - case DescriptionRole: - return fac->description(); - case RowTypeRole: - return TopLevelFactory; - default: - return QVariant(); - } - } - case AccountModelNode::AtticaType: - { - Attica::Content c = node->atticaContent; - Q_ASSERT( !c.id().isNull() ); - - switch( role ) - { - case Qt::DisplayRole: - return c.name(); - case Qt::DecorationRole: - return QVariant::fromValue< QPixmap >( AtticaManager::instance()->iconForResolver( c ) ); - case StateRole: - return (int)AtticaManager::instance()->resolverState( c ); - case DescriptionRole: - return c.description(); - case AuthorRole: - return c.author(); - case RowTypeRole: - return TopLevelAccount; - case RatingRole: - return c.rating() / 20; // rating is out of 100 - case DownloadCounterRole: - return c.downloads(); - case VersionRole: - return c.version(); - case UserHasRatedRole: - return AtticaManager::instance()->userHasRated( c ); + case HasConfig: + return atticaAcct->configurationWidget() != 0; + case Qt::CheckStateRole: + return atticaAcct->enabled() ? Qt::Checked : Qt::Unchecked; + case AccountData: + return QVariant::fromValue< QObject* >( atticaAcct ); + case ConnectionStateRole: + return atticaAcct->connectionState(); default: ; } - - AtticaResolverAccount* atticaAcct = node->atticaAccount; - if ( atticaAcct ) - { - // If the resolver is installed or on disk, we expose some additional data - switch ( role ) - { - case HasConfig: - return atticaAcct->configurationWidget() != 0; - case Qt::CheckStateRole: - return atticaAcct->enabled() ? Qt::Checked : Qt::Unchecked; - case AccountData: - return QVariant::fromValue< QObject* >( atticaAcct ); - case ConnectionStateRole: - return atticaAcct->connectionState(); - default: - ; - } - } - return QVariant(); } - case AccountModelNode::ManualResolverType: - case AccountModelNode::UniqueFactoryType: - { - Account* acct = 0; - if ( node->type == AccountModelNode::ManualResolverType ) - acct = node->resolverAccount; - else if ( node->type == AccountModelNode::UniqueFactoryType ) - acct = node->account; - - // If there's no account*, then it means it's a unique factory that hasn't been created - if ( !acct ) - { - Q_ASSERT( node->type == AccountModelNode::UniqueFactoryType ); - Q_ASSERT( node->factory ); - - switch( role ) - { - case Qt::DisplayRole: - return node->factory->prettyName(); - case Qt::DecorationRole: - return node->factory->icon(); - case DescriptionRole: - return node->factory->description(); - case RowTypeRole: - return TopLevelFactory; - case StateRole: - return Uninstalled; - default: - return QVariant(); - } - } - else - { - switch ( role ) - { - case Qt::DisplayRole: - return acct->accountFriendlyName(); - case Qt::DecorationRole: - return acct->icon(); - case DescriptionRole: - return node->type == AccountModelNode::ManualResolverType ? QString() : node->factory->description(); - case Qt::CheckStateRole: - return acct->enabled() ? Qt::Checked : Qt::Unchecked; - case AccountData: - return QVariant::fromValue< QObject* >( acct ); - case RowTypeRole: - return TopLevelAccount; - case ConnectionStateRole: - return acct->connectionState(); - case HasConfig: - return acct->configurationWidget() != 0; - case StateRole: - return Installed; - default: - return QVariant(); - } - } - } - case AccountModelNode::AccountType: - Q_ASSERT( false ); // Should not be here---all account nodes should be children of top level nodes + return QVariant(); } - } - else - { - // This is a child account* of an accountfactory* - Q_ASSERT( node->type == AccountModelNode::AccountType ); - Q_ASSERT( node->children.isEmpty() ); - Q_ASSERT( node->account ); - - Account* acc = node->account; - switch ( role ) + case AccountModelNode::ManualResolverType: + case AccountModelNode::UniqueFactoryType: { - case RowTypeRole: - return ChildAccount; - case Qt::DisplayRole: - return acc->accountFriendlyName(); - case ConnectionStateRole: - return acc->connectionState(); - case HasConfig: - return ( acc->configurationWidget() != 0 ); - case ErrorString: - return acc->errorMessage(); - case Qt::CheckStateRole: - return acc->enabled() ? Qt::Checked : Qt::Unchecked; - case AccountData: - return QVariant::fromValue< QObject* >( acc ); - default: - return QVariant(); + Account* acct = 0; + if ( node->type == AccountModelNode::ManualResolverType ) + acct = node->resolverAccount; + else if ( node->type == AccountModelNode::UniqueFactoryType ) + acct = node->accounts.first(); + + // If there's no account*, then it means it's a unique factory that hasn't been created + if ( !acct ) + { + Q_ASSERT( node->type == AccountModelNode::UniqueFactoryType ); + Q_ASSERT( node->factory ); + + switch( role ) + { + case Qt::DisplayRole: + return node->factory->prettyName(); + case Qt::DecorationRole: + return node->factory->icon(); + case DescriptionRole: + return node->factory->description(); + case RowTypeRole: + return TopLevelFactory; + case StateRole: + return Uninstalled; + default: + return QVariant(); + } + } + else + { + switch ( role ) + { + case Qt::DisplayRole: + return acct->accountFriendlyName(); + case Qt::DecorationRole: + return acct->icon(); + case DescriptionRole: + return node->type == AccountModelNode::ManualResolverType ? QString() : node->factory->description(); + case Qt::CheckStateRole: + return acct->enabled() ? Qt::Checked : Qt::Unchecked; + case AccountData: + return QVariant::fromValue< QObject* >( acct ); + case RowTypeRole: + return TopLevelAccount; + case ConnectionStateRole: + return acct->connectionState(); + case HasConfig: + return acct->configurationWidget() != 0; + case StateRole: + return Installed; + default: + return QVariant(); + } + } } } @@ -267,32 +232,54 @@ AccountModel::setData( const QModelIndex& index, const QVariant& value, int role if ( !index.isValid() || !hasIndex( index.row(), index.column(), index.parent() ) ) return false; - AccountModelNode* node = nodeFromIndex( index ); + AccountModelNode* node = m_accounts.at( index.row() ); if ( role == CheckboxClickedRole ) { - // All checkboxes are for turning on/off an account. So we can just do that - Q_ASSERT( node->account || node->resolverAccount || node->atticaAccount ); - Q_ASSERT( node->type != AccountModelNode::FactoryType ); - Account* acct = 0; switch ( node->type ) { - case AccountModelNode::AccountType: case AccountModelNode::UniqueFactoryType: - acct = node->account; + Q_ASSERT( node->accounts.size() == 1 ); + acct = node->accounts.first(); break; case AccountModelNode::AtticaType: - acct = node->atticaAccount; - break; + { + // This may or may not be installed. if it's not installed yet, install it, then go ahead and enable it + Q_ASSERT( node->atticaContent.isValid() ); + + Attica::Content resolver = node->atticaContent; + AtticaManager::ResolverState state = AtticaManager::instance()->resolverState( resolver ); + if ( state == AtticaManager::Installed ) + { + acct = node->atticaAccount; + break; + } + else + { + connect( AtticaManager::instance(), SIGNAL( resolverInstalled( QString ) ), this, SLOT( atticaInstalled( QString ) ) ); + m_waitingForAtticaInstall.insert( resolver.id() ); + + AtticaManager::instance()->installResolver( resolver ); + return true; + } + + } case AccountModelNode::ManualResolverType: acct = node->resolverAccount; break; default: ; }; - Q_ASSERT( acct ); + if ( node->type == AccountModelNode::FactoryType ) + { + // TODO handle overall on/off + + return false; + } + + Q_ASSERT( acct ); Qt::CheckState state = static_cast< Qt::CheckState >( value.toInt() ); if ( state == Qt::Checked && !acct->enabled() ) @@ -307,69 +294,15 @@ AccountModel::setData( const QModelIndex& index, const QVariant& value, int role } // The install/create/remove/etc button was clicked. Handle it properly depending on this item - if ( role == ButtonClickedRole ) + if ( role == AddAccountButtonRole ) { - switch ( node->type ) - { - case AccountModelNode::FactoryType: - case AccountModelNode::UniqueFactoryType: - { - Q_ASSERT( node->factory ); - - // Make a new account of this factory type - emit createAccount( node->factory ); - break; - } - case AccountModelNode::AccountType: - case AccountModelNode::ManualResolverType: - { - Q_ASSERT( node->account || node->resolverAccount ); - Account* acct = node->type == AccountModelNode::AccountType ? node->account : node->resolverAccount; - - // This is a child account, and the remove button was just hit. Remove it! - // OR this is a manually added resolver, and - // the only thing we can do with a manual resolver is remove it completely from the list - AccountManager::instance()->removeAccount( acct ); - - break; - } - case AccountModelNode::AtticaType: - { - // This is an attica resolver, may be installed or not. Handle it properly - Q_ASSERT( node->atticaContent.isValid() ); - - Attica::Content resolver = node->atticaContent; - AtticaManager::ResolverState state = AtticaManager::instance()->resolverState( resolver ); - if ( role == Qt::EditRole ) - { - switch( state ) - { - case AtticaManager::Uninstalled: - // install - AtticaManager::instance()->installResolver( resolver ); - break; - case AtticaManager::Installing: - case AtticaManager::Upgrading: - // Do nothing, busy - break; - case AtticaManager::Installed: - // Uninstall - AtticaManager::instance()->uninstallResolver( resolver ); - break; - case AtticaManager::NeedsUpgrade: - AtticaManager::instance()->upgradeResolver( resolver ); - break; - default: - //FIXME -- this handles e.g. Failed - break; - }; - } - emit dataChanged( index, index ); - } - } - + Q_ASSERT( node->type == AccountModelNode::FactoryType ); + // Make a new account of this factory type + emit createAccount( node->factory ); return true; } + + if ( role == RatingRole ) { // We only support rating Attica resolvers for the moment. @@ -398,30 +331,16 @@ AccountModel::accountAdded( Account* account ) { // Find the factory this belongs up, and update AccountFactory* factory = AccountManager::instance()->factoryForAccount( account ); - for ( int i = 0; i < m_rootItem->children.size(); i++ ) + for ( int i = 0; i < m_accounts.size(); i++ ) { - AccountModelNode* n = m_rootItem->children.at( i ); + AccountModelNode* n = m_accounts.at( i ); if ( n->factory == factory ) { - if ( factory->isUnique() ) - { - Q_ASSERT( n->type == AccountModelNode::UniqueFactoryType ); - n->account = account; - const QModelIndex idx = index( i, 0, QModelIndex() ); - emit dataChanged( idx, idx ); + n->accounts << account; + const QModelIndex idx = index( i, 0, QModelIndex() ); + dataChanged( idx, idx ); - return; - } - else - { - Q_ASSERT( n->type == AccountModelNode::FactoryType ); - // This is our parent - beginInsertRows( index( i, 0, QModelIndex() ), n->children.size(), n->children.size() ); - new AccountModelNode( n, account ); - endInsertRows(); - - return; - } + return; } } @@ -434,12 +353,24 @@ AccountModel::accountAdded( Account* account ) if ( attica->atticaId() == c.id() ) { // This is us. Create the row -// const int count = m_rootItem->children.size() -// beginInsertRows( QModelIndex(), ); -// new AccountModelNode( ); + const int count = m_accounts.size(); + beginInsertRows( QModelIndex(), count, count ); + m_accounts << new AccountModelNode( c ); + endInsertRows(); + + return; } } } + + // Ok, just a plain resolver. add it at the end + if ( ResolverAccount* resolver = qobject_cast< ResolverAccount* >( account ) ) + { + const int count = m_accounts.size(); + beginInsertRows( QModelIndex(), count, count ); + m_accounts << new AccountModelNode( resolver ); + endInsertRows(); + } } @@ -448,15 +379,14 @@ AccountModel::accountStateChanged( Account* account , Account::ConnectionState ) { // Find the factory this belongs up, and update AccountFactory* factory = AccountManager::instance()->factoryForAccount( account ); - for ( int i = 0; i < m_rootItem->children.size(); i++ ) + for ( int i = 0; i < m_accounts.size(); i++ ) { - AccountModelNode* n = m_rootItem->children.at( i ); + AccountModelNode* n = m_accounts.at( i ); if ( n->type != AccountModelNode::FactoryType ) { // If this is not a non-unique factory, it has as top-level account, so find that and update it // For each type that this node could be, check the corresponding data - if ( ( n->type == AccountModelNode::UniqueFactoryType && n->account && n->account == account ) || - ( n->type == AccountModelNode::AccountType && n->account == account ) || + if ( ( n->type == AccountModelNode::UniqueFactoryType && n->accounts.size() && n->accounts.first() == account ) || ( n->type == AccountModelNode::AtticaType && n->atticaAccount && n->atticaAccount == account ) || ( n->type == AccountModelNode::ManualResolverType && n->resolverAccount && n->resolverAccount == account ) ) { @@ -466,14 +396,13 @@ AccountModel::accountStateChanged( Account* account , Account::ConnectionState ) } else { - for ( int k = 0; k < n->children.size(); k++ ) + for ( int k = 0; k < n->accounts.size(); k++ ) { - AccountModelNode* childAccount = n->children.at( k ); - Q_ASSERT( childAccount->type == AccountModelNode::AccountType ); - if ( childAccount->account == account ) + Account* childAccount = n->accounts.at( k ); + + if ( childAccount == account ) { - const QModelIndex parent = index( i, 0, QModelIndex() ); - const QModelIndex idx = index( k, 0, parent ); + const QModelIndex idx = index( i, 0, QModelIndex() ); emit dataChanged( idx, idx ); } } @@ -488,96 +417,44 @@ AccountModel::accountRemoved( Account* account ) { // Find the factory this belongs up, and update AccountFactory* factory = AccountManager::instance()->factoryForAccount( account ); - for ( int i = 0; i < m_rootItem->children.size(); i++ ) + for ( int i = 0; i < m_accounts.size(); i++ ) { - AccountModelNode* n = m_rootItem->children.at( i ); - if ( n->factory == factory ) + AccountModelNode* n = m_accounts.at( i ); + + if ( n->type == AccountModelNode::FactoryType && + n->factory == factory ) { - if ( factory->isUnique() ) - { - Q_ASSERT( n->type == AccountModelNode::UniqueFactoryType ); - n->account = account; - const QModelIndex idx = index( i, 0, QModelIndex() ); - emit dataChanged( idx, idx ); - } - else - { - Q_ASSERT( n->type == AccountModelNode::FactoryType ); - // This is our parent - beginInsertRows( index( i, 0, QModelIndex() ), n->children.size(), n->children.size() ); - new AccountModelNode( n, account ); - endInsertRows(); - } + n->accounts.removeAll( account ); + const QModelIndex idx = index( i, 0, QModelIndex() ); + emit dataChanged( idx, idx ); + + return; + } + + if ( ( n->type == AccountModelNode::UniqueFactoryType && n->accounts.size() && n->accounts.first() == account ) || + ( n->type == AccountModelNode::AtticaType && n->atticaAccount && n->atticaAccount == account ) || + ( n->type == AccountModelNode::ManualResolverType && n->resolverAccount && n->resolverAccount == account ) ) + { + beginRemoveRows( QModelIndex(), i, i ); + m_accounts.removeAt( i ); + endRemoveRows(); + + return; } } } -int -AccountModel::columnCount( const QModelIndex& parent ) const +void +AccountModel::atticaInstalled( const QString& atticaId ) { - return 1; + } int -AccountModel::rowCount( const QModelIndex& parent ) const +AccountModel::rowCount( const QModelIndex& ) const { - if ( !parent.isValid() ) - { - return m_rootItem->children.count(); - } - - // If it's a top-level item, return child count. Only factories will have any. - return nodeFromIndex( parent )->children.count(); + return m_accounts.size(); } - -QModelIndex -AccountModel::parent( const QModelIndex& child ) const -{ - if ( !child.isValid() ) - { - return QModelIndex(); - } - - AccountModelNode* node = nodeFromIndex( child ); - AccountModelNode* parent = node->parent; - - // top level, none - if( parent == m_rootItem ) - return QModelIndex(); - - // child Account* of an AccountFactory* - Q_ASSERT( m_rootItem->children.contains( parent ) ); - return createIndex( m_rootItem->children.indexOf( parent ), 0, parent ); -} - - -QModelIndex -AccountModel::index( int row, int column, const QModelIndex& parent ) const -{ - if( row < 0 || column < 0 ) - return QModelIndex(); - - if( hasIndex( row, column, parent ) ) - { - AccountModelNode *parentNode = nodeFromIndex( parent ); - AccountModelNode *childNode = parentNode->children.at( row ); - return createIndex( row, column, childNode ); - } - - return QModelIndex(); -} - - -AccountModelNode* -AccountModel::nodeFromIndex( const QModelIndex& idx ) const -{ - if( !idx.isValid() ) - return m_rootItem; - - Q_ASSERT( idx.internalPointer() ); - - return reinterpret_cast< AccountModelNode* >( idx.internalPointer() ); -} diff --git a/src/libtomahawk/accounts/AccountModel.h b/src/libtomahawk/accounts/AccountModel.h index ad16c4add..97da15c73 100644 --- a/src/libtomahawk/accounts/AccountModel.h +++ b/src/libtomahawk/accounts/AccountModel.h @@ -23,7 +23,7 @@ #include "Account.h" -#include +#include namespace Tomahawk { @@ -32,7 +32,7 @@ namespace Accounts { class AccountModelNode; -class DLLEXPORT AccountModel : public QAbstractItemModel +class DLLEXPORT AccountModel : public QAbstractListModel { Q_OBJECT @@ -58,7 +58,7 @@ public: AccountData = Qt::UserRole + 28, // raw plugin CheckboxClickedRole = Qt::UserRole + 29, // the checkbox for this row was toggled - ButtonClickedRole = Qt::UserRole + 30, // the generic install/create/remove/etc/ button was clicked + AddAccountButtonRole = Qt::UserRole + 30, // the add account button }; enum RowType { @@ -81,11 +81,8 @@ public: explicit AccountModel( QObject* parent = 0 ); virtual QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const; - virtual int columnCount( const QModelIndex& parent = QModelIndex() ) const; virtual int rowCount( const QModelIndex& parent = QModelIndex() ) const; - virtual QModelIndex parent( const QModelIndex& child ) const; - virtual QModelIndex index( int row, int column, const QModelIndex& parent = QModelIndex() ) const; - virtual bool setData( const QModelIndex& index, const QVariant& value, int role = Qt::EditRole ); + virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole); signals: void createAccount( Tomahawk::Accounts::AccountFactory* factory ); @@ -95,11 +92,12 @@ private slots: void accountRemoved( Tomahawk::Accounts::Account* ); void accountStateChanged( Account*, Accounts::Account::ConnectionState ); + void atticaInstalled( const QString& atticaId ); private: - AccountModelNode* nodeFromIndex( const QModelIndex& index ) const; void loadData(); - AccountModelNode* m_rootItem; + QList< AccountModelNode* > m_accounts; + QSet< QString > m_waitingForAtticaInstall; }; } diff --git a/src/libtomahawk/accounts/AccountModelNode.h b/src/libtomahawk/accounts/AccountModelNode.h index 5c8396ba2..6b333a3b8 100644 --- a/src/libtomahawk/accounts/AccountModelNode.h +++ b/src/libtomahawk/accounts/AccountModelNode.h @@ -33,11 +33,9 @@ namespace Accounts { * Node for account tree. * * Basically a union with possible types: - * 1) AccountFactory* for accounts that are not unique (jabber, google, twitter) - * 2) Account* for accounts that are associated with an AccountFactory (children of AccountFactory) - * 3) Attica::Content for AtticaResolverAccounts (with associated AtticaResolverAccount*) (all synchrotron resolvers) - * 4) ResolverAccount* for manually added resolvers (from file). - * 5) AccountFactory* + Account* for factories that are unique + * 1) AccountFactory* for all factories that have child accounts. Also a list of children + * 2) Attica::Content for AtticaResolverAccounts (with associated AtticaResolverAccount*) (all synchrotron resolvers) + * 3) ResolverAccount* for manually added resolvers (from file). * * These are the top-level items in tree. * @@ -52,29 +50,25 @@ struct AccountModelNode { enum NodeType { FactoryType, UniqueFactoryType, - AccountType, AtticaType, ManualResolverType }; AccountModelNode* parent; NodeType type; - QList< AccountModelNode* > children; // list of children accounts (actually existing and configured accounts) - /// 1. + /// 1, 4 AccountFactory* factory; + QList< Account* > accounts; // list of children accounts (actually existing and configured accounts) /// 2. - Account* account; - - /// 3. Attica::Content atticaContent; AtticaResolverAccount* atticaAccount; - /// 4. + /// 3. ResolverAccount* resolverAccount; // Construct in one of four ways. Then access the corresponding members - explicit AccountModelNode( AccountModelNode* p, AccountFactory* fac ) : parent( p ), type( FactoryType ) + explicit AccountModelNode( AccountFactory* fac ) : type( FactoryType ) { init(); factory = fac; @@ -88,26 +82,12 @@ struct AccountModelNode { if ( AccountManager::instance()->factoryForAccount( acct ) == fac ) { qDebug() << "Found account for factory:" << acct->accountFriendlyName(); - if ( fac->isUnique() ) - { - account = acct; - break; - } - else - { - new AccountModelNode( this, acct ); - } + accounts.append( acct ); } } } - AccountModelNode( AccountModelNode* p, Account* acct ) : parent( p ), type( AccountType ) - { - init(); - account = acct; - } - - explicit AccountModelNode( AccountModelNode* p, Attica::Content cnt ) : parent( p ), type( AtticaType ) + explicit AccountModelNode( Attica::Content cnt ) : type( AtticaType ) { init(); atticaContent = cnt; @@ -128,26 +108,15 @@ struct AccountModelNode { } } - explicit AccountModelNode( AccountModelNode* p, ResolverAccount* ra ) : parent( p ), type( ManualResolverType ) + explicit AccountModelNode( ResolverAccount* ra ) : type( ManualResolverType ) { init(); resolverAccount = ra; } - AccountModelNode() : parent( 0 ) {} - - ~AccountModelNode() - { - qDeleteAll( children ); - } - - void init() { - parent->children.append( this ); - factory = 0; - account = 0; atticaAccount = 0; resolverAccount = 0; } diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index cbd83833a..d015aabd7 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -113,7 +113,6 @@ SettingsDialog::SettingsDialog( QWidget *parent ) m_accountModel = new AccountModel( this ); ui->accountsView->setModel( m_accountModel ); - ui->accountsView->expandAll(); connect( m_accountModel, SIGNAL( createAccount( Tomahawk::Accounts::AccountFactory* ) ), this, SLOT( createAccountFromFactory( Tomahawk::Accounts::AccountFactory* ) ) ); diff --git a/src/stackedsettingsdialog.ui b/src/stackedsettingsdialog.ui index 82edf4921..c04c387ef 100644 --- a/src/stackedsettingsdialog.ui +++ b/src/stackedsettingsdialog.ui @@ -127,26 +127,7 @@ - - - 6 - - - false - - - false - - - true - - - true - - - false - - + From 0cfe2d2357263f40f4e551f317165769e1c87edc Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sun, 5 Feb 2012 15:33:53 -0500 Subject: [PATCH 054/104] refactored UI again --- src/AccountDelegate.cpp | 337 ++++++++++++++-------- src/AccountDelegate.h | 8 +- src/libtomahawk/accounts/Account.h | 2 + src/libtomahawk/accounts/AccountModel.cpp | 12 + src/libtomahawk/accounts/AccountModel.h | 7 +- 5 files changed, 235 insertions(+), 131 deletions(-) diff --git a/src/AccountDelegate.cpp b/src/AccountDelegate.cpp index 5a4896bc1..99df128bc 100644 --- a/src/AccountDelegate.cpp +++ b/src/AccountDelegate.cpp @@ -35,9 +35,9 @@ #define STAR_SIZE 12 #ifdef Q_WS_MAC -#define TOPLEVEL_ACCOUNT_HEIGHT 70 +#define TOPLEVEL_ACCOUNT_HEIGHT 72 #else -#define TOPLEVEL_ACCOUNT_HEIGHT 60 +#define TOPLEVEL_ACCOUNT_HEIGHT 62 #endif #define ICONSIZE 40 @@ -52,7 +52,6 @@ using namespace Accounts; AccountDelegate::AccountDelegate( QObject* parent ) : QStyledItemDelegate ( parent ) - , m_widestTextWidth( 0 ) { m_defaultCover.load( RESPATH "images/sipplugin-online.png" ); @@ -70,22 +69,10 @@ AccountDelegate::AccountDelegate( QObject* parent ) m_onHoverStar = m_onHoverStar.scaled( STAR_SIZE, STAR_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation ); m_removeIcon = m_removeIcon.scaled( REMOVE_ICON_SIZE, REMOVE_ICON_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation ); - const int w = TOPLEVEL_ACCOUNT_HEIGHT - 2*PADDING; - m_defaultCover = m_defaultCover.scaled( w, w, Qt::KeepAspectRatio, Qt::SmoothTransformation ); + m_defaultCover = m_defaultCover.scaled( ICONSIZE, ICONSIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation ); m_cachedIcons[ "sipplugin-online" ] = QPixmap( RESPATH "images/sipplugin-online.png" ).scaled( STATUS_ICON_SIZE, STATUS_ICON_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation ); m_cachedIcons[ "sipplugin-offline" ] = QPixmap( RESPATH "images/sipplugin-offline.png" ).scaled( STATUS_ICON_SIZE, STATUS_ICON_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation ); - - // save the widest width - QFont f( QApplication::font() ); - f.setPointSize( f.pointSize() - 1 ); - QFontMetrics fm( f ); - QStringList l = QStringList() << tr( "Installed" ) << tr( "Installing" ) << tr( "Failed" ) << tr( "Uninstalling" ) << tr( "Create" ); - foreach ( const QString& str, l ) - { - if ( fm.width( str ) > m_widestTextWidth ) - m_widestTextWidth = fm.width( str ); - } } @@ -93,10 +80,20 @@ QSize AccountDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const { AccountModel::RowType rowType = static_cast< AccountModel::RowType >( index.data( AccountModel::RowTypeRole ).toInt() ); - if ( rowType == AccountModel::TopLevelAccount || rowType == AccountModel::TopLevelFactory ) + if ( rowType == AccountModel::TopLevelAccount ) return QSize( 200, TOPLEVEL_ACCOUNT_HEIGHT ); - else // individual child account - return QSize( 200, CHILD_ACCOUNT_HEIGHT ); + else if ( rowType == AccountModel::TopLevelFactory ) + { + // Make more space for eacha ccount we have to show. + AccountFactory* fac = qobject_cast< AccountFactory* >( index.data( AccountModel::AccountData ).value< QObject* >() ); + if ( fac->isUnique() ) + return QSize( 200, TOPLEVEL_ACCOUNT_HEIGHT ); + + const QList< Account* > accts = index.data( AccountModel::ChildrenOfFactoryRole ).value< QList< Tomahawk::Accounts::Account* > >(); + return QSize( 200, TOPLEVEL_ACCOUNT_HEIGHT + 14 * accts.size() ); + } + + return QSize(); } @@ -113,21 +110,6 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, painter->setRenderHint( QPainter::Antialiasing ); - AccountModel::RowType rowType = static_cast< AccountModel::RowType >( index.data( AccountModel::RowTypeRole ).toInt() ); - if ( rowType == AccountModel::TopLevelAccount || rowType == AccountModel::TopLevelFactory ) - paintTopLevel( painter, opt, index ); - else // individual child account - paintChild( painter, opt, index ); - - return; -} - - -void -AccountDelegate::paintTopLevel( QPainter* painter, const QStyleOptionViewItemV4& option, const QModelIndex& index ) const -{ - QStyleOptionViewItemV4 opt = option; - QFont titleFont = opt.font; titleFont.setBold( true ); titleFont.setPointSize( titleFont.pointSize() + 2 ); @@ -136,9 +118,9 @@ AccountDelegate::paintTopLevel( QPainter* painter, const QStyleOptionViewItemV4& QFont authorFont = opt.font; authorFont.setItalic( true ); authorFont.setPointSize( authorFont.pointSize() - 1 ); -#ifdef Q_OS_MAC + #ifdef Q_OS_MAC authorFont.setPointSize( authorFont.pointSize() - 1 ); -#endif + #endif const QFontMetrics authorMetrics( authorFont ); QFont descFont = authorFont; @@ -152,28 +134,20 @@ AccountDelegate::paintTopLevel( QPainter* painter, const QStyleOptionViewItemV4& const int height = opt.rect.height(); const int center = height / 2 + opt.rect.top(); - // Left account enable/disable checkbox if this is not a factory + // Left account enable/disable checkbox const AccountModel::RowType rowType = static_cast< AccountModel::RowType >( index.data( AccountModel::RowTypeRole ).toInt() ); int leftEdge = PADDING; - if ( rowType != AccountModel::TopLevelFactory ) - { - // draw checkbox first - int ypos = ( center ) - ( WRENCH_SIZE / 2 ); - QRect checkRect = QRect( leftEdge, ypos, WRENCH_SIZE, WRENCH_SIZE ); - QStyleOptionViewItemV4 opt2 = opt; - opt2.rect = checkRect; - const AccountModel::ItemState state = static_cast< AccountModel::ItemState >( index.data( AccountModel::StateRole ).toInt() ); - const bool canCheck = ( state == AccountModel::Installed || state == AccountModel::ShippedWithTomahawk ); - if ( !canCheck ) - opt2.state &= ~QStyle::State_Enabled; - drawCheckBox( opt2, painter, opt.widget ); - } + // draw checkbox first + const int checkboxYPos = ( center ) - ( WRENCH_SIZE / 2 ); + QRect checkRect = QRect( leftEdge, checkboxYPos, WRENCH_SIZE, WRENCH_SIZE ); + QStyleOptionViewItemV4 opt2 = opt; + opt2.rect = checkRect; + drawCheckBox( opt2, painter, opt.widget ); leftEdge += WRENCH_SIZE + PADDING / 2; // Pixmap QPixmap p = index.data( Qt::DecorationRole ).value< QPixmap >(); - const int pixmapWidth = height - 2*PADDING; - QRect pixmapRect( leftEdge + PADDING, PADDING + opt.rect.top(), pixmapWidth, pixmapWidth ); + QRect pixmapRect( leftEdge + PADDING, center - ICONSIZE/2, ICONSIZE, ICONSIZE ); if ( p.isNull() ) // default image... TODO p = m_defaultCover; else @@ -181,48 +155,53 @@ AccountDelegate::paintTopLevel( QPainter* painter, const QStyleOptionViewItemV4& painter->drawPixmap( pixmapRect, p ); + // Draw config wrench if there is one + const bool hasConfigWrench = index.data( AccountModel::HasConfig ).toBool(); + int rightEdge = opt.rect.right(); + if ( hasConfigWrench ) + { + const QRect confRect = QRect( rightEdge - 2*PADDING - WRENCH_SIZE, center - WRENCH_SIZE / 2, WRENCH_SIZE, WRENCH_SIZE ); + QStyleOptionToolButton topt; + topt.rect = confRect; + topt.pos = confRect.topLeft(); - // Go from right edge now, stars, install/create button, downloaded info, config wrench and status etc + drawConfigWrench( painter, opt, topt ); + m_cachedConfigRects[ index ] = confRect; + rightEdge = confRect.left(); - // install / status button - const AccountModel::ItemState state = static_cast< AccountModel::ItemState >( index.data( AccountModel::StateRole ).toInt() ); - int edgeOfRightExtras = opt.rect.right(); + } + + // Draw individual accounts and add account button for factories if ( rowType == Tomahawk::Accounts::AccountModel::TopLevelFactory ) { - QString actionText; - switch( state ) - { - case AccountModel::Uninstalled: - actionText = tr( "Install" ); - break; - case AccountModel::Installing: - actionText = tr( "Installing" ); - break; - case AccountModel::Upgrading: - actionText = tr( "Upgrading" ); - break; - case AccountModel::Failed: - actionText = tr( "Failed" ); - break; - case AccountModel::Installed: - actionText = tr( "Uninstall" ); - break; - case AccountModel::NeedsUpgrade: - actionText = tr( "Upgrade" ); - break; - case AccountModel::ShippedWithTomahawk: - actionText = tr( "Create" ); - break; - case AccountModel::UniqueFactory: - actionText = tr( "Installed" ); - break; - } - // title and description - const int btnWidth = m_widestTextWidth + 7; - leftEdge = opt.rect.width() - PADDING - btnWidth - 3; - const QRect btnRect( leftEdge, center - ( installMetrics.height() + 4 ) / 2, btnWidth, installMetrics.height() + 4 ); - m_cachedButtonRects[ index ] = btnRect; + const QList< Account* > accts = index.data( AccountModel::ChildrenOfFactoryRole ).value< QList< Tomahawk::Accounts::Account* > >(); + QRect btnRect; + const QString btnText = tr( "Add Account" ); + const int btnWidth = installMetrics.width( btnText ) + 2*PADDING; + + if ( accts.isEmpty() ) + { + Q_ASSERT( !hasConfigWrench ); + + // Draw button in center of row + btnRect= QRect( opt.rect.right() - PADDING - btnWidth, center - ( installMetrics.height() + 4 ) / 2, btnWidth, installMetrics.height() + 4 ); + rightEdge = btnRect.left(); + } + else + { + painter->save(); + painter->setFont( installFont ); + int oldRightEdge = rightEdge; + rightEdge = drawAccountList( painter, opt, accts, rightEdge ); + painter->restore(); + + int centeredUnderAccounts = oldRightEdge - (oldRightEdge - rightEdge)/2 - (btnWidth/2); + btnRect = QRect( opt.rect.right() - PADDING - btnWidth, opt.rect.bottom() - installMetrics.height() - 3*PADDING, btnWidth, installMetrics.height() + 2*PADDING ); + } + + leftEdge = btnRect.left(); + m_cachedButtonRects[ index ] = btnRect; painter->save(); painter->setPen( opt.palette.color( QPalette::Active, QPalette::AlternateBase ) ); @@ -230,20 +209,104 @@ AccountDelegate::paintTopLevel( QPainter* painter, const QStyleOptionViewItemV4& drawRoundedButton( painter, btnRect ); painter->setFont( installFont ); - painter->drawText( btnRect, Qt::AlignCenter, actionText ); + painter->drawText( btnRect, Qt::AlignCenter, btnText ); painter->restore(); - - edgeOfRightExtras = btnRect.left(); } + // Draw the title and description + // title + QString title = index.data( Qt::DisplayRole ).toString(); + const int rightTitleEdge = rightEdge - PADDING; + const int leftTitleEdge = pixmapRect.right() + PADDING; + painter->setFont( titleFont ); + QRect textRect; + if ( index.data( AccountModel::CanRateRole ).toBool() ) + { + textRect = QRect( leftTitleEdge, opt.rect.top() + PADDING, rightTitleEdge - leftTitleEdge, painter->fontMetrics().height() ); + } + else + { + textRect = QRect( leftTitleEdge, opt.rect.top() + PADDING, rightTitleEdge - leftTitleEdge, center - opt.rect.top() - PADDING ); + } + painter->drawText( textRect, Qt::AlignVCenter | Qt::AlignLeft, title ); + // description + QString desc = index.data( AccountModel::DescriptionRole ).toString(); + const int descWidth = rightEdge - leftTitleEdge - PADDING; + painter->setFont( descFont ); + const QRect descRect( leftTitleEdge, textRect.bottom() + PADDING/2, descWidth, painter->fontMetrics().height() ); + painter->drawText( descRect, Qt::AlignLeft | Qt::TextWordWrap | Qt::AlignTop, desc ); + +// install / status button + + if ( index.data( AccountModel::CanRateRole ).toBool() ) + { + // rating stars + const int rating = index.data( AccountModel::RatingRole ).toInt(); + const int ratingWidth = 5 * ( m_ratingStarPositive.width() + PADDING_BETWEEN_STARS ); + + // int runningEdge = ( btnRect.right() - btnRect.width() / 2 ) - ratingWidth / 2; + int runningEdge = textRect.left(); + for ( int i = 1; i < 6; i++ ) + { + QRect r( runningEdge, opt.rect.bottom() - 4*PADDING - m_ratingStarNegative.height(), m_ratingStarPositive.width(), m_ratingStarPositive.height() ); + if ( i == 1 ) + m_cachedStarRects[ index ] = r; + + const bool userHasRated = index.data( AccountModel::UserHasRatedRole ).toBool(); + if ( !userHasRated && // Show on-hover animation if the user hasn't rated it yet, and is hovering over it + m_hoveringOver > -1 && + m_hoveringItem == index ) + { + if ( i <= m_hoveringOver ) // positive star + painter->drawPixmap( r, m_onHoverStar ); + else + painter->drawPixmap( r, m_ratingStarNegative ); + } + else + { + if ( i <= rating ) // positive or rated star + { + if ( userHasRated ) + painter->drawPixmap( r, m_onHoverStar ); + else + painter->drawPixmap( r, m_ratingStarPositive ); + } + else + painter->drawPixmap( r, m_ratingStarNegative ); + } + runningEdge += m_ratingStarPositive.width() + PADDING_BETWEEN_STARS; + } + + // author + QString author = index.data( AccountModel::AuthorRole ).toString(); + painter->setFont( authorFont ); + const int authorWidth = authorMetrics.width( author ); + const int topTextLine = opt.rect.top() + PADDING; + const QRect authorRect( opt.rect.right() - 2*PADDING - authorWidth, opt.rect.bottom() - 2*PADDING - painter->fontMetrics().height(), authorWidth + 6, authorMetrics.height() ); + painter->drawText( authorRect, Qt::AlignLeft, author ); + + // downloaded num times, underneath button + QString count = tr( "%1 downloads" ).arg( index.data( AccountModel::DownloadCounterRole ).toInt() ); + + painter->setFont( descFont ); + const int countW = painter->fontMetrics().width( count ); + + const QRect countRect( authorRect.right() - 25*PADDING - countW, authorRect.top(), countW, painter->fontMetrics().height() ); + count = painter->fontMetrics().elidedText( count, Qt::ElideRight, authorRect.left() - countRect.left() ); + painter->drawText( countRect, Qt::AlignLeft | Qt::TextWordWrap, count ); + + +// runningEdge = authorRect.x(); + } + /* if ( rowType == AccountModel::TopLevelAccount ) { // rating stars const int rating = index.data( AccountModel::RatingRole ).toInt(); const int ratingWidth = 5 * ( m_ratingStarPositive.width() + PADDING_BETWEEN_STARS ); -// int runningEdge = ( btnRect.right() - btnRect.width() / 2 ) - ratingWidth / 2; + // int runningEdge = ( btnRect.right() - btnRect.width() / 2 ) - ratingWidth / 2; int runningEdge = opt.rect.right() - PADDING - ratingWidth; edgeOfRightExtras = runningEdge; for ( int i = 1; i < 6; i++ ) @@ -304,8 +367,8 @@ AccountDelegate::paintTopLevel( QPainter* painter, const QStyleOptionViewItemV4& // painter->drawText( versionRect, Qt::AlignCenter, version ); edgeOfRightExtras = authorRect.x(); - } - + }*/ +/* // if this is a real resolver, show config wrench, state/status, and string m_cachedConfigRects.remove( index ); if ( rowType == AccountModel::TopLevelAccount ) @@ -329,29 +392,54 @@ AccountDelegate::paintTopLevel( QPainter* painter, const QStyleOptionViewItemV4& edgeOfRightExtras = drawStatus( painter, QPointF( edgeOfRightExtras - PADDING, center ), index ); painter->restore(); } - } + }*/ // Title and description! - // title - QString title = index.data( Qt::DisplayRole ).toString(); - const int rightTitleEdge = edgeOfRightExtras - PADDING; - const int leftTitleEdge = pixmapRect.right() + PADDING; - const QRect textRect( leftTitleEdge, opt.rect.top() + PADDING, rightTitleEdge - leftTitleEdge, center - opt.rect.top() - PADDING ); - painter->setFont( titleFont ); - painter->drawText( textRect, Qt::AlignVCenter | Qt::AlignLeft, title ); - - // description - QString desc = index.data( AccountModel::DescriptionRole ).toString(); - const int descWidth = edgeOfRightExtras - leftTitleEdge - PADDING; - const QRect descRect( leftTitleEdge, center, descWidth, opt.rect.bottom() - center + PADDING ); - painter->setFont( descFont ); - painter->drawText( descRect, Qt::AlignLeft | Qt::TextWordWrap, desc ); - - painter->setRenderHints( QPainter::RenderHints() ); - painter->drawLine( opt.rect.bottomLeft(), opt.rect.bottomRight() ); + return; } +int +AccountDelegate::drawAccountList( QPainter* painter, QStyleOptionViewItemV4& opt, const QList< Account* > accts, int rightEdge ) const +{ + // list each account name, and show the online, offline icon + const int textHeight = painter->fontMetrics().height() + 1; + const int mid = opt.rect.bottom() - opt.rect.height() / 2; + int runningRightEdge = rightEdge; + int current = 0; + + int leftOfAccounts = 0; + + if ( accts.size() % 2 == 1 ) + { + // If there's an odd number, the center one is centered + current = mid - ((textHeight + PADDING/2) * (accts.size()/2) ) - textHeight / 2; + } + else + { + // Even number, center between the middle ones + current = mid - ((textHeight + PADDING/2) * (accts.size()/2) ); + } + + for ( int i = 0; i < accts.size(); i++ ) + { + // draw lightbulb and text + runningRightEdge = drawStatus( painter, QPointF( rightEdge - PADDING, current), accts.at( i ) ); + + const QString label = accts.at( i )->accountFriendlyName(); + const QPoint textTopLeft( runningRightEdge - PADDING - painter->fontMetrics().width( label ), current); + painter->drawText( QRect( textTopLeft, QSize( painter->fontMetrics().width( label ) + 1, textHeight ) ), label ); + + current += textHeight + PADDING/2; + + leftOfAccounts = qMax( leftOfAccounts, textTopLeft.x() ); + } + + return leftOfAccounts; +} + + +/* void AccountDelegate::paintChild( QPainter* painter, const QStyleOptionViewItemV4& option, const QModelIndex& index ) const { @@ -413,7 +501,7 @@ AccountDelegate::paintChild( QPainter* painter, const QStyleOptionViewItemV4& op painter->setFont( smallFont ); drawStatus( painter, QPointF( edgeOfRightExtras - PADDING, center ), index ); painter->restore(); -} +}*/ bool @@ -551,11 +639,11 @@ AccountDelegate::drawRoundedButton( QPainter* painter, const QRect& btnRect ) co int -AccountDelegate::drawStatus( QPainter* painter, const QPointF& rightCenterEdge, const QModelIndex& index ) const +AccountDelegate::drawStatus( QPainter* painter, const QPointF& rightTopEdge, Account* acct ) const { QPixmap p; QString statusText; - Account::ConnectionState state = static_cast< Account::ConnectionState >( index.data( AccountModel::ConnectionStateRole ).toInt() ); + Account::ConnectionState state = acct->connectionState(); if ( state == Account::Connected ) { p = m_onlineIcon; @@ -572,15 +660,16 @@ AccountDelegate::drawStatus( QPainter* painter, const QPointF& rightCenterEdge, statusText = tr( "Offline" ); } - const int yPos = rightCenterEdge.y() - painter->fontMetrics().height() / 2; - const QRect connectIconRect( rightCenterEdge.x() - STATUS_ICON_SIZE, yPos, STATUS_ICON_SIZE, STATUS_ICON_SIZE ); + const int yPos = rightTopEdge.y(); + const QRect connectIconRect( rightTopEdge.x() - STATUS_ICON_SIZE, yPos, STATUS_ICON_SIZE, STATUS_ICON_SIZE ); painter->drawPixmap( connectIconRect, p ); - int width = painter->fontMetrics().width( statusText ); - int statusTextX = connectIconRect.x() - PADDING - width; - painter->drawText( QRect( statusTextX, yPos, width, painter->fontMetrics().height() ), statusText ); + // For now, disable text next to icon +// int width = painter->fontMetrics().width( statusText ); +// int statusTextX = connectIconRect.x() - PADDING - width; +// painter->drawText( QRect( statusTextX, yPos, width, painter->fontMetrics().height() ), statusText ); - return statusTextX; + return connectIconRect.x(); } @@ -630,14 +719,14 @@ AccountDelegate::checkRectForIndex( const QStyleOptionViewItem& option, const QM const int ypos = ( opt.rect.top() + opt.rect.height() / 2 ) - ( WRENCH_SIZE / 2 ); QRect checkRect = QRect( PADDING, ypos, WRENCH_SIZE, WRENCH_SIZE ); return checkRect; - } else if ( rowType == AccountModel::ChildAccount ) + } /*else if ( rowType == AccountModel::ChildAccount ) { // Return smaller rect of individual child account const int smallWrenchSize = opt.rect.height() - PADDING; int ypos = ( opt.rect.center().y() ) - ( smallWrenchSize / 2 ); QRect checkRect = QRect( opt.rect.left() + PADDING, ypos, smallWrenchSize, smallWrenchSize ); return checkRect; - } + }*/ return QRect(); } diff --git a/src/AccountDelegate.h b/src/AccountDelegate.h index f9b565d79..f0e557c76 100644 --- a/src/AccountDelegate.h +++ b/src/AccountDelegate.h @@ -46,20 +46,18 @@ signals: void openConfig( Tomahawk::Accounts::Account* ); private: - void paintTopLevel( QPainter* painter, const QStyleOptionViewItemV4& option, const QModelIndex& index ) const; - void paintChild( QPainter* painter, const QStyleOptionViewItemV4& option, const QModelIndex& index ) const; - void drawRoundedButton( QPainter* painter, const QRect& buttonRect ) const; // Returns new left edge - int drawStatus( QPainter* painter, const QPointF& rightCenterEdge, const QModelIndex& index ) const; + int drawStatus( QPainter* painter, const QPointF& rightTopEdge, Account* acct ) const; void drawCheckBox( QStyleOptionViewItemV4& opt, QPainter* p, const QWidget* w ) const; void drawConfigWrench( QPainter* painter, QStyleOptionViewItemV4& option, QStyleOptionToolButton& topt ) const; + // returns new left edge + int drawAccountList( QPainter* painter, QStyleOptionViewItemV4& option, const QList< Account* > accounts, int rightEdge ) const; QRect checkRectForIndex( const QStyleOptionViewItem &option, const QModelIndex &idx ) const; QMap< QString, QPixmap > m_cachedIcons; QPixmap m_offlineIcon, m_onlineIcon, m_defaultCover, m_onHoverStar, m_ratingStarPositive, m_ratingStarNegative, m_removeIcon; - int m_widestTextWidth; int m_hoveringOver; QPersistentModelIndex m_hoveringItem, m_configPressed; mutable QHash< QPersistentModelIndex, QRect > m_cachedButtonRects; diff --git a/src/libtomahawk/accounts/Account.h b/src/libtomahawk/accounts/Account.h index 9513b4839..b8164d200 100644 --- a/src/libtomahawk/accounts/Account.h +++ b/src/libtomahawk/accounts/Account.h @@ -182,4 +182,6 @@ public: Q_DECLARE_INTERFACE( Tomahawk::Accounts::AccountFactory, "tomahawk.AccountFactory/1.0" ) +Q_DECLARE_METATYPE( QList< Tomahawk::Accounts::Account* > ) + #endif diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index 7a2c06660..8fc75c04c 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -104,8 +104,16 @@ AccountModel::data( const QModelIndex& index, int role ) const return ShippedWithTomahawk; case DescriptionRole: return fac->description(); + case CanRateRole: + return false; case RowTypeRole: return TopLevelFactory; + case AccountData: + return QVariant::fromValue< QObject* >( node->factory ); + case ChildrenOfFactoryRole: + return QVariant::fromValue< QList< Tomahawk::Accounts::Account* > >( node->accounts ); + case HasConfig: + return !node->accounts.isEmpty(); default: return QVariant(); } @@ -133,6 +141,8 @@ AccountModel::data( const QModelIndex& index, int role ) const return c.rating() / 20; // rating is out of 100 case DownloadCounterRole: return c.downloads(); + case CanRateRole: + return true; case VersionRole: return c.version(); case UserHasRatedRole: @@ -188,6 +198,8 @@ AccountModel::data( const QModelIndex& index, int role ) const return TopLevelFactory; case StateRole: return Uninstalled; + case CanRateRole: + return false; default: return QVariant(); } diff --git a/src/libtomahawk/accounts/AccountModel.h b/src/libtomahawk/accounts/AccountModel.h index 97da15c73..37ab56a51 100644 --- a/src/libtomahawk/accounts/AccountModel.h +++ b/src/libtomahawk/accounts/AccountModel.h @@ -56,15 +56,18 @@ public: // used by individual accounts AccountData = Qt::UserRole + 28, // raw plugin + CanRateRole = Qt::UserRole + 32, CheckboxClickedRole = Qt::UserRole + 29, // the checkbox for this row was toggled AddAccountButtonRole = Qt::UserRole + 30, // the add account button + + // Used by factories + ChildrenOfFactoryRole = Qt::UserRole + 31 }; enum RowType { TopLevelFactory, - TopLevelAccount, - ChildAccount + TopLevelAccount }; enum ItemState { From 001b9d062727f79159a85155e8b721d585ec687c Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Mon, 6 Feb 2012 11:27:17 -0500 Subject: [PATCH 055/104] revampify layout Please enter the commit message for your changes. Lines starting --- src/AccountDelegate.cpp | 214 ++++++---------------------------------- 1 file changed, 31 insertions(+), 183 deletions(-) diff --git a/src/AccountDelegate.cpp b/src/AccountDelegate.cpp index 99df128bc..a93284d83 100644 --- a/src/AccountDelegate.cpp +++ b/src/AccountDelegate.cpp @@ -37,7 +37,7 @@ #ifdef Q_WS_MAC #define TOPLEVEL_ACCOUNT_HEIGHT 72 #else -#define TOPLEVEL_ACCOUNT_HEIGHT 62 +#define TOPLEVEL_ACCOUNT_HEIGHT 68 #endif #define ICONSIZE 40 @@ -90,7 +90,7 @@ AccountDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex return QSize( 200, TOPLEVEL_ACCOUNT_HEIGHT ); const QList< Account* > accts = index.data( AccountModel::ChildrenOfFactoryRole ).value< QList< Tomahawk::Accounts::Account* > >(); - return QSize( 200, TOPLEVEL_ACCOUNT_HEIGHT + 14 * accts.size() ); + return QSize( 200, TOPLEVEL_ACCOUNT_HEIGHT + 12 * accts.size()-1 ); } return QSize(); @@ -220,7 +220,8 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, const int leftTitleEdge = pixmapRect.right() + PADDING; painter->setFont( titleFont ); QRect textRect; - if ( index.data( AccountModel::CanRateRole ).toBool() ) + const bool canRate = index.data( AccountModel::CanRateRole ).toBool(); + if ( canRate ) { textRect = QRect( leftTitleEdge, opt.rect.top() + PADDING, rightTitleEdge - leftTitleEdge, painter->fontMetrics().height() ); } @@ -230,14 +231,29 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, } painter->drawText( textRect, Qt::AlignVCenter | Qt::AlignLeft, title ); + // author + QString author = index.data( AccountModel::AuthorRole ).toString(); + int runningBottom = textRect.bottom(); + if ( !author.isEmpty() && canRate ) + { + painter->save(); + painter->setFont( authorFont ); + painter->setPen( QColor( Qt::gray ).darker( 150 ) ); + const int authorWidth = authorMetrics.width( author ); + const QRect authorRect( textRect.left(), textRect.bottom() + PADDING/2, authorWidth + 6, authorMetrics.height() ); + painter->drawText( authorRect, Qt::AlignLeft | Qt::AlignVCenter, author ); + painter->restore(); + + runningBottom = authorRect.bottom(); + } + // description QString desc = index.data( AccountModel::DescriptionRole ).toString(); const int descWidth = rightEdge - leftTitleEdge - PADDING; painter->setFont( descFont ); - const QRect descRect( leftTitleEdge, textRect.bottom() + PADDING/2, descWidth, painter->fontMetrics().height() ); + const QRect descRect( leftTitleEdge, runningBottom + PADDING, descWidth, painter->fontMetrics().height() ); painter->drawText( descRect, Qt::AlignLeft | Qt::TextWordWrap | Qt::AlignTop, desc ); - -// install / status button + runningBottom = descRect.bottom(); if ( index.data( AccountModel::CanRateRole ).toBool() ) { @@ -245,11 +261,14 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, const int rating = index.data( AccountModel::RatingRole ).toInt(); const int ratingWidth = 5 * ( m_ratingStarPositive.width() + PADDING_BETWEEN_STARS ); - // int runningEdge = ( btnRect.right() - btnRect.width() / 2 ) - ratingWidth / 2; +// int runningEdge = opt.rect.right() - 2*PADDING - ratingWidth; int runningEdge = textRect.left(); +// int starsTop = opt.rect.bottom() - 3*PADDING - m_ratingStarNegative.height(); + int starsTop = runningBottom + PADDING; for ( int i = 1; i < 6; i++ ) { - QRect r( runningEdge, opt.rect.bottom() - 4*PADDING - m_ratingStarNegative.height(), m_ratingStarPositive.width(), m_ratingStarPositive.height() ); + QRect r( runningEdge, starsTop, m_ratingStarPositive.width(), m_ratingStarPositive.height() ); +// QRect r( runningEdge, opt.rect.top() + PADDING, m_ratingStarPositive.width(), m_ratingStarPositive.height() ); if ( i == 1 ) m_cachedStarRects[ index ] = r; @@ -278,121 +297,15 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, runningEdge += m_ratingStarPositive.width() + PADDING_BETWEEN_STARS; } - // author - QString author = index.data( AccountModel::AuthorRole ).toString(); - painter->setFont( authorFont ); - const int authorWidth = authorMetrics.width( author ); - const int topTextLine = opt.rect.top() + PADDING; - const QRect authorRect( opt.rect.right() - 2*PADDING - authorWidth, opt.rect.bottom() - 2*PADDING - painter->fontMetrics().height(), authorWidth + 6, authorMetrics.height() ); - painter->drawText( authorRect, Qt::AlignLeft, author ); - - // downloaded num times, underneath button + // downloaded num times QString count = tr( "%1 downloads" ).arg( index.data( AccountModel::DownloadCounterRole ).toInt() ); - painter->setFont( descFont ); const int countW = painter->fontMetrics().width( count ); - - const QRect countRect( authorRect.right() - 25*PADDING - countW, authorRect.top(), countW, painter->fontMetrics().height() ); - count = painter->fontMetrics().elidedText( count, Qt::ElideRight, authorRect.left() - countRect.left() ); + const QRect countRect( runningEdge + 50, starsTop, countW, painter->fontMetrics().height() ); + count = painter->fontMetrics().elidedText( count, Qt::ElideRight, rightEdge - PADDING - countRect.left() ); painter->drawText( countRect, Qt::AlignLeft | Qt::TextWordWrap, count ); - - -// runningEdge = authorRect.x(); + // runningEdge = authorRect.x(); } - /* - if ( rowType == AccountModel::TopLevelAccount ) - { - // rating stars - const int rating = index.data( AccountModel::RatingRole ).toInt(); - const int ratingWidth = 5 * ( m_ratingStarPositive.width() + PADDING_BETWEEN_STARS ); - - // int runningEdge = ( btnRect.right() - btnRect.width() / 2 ) - ratingWidth / 2; - int runningEdge = opt.rect.right() - PADDING - ratingWidth; - edgeOfRightExtras = runningEdge; - for ( int i = 1; i < 6; i++ ) - { - QRect r( runningEdge, opt.rect.top() + PADDING, m_ratingStarPositive.width(), m_ratingStarPositive.height() ); - if ( i == 1 ) - m_cachedStarRects[ index ] = r; - - const bool userHasRated = index.data( AccountModel::UserHasRatedRole ).toBool(); - if ( !userHasRated && // Show on-hover animation if the user hasn't rated it yet, and is hovering over it - m_hoveringOver > -1 && - m_hoveringItem == index ) - { - if ( i <= m_hoveringOver ) // positive star - painter->drawPixmap( r, m_onHoverStar ); - else - painter->drawPixmap( r, m_ratingStarNegative ); - } - else - { - if ( i <= rating ) // positive or rated star - { - if ( userHasRated ) - painter->drawPixmap( r, m_onHoverStar ); - else - painter->drawPixmap( r, m_ratingStarPositive ); - } - else - painter->drawPixmap( r, m_ratingStarNegative ); - } - runningEdge += m_ratingStarPositive.width() + PADDING_BETWEEN_STARS; - } - - // downloaded num times, underneath button - QString count = tr( "%1 downloads" ).arg( index.data( AccountModel::DownloadCounterRole ).toInt() ); - - QFont countFont = descFont; - countFont.setPointSize( countFont.pointSize() - 2 ); - countFont.setBold( true ); - painter->setFont( countFont ); - const int countW = painter->fontMetrics().width( count ); - - const QRect countRect( opt.rect.right() - PADDING - countW, opt.rect.bottom() - PADDING - painter->fontMetrics().height(), countW, painter->fontMetrics().height() ); - painter->setFont( countFont ); - painter->drawText( countRect, Qt::AlignCenter | Qt::TextWordWrap, count ); - - // author and version - QString author = index.data( AccountModel::AuthorRole ).toString(); - painter->setFont( authorFont ); - const int authorWidth = authorMetrics.width( author ); - const int topTextLine = opt.rect.top() + PADDING; - const QRect authorRect( edgeOfRightExtras - 2*PADDING - authorWidth, topTextLine, authorWidth + 6, authorMetrics.height() ); - painter->drawText( authorRect, Qt::AlignCenter, author ); - - // Disable version for now, that space is used - // const QRect versionRect = authorRect.translated( 0, authorRect.height() ); - // QString version = index.data( AccountModel::VersionRole ).toString(); - // painter->drawText( versionRect, Qt::AlignCenter, version ); - - edgeOfRightExtras = authorRect.x(); - }*/ -/* - // if this is a real resolver, show config wrench, state/status, and string - m_cachedConfigRects.remove( index ); - if ( rowType == AccountModel::TopLevelAccount ) - { - const QRect confRect = QRect( edgeOfRightExtras - 2*PADDING - WRENCH_SIZE, center - WRENCH_SIZE / 2, WRENCH_SIZE, WRENCH_SIZE ); - if( index.data( AccountModel::HasConfig ).toBool() ) { - - QStyleOptionToolButton topt; - topt.rect = confRect; - topt.pos = confRect.topLeft(); - - drawConfigWrench( painter, opt, topt ); - m_cachedConfigRects[ index ] = confRect; - edgeOfRightExtras = confRect.left(); - } - - if ( state == AccountModel::Installed || state == AccountModel::ShippedWithTomahawk || state == AccountModel::NeedsUpgrade ) - { - painter->save(); - painter->setFont( installFont ); - edgeOfRightExtras = drawStatus( painter, QPointF( edgeOfRightExtras - PADDING, center ), index ); - painter->restore(); - } - }*/ // Title and description! return; @@ -439,71 +352,6 @@ AccountDelegate::drawAccountList( QPainter* painter, QStyleOptionViewItemV4& opt } -/* -void -AccountDelegate::paintChild( QPainter* painter, const QStyleOptionViewItemV4& option, const QModelIndex& index ) const -{ - const int radius = 6; - const int top = option.rect.top(); - const int center = top + option.rect.height() / 2; - QPainterPath outline; - outline.moveTo( option.rect.topLeft() ); - - const int rightPadding = 2; - outline.lineTo( option.rect.left(), option.rect.bottom() - radius ); - outline.quadTo( option.rect.bottomLeft(), QPointF( option.rect.left() + radius, option.rect.bottom() ) ); - outline.lineTo( option.rect.right() - radius - rightPadding, option.rect.bottom() ); - outline.quadTo( QPointF( option.rect.right() - rightPadding, option.rect.bottom() ), QPointF( option.rect.right() - rightPadding, option.rect.bottom() - radius ) ); - outline.lineTo( option.rect.right() - 2, top ); - - painter->drawPath( outline ); - - // draw checkbox first - const int smallWrenchSize = option.rect.height() - PADDING; - int ypos = ( option.rect.center().y() ) - ( smallWrenchSize / 2 ); - QRect checkRect = QRect( option.rect.left() + PADDING, ypos, smallWrenchSize, smallWrenchSize ); - QStyleOptionViewItemV4 opt2 = option; - opt2.rect = checkRect; - drawCheckBox( opt2, painter, opt2.widget ); - - const QString username = index.data( Qt::DisplayRole ).toString(); - QFont f = option.font; - f.setPointSize( 9 ); - painter->setFont( f ); - painter->drawText( option.rect.adjusted( PADDING + checkRect.right(), 0, 0, 0 ), Qt::AlignVCenter | Qt::AlignLeft, username ); - - // draw remove icon, config wrench, and then status from right edge - const QRect removeRect( option.rect.right() - rightPadding - PADDING - REMOVE_ICON_SIZE, center - REMOVE_ICON_SIZE/2, REMOVE_ICON_SIZE, REMOVE_ICON_SIZE ); - m_cachedButtonRects[ index ] = removeRect; - painter->drawPixmap( removeRect, m_removeIcon ); - - int edgeOfRightExtras = removeRect.left(); - - m_cachedConfigRects.remove( index ); - if ( index.data( AccountModel::HasConfig ).toBool() ) - { - const QRect confRect = QRect( removeRect.x() - PADDING - SMALL_WRENCH_SIZE, center - SMALL_WRENCH_SIZE / 2, SMALL_WRENCH_SIZE, SMALL_WRENCH_SIZE ); - - QStyleOptionToolButton topt; - topt.rect = confRect; - topt.pos = confRect.topLeft(); - - QStyleOptionViewItemV4 opt3 = option; - drawConfigWrench( painter, opt3, topt ); - m_cachedConfigRects[ index ] = confRect; - - edgeOfRightExtras = confRect.left(); - } - - painter->save(); - QFont smallFont = option.font; - smallFont.setPointSize( smallFont.pointSize() - 2 ); - painter->setFont( smallFont ); - drawStatus( painter, QPointF( edgeOfRightExtras - PADDING, center ), index ); - painter->restore(); -}*/ - - bool AccountDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index ) { From 0dd4823a23eaad259fc0d68f7ca8a4b4c96b38e8 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Mon, 6 Feb 2012 17:48:38 -0500 Subject: [PATCH 056/104] SHow online/offline status for factory with an account as well --- src/AccountDelegate.cpp | 30 ++++++++++++++++++----- src/AccountDelegate.h | 2 +- src/libtomahawk/accounts/AccountModel.cpp | 9 ++++--- src/libtomahawk/accounts/AccountModel.h | 4 +-- 4 files changed, 32 insertions(+), 13 deletions(-) diff --git a/src/AccountDelegate.cpp b/src/AccountDelegate.cpp index a93284d83..5a2fdc55d 100644 --- a/src/AccountDelegate.cpp +++ b/src/AccountDelegate.cpp @@ -80,7 +80,7 @@ QSize AccountDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const { AccountModel::RowType rowType = static_cast< AccountModel::RowType >( index.data( AccountModel::RowTypeRole ).toInt() ); - if ( rowType == AccountModel::TopLevelAccount ) + if ( rowType == AccountModel::TopLevelAccount || rowType == AccountModel::UniqueFactory ) return QSize( 200, TOPLEVEL_ACCOUNT_HEIGHT ); else if ( rowType == AccountModel::TopLevelFactory ) { @@ -212,6 +212,18 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, painter->drawText( btnRect, Qt::AlignCenter, btnText ); painter->restore(); } + else if ( rowType == AccountModel::UniqueFactory ) + { + // Display as usual, except if it has an account, show the status. + const QList< Account* > accts = index.data( AccountModel::ChildrenOfFactoryRole ).value< QList< Tomahawk::Accounts::Account* > >(); + if ( !accts.isEmpty() ) + { + Q_ASSERT( accts.size() == 1 ); + + rightEdge = drawStatus( painter, QPointF( rightEdge, center - painter->fontMetrics().height()/2 ), accts.first(), true ); + } + + } // Draw the title and description // title @@ -487,7 +499,7 @@ AccountDelegate::drawRoundedButton( QPainter* painter, const QRect& btnRect ) co int -AccountDelegate::drawStatus( QPainter* painter, const QPointF& rightTopEdge, Account* acct ) const +AccountDelegate::drawStatus( QPainter* painter, const QPointF& rightTopEdge, Account* acct, bool drawText ) const { QPixmap p; QString statusText; @@ -512,12 +524,18 @@ AccountDelegate::drawStatus( QPainter* painter, const QPointF& rightTopEdge, Acc const QRect connectIconRect( rightTopEdge.x() - STATUS_ICON_SIZE, yPos, STATUS_ICON_SIZE, STATUS_ICON_SIZE ); painter->drawPixmap( connectIconRect, p ); + int leftEdge = connectIconRect.x(); // For now, disable text next to icon -// int width = painter->fontMetrics().width( statusText ); -// int statusTextX = connectIconRect.x() - PADDING - width; -// painter->drawText( QRect( statusTextX, yPos, width, painter->fontMetrics().height() ), statusText ); + if ( drawText ) + { + int width = painter->fontMetrics().width( statusText ); + int statusTextX = connectIconRect.x() - PADDING - width; + painter->drawText( QRect( statusTextX, yPos, width, painter->fontMetrics().height() ), statusText ); - return connectIconRect.x(); + leftEdge = statusTextX; + } + + return leftEdge; } diff --git a/src/AccountDelegate.h b/src/AccountDelegate.h index f0e557c76..6a1378403 100644 --- a/src/AccountDelegate.h +++ b/src/AccountDelegate.h @@ -48,7 +48,7 @@ signals: private: void drawRoundedButton( QPainter* painter, const QRect& buttonRect ) const; // Returns new left edge - int drawStatus( QPainter* painter, const QPointF& rightTopEdge, Account* acct ) const; + int drawStatus( QPainter* painter, const QPointF& rightTopEdge, Account* acct, bool drawText = false ) const; void drawCheckBox( QStyleOptionViewItemV4& opt, QPainter* p, const QWidget* w ) const; void drawConfigWrench( QPainter* painter, QStyleOptionViewItemV4& option, QStyleOptionToolButton& topt ) const; // returns new left edge diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index 8fc75c04c..e98c93f38 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -174,6 +174,9 @@ AccountModel::data( const QModelIndex& index, int role ) const case AccountModelNode::ManualResolverType: case AccountModelNode::UniqueFactoryType: { + if ( role == RowTypeRole ) + return UniqueFactory; + Account* acct = 0; if ( node->type == AccountModelNode::ManualResolverType ) acct = node->resolverAccount; @@ -194,8 +197,6 @@ AccountModel::data( const QModelIndex& index, int role ) const return node->factory->icon(); case DescriptionRole: return node->factory->description(); - case RowTypeRole: - return TopLevelFactory; case StateRole: return Uninstalled; case CanRateRole: @@ -218,14 +219,14 @@ AccountModel::data( const QModelIndex& index, int role ) const return acct->enabled() ? Qt::Checked : Qt::Unchecked; case AccountData: return QVariant::fromValue< QObject* >( acct ); - case RowTypeRole: - return TopLevelAccount; case ConnectionStateRole: return acct->connectionState(); case HasConfig: return acct->configurationWidget() != 0; case StateRole: return Installed; + case ChildrenOfFactoryRole: + return QVariant::fromValue< QList< Tomahawk::Accounts::Account* > >( node->accounts ); default: return QVariant(); } diff --git a/src/libtomahawk/accounts/AccountModel.h b/src/libtomahawk/accounts/AccountModel.h index 37ab56a51..eaa676172 100644 --- a/src/libtomahawk/accounts/AccountModel.h +++ b/src/libtomahawk/accounts/AccountModel.h @@ -67,7 +67,8 @@ public: enum RowType { TopLevelFactory, - TopLevelAccount + TopLevelAccount, + UniqueFactory }; enum ItemState { @@ -78,7 +79,6 @@ public: Upgrading, Failed, ShippedWithTomahawk, // Built-in account/factory state: Can't uninstall or uninstall, just create - UniqueFactory // Shipped with tomahawk but is a unique account }; explicit AccountModel( QObject* parent = 0 ); From ecccf879923966a2a9550f094366c123e123b6a0 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Thu, 9 Feb 2012 23:16:18 -0500 Subject: [PATCH 057/104] Add multi-account config widget and hook things up --- src/AccountDelegate.cpp | 36 +++-- src/AccountDelegate.h | 2 +- src/AccountFactoryWrapper.cpp | 137 ++++++++++++++++++ src/AccountFactoryWrapper.h | 67 +++++++++ src/AccountFactoryWrapper.ui | 110 ++++++++++++++ src/AccountFactoryWrapperDelegate.cpp | 166 ++++++++++++++++++++++ src/AccountFactoryWrapperDelegate.h | 58 ++++++++ src/CMakeLists.txt | 6 + src/delegateconfigwrapper.h | 30 +++- src/libtomahawk/accounts/AccountModel.cpp | 56 +++++++- src/settingsdialog.cpp | 117 +++++++-------- src/settingsdialog.h | 10 +- 12 files changed, 709 insertions(+), 86 deletions(-) create mode 100644 src/AccountFactoryWrapper.cpp create mode 100644 src/AccountFactoryWrapper.h create mode 100644 src/AccountFactoryWrapper.ui create mode 100644 src/AccountFactoryWrapperDelegate.cpp create mode 100644 src/AccountFactoryWrapperDelegate.h diff --git a/src/AccountDelegate.cpp b/src/AccountDelegate.cpp index 5a2fdc55d..71e76c786 100644 --- a/src/AccountDelegate.cpp +++ b/src/AccountDelegate.cpp @@ -71,8 +71,6 @@ AccountDelegate::AccountDelegate( QObject* parent ) m_defaultCover = m_defaultCover.scaled( ICONSIZE, ICONSIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation ); - m_cachedIcons[ "sipplugin-online" ] = QPixmap( RESPATH "images/sipplugin-online.png" ).scaled( STATUS_ICON_SIZE, STATUS_ICON_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation ); - m_cachedIcons[ "sipplugin-offline" ] = QPixmap( RESPATH "images/sipplugin-offline.png" ).scaled( STATUS_ICON_SIZE, STATUS_ICON_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation ); } @@ -381,9 +379,28 @@ AccountDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const QS { m_configPressed = index; - Account* acct = qobject_cast< Account* >( index.data( AccountModel::AccountData ).value< QObject* >() ); - Q_ASSERT( acct ); // Should not be showing a config wrench if there is no account! - emit openConfig( acct ); + const AccountModel::RowType rowType = static_cast< AccountModel::RowType >( index.data( AccountModel::RowTypeRole ).toInt() ); + if ( rowType == AccountModel::TopLevelAccount ) + { + Account* acct = qobject_cast< Account* >( index.data( AccountModel::AccountData ).value< QObject* >() ); + Q_ASSERT( acct ); // Should not be showing a config wrench if there is no account! + + emit openConfig( acct ); + } + else if ( rowType == AccountModel::TopLevelFactory ) + { + AccountFactory* fac = qobject_cast< AccountFactory* >( index.data( AccountModel::AccountData ).value< QObject* >() ); + Q_ASSERT( fac ); // Should not be showing a config wrench if there is no account! + emit openConfig( fac ); + } + else if ( rowType == AccountModel::UniqueFactory ) + { + const QList< Account* > accts = index.data( AccountModel::ChildrenOfFactoryRole ).value< QList< Tomahawk::Accounts::Account* > >(); + + Q_ASSERT( !accts.isEmpty() ); // If there's no account, why is there a config widget for this factory? + Q_ASSERT( accts.size() == 1 ); + emit openConfig( accts.first() ); + } return true; } } else if ( event->type() == QEvent::MouseButtonRelease || event->type() == QEvent::MouseButtonDblClick ) @@ -395,13 +412,7 @@ AccountDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const QS m_configPressed = QModelIndex(); const AccountModel::ItemState state = static_cast< AccountModel::ItemState >( index.data( AccountModel::StateRole ).toInt() ); - const bool canCheck = ( state == AccountModel::Installed || state == AccountModel::ShippedWithTomahawk ); - if ( !canCheck ) - return false; - // A few options. First, could be the checkbox on/off. - // second, could be the install/uninstall/create button - // third could be the config button if ( checkRectForIndex( option, index ).contains( me->pos() ) ) { // Check box for this row @@ -525,7 +536,6 @@ AccountDelegate::drawStatus( QPainter* painter, const QPointF& rightTopEdge, Acc painter->drawPixmap( connectIconRect, p ); int leftEdge = connectIconRect.x(); - // For now, disable text next to icon if ( drawText ) { int width = painter->fontMetrics().width( statusText ); @@ -557,7 +567,7 @@ AccountDelegate::drawConfigWrench ( QPainter* painter, QStyleOptionViewItemV4& o // draw it the same size as the check belox topt.font = opt.font; topt.icon = QIcon( RESPATH "images/configure.png" ); - topt.iconSize = QSize( 16, 16 ); + topt.iconSize = QSize( 14, 14 ); topt.subControls = QStyle::SC_ToolButton; topt.activeSubControls = QStyle::SC_None; topt.features = QStyleOptionToolButton::None; diff --git a/src/AccountDelegate.h b/src/AccountDelegate.h index 6a1378403..4cadd38c8 100644 --- a/src/AccountDelegate.h +++ b/src/AccountDelegate.h @@ -44,6 +44,7 @@ protected: signals: void update( const QModelIndex& idx ); void openConfig( Tomahawk::Accounts::Account* ); + void openConfig( Tomahawk::Accounts::AccountFactory* ); private: void drawRoundedButton( QPainter* painter, const QRect& buttonRect ) const; @@ -56,7 +57,6 @@ private: QRect checkRectForIndex( const QStyleOptionViewItem &option, const QModelIndex &idx ) const; - QMap< QString, QPixmap > m_cachedIcons; QPixmap m_offlineIcon, m_onlineIcon, m_defaultCover, m_onHoverStar, m_ratingStarPositive, m_ratingStarNegative, m_removeIcon; int m_hoveringOver; QPersistentModelIndex m_hoveringItem, m_configPressed; diff --git a/src/AccountFactoryWrapper.cpp b/src/AccountFactoryWrapper.cpp new file mode 100644 index 000000000..86e824512 --- /dev/null +++ b/src/AccountFactoryWrapper.cpp @@ -0,0 +1,137 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Leo Franchi + * + * 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 "AccountFactoryWrapper.h" + +#include "accounts/Account.h" +#include +#include "AccountFactoryWrapperDelegate.h" +#include "delegateconfigwrapper.h" +#include "ui_AccountFactoryWrapper.h" + +using namespace Tomahawk::Accounts; +AccountFactoryWrapper::AccountFactoryWrapper( AccountFactory* factory, QWidget* parent ) + : QDialog( parent, Qt::Sheet ) + , m_factory( factory ) + , m_ui( new Ui_AccountFactoryWrapper ) + , m_createAccount( false ) +{ + m_ui->setupUi( this ); + + setWindowTitle( factory->prettyName() ); + + m_ui->factoryIcon->setPixmap( factory->icon() ); + m_ui->factoryDescription->setText( factory->description() ); + + m_addButton = m_ui->buttonBox->addButton( tr( "Add Account" ), QDialogButtonBox::ActionRole ); + + AccountFactoryWrapperDelegate* del = new AccountFactoryWrapperDelegate( m_ui->accountsList ); + m_ui->accountsList->setItemDelegate( del ); + + connect( del, SIGNAL( openConfig( Tomahawk::Accounts::Account* ) ), this, SLOT( openAccountConfig( Tomahawk::Accounts::Account* ) ) ); + connect( del, SIGNAL( removeAccount( Tomahawk::Accounts::Account* ) ), this, SLOT( removeAccount( Tomahawk::Accounts::Account* ) ) ); + + load(); + + + connect( m_ui->buttonBox, SIGNAL( rejected() ), this, SLOT( reject() ) ); + connect( m_ui->buttonBox, SIGNAL( accepted() ), this, SLOT( accept() ) ); + connect( m_ui->buttonBox, SIGNAL( clicked( QAbstractButton*) ), this, SLOT( buttonClicked() ) ); +#ifdef Q_OS_MAC + setContentsMargins( 0, 0, 0, 0 ); + m_ui->verticalLayout->setSpacing( 4 ); +#endif +} + +void +AccountFactoryWrapper::load() +{ + m_ui->accountsList->clear(); + foreach ( Account* acc, AccountManager::instance()->accounts() ) + { + if ( AccountManager::instance()->factoryForAccount( acc ) == m_factory ) + { + QTreeWidgetItem* item = new QTreeWidgetItem( m_ui->accountsList ); + item->setData( 0, AccountRole, QVariant::fromValue< QObject *>( acc ) ); + } + } + + const int height = m_ui->accountsList->model()->rowCount( QModelIndex() ) * ACCOUNT_ROW_HEIGHT + 7; + m_ui->accountsList->setFixedHeight( height ); +} + + +void +AccountFactoryWrapper::openAccountConfig( Account* account ) +{ + if( account->configurationWidget() ) + { +#ifndef Q_WS_MAC + DelegateConfigWrapper dialog( account->configurationWidget(), QString("%1 Configuration" ).arg( account->accountFriendlyName() ), this ); + QWeakPointer< DelegateConfigWrapper > watcher( &dialog ); + int ret = dialog.exec(); + if( !watcher.isNull() && ret == QDialog::Accepted ) + { + // send changed config to resolver + account->saveConfig(); + } +#else + // on osx a sheet needs to be non-modal + DelegateConfigWrapper* dialog = new DelegateConfigWrapper( account->configurationWidget(), QString("%1 Configuration" ).arg( account->accountFriendlyName() ), this, Qt::Sheet ); + dialog->setProperty( "accountplugin", QVariant::fromValue< QObject* >( account ) ); + connect( dialog, SIGNAL( finished( int ) ), this, SLOT( accountConfigClosed( int ) ) ); + + dialog->show(); +#endif + } +} + + +void +AccountFactoryWrapper::accountConfigClosed( int value ) +{ + if( value == QDialog::Accepted ) + { + DelegateConfigWrapper* dialog = qobject_cast< DelegateConfigWrapper* >( sender() ); + Account* account = qobject_cast< Account* >( dialog->property( "accountplugin" ).value< QObject* >() ); + account->saveConfig(); + } +} + +void +AccountFactoryWrapper::removeAccount( Tomahawk::Accounts::Account* acct ) +{ + AccountManager::instance()->removeAccount( acct ); + + load(); +} + +void +AccountFactoryWrapper::buttonClicked( QAbstractButton* button ) +{ + if ( button == m_addButton ) + { + m_createAccount = true; + emit createAccount( m_factory ); + accept(); + return; + } + else + reject(); +} + diff --git a/src/AccountFactoryWrapper.h b/src/AccountFactoryWrapper.h new file mode 100644 index 000000000..62fa9a23d --- /dev/null +++ b/src/AccountFactoryWrapper.h @@ -0,0 +1,67 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Leo Franchi + * + * 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 ACCOUNTFACTORYWRAPPER_H +#define ACCOUNTFACTORYWRAPPER_H + +#include + +class QAbstractButton; +namespace Tomahawk { +namespace Accounts { + class AccountFactory; +class Account; +} +} + +class Ui_AccountFactoryWrapper; + +// class AccountFactoryWrapper_ +class AccountFactoryWrapper : public QDialog +{ + Q_OBJECT +public: + enum ExtraRoles { + AccountRole = Qt::UserRole + 140 + }; + + explicit AccountFactoryWrapper( Tomahawk::Accounts::AccountFactory* factory, QWidget* parent = 0 ); + + bool doCreateAccount() const { return m_createAccount; } + +signals: + void createAccount( Tomahawk::Accounts::AccountFactory* factory ); + +public slots: + void openAccountConfig( Tomahawk::Accounts::Account* ); + void accountConfigClosed( int value ); + void removeAccount( Tomahawk::Accounts::Account* ); + +private slots: + void buttonClicked( QAbstractButton* ); + +private: + void load(); + + Tomahawk::Accounts::AccountFactory* m_factory; + Ui_AccountFactoryWrapper* m_ui; + QPushButton* m_addButton; + bool m_createAccount; +}; + +#endif // ACCOUNTFACTORYWRAPPER_H diff --git a/src/AccountFactoryWrapper.ui b/src/AccountFactoryWrapper.ui new file mode 100644 index 000000000..9a119015e --- /dev/null +++ b/src/AccountFactoryWrapper.ui @@ -0,0 +1,110 @@ + + + AccountFactoryWrapper + + + + 0 + 0 + 507 + 298 + + + + Dialog + + + + + + + + + Qt::AlignCenter + + + + + + + Description goes here + + + Qt::AlignCenter + + + + + + + Qt::Vertical + + + + 20 + 20 + + + + + + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + false + + + QAbstractItemView::NoSelection + + + QAbstractItemView::ScrollPerItem + + + false + + + true + + + false + + + + 1 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Close + + + + + + + + diff --git a/src/AccountFactoryWrapperDelegate.cpp b/src/AccountFactoryWrapperDelegate.cpp new file mode 100644 index 000000000..fcd89701b --- /dev/null +++ b/src/AccountFactoryWrapperDelegate.cpp @@ -0,0 +1,166 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Leo Franchi + * + * 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 "AccountFactoryWrapperDelegate.h" +#include "accounts/Account.h" +#include "AccountFactoryWrapper.h" +#include "utils/tomahawkutils.h" + +#include +#include +#include + +using namespace Tomahawk::Accounts; + +#define ICON_SIZE 15 +#define CONFIG_WRENCH_SIZE 20 +#define PADDING 4 + +AccountFactoryWrapperDelegate::AccountFactoryWrapperDelegate( QObject* parent ) + : QStyledItemDelegate( parent ) +{ + m_removePixmap.load( RESPATH "images/list-remove.png" ); + m_onlineIcon.load( RESPATH "images/sipplugin-online.png" ); + m_offlineIcon.load( RESPATH "images/sipplugin-offline.png" ); + + m_removePixmap = m_removePixmap.scaled( ICON_SIZE, ICON_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation ); + m_onlineIcon = m_onlineIcon.scaled( ICON_SIZE, ICON_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation ); + m_offlineIcon = m_offlineIcon.scaled( ICON_SIZE, ICON_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation ); + + m_configIcon.addFile( RESPATH "images/configure.png", QSize( CONFIG_WRENCH_SIZE - 8, CONFIG_WRENCH_SIZE - 8 ) ); +} + +void +AccountFactoryWrapperDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const +{ + QStyleOptionViewItemV4 opt = option; + initStyleOption( &opt, index ); + + const int center = opt.rect.height() / 2 + opt.rect.top(); + const int topIcon = center - ICON_SIZE/2; + + // draw the background + const QWidget* w = opt.widget; + QStyle* style = w ? w->style() : QApplication::style(); + style->drawPrimitive( QStyle::PE_PanelItemViewItem, &opt, painter, w ); + + Account* acc = qobject_cast< Account* >( index.data( AccountFactoryWrapper::AccountRole ).value< QObject* >() ); + Q_ASSERT( acc ); + + // name on left + painter->drawText( opt.rect.adjusted( PADDING, PADDING, -PADDING, -PADDING ), Qt::AlignLeft | Qt::AlignVCenter, acc->accountFriendlyName() ); + + // remove, config, status on right + const QRect pmRect( opt.rect.right() - PADDING - m_removePixmap.width(), topIcon, ICON_SIZE, ICON_SIZE ); + painter->drawPixmap( pmRect, m_removePixmap ); + m_cachedButtonRects[ index ] = pmRect; + + const QRect confRect( pmRect.left() - PADDING - CONFIG_WRENCH_SIZE, center - CONFIG_WRENCH_SIZE/2, CONFIG_WRENCH_SIZE, CONFIG_WRENCH_SIZE ); + + QStyleOptionToolButton topt; + topt.rect = confRect; + topt.pos = confRect.topLeft(); + topt.font = opt.font; + topt.icon = m_configIcon; + topt.iconSize = QSize( CONFIG_WRENCH_SIZE - 8, CONFIG_WRENCH_SIZE - 8 ); + topt.subControls = QStyle::SC_ToolButton; + topt.activeSubControls = QStyle::SC_None; + topt.features = QStyleOptionToolButton::None; + bool pressed = ( m_configPressed == opt.index ); + topt.state = pressed ? QStyle::State_On : QStyle::State_Raised; + if( opt.state & QStyle::State_MouseOver || pressed ) + topt.state |= QStyle::State_HasFocus; + style->drawComplexControl( QStyle::CC_ToolButton, &topt, painter, w ); + m_cachedConfigRects[ index ] = confRect; + + QPixmap p; + QString statusText; + Account::ConnectionState state = acc->connectionState(); + if ( state == Account::Connected ) + { + p = m_onlineIcon; + statusText = tr( "Online" ); + } + else if ( state == Account::Connecting ) + { + p = m_offlineIcon; + statusText = tr( "Connecting..." ); + } + else + { + p = m_offlineIcon; + statusText = tr( "Offline" ); + } + + const QRect connectIconRect( confRect.left() - PADDING - ICON_SIZE, topIcon, ICON_SIZE, ICON_SIZE ); + painter->drawPixmap( connectIconRect, p ); + + int width = painter->fontMetrics().width( statusText ); + painter->drawText( QRect( connectIconRect.left() - PADDING - width, center - painter->fontMetrics().height()/2, width, painter->fontMetrics().height() ), statusText ); + +} + +QSize +AccountFactoryWrapperDelegate::sizeHint(const QStyleOptionViewItem&, const QModelIndex&) const +{ + return QSize( 200, ACCOUNT_ROW_HEIGHT ); +} + + +bool +AccountFactoryWrapperDelegate::editorEvent( QEvent* event, QAbstractItemModel*, const QStyleOptionViewItem&, const QModelIndex& index ) +{ + if ( event->type() != QEvent::MouseButtonPress && + event->type() != QEvent::MouseButtonRelease && + event->type() != QEvent::MouseButtonDblClick && + event->type() != QEvent::MouseMove ) + return false; + + if ( event->type() == QEvent::MouseButtonPress ) + { + // Show the config wrench as depressed on click + QMouseEvent* me = static_cast< QMouseEvent* >( event ); + if ( me->button() == Qt::LeftButton && m_cachedConfigRects.contains( index ) && m_cachedConfigRects[ index ].contains( me->pos() ) ) + { + m_configPressed = index; + Account* acct = qobject_cast< Account* >( index.data( AccountFactoryWrapper::AccountRole ).value< QObject* >() ); + Q_ASSERT( acct ); // Should not be showing a config wrench if there is no account! + + emit openConfig( acct ); + + return true; + } + } else if ( event->type() == QEvent::MouseButtonRelease || event->type() == QEvent::MouseButtonDblClick ) + { + QMouseEvent* me = static_cast< QMouseEvent* >( event ); + if ( m_configPressed.isValid() ) + emit update( m_configPressed ); + + m_configPressed = QModelIndex(); + + if ( m_cachedButtonRects.contains( index ) && m_cachedButtonRects[ index ].contains( me->pos() ) ) + { + Account* acct = qobject_cast< Account* >( index.data( AccountFactoryWrapper::AccountRole ).value< QObject* >() ); + emit removeAccount( acct ); + + return true; + } + } + return false; +} + diff --git a/src/AccountFactoryWrapperDelegate.h b/src/AccountFactoryWrapperDelegate.h new file mode 100644 index 000000000..699ed22f8 --- /dev/null +++ b/src/AccountFactoryWrapperDelegate.h @@ -0,0 +1,58 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2012, Leo Franchi + * + * 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 ACCOUNTFACTORYWRAPPERDELEGATE_H +#define ACCOUNTFACTORYWRAPPERDELEGATE_H + +#include + +#define ACCOUNT_ROW_HEIGHT 20 + +namespace Tomahawk { +namespace Accounts { +class Account; +} +} + +class AccountFactoryWrapperDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + explicit AccountFactoryWrapperDelegate( QObject* parent = 0 ); + + virtual void paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const; + + virtual QSize sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const; + virtual bool editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index); + +signals: + void update( const QModelIndex& ); + + void openConfig( Tomahawk::Accounts::Account* ); + void removeAccount( Tomahawk::Accounts::Account* ); + +private: + QPixmap m_removePixmap, m_offlineIcon, m_onlineIcon; + QIcon m_configIcon; + QModelIndex m_configPressed; + + mutable QHash< QPersistentModelIndex, QRect > m_cachedButtonRects; + mutable QHash< QPersistentModelIndex, QRect > m_cachedConfigRects; +}; + +#endif // ACCOUNTFACTORYWRAPPERDELEGATE_H diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 72de137ed..ee8ac9b0b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -78,6 +78,8 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui} settingslistdelegate.cpp tomahawkwindow.cpp LoadXSPFDialog.cpp + AccountFactoryWrapper.cpp + AccountFactoryWrapperDelegate.cpp ) SET( tomahawkHeaders ${tomahawkHeaders} @@ -121,6 +123,8 @@ SET( tomahawkHeadersGui ${tomahawkHeadersGui} delegateconfigwrapper.h tomahawkwindow.h LoadXSPFDialog.h + AccountFactoryWrapper.h + AccountFactoryWrapperDelegate.h ) SET( tomahawkUI ${tomahawkUI} @@ -132,6 +136,8 @@ SET( tomahawkUI ${tomahawkUI} audiocontrols.ui LoadXSPFDialog.ui + + AccountFactoryWrapper.ui ) INCLUDE_DIRECTORIES( diff --git a/src/delegateconfigwrapper.h b/src/delegateconfigwrapper.h index 5e71bdcac..4ff15313b 100644 --- a/src/delegateconfigwrapper.h +++ b/src/delegateconfigwrapper.h @@ -28,7 +28,7 @@ class DelegateConfigWrapper : public QDialog { Q_OBJECT public: - DelegateConfigWrapper( QWidget* conf, const QString& title, QWidget* parent, Qt::WindowFlags flags = 0 ) : QDialog( parent, flags ), m_widget( conf ) + DelegateConfigWrapper( QWidget* conf, const QString& title, QWidget* parent, Qt::WindowFlags flags = 0 ) : QDialog( parent, flags ), m_widget( conf ), m_deleted( false ) { m_widget->setWindowFlags( Qt::Sheet ); #ifdef Q_WS_MAC @@ -39,11 +39,11 @@ public: v->setContentsMargins( 0, 0, 0, 0 ); v->addWidget( m_widget ); - QDialogButtonBox* buttons = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this ); - m_okButton = buttons->button( QDialogButtonBox::Ok ); - connect( buttons, SIGNAL( clicked( QAbstractButton*) ), this, SLOT( closed( QAbstractButton* ) ) ); + m_buttons = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this ); + m_okButton = m_buttons->button( QDialogButtonBox::Ok ); + connect( m_buttons, SIGNAL( clicked( QAbstractButton*) ), this, SLOT( closed( QAbstractButton* ) ) ); connect( this, SIGNAL( rejected() ), this, SLOT( rejected() ) ); - v->addWidget( buttons ); + v->addWidget( m_buttons ); setLayout( v ); @@ -62,6 +62,14 @@ public: ~DelegateConfigWrapper() {} + void setShowDelete( bool del ) + { + if ( del ) + m_deleteButton = m_buttons->addButton( tr( "Delete Account" ), QDialogButtonBox::DestructiveRole ); + } + + bool deleted() const { return m_deleted; } + public slots: void toggleOkButton( bool dataError ) { @@ -78,6 +86,11 @@ public slots: QDialogButtonBox* buttons = qobject_cast< QDialogButtonBox* >( sender() ); if( buttons->standardButton( b ) == QDialogButtonBox::Ok ) done( QDialog::Accepted ); + else if ( b == m_deleteButton ) + { + m_deleted = true; + emit deleted(); + } else done( QDialog::Rejected ); } @@ -100,9 +113,14 @@ public slots: show(); } +signals: + void closedWithDelete(); + private: + QDialogButtonBox* m_buttons; QWidget* m_widget; - QPushButton* m_okButton; + QPushButton *m_okButton, *m_deleteButton; + bool m_deleted; }; #endif diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index e98c93f38..44a16919b 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -72,6 +72,7 @@ AccountModel::loadData() connect ( AccountManager::instance(), SIGNAL( removed( Tomahawk::Accounts::Account* ) ), this, SLOT( accountRemoved( Tomahawk::Accounts::Account* ) ) ); connect ( AccountManager::instance(), SIGNAL( stateChanged( Account* ,Accounts::Account::ConnectionState ) ), this, SLOT( accountStateChanged( Account*, Accounts::Account::ConnectionState ) ) ); + connect( AtticaManager::instance(), SIGNAL( resolverInstalled( QString ) ), this, SLOT( atticaInstalled( QString ) ) ); } @@ -175,7 +176,12 @@ AccountModel::data( const QModelIndex& index, int role ) const case AccountModelNode::UniqueFactoryType: { if ( role == RowTypeRole ) - return UniqueFactory; + { + if ( node->type == AccountModelNode::ManualResolverType ) + return TopLevelAccount; + else + return UniqueFactory; + } Account* acct = 0; if ( node->type == AccountModelNode::ManualResolverType ) @@ -270,7 +276,6 @@ AccountModel::setData( const QModelIndex& index, const QVariant& value, int role } else { - connect( AtticaManager::instance(), SIGNAL( resolverInstalled( QString ) ), this, SLOT( atticaInstalled( QString ) ) ); m_waitingForAtticaInstall.insert( resolver.id() ); AtticaManager::instance()->installResolver( resolver ); @@ -461,7 +466,54 @@ AccountModel::accountRemoved( Account* account ) void AccountModel::atticaInstalled( const QString& atticaId ) { + if ( !m_waitingForAtticaInstall.contains( atticaId ) ) + return; + m_waitingForAtticaInstall.remove( atticaId ); + + // find associated Account*, set on to the saved resolver, and update state + AccountModelNode* node = 0; + AtticaResolverAccount* acct = 0; + + foreach ( AccountModelNode* n, m_accounts ) + { + if ( n->type == AccountModelNode::AtticaType && + n->atticaContent.id() == atticaId ) + { + node = n; + break; + } + } + + if ( !node ) + { + Q_ASSERT( false ); + return; // Couldn't find it?? + } + + foreach ( Account* acc, AccountManager::instance()->accounts( ResolverType ) ) + { + if ( AtticaResolverAccount* ra = qobject_cast< AtticaResolverAccount* >( acc ) ) + { + if ( ra->atticaId() == atticaId ) + { + acct = ra; + break; + } + } + } + + if ( !acct ) + { + qWarning() << "Got installed attica resolver but couldnt' find a resolver account for it??"; + return; + } + + AccountManager::instance()->enableAccount( acct ); + + node->atticaAccount = acct; + const QModelIndex idx = index( m_accounts.indexOf( node ), 0, QModelIndex() ); + emit dataChanged( idx, idx ); } diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index d015aabd7..1e089eac4 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -53,6 +53,7 @@ #include "accounts/Account.h" #include "accounts/AccountManager.h" #include "utils/logger.h" +#include "AccountFactoryWrapper.h" #include "ui_proxydialog.h" #include "ui_stackedsettingsdialog.h" @@ -105,8 +106,10 @@ SettingsDialog::SettingsDialog( QWidget *parent ) ui->accountsView->setItemDelegate( accountDelegate ); ui->accountsView->setContextMenuPolicy( Qt::CustomContextMenu ); ui->accountsView->setVerticalScrollMode( QAbstractItemView::ScrollPerPixel ); + ui->accountsView->setMouseTracking( true ); connect( accountDelegate, SIGNAL( openConfig( Tomahawk::Accounts::Account* ) ), this, SLOT( openAccountConfig( Tomahawk::Accounts::Account* ) ) ); + connect( accountDelegate, SIGNAL( openConfig( Tomahawk::Accounts::AccountFactory* ) ), this, SLOT( openAccountFactoryConfig( Tomahawk::Accounts::AccountFactory* ) ) ); connect( accountDelegate, SIGNAL( update( QModelIndex ) ), ui->accountsView, SLOT( update( QModelIndex ) ) ); connect( ui->accountsView, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( accountContextMenuRequest( QPoint ) ) ); @@ -425,20 +428,6 @@ SettingsDialog::onLastFmFinished() } -void -SettingsDialog::accountInstalled(Account* account) -{ -// m_resolversModel->atticaResolverInstalled( resolverId ); -} - - -void -SettingsDialog::accountUninstalled(const QString& acct) -{ -// m_resolversModel->removeResolver( AtticaManager::instance()->pathFromId( resolverId ) ); -} - - void SettingsDialog::accountsSelectionChanged() { @@ -454,15 +443,20 @@ SettingsDialog::accountsSelectionChanged() void -SettingsDialog::openAccountConfig( Account* account ) +SettingsDialog::openAccountConfig( Account* account, bool showDelete ) { if( account->configurationWidget() ) { #ifndef Q_WS_MAC DelegateConfigWrapper dialog( account->configurationWidget(), QString("%1 Configuration" ).arg( account->accountFriendlyName() ), this ); + dialog.setShowDelete( showDelete ); QWeakPointer< DelegateConfigWrapper > watcher( &dialog ); int ret = dialog.exec(); - if( !watcher.isNull() && ret == QDialog::Accepted ) + if ( !watcher.isNull() && dialog.deleted() ) + { + AccountManager::instance()->removeAccount( account ); + } + else if( !watcher.isNull() && ret == QDialog::Accepted ) { // send changed config to resolver account->saveConfig(); @@ -470,8 +464,10 @@ SettingsDialog::openAccountConfig( Account* account ) #else // on osx a sheet needs to be non-modal DelegateConfigWrapper* dialog = new DelegateConfigWrapper( account->configurationWidget(), QString("%1 Configuration" ).arg( account->accountFriendlyName() ), this, Qt::Sheet ); + dialog->setShowDelete( showDelete ); dialog->setProperty( "accountplugin", QVariant::fromValue< QObject* >( account ) ); connect( dialog, SIGNAL( finished( int ) ), this, SLOT( accountConfigClosed( int ) ) ); + connect( dialog, SIGNAL( closedWithDelete() ), this, SLOT( accountConfigDelete() ) ); dialog->show(); #endif @@ -491,6 +487,54 @@ SettingsDialog::accountConfigClosed( int value ) } +void +SettingsDialog::accountConfigDelete() +{ + DelegateConfigWrapper* dialog = qobject_cast< DelegateConfigWrapper* >( sender() ); + Account* account = qobject_cast< Account* >( dialog->property( "accountplugin" ).value< QObject* >() ); + Q_ASSERT( account ); + AccountManager::instance()->removeAccount( account ); + + sender()->deleteLater(); +} + + +void +SettingsDialog::openAccountFactoryConfig( AccountFactory* factory ) +{ + QList< Account* > accts; + foreach ( Account* acct, AccountManager::instance()->accounts() ) + { + if ( AccountManager::instance()->factoryForAccount( acct ) == factory ) + accts << acct; + if ( accts.size() > 1 ) + break; + } + Q_ASSERT( accts.size() > 0 ); // Shouldn't have a config wrench if there are no accounts! + if ( accts.size() == 1 ) + { + // If there's just one, open the config directly w/ the delete button. Otherwise open the multi dialog + openAccountConfig( accts.first() ); + return; + } + +#ifndef Q_WS_MAC + AccountFactoryWrapper dialog( factory, this ); + QWeakPointer< AccountFactoryWrapper > watcher( &dialog ); + + int ret = dialog.exec(); + if ( !watcher.isNull() && dialog.doCreateAccount() ) + createAccountFromFactory( factory ); +#else + // on osx a sheet needs to be non-modal + AccountFactoryWrapper* dialog = new AccountFactoryWrapper( factory, this ); + connect( dialog, SIGNAL( createAccount( Tomahawk::Accounts::AccountFactory ) ), this, SLOT( createAccountFromFactory( Tomahawk::Accounts::AccountFactory* ) ) ); + + dialog->show(); +#endif +} + + void SettingsDialog::createAccountFromFactory( AccountFactory* factory ) { @@ -568,47 +612,6 @@ SettingsDialog::handleAccountAdded( Account* account, bool added ) } -void -SettingsDialog::accountContextMenuRequest( const QPoint& p ) -{ - QModelIndex idx = ui->accountsView->indexAt( p ); - // if it's an account, allow to delete - if( idx.isValid() ) - { -// QList< QAction* > acts; -// acts << new QAction( tr( "Delete Service" ), this ); -// acts.first()->setProperty( "accountplugin", idx.data( AccountModel::AccountData ) ); -// connect( acts.first(), SIGNAL( triggered( bool ) ), this, SLOT( onAccountRowDeleted( bool ) ) ); -// QMenu::exec( acts, ui->accountsView->mapToGlobal( p ) ); - } -} - - -void -SettingsDialog::onAccountRowDeleted( bool ) -{ - Account* account = qobject_cast< Account* >( qobject_cast< QAction* >( sender() )->property( "accountplugin" ).value< QObject* >() ); - - AccountManager::instance()->removeAccount( account ); -} - - -void -SettingsDialog::accountDeleted( bool ) -{ - QModelIndexList indexes = ui->accountsView->selectionModel()->selectedIndexes(); - // if it's an account, allow to delete - foreach( const QModelIndex& idx, indexes ) - { - if( idx.isValid() ) - { -// Account* account = qobject_cast< Account* >( idx.data( AccountModel::AccountData ).value< QObject* >() ); -// AccountManager::instance()->removeAccount( account ); - } - } -} - - void SettingsDialog::requiresRestart() { diff --git a/src/settingsdialog.h b/src/settingsdialog.h index 5f8300171..6be871778 100644 --- a/src/settingsdialog.h +++ b/src/settingsdialog.h @@ -88,18 +88,14 @@ private slots: void testLastFmLogin(); void onLastFmFinished(); - void openAccountConfig( Tomahawk::Accounts::Account* ); void createAccountFromFactory( Tomahawk::Accounts::AccountFactory* ); - void accountContextMenuRequest( const QPoint& ); - void accountDeleted( bool ); - void onAccountRowDeleted( bool ); void accountsSelectionChanged(); - void accountInstalled( Tomahawk::Accounts::Account* account ); - void accountUninstalled( const QString& acct ); - + void openAccountConfig( Tomahawk::Accounts::Account*, bool showDelete = false ); + void openAccountFactoryConfig( Tomahawk::Accounts::AccountFactory* ); void accountConfigClosed( int value ); + void accountConfigDelete(); void accountCreateConfigClosed( int value ); void updateScanOptionsView(); From 23d14bd4764c0e4ff55e7c96dcb40cc64153a8aa Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 10 Feb 2012 17:22:59 -0500 Subject: [PATCH 058/104] bit of osx tweaks --- src/AccountFactoryWrapper.cpp | 11 ++++++++--- src/settingsdialog.cpp | 3 --- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/AccountFactoryWrapper.cpp b/src/AccountFactoryWrapper.cpp index 86e824512..ce0b3de55 100644 --- a/src/AccountFactoryWrapper.cpp +++ b/src/AccountFactoryWrapper.cpp @@ -48,10 +48,10 @@ AccountFactoryWrapper::AccountFactoryWrapper( AccountFactory* factory, QWidget* load(); - connect( m_ui->buttonBox, SIGNAL( rejected() ), this, SLOT( reject() ) ); connect( m_ui->buttonBox, SIGNAL( accepted() ), this, SLOT( accept() ) ); - connect( m_ui->buttonBox, SIGNAL( clicked( QAbstractButton*) ), this, SLOT( buttonClicked() ) ); + connect( m_ui->buttonBox, SIGNAL( clicked( QAbstractButton*) ), this, SLOT( buttonClicked( QAbstractButton* ) ) ); + #ifdef Q_OS_MAC setContentsMargins( 0, 0, 0, 0 ); m_ui->verticalLayout->setSpacing( 4 ); @@ -70,8 +70,13 @@ AccountFactoryWrapper::load() item->setData( 0, AccountRole, QVariant::fromValue< QObject *>( acc ) ); } } +#ifndef Q_OS_MAC + const int padding = 7; +#else + const int padding = 8; +#endif + const int height = m_ui->accountsList->model()->rowCount( QModelIndex() ) * ACCOUNT_ROW_HEIGHT + padding; - const int height = m_ui->accountsList->model()->rowCount( QModelIndex() ) * ACCOUNT_ROW_HEIGHT + 7; m_ui->accountsList->setFixedHeight( height ); } diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index 1e089eac4..545e4ca00 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -119,9 +119,6 @@ SettingsDialog::SettingsDialog( QWidget *parent ) connect( m_accountModel, SIGNAL( createAccount( Tomahawk::Accounts::AccountFactory* ) ), this, SLOT( createAccountFromFactory( Tomahawk::Accounts::AccountFactory* ) ) ); - connect( AtticaManager::instance(), SIGNAL( resolverInstalled( QString ) ), this, SLOT( accountAdded( Tomahawk::Accounts::Account* ) ) ); - connect( AtticaManager::instance(), SIGNAL( resolverUninstalled( QString ) ), this, SLOT( accountUninstalled( QString ) ) ); - connect( ui->accountsView->selectionModel(), SIGNAL( selectionChanged( QItemSelection,QItemSelection ) ), this, SLOT( accountsSelectionChanged() ) ); if ( !Servent::instance()->isReady() ) From 9ab47d769bc240977f544ab7a61fb00b39a0aadf Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 10 Feb 2012 18:31:46 -0500 Subject: [PATCH 059/104] Some fixes to the dialogs --- src/AccountDelegate.cpp | 4 +++- src/AccountFactoryWrapper.cpp | 10 +++++++++- src/AccountFactoryWrapper.h | 3 +-- src/AccountFactoryWrapper.ui | 2 +- src/delegateconfigwrapper.h | 1 + src/settingsdialog.cpp | 6 +++--- 6 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/AccountDelegate.cpp b/src/AccountDelegate.cpp index 71e76c786..c2074a4b1 100644 --- a/src/AccountDelegate.cpp +++ b/src/AccountDelegate.cpp @@ -156,6 +156,7 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, // Draw config wrench if there is one const bool hasConfigWrench = index.data( AccountModel::HasConfig ).toBool(); int rightEdge = opt.rect.right(); + m_cachedConfigRects[ index ] = QRect(); if ( hasConfigWrench ) { const QRect confRect = QRect( rightEdge - 2*PADDING - WRENCH_SIZE, center - WRENCH_SIZE / 2, WRENCH_SIZE, WRENCH_SIZE ); @@ -170,6 +171,7 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, } // Draw individual accounts and add account button for factories + m_cachedButtonRects[ index ] = QRect(); if ( rowType == Tomahawk::Accounts::AccountModel::TopLevelFactory ) { const QList< Account* > accts = index.data( AccountModel::ChildrenOfFactoryRole ).value< QList< Tomahawk::Accounts::Account* > >(); @@ -183,7 +185,7 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, Q_ASSERT( !hasConfigWrench ); // Draw button in center of row - btnRect= QRect( opt.rect.right() - PADDING - btnWidth, center - ( installMetrics.height() + 4 ) / 2, btnWidth, installMetrics.height() + 4 ); + btnRect= QRect( opt.rect.right() - PADDING - btnWidth, center - ( installMetrics.height() + 4 ) / 2, btnWidth, installMetrics.height() + 2*PADDING ); rightEdge = btnRect.left(); } else diff --git a/src/AccountFactoryWrapper.cpp b/src/AccountFactoryWrapper.cpp index ce0b3de55..2704d3830 100644 --- a/src/AccountFactoryWrapper.cpp +++ b/src/AccountFactoryWrapper.cpp @@ -52,6 +52,10 @@ AccountFactoryWrapper::AccountFactoryWrapper( AccountFactory* factory, QWidget* connect( m_ui->buttonBox, SIGNAL( accepted() ), this, SLOT( accept() ) ); connect( m_ui->buttonBox, SIGNAL( clicked( QAbstractButton*) ), this, SLOT( buttonClicked( QAbstractButton* ) ) ); + + connect ( AccountManager::instance(), SIGNAL( added( Tomahawk::Accounts::Account* ) ), this, SLOT( load() ) ); + connect ( AccountManager::instance(), SIGNAL( removed( Tomahawk::Accounts::Account* ) ), this, SLOT( load() ) ); + #ifdef Q_OS_MAC setContentsMargins( 0, 0, 0, 0 ); m_ui->verticalLayout->setSpacing( 4 ); @@ -70,6 +74,10 @@ AccountFactoryWrapper::load() item->setData( 0, AccountRole, QVariant::fromValue< QObject *>( acc ) ); } } + + if ( m_ui->accountsList->model()->rowCount() == 0 ) + accept(); + #ifndef Q_OS_MAC const int padding = 7; #else @@ -133,7 +141,7 @@ AccountFactoryWrapper::buttonClicked( QAbstractButton* button ) { m_createAccount = true; emit createAccount( m_factory ); - accept(); +// accept(); return; } else diff --git a/src/AccountFactoryWrapper.h b/src/AccountFactoryWrapper.h index 62fa9a23d..02c8ec335 100644 --- a/src/AccountFactoryWrapper.h +++ b/src/AccountFactoryWrapper.h @@ -54,10 +54,9 @@ public slots: private slots: void buttonClicked( QAbstractButton* ); - -private: void load(); +private: Tomahawk::Accounts::AccountFactory* m_factory; Ui_AccountFactoryWrapper* m_ui; QPushButton* m_addButton; diff --git a/src/AccountFactoryWrapper.ui b/src/AccountFactoryWrapper.ui index 9a119015e..b7ba54df3 100644 --- a/src/AccountFactoryWrapper.ui +++ b/src/AccountFactoryWrapper.ui @@ -7,7 +7,7 @@ 0 0 507 - 298 + 150 diff --git a/src/delegateconfigwrapper.h b/src/delegateconfigwrapper.h index 4ff15313b..5bd4faad6 100644 --- a/src/delegateconfigwrapper.h +++ b/src/delegateconfigwrapper.h @@ -90,6 +90,7 @@ public slots: { m_deleted = true; emit deleted(); + reject(); } else done( QDialog::Rejected ); diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index 545e4ca00..e3f73d2b3 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -511,11 +511,11 @@ SettingsDialog::openAccountFactoryConfig( AccountFactory* factory ) if ( accts.size() == 1 ) { // If there's just one, open the config directly w/ the delete button. Otherwise open the multi dialog - openAccountConfig( accts.first() ); + openAccountConfig( accts.first(), true ); return; } -#ifndef Q_WS_MAC +#ifndef Q_OS_MAC AccountFactoryWrapper dialog( factory, this ); QWeakPointer< AccountFactoryWrapper > watcher( &dialog ); @@ -525,7 +525,7 @@ SettingsDialog::openAccountFactoryConfig( AccountFactory* factory ) #else // on osx a sheet needs to be non-modal AccountFactoryWrapper* dialog = new AccountFactoryWrapper( factory, this ); - connect( dialog, SIGNAL( createAccount( Tomahawk::Accounts::AccountFactory ) ), this, SLOT( createAccountFromFactory( Tomahawk::Accounts::AccountFactory* ) ) ); + connect( dialog, SIGNAL( createAccount( Tomahawk::Accounts::AccountFactory* ) ), this, SLOT( createAccountFromFactory( Tomahawk::Accounts::AccountFactory* ) ) ); dialog->show(); #endif From 7bae6c6b8afead51c29e6891632ebd1deb19dfac Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 10 Feb 2012 18:45:28 -0500 Subject: [PATCH 060/104] fix deleting --- src/delegateconfigwrapper.h | 2 +- src/settingsdialog.cpp | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/delegateconfigwrapper.h b/src/delegateconfigwrapper.h index 5bd4faad6..4a2d4bfd1 100644 --- a/src/delegateconfigwrapper.h +++ b/src/delegateconfigwrapper.h @@ -89,7 +89,7 @@ public slots: else if ( b == m_deleteButton ) { m_deleted = true; - emit deleted(); + emit closedWithDelete(); reject(); } else diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index e3f73d2b3..388977d18 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -444,7 +444,7 @@ SettingsDialog::openAccountConfig( Account* account, bool showDelete ) { if( account->configurationWidget() ) { -#ifndef Q_WS_MAC +#if 0 DelegateConfigWrapper dialog( account->configurationWidget(), QString("%1 Configuration" ).arg( account->accountFriendlyName() ), this ); dialog.setShowDelete( showDelete ); QWeakPointer< DelegateConfigWrapper > watcher( &dialog ); @@ -491,8 +491,6 @@ SettingsDialog::accountConfigDelete() Account* account = qobject_cast< Account* >( dialog->property( "accountplugin" ).value< QObject* >() ); Q_ASSERT( account ); AccountManager::instance()->removeAccount( account ); - - sender()->deleteLater(); } From eea70f104fa859e1cc524ccb84ded7660c69f4f9 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 10 Feb 2012 18:47:30 -0500 Subject: [PATCH 061/104] dialogs-- --- src/stackedsettingsdialog.ui | 42 +----------------------------------- 1 file changed, 1 insertion(+), 41 deletions(-) diff --git a/src/stackedsettingsdialog.ui b/src/stackedsettingsdialog.ui index c04c387ef..a32f74f67 100644 --- a/src/stackedsettingsdialog.ui +++ b/src/stackedsettingsdialog.ui @@ -102,51 +102,11 @@ 2 - - - - - Show music sources - - - - - - - Show friend sources - - - - - - - Show update services - - - - + - - - - - - Add new service... - - - - - - - Remove Service - - - - - From 41b146f38a0c83878fc782c37791c05a2474f49d Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 10 Feb 2012 18:50:51 -0500 Subject: [PATCH 062/104] small cleanup --- src/AccountFactoryWrapper.cpp | 2 +- src/settingsdialog.cpp | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/AccountFactoryWrapper.cpp b/src/AccountFactoryWrapper.cpp index 2704d3830..0bf60f634 100644 --- a/src/AccountFactoryWrapper.cpp +++ b/src/AccountFactoryWrapper.cpp @@ -58,7 +58,7 @@ AccountFactoryWrapper::AccountFactoryWrapper( AccountFactory* factory, QWidget* #ifdef Q_OS_MAC setContentsMargins( 0, 0, 0, 0 ); - m_ui->verticalLayout->setSpacing( 4 ); + m_ui->verticalLayout->setSpacing( 6 ); #endif } diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index e3f73d2b3..2f7e5ec10 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -112,7 +112,6 @@ SettingsDialog::SettingsDialog( QWidget *parent ) connect( accountDelegate, SIGNAL( openConfig( Tomahawk::Accounts::AccountFactory* ) ), this, SLOT( openAccountFactoryConfig( Tomahawk::Accounts::AccountFactory* ) ) ); connect( accountDelegate, SIGNAL( update( QModelIndex ) ), ui->accountsView, SLOT( update( QModelIndex ) ) ); - connect( ui->accountsView, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( accountContextMenuRequest( QPoint ) ) ); m_accountModel = new AccountModel( this ); ui->accountsView->setModel( m_accountModel ); From 369c8ecd9855ad71c278e7f6b4eab9ab0f6a99fb Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 10 Feb 2012 19:08:01 -0500 Subject: [PATCH 063/104] ui cleanup --- src/settingsdialog.cpp | 20 -------------------- src/settingsdialog.h | 2 -- src/stackedsettingsdialog.ui | 35 +++++++++++++++++++++++++++-------- 3 files changed, 27 insertions(+), 30 deletions(-) diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index 29162aeec..29a0471d1 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -118,15 +118,11 @@ SettingsDialog::SettingsDialog( QWidget *parent ) connect( m_accountModel, SIGNAL( createAccount( Tomahawk::Accounts::AccountFactory* ) ), this, SLOT( createAccountFromFactory( Tomahawk::Accounts::AccountFactory* ) ) ); - connect( ui->accountsView->selectionModel(), SIGNAL( selectionChanged( QItemSelection,QItemSelection ) ), this, SLOT( accountsSelectionChanged() ) ); - if ( !Servent::instance()->isReady() ) { m_sipSpinner = new LoadingSpinner( ui->accountsView ); m_sipSpinner->fadeIn(); - ui->addNewServiceBtn->setEnabled( false ); - ui->removeServiceBtn->setEnabled( false ); connect( Servent::instance(), SIGNAL( ready() ), this, SLOT( serventReady() ) ); } ui->staticHostName->setText( s->externalHostname() ); @@ -225,8 +221,6 @@ void SettingsDialog::serventReady() { m_sipSpinner->fadeOut(); - ui->addNewServiceBtn->setEnabled( true ); - ui->removeServiceBtn->setEnabled( true ); } @@ -424,20 +418,6 @@ SettingsDialog::onLastFmFinished() } -void -SettingsDialog::accountsSelectionChanged() -{ - if( !ui->accountsView->selectionModel()->selectedIndexes().isEmpty() ) - { - ui->removeServiceBtn->setEnabled( true ); - } - else - { - ui->addNewServiceBtn->setEnabled( false ); - } -} - - void SettingsDialog::openAccountConfig( Account* account, bool showDelete ) { diff --git a/src/settingsdialog.h b/src/settingsdialog.h index 6be871778..363dc3a2f 100644 --- a/src/settingsdialog.h +++ b/src/settingsdialog.h @@ -90,8 +90,6 @@ private slots: void createAccountFromFactory( Tomahawk::Accounts::AccountFactory* ); - void accountsSelectionChanged(); - void openAccountConfig( Tomahawk::Accounts::Account*, bool showDelete = false ); void openAccountFactoryConfig( Tomahawk::Accounts::AccountFactory* ); void accountConfigClosed( int value ); diff --git a/src/stackedsettingsdialog.ui b/src/stackedsettingsdialog.ui index a32f74f67..584a89ace 100644 --- a/src/stackedsettingsdialog.ui +++ b/src/stackedsettingsdialog.ui @@ -97,12 +97,33 @@ Internet Sources - - - 2 - + - + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Filter by capability: + + + + + + + @@ -519,9 +540,7 @@
widgets/checkdirtree.h
- - - + buttonBox From 132460b797ade46f20f20fce5a610858d7fb7896 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 10 Feb 2012 19:38:36 -0500 Subject: [PATCH 064/104] Non-working save --- src/accounts/twitter/twitteraccount.h | 1 + src/accounts/xmpp/xmppaccount.h | 1 + src/accounts/zeroconf/zeroconfaccount.h | 1 + src/libtomahawk/accounts/Account.cpp | 15 +++++++ src/libtomahawk/accounts/Account.h | 5 +++ .../accounts/AccountModelFilterProxy.cpp | 44 +++++++++++++++++++ .../accounts/AccountModelFilterProxy.h | 41 +++++++++++++++++ src/libtomahawk/accounts/ResolverAccount.h | 1 + src/settingsdialog.cpp | 11 ++++- src/settingsdialog.h | 2 + src/stackedsettingsdialog.ui | 2 +- 11 files changed, 122 insertions(+), 2 deletions(-) create mode 100644 src/libtomahawk/accounts/AccountModelFilterProxy.cpp create mode 100644 src/libtomahawk/accounts/AccountModelFilterProxy.h diff --git a/src/accounts/twitter/twitteraccount.h b/src/accounts/twitter/twitteraccount.h index d943b2591..e4c706ce2 100644 --- a/src/accounts/twitter/twitteraccount.h +++ b/src/accounts/twitter/twitteraccount.h @@ -48,6 +48,7 @@ public: QString factoryId() const { return "twitteraccount"; } QString description() const { return tr( "Connect to your Twitter followers." ); } QPixmap icon() const { return QPixmap( ":/twitter-icon.png" ); } + AccountTypes types() const { return AccountTypes( SipType ); }; Account* createAccount( const QString& pluginId = QString() ); }; diff --git a/src/accounts/xmpp/xmppaccount.h b/src/accounts/xmpp/xmppaccount.h index 77ba97904..5692c2c20 100644 --- a/src/accounts/xmpp/xmppaccount.h +++ b/src/accounts/xmpp/xmppaccount.h @@ -50,6 +50,7 @@ public: 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-icon.png" ); } + AccountTypes types() const { return AccountTypes( SipType ); }; Account* createAccount( const QString& pluginId = QString() ); }; diff --git a/src/accounts/zeroconf/zeroconfaccount.h b/src/accounts/zeroconf/zeroconfaccount.h index 726e5c5a2..29a6673fd 100644 --- a/src/accounts/zeroconf/zeroconfaccount.h +++ b/src/accounts/zeroconf/zeroconfaccount.h @@ -41,6 +41,7 @@ public: virtual QString prettyName() const { return "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; #endif diff --git a/src/libtomahawk/accounts/Account.cpp b/src/libtomahawk/accounts/Account.cpp index 9227c7f5c..73dffaded 100644 --- a/src/libtomahawk/accounts/Account.cpp +++ b/src/libtomahawk/accounts/Account.cpp @@ -25,6 +25,21 @@ namespace Tomahawk namespace Accounts { +QString +accountTypeToString( AccountType type ) +{ + switch ( type ) + { + case SipType: + return tr( "Friend Finders" ); + case ResolverType: + return tr( "Music Finders" ); + case InfoType: + return tr( "Status Updaters" ); + } +} + + Account::Account( const QString& accountId ) : QObject() , m_enabled( false ) diff --git a/src/libtomahawk/accounts/Account.h b/src/libtomahawk/accounts/Account.h index b8164d200..73448fd2b 100644 --- a/src/libtomahawk/accounts/Account.h +++ b/src/libtomahawk/accounts/Account.h @@ -53,6 +53,8 @@ enum AccountType ResolverType = 0x04 }; +DLLEXPORT QString accountTypeToString( AccountType type ); + Q_DECLARE_FLAGS(AccountTypes, AccountType); inline QString generateId( const QString &factoryId ) @@ -173,6 +175,9 @@ public: virtual QPixmap icon() const { return QPixmap(); } virtual bool allowUserCreation() const { return true; } + // What are the supported types for accounts this factory creates? + virtual AccountTypes types() const = 0; + virtual Account* createAccount( const QString& accountId = QString() ) = 0; }; diff --git a/src/libtomahawk/accounts/AccountModelFilterProxy.cpp b/src/libtomahawk/accounts/AccountModelFilterProxy.cpp new file mode 100644 index 000000000..faf14c7cb --- /dev/null +++ b/src/libtomahawk/accounts/AccountModelFilterProxy.cpp @@ -0,0 +1,44 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Leo Franchi + * + * 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 "AccountModelFilterProxy.h" + +#include "AccountModel.h" + +using namespace Tomahawk; +using namespace Accounts; + +AccountModelFilterProxy::AccountModelFilterProxy( QObject* parent ) + : QSortFilterProxyModel(parent) +{ + +} + +bool +AccountModelFilterProxy::filterAcceptsRow( int sourceRow, const QModelIndex& sourceParent ) const +{ + if ( m_filterType == NoType ) + return true; + + const QModeIndex idx = sourceParent.child( sourceRow, 0 ); + const AccountModel::RowType rowType = static_cast< AccountModel::RowType >( idx.data( AccountModel::RowTypeRole ).toInt() ); + + + +} + diff --git a/src/libtomahawk/accounts/AccountModelFilterProxy.h b/src/libtomahawk/accounts/AccountModelFilterProxy.h new file mode 100644 index 000000000..02ebb161a --- /dev/null +++ b/src/libtomahawk/accounts/AccountModelFilterProxy.h @@ -0,0 +1,41 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2012, Leo Franchi + * + * 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 ACCOUNTMODELFILTERPROXY_H +#define ACCOUNTMODELFILTERPROXY_H + +#include +#include "Account.h" + + +class AccountModelFilterProxy : public QSortFilterProxyModel +{ + Q_OBJECT +public: + AccountModelFilterProxy( QObject* parent = 0 ); + + void setFilterType( Tomahawk::Accounts::AccountType type ); + +protected: + virtual bool filterAcceptsRow ( int sourceRow, const QModelIndex& sourceParent ) const; + +private: + Tomahawk::Accounts::AccountType m_filterType; +}; + +#endif // ACCOUNTMODELFILTERPROXY_H diff --git a/src/libtomahawk/accounts/ResolverAccount.h b/src/libtomahawk/accounts/ResolverAccount.h index 9ee94bee4..f3cf4a594 100644 --- a/src/libtomahawk/accounts/ResolverAccount.h +++ b/src/libtomahawk/accounts/ResolverAccount.h @@ -38,6 +38,7 @@ public: virtual QString factoryId() const { return "resolveraccount"; } virtual QString description() const { return QString(); } virtual QString prettyName() const { return QString(); } // Internal, not displayed + AccountTypes types() const { return AccountTypes( ResolverType ); }; virtual bool allowUserCreation() const { return false; } // Used to create a new resolver from a script on disk, either chosen by diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index 29a0471d1..e48c060d5 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -101,7 +101,7 @@ SettingsDialog::SettingsDialog( QWidget *parent ) p->setFixedSize( 0, 0 ); #endif - // SIP PLUGINS + // Accounts AccountDelegate* accountDelegate = new AccountDelegate( this ); ui->accountsView->setItemDelegate( accountDelegate ); ui->accountsView->setContextMenuPolicy( Qt::CustomContextMenu ); @@ -118,6 +118,13 @@ SettingsDialog::SettingsDialog( QWidget *parent ) connect( m_accountModel, SIGNAL( createAccount( Tomahawk::Accounts::AccountFactory* ) ), this, SLOT( createAccountFromFactory( Tomahawk::Accounts::AccountFactory* ) ) ); + ui->accountsFilterCombo->addItem( tr( "All" ), Accounts::NoType ); + ui->accountsFilterCombo->addItem( accountTypeToString( SipType ), SipType ); + ui->accountsFilterCombo->addItem( accountTypeToString( ResolverType ), ResolverType ); + ui->accountsFilterCombo->addItem( accountTypeToString( InfoType ), InfoType ); + + connect( ui->accountsFilterCombo, SIGNAL( activated( int ) ), this, SLOT( accountsFilterChanged( int ) ) ); + if ( !Servent::instance()->isReady() ) { m_sipSpinner = new LoadingSpinner( ui->accountsView ); @@ -125,6 +132,8 @@ SettingsDialog::SettingsDialog( QWidget *parent ) connect( Servent::instance(), SIGNAL( ready() ), this, SLOT( serventReady() ) ); } + + // ADVANCED ui->staticHostName->setText( s->externalHostname() ); ui->staticPort->setValue( s->externalPort() ); ui->proxyButton->setVisible( true ); diff --git a/src/settingsdialog.h b/src/settingsdialog.h index 363dc3a2f..544b1ff70 100644 --- a/src/settingsdialog.h +++ b/src/settingsdialog.h @@ -88,6 +88,8 @@ private slots: void testLastFmLogin(); void onLastFmFinished(); + void accountsFilterChanged( int ); + void createAccountFromFactory( Tomahawk::Accounts::AccountFactory* ); void openAccountConfig( Tomahawk::Accounts::Account*, bool showDelete = false ); diff --git a/src/stackedsettingsdialog.ui b/src/stackedsettingsdialog.ui index 584a89ace..69664c495 100644 --- a/src/stackedsettingsdialog.ui +++ b/src/stackedsettingsdialog.ui @@ -121,7 +121,7 @@
- +
From 40041f5c1ef6c28d199df0f470a82ac74df80a83 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sat, 11 Feb 2012 12:16:56 -0500 Subject: [PATCH 065/104] Finish adding filter imlpementation --- src/libtomahawk/CMakeLists.txt | 2 ++ src/libtomahawk/accounts/Account.cpp | 8 +++++--- src/libtomahawk/accounts/Account.h | 2 +- src/libtomahawk/accounts/AccountModel.cpp | 8 ++++++++ src/libtomahawk/accounts/AccountModel.h | 1 + .../accounts/AccountModelFilterProxy.cpp | 18 +++++++++++++++--- .../accounts/AccountModelFilterProxy.h | 11 +++++++++-- src/main.cpp | 9 --------- src/settingsdialog.cpp | 15 +++++++++++++-- src/settingsdialog.h | 2 ++ 10 files changed, 56 insertions(+), 20 deletions(-) diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index b8f88affb..9af7daf0c 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -306,6 +306,7 @@ set( libSources accounts/AccountManager.cpp accounts/Account.cpp accounts/AccountModel.cpp + accounts/AccountModelFilterProxy.cpp accounts/ResolverAccount.cpp sip/SipPlugin.cpp @@ -447,6 +448,7 @@ set( libHeaders accounts/Account.h accounts/AccountManager.h accounts/AccountModel.h + accounts/AccountModelFilterProxy.h accounts/ResolverAccount.h EchonestCatalogSynchronizer.h diff --git a/src/libtomahawk/accounts/Account.cpp b/src/libtomahawk/accounts/Account.cpp index 73dffaded..36a22ebef 100644 --- a/src/libtomahawk/accounts/Account.cpp +++ b/src/libtomahawk/accounts/Account.cpp @@ -31,12 +31,14 @@ accountTypeToString( AccountType type ) switch ( type ) { case SipType: - return tr( "Friend Finders" ); + return QObject::tr( "Friend Finders" ); case ResolverType: - return tr( "Music Finders" ); + return QObject::tr( "Music Finders" ); case InfoType: - return tr( "Status Updaters" ); + return QObject::tr( "Status Updaters" ); } + + return QString(); } diff --git a/src/libtomahawk/accounts/Account.h b/src/libtomahawk/accounts/Account.h index 73448fd2b..addc02184 100644 --- a/src/libtomahawk/accounts/Account.h +++ b/src/libtomahawk/accounts/Account.h @@ -188,5 +188,5 @@ public: Q_DECLARE_INTERFACE( Tomahawk::Accounts::AccountFactory, "tomahawk.AccountFactory/1.0" ) Q_DECLARE_METATYPE( QList< Tomahawk::Accounts::Account* > ) - +Q_DECLARE_METATYPE( Tomahawk::Accounts::AccountTypes ) #endif diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index 44a16919b..98113352d 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -115,6 +115,8 @@ AccountModel::data( const QModelIndex& index, int role ) const return QVariant::fromValue< QList< Tomahawk::Accounts::Account* > >( node->accounts ); case HasConfig: return !node->accounts.isEmpty(); + case AccountTypeRole: + return QVariant::fromValue< AccountTypes >( node->factory->types() ); default: return QVariant(); } @@ -144,6 +146,8 @@ AccountModel::data( const QModelIndex& index, int role ) const return c.downloads(); case CanRateRole: return true; + case AccountTypeRole: + return QVariant::fromValue< AccountTypes >( AccountTypes( ResolverType ) ); case VersionRole: return c.version(); case UserHasRatedRole: @@ -207,6 +211,8 @@ AccountModel::data( const QModelIndex& index, int role ) const return Uninstalled; case CanRateRole: return false; + case AccountTypeRole: + return QVariant::fromValue< AccountTypes >( node->factory->types() ); default: return QVariant(); } @@ -233,6 +239,8 @@ AccountModel::data( const QModelIndex& index, int role ) const return Installed; case ChildrenOfFactoryRole: return QVariant::fromValue< QList< Tomahawk::Accounts::Account* > >( node->accounts ); + case AccountTypeRole: + return QVariant::fromValue< AccountTypes >( acct->types() ); default: return QVariant(); } diff --git a/src/libtomahawk/accounts/AccountModel.h b/src/libtomahawk/accounts/AccountModel.h index eaa676172..a1c6a2e31 100644 --- a/src/libtomahawk/accounts/AccountModel.h +++ b/src/libtomahawk/accounts/AccountModel.h @@ -57,6 +57,7 @@ public: // used by individual accounts AccountData = Qt::UserRole + 28, // raw plugin CanRateRole = Qt::UserRole + 32, + AccountTypeRole = Qt::UserRole + 33, CheckboxClickedRole = Qt::UserRole + 29, // the checkbox for this row was toggled AddAccountButtonRole = Qt::UserRole + 30, // the add account button diff --git a/src/libtomahawk/accounts/AccountModelFilterProxy.cpp b/src/libtomahawk/accounts/AccountModelFilterProxy.cpp index faf14c7cb..ff3de4063 100644 --- a/src/libtomahawk/accounts/AccountModelFilterProxy.cpp +++ b/src/libtomahawk/accounts/AccountModelFilterProxy.cpp @@ -20,11 +20,13 @@ #include "AccountModel.h" + using namespace Tomahawk; using namespace Accounts; AccountModelFilterProxy::AccountModelFilterProxy( QObject* parent ) : QSortFilterProxyModel(parent) + , m_filterType( NoType ) { } @@ -35,10 +37,20 @@ AccountModelFilterProxy::filterAcceptsRow( int sourceRow, const QModelIndex& sou if ( m_filterType == NoType ) return true; - const QModeIndex idx = sourceParent.child( sourceRow, 0 ); - const AccountModel::RowType rowType = static_cast< AccountModel::RowType >( idx.data( AccountModel::RowTypeRole ).toInt() ); - + const QModelIndex idx = sourceModel()->index( sourceRow, 0, sourceParent ); + const AccountTypes types = static_cast< AccountTypes >( idx.data( AccountModel::AccountTypeRole ).value< AccountTypes >() ); + return types.testFlag( m_filterType ); } + +void +AccountModelFilterProxy::setFilterType( AccountType type ) +{ + if ( type == m_filterType ) + return; + + m_filterType = type; + invalidate(); +} diff --git a/src/libtomahawk/accounts/AccountModelFilterProxy.h b/src/libtomahawk/accounts/AccountModelFilterProxy.h index 02ebb161a..f22f8f4e9 100644 --- a/src/libtomahawk/accounts/AccountModelFilterProxy.h +++ b/src/libtomahawk/accounts/AccountModelFilterProxy.h @@ -19,11 +19,15 @@ #ifndef ACCOUNTMODELFILTERPROXY_H #define ACCOUNTMODELFILTERPROXY_H -#include #include "Account.h" +#include "dllmacro.h" +#include -class AccountModelFilterProxy : public QSortFilterProxyModel +namespace Tomahawk { +namespace Accounts { + +class DLLEXPORT AccountModelFilterProxy : public QSortFilterProxyModel { Q_OBJECT public: @@ -38,4 +42,7 @@ private: Tomahawk::Accounts::AccountType m_filterType; }; +} + +} #endif // ACCOUNTMODELFILTERPROXY_H diff --git a/src/main.cpp b/src/main.cpp index f326cca78..10591e684 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -81,15 +81,6 @@ main( int argc, char *argv[] ) AEInstallEventHandler( 'GURL', 'GURL', h, 0, false ); #endif -/* // Unity hack taken from Clementine's main.cpp -#ifdef Q_OS_LINUX - // In 11.04 Ubuntu decided that the system tray should be reserved for certain - // whitelisted applications. Tomahawk will override this setting and insert - // itself into the list of whitelisted apps. - setenv( "QT_X11_NO_NATIVE_MENUBAR", "1", true ); - UbuntuUnityHack hack; -#endif*/ - TomahawkApp a( argc, argv ); // MUST register StateHash ****before*** initing TomahawkSettingsGui as constructor of settings does upgrade before Gui subclass registers type diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index e48c060d5..10a04fdf6 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -52,6 +52,7 @@ #include "accounts/AccountModel.h" #include "accounts/Account.h" #include "accounts/AccountManager.h" +#include #include "utils/logger.h" #include "AccountFactoryWrapper.h" @@ -113,8 +114,10 @@ SettingsDialog::SettingsDialog( QWidget *parent ) connect( accountDelegate, SIGNAL( update( QModelIndex ) ), ui->accountsView, SLOT( update( QModelIndex ) ) ); m_accountModel = new AccountModel( this ); + m_accountProxy = new AccountModelFilterProxy( m_accountModel ); + m_accountProxy->setSourceModel( m_accountModel ); - ui->accountsView->setModel( m_accountModel ); + ui->accountsView->setModel( m_accountProxy ); connect( m_accountModel, SIGNAL( createAccount( Tomahawk::Accounts::AccountFactory* ) ), this, SLOT( createAccountFromFactory( Tomahawk::Accounts::AccountFactory* ) ) ); @@ -427,12 +430,20 @@ SettingsDialog::onLastFmFinished() } +void +SettingsDialog::accountsFilterChanged( int ) +{ + AccountType filter = static_cast< AccountType >( ui->accountsFilterCombo->itemData( ui->accountsFilterCombo->currentIndex() ).toInt() ); + m_accountProxy->setFilterType( filter ); +} + + void SettingsDialog::openAccountConfig( Account* account, bool showDelete ) { if( account->configurationWidget() ) { -#if 0 +#ifndef Q_OS_MAC DelegateConfigWrapper dialog( account->configurationWidget(), QString("%1 Configuration" ).arg( account->accountFriendlyName() ), this ); dialog.setShowDelete( showDelete ); QWeakPointer< DelegateConfigWrapper > watcher( &dialog ); diff --git a/src/settingsdialog.h b/src/settingsdialog.h index 544b1ff70..2c642e6e2 100644 --- a/src/settingsdialog.h +++ b/src/settingsdialog.h @@ -46,6 +46,7 @@ namespace Tomahawk class Account; class AccountFactory; class Account; +class AccountModelFilterProxy; } } @@ -114,6 +115,7 @@ private: ProxyDialog m_proxySettings; bool m_rejected; Tomahawk::Accounts::AccountModel* m_accountModel; + Tomahawk::Accounts::AccountModelFilterProxy* m_accountProxy; LoadingSpinner* m_sipSpinner; }; From 751af7862ca38f8e98fcbfa046b19d66dbc1a67a Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sat, 11 Feb 2012 12:24:09 -0500 Subject: [PATCH 066/104] fix merge --- src/accounts/xmpp/sip/xmppsip.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/accounts/xmpp/sip/xmppsip.cpp b/src/accounts/xmpp/sip/xmppsip.cpp index 0644a5ebf..d89111ccb 100644 --- a/src/accounts/xmpp/sip/xmppsip.cpp +++ b/src/accounts/xmpp/sip/xmppsip.cpp @@ -348,7 +348,7 @@ XmppSipPlugin::errorMessage( Jreen::Client::DisconnectReason reason ) void -JabberPlugin::sendMsg( const QString& to, const QString& msg ) +XmppSipPlugin::sendMsg( const QString& to, const QString& msg ) { qDebug() << Q_FUNC_INFO << to << msg; @@ -373,7 +373,7 @@ JabberPlugin::sendMsg( const QString& to, const QString& msg ) TomahawkXmppMessage *sipMessage; if(m["visible"].toBool()) { - sipMessage = new TomahawkSipMessage( m["ip"].toString(), + sipMessage = new TomahawkXmppMessage( m["ip"].toString(), m["port"].toInt(), m["uniqname"].toString(), m["key"].toString() @@ -394,7 +394,7 @@ JabberPlugin::sendMsg( const QString& to, const QString& msg ) void -JabberPlugin::broadcastMsg( const QString& msg ) +XmppSipPlugin::broadcastMsg( const QString& msg ) { qDebug() << Q_FUNC_INFO; @@ -409,7 +409,7 @@ JabberPlugin::broadcastMsg( const QString& msg ) void -JabberPlugin::addContact( const QString& jid, const QString& msg ) +XmppSipPlugin::addContact( const QString& jid, const QString& msg ) { // Add contact to the Tomahawk group on the roster @@ -573,7 +573,7 @@ void XmppSipPlugin::removeMenuHelper() } -void JabberPlugin::onNewMessage( const Jreen::Message& message ) +void XmppSipPlugin::onNewMessage( const Jreen::Message& message ) { if ( m_state != Account::Connected ) return; @@ -658,7 +658,7 @@ void XmppSipPlugin::onPresenceReceived( const Jreen::RosterItem::Ptr &item, cons } -void JabberPlugin::onSubscriptionReceived( const Jreen::RosterItem::Ptr& item, const Jreen::Presence& presence ) +void XmppSipPlugin::onSubscriptionReceived( const Jreen::RosterItem::Ptr& item, const Jreen::Presence& presence ) { if ( m_state != Account::Connected ) return; @@ -749,7 +749,7 @@ XmppSipPlugin::onSubscriptionRequestConfirmed( int result ) } -void JabberPlugin::onNewIq( const Jreen::IQ& iq ) +void XmppSipPlugin::onNewIq( const Jreen::IQ& iq ) { if ( m_state != Account::Connected ) return; @@ -801,7 +801,7 @@ void JabberPlugin::onNewIq( const Jreen::IQ& iq ) }*/ else { - TomahawkSipMessage::Ptr sipMessage = iq.payload< TomahawkSipMessage >(); + TomahawkXmppMessage::Ptr sipMessage = iq.payload< TomahawkXmppMessage >(); if(sipMessage) { iq.accept(); @@ -831,7 +831,7 @@ void JabberPlugin::onNewIq( const Jreen::IQ& iq ) } -bool JabberPlugin::presenceMeansOnline( Jreen::Presence::Type p ) +bool XmppSipPlugin::presenceMeansOnline( Jreen::Presence::Type p ) { switch( p ) { @@ -846,7 +846,7 @@ bool JabberPlugin::presenceMeansOnline( Jreen::Presence::Type p ) } -void JabberPlugin::handlePeerStatus( const Jreen::JID& jid, Jreen::Presence::Type presenceType ) +void XmppSipPlugin::handlePeerStatus( const Jreen::JID& jid, Jreen::Presence::Type presenceType ) { QString fulljid = jid.full(); @@ -896,7 +896,7 @@ void JabberPlugin::handlePeerStatus( const Jreen::JID& jid, Jreen::Presence::Typ } -void JabberPlugin::onNewAvatar( const QString& jid ) +void XmppSipPlugin::onNewAvatar( const QString& jid ) { #ifndef ENABLE_HEADLESS // qDebug() << Q_FUNC_INFO << jid; From 82c77e64c6496f7be8d209ebae936b6126142968 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Sun, 12 Feb 2012 19:59:33 +0100 Subject: [PATCH 067/104] Fix windows --- src/accounts/twitter/CMakeLists.txt | 2 +- src/accounts/twitter/twitteraccount.h | 2 +- src/accounts/twitter/twitterconfigwidget.h | 4 ++-- src/accounts/xmpp/CMakeLists.txt | 2 +- src/accounts/xmpp/googlewrapper/CMakeLists.txt | 2 +- src/accounts/xmpp/xmppaccount.h | 2 +- src/accounts/xmpp/xmppconfigwidget.h | 4 ++-- src/accounts/zeroconf/CMakeLists.txt | 4 ++-- src/accounts/zeroconf/tomahawkzeroconf.h | 5 +++-- 9 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/accounts/twitter/CMakeLists.txt b/src/accounts/twitter/CMakeLists.txt index 253bd4e03..3ad17a72a 100644 --- a/src/accounts/twitter/CMakeLists.txt +++ b/src/accounts/twitter/CMakeLists.txt @@ -32,7 +32,7 @@ include_directories( . ${CMAKE_CURRENT_BINARY_DIR} .. qt4_wrap_cpp( twitterAccountMoc ${twitterAccountHeaders} ) qt4_wrap_ui( twitterAccountUI_H ${twitterAccountUI} ) qt4_add_resources( RC_SRCS "resources.qrc" ) -add_library( tomahawk_account_twitter SHARED ${twitterAccountUI_H} ${twitterAccountSources} ${twitterAccountMoc} ${RC_SRCS} ) +add_library( tomahawk_account_twitter MODULE ${twitterAccountUI_H} ${twitterAccountSources} ${twitterAccountMoc} ${RC_SRCS} ) IF( WIN32 ) SET( OS_SPECIFIC_LINK_LIBRARIES diff --git a/src/accounts/twitter/twitteraccount.h b/src/accounts/twitter/twitteraccount.h index e4c706ce2..a1a1c2629 100644 --- a/src/accounts/twitter/twitteraccount.h +++ b/src/accounts/twitter/twitteraccount.h @@ -52,7 +52,7 @@ public: Account* createAccount( const QString& pluginId = QString() ); }; -class DLLEXPORT TwitterAccount : public Account +class ACCOUNTDLLEXPORT TwitterAccount : public Account { Q_OBJECT diff --git a/src/accounts/twitter/twitterconfigwidget.h b/src/accounts/twitter/twitterconfigwidget.h index 7b7b87bb8..3b8048146 100644 --- a/src/accounts/twitter/twitterconfigwidget.h +++ b/src/accounts/twitter/twitterconfigwidget.h @@ -19,7 +19,7 @@ #ifndef TWITTERACCOUNTCONFIGWIDGET_H #define TWITTERACCOUNTCONFIGWIDGET_H -#include "dllmacro.h" +#include "accounts/accountdllmacro.h" #include #include @@ -42,7 +42,7 @@ namespace Accounts class TwitterAccount; -class DLLEXPORT TwitterConfigWidget : public QWidget +class ACCOUNTDLLEXPORT TwitterConfigWidget : public QWidget { Q_OBJECT diff --git a/src/accounts/xmpp/CMakeLists.txt b/src/accounts/xmpp/CMakeLists.txt index e5e4e29ea..ff1f5da2a 100644 --- a/src/accounts/xmpp/CMakeLists.txt +++ b/src/accounts/xmpp/CMakeLists.txt @@ -37,7 +37,7 @@ include_directories( . ${CMAKE_CURRENT_BINARY_DIR} .. qt4_wrap_cpp( xmppAccountMoc ${xmppAccountHeaders} ) qt4_wrap_ui( xmppAccountUI_H ${xmppAccountUI} ) qt4_add_resources( RC_SRCS "resources.qrc" ) -add_library( tomahawk_account_xmpp SHARED ${xmppAccountUI_H} ${xmppAccountSources} ${xmppAccountMoc} ${RC_SRCS} ) +add_library( tomahawk_account_xmpp MODULE ${xmppAccountUI_H} ${xmppAccountSources} ${xmppAccountMoc} ${RC_SRCS} ) IF( WIN32 ) SET( OS_SPECIFIC_LINK_LIBRARIES diff --git a/src/accounts/xmpp/googlewrapper/CMakeLists.txt b/src/accounts/xmpp/googlewrapper/CMakeLists.txt index 62a7e6c25..a2ce9560b 100644 --- a/src/accounts/xmpp/googlewrapper/CMakeLists.txt +++ b/src/accounts/xmpp/googlewrapper/CMakeLists.txt @@ -25,7 +25,7 @@ add_definitions(-DGOOGLE_WRAPPER) qt4_add_resources( RCX_SRCS "resources.qrc" ) qt4_wrap_cpp( googleMoc ${googleHeaders} ) -add_library( tomahawk_account_google SHARED ${googleSources} ${googleMoc} ${googleMoc} ${RCX_SRCS} ) +add_library( tomahawk_account_google MODULE ${googleSources} ${googleMoc} ${googleMoc} ${RCX_SRCS} ) target_link_libraries( tomahawk_account_google ${QT_LIBRARIES} diff --git a/src/accounts/xmpp/xmppaccount.h b/src/accounts/xmpp/xmppaccount.h index 5692c2c20..a6c50ae20 100644 --- a/src/accounts/xmpp/xmppaccount.h +++ b/src/accounts/xmpp/xmppaccount.h @@ -54,7 +54,7 @@ public: Account* createAccount( const QString& pluginId = QString() ); }; -class DLLEXPORT XmppAccount : public Account +class ACCOUNTDLLEXPORT XmppAccount : public Account { Q_OBJECT diff --git a/src/accounts/xmpp/xmppconfigwidget.h b/src/accounts/xmpp/xmppconfigwidget.h index d88e42631..93f41f44d 100644 --- a/src/accounts/xmpp/xmppconfigwidget.h +++ b/src/accounts/xmpp/xmppconfigwidget.h @@ -19,7 +19,7 @@ #ifndef JABBERACCOUNTCONFIGWIDGET_H #define JABBERACCOUNTCONFIGWIDGET_H -#include "dllmacro.h" +#include "accounts/accountdllmacro.h" #include @@ -38,7 +38,7 @@ class XmppAccount; class GoogleWrapper; -class DLLEXPORT XmppConfigWidget : public QWidget +class ACCOUNTDLLEXPORT XmppConfigWidget : public QWidget { Q_OBJECT diff --git a/src/accounts/zeroconf/CMakeLists.txt b/src/accounts/zeroconf/CMakeLists.txt index 66b22965f..772a24350 100644 --- a/src/accounts/zeroconf/CMakeLists.txt +++ b/src/accounts/zeroconf/CMakeLists.txt @@ -4,7 +4,7 @@ include( ${QT_USE_FILE} ) add_definitions( ${QT_DEFINITIONS} ) add_definitions( -DQT_PLUGIN ) add_definitions( -DQT_SHARED ) -add_definitions( -DSIPDLLEXPORT_PRO ) +add_definitions( -DACCOUNTDLLEXPORT_PRO ) set( zeroconfSources zeroconf.cpp @@ -24,7 +24,7 @@ include_directories( . ${CMAKE_CURRENT_BINARY_DIR} .. qt4_wrap_ui( UI_SRCS configwidget.ui ) qt4_add_resources( RC_SRCS "resources.qrc" ) qt4_wrap_cpp( zeroconfMoc ${zeroconfHeaders} ) -add_library( tomahawk_account_zeroconf SHARED ${zeroconfSources} ${zeroconfMoc} ${RC_SRCS} ${UI_SRCS} ) +add_library( tomahawk_account_zeroconf MODULE ${zeroconfSources} ${zeroconfMoc} ${RC_SRCS} ${UI_SRCS} ) IF( WIN32 ) SET( OS_SPECIFIC_LINK_LIBRARIES diff --git a/src/accounts/zeroconf/tomahawkzeroconf.h b/src/accounts/zeroconf/tomahawkzeroconf.h index 15ef6b5c4..f54b162e3 100644 --- a/src/accounts/zeroconf/tomahawkzeroconf.h +++ b/src/accounts/zeroconf/tomahawkzeroconf.h @@ -30,6 +30,7 @@ #include "database/database.h" #include "network/servent.h" +#include "accounts/accountdllmacro.h" class Node : public QObject { @@ -59,7 +60,7 @@ public slots: emit tomahawkHostFound( ip, port, "Unknown", nid ); this->deleteLater(); } - + void resolve() { QHostInfo::lookupHost( ip, this, SLOT( resolved( QHostInfo ) ) ); @@ -72,7 +73,7 @@ private: }; -class TomahawkZeroconf : public QObject +class ACCOUNTDLLEXPORT TomahawkZeroconf : public QObject { Q_OBJECT From 79fd0278cee5386d30f8bb996827bd9d29b1b029 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sun, 12 Feb 2012 11:56:14 -0500 Subject: [PATCH 068/104] Fix turning on/off toplevel accounts --- src/libtomahawk/accounts/AccountManager.cpp | 4 +++ src/libtomahawk/accounts/AccountModel.cpp | 35 +++++++++++++++++++-- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/src/libtomahawk/accounts/AccountManager.cpp b/src/libtomahawk/accounts/AccountManager.cpp index a400353fc..f99f146a6 100644 --- a/src/libtomahawk/accounts/AccountManager.cpp +++ b/src/libtomahawk/accounts/AccountManager.cpp @@ -185,6 +185,8 @@ AccountManager::enableAccount( Account* account ) account->setEnabled( true ); m_enabledAccounts << account; + + account->sync(); } @@ -197,6 +199,8 @@ AccountManager::disableAccount( Account* account ) account->deauthenticate(); account->setEnabled( false ); m_enabledAccounts.removeAll( account ); + + account->sync(); } diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index 98113352d..8d13eba19 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -117,6 +117,27 @@ AccountModel::data( const QModelIndex& index, int role ) const return !node->accounts.isEmpty(); case AccountTypeRole: return QVariant::fromValue< AccountTypes >( node->factory->types() ); + case Qt::CheckStateRole: + { + if ( node->accounts.isEmpty() ) + return Qt::Unchecked; + + // If all are checked or unchecked, return that + bool someOn = false, someOff = false; + foreach ( const Account* acct, node->accounts ) + { + if ( acct->enabled() ) + someOn = true; + else + someOff = true; + } + if ( someOn && !someOff ) + return Qt::Checked; + else if ( someOff & !someOn ) + return Qt::Unchecked; + else + return Qt::PartiallyChecked; + } default: return QVariant(); } @@ -300,9 +321,18 @@ AccountModel::setData( const QModelIndex& index, const QVariant& value, int role if ( node->type == AccountModelNode::FactoryType ) { - // TODO handle overall on/off + // Turn on or off all accounts for this factory - return false; + Qt::CheckState state = static_cast< Qt::CheckState >( value.toInt() ); + + foreach ( Account* acct, node->accounts ) + { + state == Qt::Checked ? AccountManager::instance()->enableAccount( acct ) + : AccountManager::instance()->disableAccount( acct ); + } + + emit dataChanged( index, index ); + return true; } Q_ASSERT( acct ); @@ -313,7 +343,6 @@ AccountModel::setData( const QModelIndex& index, const QVariant& value, int role else if( state == Qt::Unchecked ) AccountManager::instance()->disableAccount( acct ); - acct->sync(); emit dataChanged( index, index ); return true; From 0a3dc28bdf35bba021824f951208210cbfddf6cf Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sun, 12 Feb 2012 11:57:06 -0500 Subject: [PATCH 069/104] only migrate valid twitter accounts --- src/libtomahawk/tomahawksettings.cpp | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/libtomahawk/tomahawksettings.cpp b/src/libtomahawk/tomahawksettings.cpp index d456b1879..36c8ef1ac 100644 --- a/src/libtomahawk/tomahawksettings.cpp +++ b/src/libtomahawk/tomahawksettings.cpp @@ -209,15 +209,7 @@ TomahawkSettings::doUpgrade( int oldVersion, int newVersion ) rawpluginname.replace( "jabber", "xmpp" ); QString accountKey = QString( "%1account_%2" ).arg( rawpluginname ).arg( pluginId ); - accounts << accountKey; - beginGroup( "accounts/" + accountKey ); - setValue( "enabled", enabledSip.contains( sipPlugin ) == true ); - setValue( "autoconnect", true ); - setValue( "configuration", QVariantHash() ); - setValue( "acl", QVariantMap() ); - setValue( "types", QStringList() << "SipType" ); - endGroup(); if ( pluginName == "sipjabber" || pluginName == "sipgoogle" ) { QVariantHash credentials; @@ -232,6 +224,12 @@ TomahawkSettings::doUpgrade( int oldVersion, int newVersion ) } else if ( pluginName == "siptwitter" ) { + // Only port twitter plugin if there's a valid twitter config + if ( value( sipPlugin + "/oauthtokensecret" ).toString().isEmpty() && + value( sipPlugin + "/oauthtoken" ).toString().isEmpty() && + value( sipPlugin + "/screenname" ).toString().isEmpty() ) + continue; + QVariantHash credentials; credentials[ "cachedfriendssinceid" ] = value( sipPlugin + "/cachedfriendssinceid" ); credentials[ "cacheddirectmessagessinceid" ] = value( sipPlugin + "/cacheddirectmessagessinceid" ); @@ -250,6 +248,14 @@ TomahawkSettings::doUpgrade( int oldVersion, int newVersion ) setValue( QString( "accounts/%1/accountfriendlyname" ).arg( accountKey ), "Local Network" ); } + beginGroup( "accounts/" + accountKey ); + setValue( "enabled", enabledSip.contains( sipPlugin ) == true ); + setValue( "autoconnect", true ); + setValue( "configuration", QVariantHash() ); + setValue( "acl", QVariantMap() ); + setValue( "types", QStringList() << "SipType" ); + endGroup(); + accounts << accountKey; remove( sipPlugin ); } From e2749a7676edaa0442d53bbfdd80c64ef08c7660 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sun, 12 Feb 2012 16:24:08 -0500 Subject: [PATCH 070/104] Fix some twitter stuff --- src/accounts/twitter/sip/twittersip.cpp | 2 ++ src/accounts/twitter/twitteraccount.cpp | 3 +++ src/libtomahawk/tomahawksettings.cpp | 16 ++++++++++------ 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/accounts/twitter/sip/twittersip.cpp b/src/accounts/twitter/sip/twittersip.cpp index 446cc321d..c4daa6679 100644 --- a/src/accounts/twitter/sip/twittersip.cpp +++ b/src/accounts/twitter/sip/twittersip.cpp @@ -59,6 +59,8 @@ TwitterSipPlugin::TwitterSipPlugin( Tomahawk::Accounts::Account* account ) connect( account, SIGNAL( nowAuthenticated( const QWeakPointer< TomahawkOAuthTwitter > &, const QTweetUser & ) ), SLOT( accountAuthenticated( const QWeakPointer< TomahawkOAuthTwitter > &, const QTweetUser & ) ) ); + m_configuration = account->configuration(); + qDebug() << "SIP configuration:" << m_configuration << m_configuration[ "cachedpeers" ]; if ( Database::instance()->dbid() != m_account->configuration()[ "saveddbid" ].toString() ) { m_configuration[ "cachedpeers" ] = QVariantHash(); diff --git a/src/accounts/twitter/twitteraccount.cpp b/src/accounts/twitter/twitteraccount.cpp index 390bf55e4..67bad5148 100644 --- a/src/accounts/twitter/twitteraccount.cpp +++ b/src/accounts/twitter/twitteraccount.cpp @@ -50,6 +50,8 @@ TwitterAccount::TwitterAccount( const QString &accountId ) setAccountServiceName( "Twitter" ); setTypes( AccountTypes( InfoType | SipType ) ); + qDebug() << "Got cached peers:" << configuration() << configuration()[ "cachedpeers" ]; + m_configWidget = QWeakPointer< TwitterConfigWidget >( new TwitterConfigWidget( this, 0 ) ); connect( m_configWidget.data(), SIGNAL( twitterAuthed( bool ) ), SLOT( configDialogAuthedSignalSlot( bool ) ) ); @@ -86,6 +88,7 @@ TwitterAccount::sipPlugin() { if ( m_twitterSipPlugin.isNull() ) { + qDebug() << "CHECKING:" << configuration() << configuration()[ "cachedpeers" ]; m_twitterSipPlugin = QWeakPointer< TwitterSipPlugin >( new TwitterSipPlugin( this ) ); connect( m_twitterSipPlugin.data(), SIGNAL( stateChanged( Tomahawk::Accounts::Account::ConnectionState ) ), this, SIGNAL( connectionStateChanged( Tomahawk::Accounts::Account::ConnectionState ) ) ); diff --git a/src/libtomahawk/tomahawksettings.cpp b/src/libtomahawk/tomahawksettings.cpp index 36c8ef1ac..244a3b1b0 100644 --- a/src/libtomahawk/tomahawksettings.cpp +++ b/src/libtomahawk/tomahawksettings.cpp @@ -231,17 +231,22 @@ TomahawkSettings::doUpgrade( int oldVersion, int newVersion ) continue; QVariantHash credentials; - credentials[ "cachedfriendssinceid" ] = value( sipPlugin + "/cachedfriendssinceid" ); - credentials[ "cacheddirectmessagessinceid" ] = value( sipPlugin + "/cacheddirectmessagessinceid" ); - credentials[ "cachedpeers" ] = value( sipPlugin + "/cachedpeers" ); credentials[ "oauthtoken" ] = value( sipPlugin + "/oauthtoken" ); credentials[ "oauthtokensecret" ] = value( sipPlugin + "/oauthtokensecret" ); - credentials[ "cachedmentionssinceid" ] = value( sipPlugin + "/cachedmentionssinceid" ); credentials[ "username" ] = value( sipPlugin + "/screenname" ); - credentials[ "saveddbid" ] = value( sipPlugin + "/saveddbid" ); + + QVariantHash configuration; + configuration[ "cachedfriendssinceid" ] = value( sipPlugin + "/cachedfriendssinceid" ); + configuration[ "cacheddirectmessagessinceid" ] = value( sipPlugin + "/cacheddirectmessagessinceid" ); + configuration[ "cachedpeers" ] = value( sipPlugin + "/cachedpeers" ); + qDebug() << "FOUND CACHED PEERS:" << value( sipPlugin + "/cachedpeers" ).toHash(); + configuration[ "cachedmentionssinceid" ] = value( sipPlugin + "/cachedmentionssinceid" ); + configuration[ "saveddbid" ] = value( sipPlugin + "/saveddbid" ); setValue( QString( "accounts/%1/credentials" ).arg( accountKey ), credentials ); + setValue( QString( "accounts/%1/configuration" ).arg( accountKey ), configuration ); setValue( QString( "accounts/%1/accountfriendlyname" ).arg( accountKey ), "@" + value( sipPlugin + "/screenname" ).toString() ); + sync(); } else if ( pluginName == "sipzeroconf" ) { @@ -251,7 +256,6 @@ TomahawkSettings::doUpgrade( int oldVersion, int newVersion ) beginGroup( "accounts/" + accountKey ); setValue( "enabled", enabledSip.contains( sipPlugin ) == true ); setValue( "autoconnect", true ); - setValue( "configuration", QVariantHash() ); setValue( "acl", QVariantMap() ); setValue( "types", QStringList() << "SipType" ); endGroup(); From d0a6d8a0a27ec4b2e18e77c57b3d42d75c39008e Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Sun, 12 Feb 2012 22:48:37 +0100 Subject: [PATCH 071/104] Fix windows installer --- CMakeModules/NSIS.template.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeModules/NSIS.template.in b/CMakeModules/NSIS.template.in index 15e252d20..03122c6fa 100644 --- a/CMakeModules/NSIS.template.in +++ b/CMakeModules/NSIS.template.in @@ -280,7 +280,7 @@ Section "Tomahawk Player" SEC_TOMAHAWK_PLAYER File "${INSTALL_PATH}\bin\libtomahawk_portfwd.dll" File "${INSTALL_PATH}\bin\libtomahawk_lastfm2.dll" File "${INSTALL_PATH}\bin\libtomahawklib.dll" - File "${INSTALL_PATH}\lib\libtomahawk_sip*.dll" + File "${INSTALL_PATH}\lib\libtomahawk_account_*.dll" !endif !ifndef INSTALL_PATH ;Main executable. @@ -293,7 +293,7 @@ Section "Tomahawk Player" SEC_TOMAHAWK_PLAYER File "${BUILD_PATH}\libqxtweb-standalone.dll" File "${BUILD_PATH}\libtomahawk_portfwd.dll" File "${BUILD_PATH}\libtomahawk_lastfm2.dll" - File "${BUILD_PATH}\libtomahawk_sip*.dll" + File "${BUILD_PATH}\libtomahawk_account_*.dll" !endif ;License & release notes. From b6ce8d282c78a6d19b57894ea3464f5e292ebd79 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Mon, 13 Feb 2012 11:29:26 -0500 Subject: [PATCH 072/104] Fix twitter dm settings name --- src/accounts/twitter/sip/twittersip.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/accounts/twitter/sip/twittersip.cpp b/src/accounts/twitter/sip/twittersip.cpp index c4daa6679..ee65f50ff 100644 --- a/src/accounts/twitter/sip/twittersip.cpp +++ b/src/accounts/twitter/sip/twittersip.cpp @@ -405,7 +405,7 @@ TwitterSipPlugin::pollDirectMessages() return; if ( m_cachedDirectMessagesSinceId == 0 ) - m_cachedDirectMessagesSinceId = m_configuration[ "cacheddirectmentionssinceid" ].toLongLong(); + m_cachedDirectMessagesSinceId = m_configuration[ "cacheddirectmessagessinceid" ].toLongLong(); tDebug() << "TwitterSipPlugin looking for direct messages since id " << m_cachedDirectMessagesSinceId; From 011483ec54c185a0251da59f3342133a0a3e7d10 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Mon, 13 Feb 2012 15:52:19 -0500 Subject: [PATCH 073/104] Update UI file --- src/stackedsettingsdialog.ui | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/stackedsettingsdialog.ui b/src/stackedsettingsdialog.ui index 69664c495..78c36c9f5 100644 --- a/src/stackedsettingsdialog.ui +++ b/src/stackedsettingsdialog.ui @@ -100,6 +100,13 @@ + + + + Install from file... + + + From 3687ebdc6bd0154cfd68a69b844fa495fa38f029 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Mon, 13 Feb 2012 18:03:30 -0500 Subject: [PATCH 074/104] Add an Install From File and Remove Account option --- src/AccountDelegate.cpp | 53 +++++++++++++++++++--- src/AccountDelegate.h | 2 +- src/libtomahawk/accounts/AccountModel.cpp | 25 ++++++++-- src/libtomahawk/accounts/AccountModel.h | 3 +- src/libtomahawk/accounts/ResolverAccount.h | 5 +- src/settingsdialog.cpp | 22 +++++++++ src/settingsdialog.h | 2 + 7 files changed, 97 insertions(+), 15 deletions(-) diff --git a/src/AccountDelegate.cpp b/src/AccountDelegate.cpp index c2074a4b1..5f7a4883f 100644 --- a/src/AccountDelegate.cpp +++ b/src/AccountDelegate.cpp @@ -172,6 +172,8 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, // Draw individual accounts and add account button for factories m_cachedButtonRects[ index ] = QRect(); + + bool canDelete = index.data( AccountModel::CanDeleteRole ) .toBool(); if ( rowType == Tomahawk::Accounts::AccountModel::TopLevelFactory ) { const QList< Account* > accts = index.data( AccountModel::ChildrenOfFactoryRole ).value< QList< Tomahawk::Accounts::Account* > >(); @@ -224,6 +226,29 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, } } + else if ( canDelete ) + { + const QString btnText = tr( "Remove Account" ); + const int btnWidth = installMetrics.width( btnText ) + 2*PADDING; + QRect btnRect; + + if ( hasConfigWrench ) + btnRect = QRect( opt.rect.right() - PADDING - btnWidth, opt.rect.bottom() - installMetrics.height() - 3*PADDING, btnWidth, installMetrics.height() + 2*PADDING ); + else + btnRect = QRect( opt.rect.right() - PADDING - btnWidth, center - ( installMetrics.height() + 4 ) / 2, btnWidth, installMetrics.height() + 2*PADDING ); + + leftEdge = btnRect.left(); + m_cachedButtonRects[ index ] = btnRect; + + painter->save(); + painter->setPen( opt.palette.color( QPalette::Active, QPalette::AlternateBase ) ); + + drawRoundedButton( painter, btnRect, true ); + + painter->setFont( installFont ); + painter->drawText( btnRect, Qt::AlignCenter, btnText ); + painter->restore(); + } // Draw the title and description // title @@ -431,7 +456,7 @@ AccountDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const QS else if ( m_cachedButtonRects.contains( index ) && m_cachedButtonRects[ index ].contains( me->pos() ) ) { // Install/create/etc button for this row - model->setData( index, true, AccountModel::AddAccountButtonRole ); + model->setData( index, true, AccountModel::CustomButtonRole ); } } @@ -475,7 +500,7 @@ AccountDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const QS void -AccountDelegate::drawRoundedButton( QPainter* painter, const QRect& btnRect ) const +AccountDelegate::drawRoundedButton( QPainter* painter, const QRect& btnRect, bool red ) const { QPainterPath btnPath; const int radius = 3; @@ -490,8 +515,16 @@ AccountDelegate::drawRoundedButton( QPainter* painter, const QRect& btnRect ) co btnPath.lineTo( btnRect.left(), btnCenter ); QLinearGradient g; - g.setColorAt( 0, QColor(54, 127, 211) ); - g.setColorAt( 0.5, QColor(43, 104, 182) ); + if ( !red ) + { + g.setColorAt( 0, QColor(54, 127, 211) ); + g.setColorAt( 0.5, QColor(43, 104, 182) ); + } + else + { + g.setColorAt( 0, QColor(206, 63, 63) ); + g.setColorAt( 0.5, QColor(170, 52, 52) ); + } //painter->setPen( bg.darker() ); painter->fillPath( btnPath, g ); //painter->drawPath( btnPath ); @@ -505,8 +538,16 @@ AccountDelegate::drawRoundedButton( QPainter* painter, const QRect& btnRect ) co btnPath.lineTo( btnRect.right(), btnCenter ); btnPath.lineTo( btnRect.left(), btnCenter ); - g.setColorAt( 0, QColor(34, 85, 159) ); - g.setColorAt( 0.5, QColor(35, 79, 147) ); + if ( !red ) + { + g.setColorAt( 0, QColor(34, 85, 159) ); + g.setColorAt( 0.5, QColor(35, 79, 147) ); + } + else + { + g.setColorAt( 0, QColor(150, 50, 50) ); + g.setColorAt( 0.5, QColor(130, 40, 40) ); + } painter->fillPath( btnPath, g ); } diff --git a/src/AccountDelegate.h b/src/AccountDelegate.h index 4cadd38c8..eab8cdf7a 100644 --- a/src/AccountDelegate.h +++ b/src/AccountDelegate.h @@ -47,7 +47,7 @@ signals: void openConfig( Tomahawk::Accounts::AccountFactory* ); private: - void drawRoundedButton( QPainter* painter, const QRect& buttonRect ) const; + void drawRoundedButton( QPainter* painter, const QRect& buttonRect, bool red = false ) const; // Returns new left edge int drawStatus( QPainter* painter, const QPointF& rightTopEdge, Account* acct, bool drawText = false ) const; void drawCheckBox( QStyleOptionViewItemV4& opt, QPainter* p, const QWidget* w ) const; diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index 8d13eba19..0cbc92ed1 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -207,6 +207,10 @@ AccountModel::data( const QModelIndex& index, int role ) const else return UniqueFactory; } + else if ( role == CanDeleteRole ) + { + return node->type == AccountModelNode::ManualResolverType; + } Account* acct = 0; if ( node->type == AccountModelNode::ManualResolverType ) @@ -349,12 +353,23 @@ AccountModel::setData( const QModelIndex& index, const QVariant& value, int role } // The install/create/remove/etc button was clicked. Handle it properly depending on this item - if ( role == AddAccountButtonRole ) + if ( role == CustomButtonRole ) { - Q_ASSERT( node->type == AccountModelNode::FactoryType ); - // Make a new account of this factory type - emit createAccount( node->factory ); - return true; + if ( node->type == AccountModelNode::FactoryType ) + { + // Make a new account of this factory type + emit createAccount( node->factory ); + return true; + } + else if ( node->type == AccountModelNode::ManualResolverType ) + { + Q_ASSERT( node->resolverAccount ); + AccountManager::instance()->removeAccount( node->resolverAccount ); + + return true; + } + Q_ASSERT( false ); // Should not be here, only the above two types should have this button + return false; } diff --git a/src/libtomahawk/accounts/AccountModel.h b/src/libtomahawk/accounts/AccountModel.h index a1c6a2e31..491723d22 100644 --- a/src/libtomahawk/accounts/AccountModel.h +++ b/src/libtomahawk/accounts/AccountModel.h @@ -58,9 +58,10 @@ public: AccountData = Qt::UserRole + 28, // raw plugin CanRateRole = Qt::UserRole + 32, AccountTypeRole = Qt::UserRole + 33, + CanDeleteRole = Qt::UserRole + 34, CheckboxClickedRole = Qt::UserRole + 29, // the checkbox for this row was toggled - AddAccountButtonRole = Qt::UserRole + 30, // the add account button + CustomButtonRole = Qt::UserRole + 30, // the add account or remove account button // Used by factories ChildrenOfFactoryRole = Qt::UserRole + 31 diff --git a/src/libtomahawk/accounts/ResolverAccount.h b/src/libtomahawk/accounts/ResolverAccount.h index f3cf4a594..899f087ea 100644 --- a/src/libtomahawk/accounts/ResolverAccount.h +++ b/src/libtomahawk/accounts/ResolverAccount.h @@ -20,6 +20,7 @@ #define RESOLVERACCOUNT_H #include "accounts/Account.h" +#include "dllmacro.h" namespace Tomahawk { @@ -27,7 +28,7 @@ class ExternalResolverGui; namespace Accounts { -class ResolverAccountFactory : public AccountFactory +class DLLEXPORT ResolverAccountFactory : public AccountFactory { Q_OBJECT public: @@ -51,7 +52,7 @@ public: * * Contains the resolver* that is it wrapping */ -class ResolverAccount : public Account +class DLLEXPORT ResolverAccount : public Account { Q_OBJECT public: diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index 10a04fdf6..0fe591af7 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -53,6 +53,7 @@ #include "accounts/Account.h" #include "accounts/AccountManager.h" #include +#include #include "utils/logger.h" #include "AccountFactoryWrapper.h" @@ -119,7 +120,9 @@ SettingsDialog::SettingsDialog( QWidget *parent ) ui->accountsView->setModel( m_accountProxy ); + connect( ui->installFromFileBtn, SIGNAL( clicked( bool ) ), this, SLOT( installFromFile() ) ); connect( m_accountModel, SIGNAL( createAccount( Tomahawk::Accounts::AccountFactory* ) ), this, SLOT( createAccountFromFactory( Tomahawk::Accounts::AccountFactory* ) ) ); + connect( AccountManager::instance(), SIGNAL( added( Tomahawk::Accounts::Account* ) ), ui->accountsView, SLOT( scrollToBottom() ) ); ui->accountsFilterCombo->addItem( tr( "All" ), Accounts::NoType ); ui->accountsFilterCombo->addItem( accountTypeToString( SipType ), SipType ); @@ -606,6 +609,25 @@ SettingsDialog::handleAccountAdded( Account* account, bool added ) } +void +SettingsDialog::installFromFile() +{ + const QString resolver = QFileDialog::getOpenFileName( this, tr( "Install resolver from file" ), TomahawkSettings::instance()->scriptDefaultPath() ); + + if( !resolver.isEmpty() ) + { + Account* acct = ResolverAccountFactory::createFromPath( resolver, false ); + AccountManager::instance()->addAccount( acct ); + TomahawkSettings::instance()->addAccount( acct->accountId() ); + AccountManager::instance()->enableAccount( acct ); + + + QFileInfo resolverAbsoluteFilePath( resolver ); + TomahawkSettings::instance()->setScriptDefaultPath( resolverAbsoluteFilePath.absolutePath() ); + } +} + + void SettingsDialog::requiresRestart() { diff --git a/src/settingsdialog.h b/src/settingsdialog.h index 2c642e6e2..05bd3ba58 100644 --- a/src/settingsdialog.h +++ b/src/settingsdialog.h @@ -99,6 +99,8 @@ private slots: void accountConfigDelete(); void accountCreateConfigClosed( int value ); + void installFromFile(); + void updateScanOptionsView(); void changePage( QListWidgetItem*, QListWidgetItem* ); From 7e9fa7c2a7d04570567287361290e8b3de1232be Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Mon, 13 Feb 2012 20:04:47 -0500 Subject: [PATCH 075/104] fix addin and removing --- src/libtomahawk/accounts/AccountModel.cpp | 41 ++++++++++++----------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index 0cbc92ed1..03631fa94 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -302,6 +302,13 @@ AccountModel::setData( const QModelIndex& index, const QVariant& value, int role Attica::Content resolver = node->atticaContent; AtticaManager::ResolverState state = AtticaManager::instance()->resolverState( resolver ); + if ( state == AtticaManager::Installed && !node->resolverAccount ) + { + // Something is wrong, reinstall + AtticaManager::instance()->uninstallResolver( resolver ); + state = AtticaManager::Uninstalled; + } + if ( state == AtticaManager::Installed ) { acct = node->atticaAccount; @@ -401,12 +408,26 @@ AccountModel::accountAdded( Account* account ) { // Find the factory this belongs up, and update AccountFactory* factory = AccountManager::instance()->factoryForAccount( account ); + AtticaResolverAccount* attica = qobject_cast< AtticaResolverAccount* >( account ); for ( int i = 0; i < m_accounts.size(); i++ ) { AccountModelNode* n = m_accounts.at( i ); + bool thisIsTheOne = false; if ( n->factory == factory ) { n->accounts << account; + thisIsTheOne = true; + + return; + } + else if ( attica && n->atticaContent.id() == attica->atticaId() ) + { + n->resolverAccount = attica; + thisIsTheOne = true; + } + + if ( thisIsTheOne ) + { const QModelIndex idx = index( i, 0, QModelIndex() ); dataChanged( idx, idx ); @@ -414,28 +435,10 @@ AccountModel::accountAdded( Account* account ) } } - // Not matched with a factory. Then just add it at the end - if ( AtticaResolverAccount* attica = qobject_cast< AtticaResolverAccount* >( account ) ) - { - Attica::Content::List allAtticaContent = AtticaManager::instance()->resolvers(); - foreach ( const Attica::Content& c, allAtticaContent ) - { - if ( attica->atticaId() == c.id() ) - { - // This is us. Create the row - const int count = m_accounts.size(); - beginInsertRows( QModelIndex(), count, count ); - m_accounts << new AccountModelNode( c ); - endInsertRows(); - - return; - } - } - } - // Ok, just a plain resolver. add it at the end if ( ResolverAccount* resolver = qobject_cast< ResolverAccount* >( account ) ) { + Q_ASSERT( qobject_cast< AtticaResolverAccount* >( account ) == 0 ); // should NOT get attica accounts here, should be caught above const int count = m_accounts.size(); beginInsertRows( QModelIndex(), count, count ); m_accounts << new AccountModelNode( resolver ); From 0c231d55326761dd6812bacc30af5cd13ac1a680 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Mon, 13 Feb 2012 21:11:47 -0500 Subject: [PATCH 076/104] fix first start issues --- src/AccountDelegate.cpp | 10 ++++++++-- src/AccountDelegate.h | 1 + src/libtomahawk/AtticaManager.cpp | 2 ++ src/libtomahawk/AtticaManager.h | 2 +- src/libtomahawk/accounts/AccountModel.cpp | 8 +++++++- src/libtomahawk/accounts/AccountModel.h | 6 ++++-- .../accounts/AccountModelFilterProxy.cpp | 16 ++++++++++++++++ .../accounts/AccountModelFilterProxy.h | 8 ++++++++ src/settingsdialog.cpp | 10 +++++++++- src/settingsdialog.h | 1 + 10 files changed, 57 insertions(+), 7 deletions(-) diff --git a/src/AccountDelegate.cpp b/src/AccountDelegate.cpp index 5f7a4883f..cbad1e51e 100644 --- a/src/AccountDelegate.cpp +++ b/src/AccountDelegate.cpp @@ -82,13 +82,19 @@ AccountDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex return QSize( 200, TOPLEVEL_ACCOUNT_HEIGHT ); else if ( rowType == AccountModel::TopLevelFactory ) { - // Make more space for eacha ccount we have to show. + // Make more space for each account we have to show. AccountFactory* fac = qobject_cast< AccountFactory* >( index.data( AccountModel::AccountData ).value< QObject* >() ); if ( fac->isUnique() ) return QSize( 200, TOPLEVEL_ACCOUNT_HEIGHT ); const QList< Account* > accts = index.data( AccountModel::ChildrenOfFactoryRole ).value< QList< Tomahawk::Accounts::Account* > >(); - return QSize( 200, TOPLEVEL_ACCOUNT_HEIGHT + 12 * accts.size()-1 ); + const QSize s = QSize( 200, TOPLEVEL_ACCOUNT_HEIGHT + 12 * accts.size()-1 ); + + if ( s != m_sizeHints[ index ] ) + const_cast< AccountDelegate* >( this )->sizeHintChanged( index ); // FU KTHBBQ + + m_sizeHints[ index ] = s; + return s; } return QSize(); diff --git a/src/AccountDelegate.h b/src/AccountDelegate.h index eab8cdf7a..6787489b4 100644 --- a/src/AccountDelegate.h +++ b/src/AccountDelegate.h @@ -63,6 +63,7 @@ private: mutable QHash< QPersistentModelIndex, QRect > m_cachedButtonRects; mutable QHash< QPersistentModelIndex, QRect > m_cachedStarRects; mutable QHash< QPersistentModelIndex, QRect > m_cachedConfigRects; + mutable QHash< QPersistentModelIndex, QSize > m_sizeHints; }; } diff --git a/src/libtomahawk/AtticaManager.cpp b/src/libtomahawk/AtticaManager.cpp index 160fc5cd0..96cd70fc6 100644 --- a/src/libtomahawk/AtticaManager.cpp +++ b/src/libtomahawk/AtticaManager.cpp @@ -246,6 +246,8 @@ AtticaManager::resolversList( BaseJob* j ) } syncServerData(); + + emit resolversLoaded( m_resolvers ); } diff --git a/src/libtomahawk/AtticaManager.h b/src/libtomahawk/AtticaManager.h index d4fced92f..88333cf54 100644 --- a/src/libtomahawk/AtticaManager.h +++ b/src/libtomahawk/AtticaManager.h @@ -86,7 +86,7 @@ public slots: void upgradeResolver( const Attica::Content& resolver ); signals: - void resolversReloaded( const Attica::Content::List& resolvers ); + void resolversLoaded( const Attica::Content::List& resolvers ); void resolverStateChanged( const QString& resolverId ); void resolverInstalled( const QString& resolverId ); diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index 03631fa94..795e355b0 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -32,6 +32,7 @@ using namespace Accounts; AccountModel::AccountModel( QObject* parent ) : QAbstractListModel( parent ) { + connect( AtticaManager::instance(), SIGNAL( resolversLoaded( Attica::Content::List ) ), this, SLOT( loadData() ) ); loadData(); } @@ -41,6 +42,7 @@ AccountModel::loadData() beginResetModel(); qDeleteAll( m_accounts ); + m_accounts.clear(); // Add all factories QList< AccountFactory* > factories = AccountManager::instance()->factories(); @@ -73,6 +75,8 @@ AccountModel::loadData() connect ( AccountManager::instance(), SIGNAL( stateChanged( Account* ,Accounts::Account::ConnectionState ) ), this, SLOT( accountStateChanged( Account*, Accounts::Account::ConnectionState ) ) ); connect( AtticaManager::instance(), SIGNAL( resolverInstalled( QString ) ), this, SLOT( atticaInstalled( QString ) ) ); + + endResetModel(); } @@ -216,7 +220,7 @@ AccountModel::data( const QModelIndex& index, int role ) const if ( node->type == AccountModelNode::ManualResolverType ) acct = node->resolverAccount; else if ( node->type == AccountModelNode::UniqueFactoryType ) - acct = node->accounts.first(); + acct = node->accounts.isEmpty() ? 0 : node->accounts.first(); // If there's no account*, then it means it's a unique factory that hasn't been created if ( !acct ) @@ -443,6 +447,8 @@ AccountModel::accountAdded( Account* account ) beginInsertRows( QModelIndex(), count, count ); m_accounts << new AccountModelNode( resolver ); endInsertRows(); + + emit scrollTo( index( m_accounts.size() - 1, 0, QModelIndex() ) ); } } diff --git a/src/libtomahawk/accounts/AccountModel.h b/src/libtomahawk/accounts/AccountModel.h index 491723d22..cbdecf410 100644 --- a/src/libtomahawk/accounts/AccountModel.h +++ b/src/libtomahawk/accounts/AccountModel.h @@ -91,16 +91,18 @@ public: signals: void createAccount( Tomahawk::Accounts::AccountFactory* factory ); + void scrollTo( const QModelIndex& idx ); private slots: + void loadData(); + void accountAdded( Tomahawk::Accounts::Account* ); void accountRemoved( Tomahawk::Accounts::Account* ); void accountStateChanged( Account*, Accounts::Account::ConnectionState ); void atticaInstalled( const QString& atticaId ); -private: - void loadData(); +private: QList< AccountModelNode* > m_accounts; QSet< QString > m_waitingForAtticaInstall; }; diff --git a/src/libtomahawk/accounts/AccountModelFilterProxy.cpp b/src/libtomahawk/accounts/AccountModelFilterProxy.cpp index ff3de4063..23dca5dfc 100644 --- a/src/libtomahawk/accounts/AccountModelFilterProxy.cpp +++ b/src/libtomahawk/accounts/AccountModelFilterProxy.cpp @@ -31,6 +31,15 @@ AccountModelFilterProxy::AccountModelFilterProxy( QObject* parent ) } + +void +AccountModelFilterProxy::setSourceModel( QAbstractItemModel* sourceModel ) +{ + connect( sourceModel, SIGNAL( scrollTo( QModelIndex ) ), this, SLOT( onScrollTo( QModelIndex ) ) ); + QSortFilterProxyModel::setSourceModel( sourceModel ); +} + + bool AccountModelFilterProxy::filterAcceptsRow( int sourceRow, const QModelIndex& sourceParent ) const { @@ -54,3 +63,10 @@ AccountModelFilterProxy::setFilterType( AccountType type ) m_filterType = type; invalidate(); } + + +void +AccountModelFilterProxy::onScrollTo( const QModelIndex& idx ) +{ + emit scrollTo( mapFromSource( idx ) ); +} diff --git a/src/libtomahawk/accounts/AccountModelFilterProxy.h b/src/libtomahawk/accounts/AccountModelFilterProxy.h index f22f8f4e9..92c61d469 100644 --- a/src/libtomahawk/accounts/AccountModelFilterProxy.h +++ b/src/libtomahawk/accounts/AccountModelFilterProxy.h @@ -35,9 +35,17 @@ public: void setFilterType( Tomahawk::Accounts::AccountType type ); + virtual void setSourceModel( QAbstractItemModel* sourceModel ); + +signals: + void scrollTo( const QModelIndex& idx ); + protected: virtual bool filterAcceptsRow ( int sourceRow, const QModelIndex& sourceParent ) const; +private slots: + void onScrollTo( const QModelIndex& idx ); + private: Tomahawk::Accounts::AccountType m_filterType; }; diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index 0fe591af7..f784f34ae 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -118,11 +118,12 @@ SettingsDialog::SettingsDialog( QWidget *parent ) m_accountProxy = new AccountModelFilterProxy( m_accountModel ); m_accountProxy->setSourceModel( m_accountModel ); + connect( m_accountProxy, SIGNAL( scrollTo( QModelIndex ) ), this, SLOT( scrollTo( QModelIndex ) ) ); + ui->accountsView->setModel( m_accountProxy ); connect( ui->installFromFileBtn, SIGNAL( clicked( bool ) ), this, SLOT( installFromFile() ) ); connect( m_accountModel, SIGNAL( createAccount( Tomahawk::Accounts::AccountFactory* ) ), this, SLOT( createAccountFromFactory( Tomahawk::Accounts::AccountFactory* ) ) ); - connect( AccountManager::instance(), SIGNAL( added( Tomahawk::Accounts::Account* ) ), ui->accountsView, SLOT( scrollToBottom() ) ); ui->accountsFilterCombo->addItem( tr( "All" ), Accounts::NoType ); ui->accountsFilterCombo->addItem( accountTypeToString( SipType ), SipType ); @@ -628,6 +629,13 @@ SettingsDialog::installFromFile() } +void +SettingsDialog::scrollTo( const QModelIndex& idx ) +{ + ui->accountsView->scrollTo( idx, QAbstractItemView::PositionAtBottom ); +} + + void SettingsDialog::requiresRestart() { diff --git a/src/settingsdialog.h b/src/settingsdialog.h index 05bd3ba58..dc61925d7 100644 --- a/src/settingsdialog.h +++ b/src/settingsdialog.h @@ -100,6 +100,7 @@ private slots: void accountCreateConfigClosed( int value ); void installFromFile(); + void scrollTo( const QModelIndex& ); void updateScanOptionsView(); From 75ea38010f444c80abf96dd5e29ff1deeeef9183 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Tue, 14 Feb 2012 18:38:44 -0500 Subject: [PATCH 077/104] fix creating factory and other first start issue --- src/AccountDelegate.cpp | 23 ++++------------ .../xmpp/googlewrapper/googlewrapper.cpp | 1 + src/accounts/xmpp/xmppconfigwidget.cpp | 12 ++++++--- src/libtomahawk/accounts/AccountModel.cpp | 26 ++++++++++++------- 4 files changed, 30 insertions(+), 32 deletions(-) diff --git a/src/AccountDelegate.cpp b/src/AccountDelegate.cpp index cbad1e51e..618f7d59c 100644 --- a/src/AccountDelegate.cpp +++ b/src/AccountDelegate.cpp @@ -632,28 +632,15 @@ AccountDelegate::drawConfigWrench ( QPainter* painter, QStyleOptionViewItemV4& o QRect AccountDelegate::checkRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const { - // the checkbox for this row was hit - const AccountModel::RowType rowType = static_cast< AccountModel::RowType >( idx.data( AccountModel::RowTypeRole ).toInt() ); - QStyleOptionViewItemV4 opt = option; initStyleOption( &opt, idx ); - if ( rowType == AccountModel::TopLevelAccount || rowType == AccountModel::TopLevelFactory ) - { - // Top level item, return the corresponding rect - const int ypos = ( opt.rect.top() + opt.rect.height() / 2 ) - ( WRENCH_SIZE / 2 ); - QRect checkRect = QRect( PADDING, ypos, WRENCH_SIZE, WRENCH_SIZE ); - return checkRect; - } /*else if ( rowType == AccountModel::ChildAccount ) - { - // Return smaller rect of individual child account - const int smallWrenchSize = opt.rect.height() - PADDING; - int ypos = ( opt.rect.center().y() ) - ( smallWrenchSize / 2 ); - QRect checkRect = QRect( opt.rect.left() + PADDING, ypos, smallWrenchSize, smallWrenchSize ); - return checkRect; - }*/ + // Top level item, return the corresponding rect + const int ypos = ( opt.rect.top() + opt.rect.height() / 2 ) - ( WRENCH_SIZE / 2 ); + const QRect checkRect = QRect( PADDING, ypos, WRENCH_SIZE, WRENCH_SIZE ); + + return checkRect; - return QRect(); } diff --git a/src/accounts/xmpp/googlewrapper/googlewrapper.cpp b/src/accounts/xmpp/googlewrapper/googlewrapper.cpp index d60a91740..858565aba 100644 --- a/src/accounts/xmpp/googlewrapper/googlewrapper.cpp +++ b/src/accounts/xmpp/googlewrapper/googlewrapper.cpp @@ -81,6 +81,7 @@ GoogleWrapper::GoogleWrapper ( const QString& pluginID ) config->m_ui->headerLabel->setText( tr( "Configure this Google Account" ) ); config->m_ui->emailLabel->setText( tr( "Google Address" ) ); config->m_ui->xmppBlurb->setText( tr( "Enter your Google login to connect with your friends using Tomahawk!" ) ); + config->m_ui->xmppUsername->setPlaceholderText( tr( "username@gmail.com" ) ); config->m_ui->logoLabel->setPixmap( QPixmap( ":/gmail-logo.png" ) ); config->m_ui->xmppServer->setText( "talk.google.com" ); config->m_ui->xmppPort->setValue( 5222 ); diff --git a/src/accounts/xmpp/xmppconfigwidget.cpp b/src/accounts/xmpp/xmppconfigwidget.cpp index 9a9390e82..b85b6e7c3 100644 --- a/src/accounts/xmpp/xmppconfigwidget.cpp +++ b/src/accounts/xmpp/xmppconfigwidget.cpp @@ -57,12 +57,16 @@ void XmppConfigWidget::saveConfig() { QVariantHash credentials = m_account->credentials(); - credentials[ "username" ] = m_ui->xmppUsername->text(); - credentials[ "password" ] = m_ui->xmppPassword->text(); - credentials[ "server" ] = m_ui->xmppServer->text(); - credentials[ "port" ] = m_ui->xmppPort->text(); + credentials[ "username" ] = m_ui->xmppUsername->text().trimmed(); + credentials[ "password" ] = m_ui->xmppPassword->text().trimmed(); + + QVariantHash configuration = m_account->configuration(); + configuration[ "server" ] = m_ui->xmppServer->text().trimmed(); + configuration[ "port" ] = m_ui->xmppPort->text().trimmed(); + m_account->setAccountFriendlyName( m_ui->xmppUsername->text() ); m_account->setCredentials( credentials ); + m_account->setConfiguration( configuration); m_account->sync(); static_cast< XmppSipPlugin* >( m_account->sipPlugin() )->checkSettings(); diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index 795e355b0..c9073dd2c 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -33,6 +33,13 @@ AccountModel::AccountModel( QObject* parent ) : QAbstractListModel( parent ) { connect( AtticaManager::instance(), SIGNAL( resolversLoaded( Attica::Content::List ) ), this, SLOT( loadData() ) ); + + connect( AccountManager::instance(), SIGNAL( added( Tomahawk::Accounts::Account* ) ), this, SLOT( accountAdded( Tomahawk::Accounts::Account* ) ) ); + connect( AccountManager::instance(), SIGNAL( removed( Tomahawk::Accounts::Account* ) ), this, SLOT( accountRemoved( Tomahawk::Accounts::Account* ) ) ); + connect( AccountManager::instance(), SIGNAL( stateChanged( Account* ,Accounts::Account::ConnectionState ) ), this, SLOT( accountStateChanged( Account*, Accounts::Account::ConnectionState ) ) ); + + connect( AtticaManager::instance(), SIGNAL( resolverInstalled( QString ) ), this, SLOT( atticaInstalled( QString ) ) ); + loadData(); } @@ -70,12 +77,6 @@ AccountModel::loadData() } } - connect ( AccountManager::instance(), SIGNAL( added( Tomahawk::Accounts::Account* ) ), this, SLOT( accountAdded( Tomahawk::Accounts::Account* ) ) ); - connect ( AccountManager::instance(), SIGNAL( removed( Tomahawk::Accounts::Account* ) ), this, SLOT( accountRemoved( Tomahawk::Accounts::Account* ) ) ); - connect ( AccountManager::instance(), SIGNAL( stateChanged( Account* ,Accounts::Account::ConnectionState ) ), this, SLOT( accountStateChanged( Account*, Accounts::Account::ConnectionState ) ) ); - - connect( AtticaManager::instance(), SIGNAL( resolverInstalled( QString ) ), this, SLOT( atticaInstalled( QString ) ) ); - endResetModel(); } @@ -296,8 +297,14 @@ AccountModel::setData( const QModelIndex& index, const QVariant& value, int role switch ( node->type ) { case AccountModelNode::UniqueFactoryType: - Q_ASSERT( node->accounts.size() == 1 ); - acct = node->accounts.first(); + if ( node->accounts.isEmpty() ) + { + // No account for this unique factory, create it + // Don't add it to node->accounts here, slot attached to accountmanager::accountcreated will do it for us + acct = node->factory->createAccount(); + AccountManager::instance()->addAccount( acct ); + TomahawkSettings::instance()->addAccount( acct->accountId() ); + } break; case AccountModelNode::AtticaType: { @@ -411,6 +418,7 @@ void AccountModel::accountAdded( Account* account ) { // Find the factory this belongs up, and update + qDebug() << "IN ACCOUNT ADDED!!!!"; AccountFactory* factory = AccountManager::instance()->factoryForAccount( account ); AtticaResolverAccount* attica = qobject_cast< AtticaResolverAccount* >( account ); for ( int i = 0; i < m_accounts.size(); i++ ) @@ -421,8 +429,6 @@ AccountModel::accountAdded( Account* account ) { n->accounts << account; thisIsTheOne = true; - - return; } else if ( attica && n->atticaContent.id() == attica->atticaId() ) { From 9adc4be099db97f769d09751bfe627f468f137a6 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Tue, 14 Feb 2012 18:51:38 -0500 Subject: [PATCH 078/104] elide and tooltip --- src/AccountDelegate.cpp | 1 + src/libtomahawk/accounts/AccountModel.cpp | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/AccountDelegate.cpp b/src/AccountDelegate.cpp index 618f7d59c..906cb7c03 100644 --- a/src/AccountDelegate.cpp +++ b/src/AccountDelegate.cpp @@ -295,6 +295,7 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, const int descWidth = rightEdge - leftTitleEdge - PADDING; painter->setFont( descFont ); const QRect descRect( leftTitleEdge, runningBottom + PADDING, descWidth, painter->fontMetrics().height() ); + desc = painter->fontMetrics().elidedText( desc, Qt::ElideRight, descWidth ); painter->drawText( descRect, Qt::AlignLeft | Qt::TextWordWrap | Qt::AlignTop, desc ); runningBottom = descRect.bottom(); diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index c9073dd2c..6a4959c93 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -108,6 +108,7 @@ AccountModel::data( const QModelIndex& index, int role ) const return fac->icon(); case StateRole: return ShippedWithTomahawk; + case Qt::ToolTipRole: case DescriptionRole: return fac->description(); case CanRateRole: @@ -160,6 +161,7 @@ AccountModel::data( const QModelIndex& index, int role ) const return QVariant::fromValue< QPixmap >( AtticaManager::instance()->iconForResolver( c ) ); case StateRole: return (int)AtticaManager::instance()->resolverState( c ); + case Qt::ToolTipRole: case DescriptionRole: return c.description(); case AuthorRole: @@ -235,6 +237,7 @@ AccountModel::data( const QModelIndex& index, int role ) const return node->factory->prettyName(); case Qt::DecorationRole: return node->factory->icon(); + case Qt::ToolTipRole: case DescriptionRole: return node->factory->description(); case StateRole: From 638718a48c1b87f2d827a6cd3d828d54b9ae042f Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Wed, 15 Feb 2012 08:29:09 -0500 Subject: [PATCH 079/104] Add an assert and debug --- src/libtomahawk/accounts/ResolverAccount.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libtomahawk/accounts/ResolverAccount.cpp b/src/libtomahawk/accounts/ResolverAccount.cpp index cb33caf09..ac0e241a8 100644 --- a/src/libtomahawk/accounts/ResolverAccount.cpp +++ b/src/libtomahawk/accounts/ResolverAccount.cpp @@ -107,6 +107,9 @@ ResolverAccount::~ResolverAccount() void ResolverAccount::authenticate() { + qDebug() << Q_FUNC_INFO << "Authenticating/starting resolver, exists?" << m_resolver; + Q_ASSERT( m_resolver ); + if ( !m_resolver->running() ) m_resolver->start(); From dc41b29ab7f25fd680a98defcb5e9be575a63db0 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Thu, 16 Feb 2012 22:22:46 -0500 Subject: [PATCH 080/104] add some debug to account adding --- src/libtomahawk/accounts/AccountModel.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index 6a4959c93..95c5a62dd 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -421,13 +421,16 @@ void AccountModel::accountAdded( Account* account ) { // Find the factory this belongs up, and update - qDebug() << "IN ACCOUNT ADDED!!!!"; + qDebug() << "IN ACCOUNT ADDED, new account:" << account->accountFriendlyName(); AccountFactory* factory = AccountManager::instance()->factoryForAccount( account ); AtticaResolverAccount* attica = qobject_cast< AtticaResolverAccount* >( account ); for ( int i = 0; i < m_accounts.size(); i++ ) { AccountModelNode* n = m_accounts.at( i ); bool thisIsTheOne = false; + qDebug() << "Checking for added account's related factory or attica:" << n->factory << attica; + if ( attica ) + qDebug() << n->atticaContent.id() << attica->atticaId(); if ( n->factory == factory ) { n->accounts << account; From 6638d74687ed03869c312d12dfc95f6672d4fffb Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Thu, 16 Feb 2012 22:31:01 -0500 Subject: [PATCH 081/104] Fix typo, left->right is small->big... --- src/AccountDelegate.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AccountDelegate.cpp b/src/AccountDelegate.cpp index 906cb7c03..388f44895 100644 --- a/src/AccountDelegate.cpp +++ b/src/AccountDelegate.cpp @@ -389,7 +389,7 @@ AccountDelegate::drawAccountList( QPainter* painter, QStyleOptionViewItemV4& opt current += textHeight + PADDING/2; - leftOfAccounts = qMax( leftOfAccounts, textTopLeft.x() ); + leftOfAccounts = qMin( leftOfAccounts, textTopLeft.x() ); } return leftOfAccounts; From 2412266a345daea349e2a803c856c44f4639e413 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Thu, 16 Feb 2012 22:36:46 -0500 Subject: [PATCH 082/104] Fix painting initial coordinate for qMin --- src/AccountDelegate.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AccountDelegate.cpp b/src/AccountDelegate.cpp index 388f44895..ba8342302 100644 --- a/src/AccountDelegate.cpp +++ b/src/AccountDelegate.cpp @@ -365,7 +365,7 @@ AccountDelegate::drawAccountList( QPainter* painter, QStyleOptionViewItemV4& opt int runningRightEdge = rightEdge; int current = 0; - int leftOfAccounts = 0; + int leftOfAccounts = rightEdge; if ( accts.size() % 2 == 1 ) { From 06be1868ea342a356608d3f8f12ea89c972b86e7 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Thu, 16 Feb 2012 22:39:12 -0500 Subject: [PATCH 083/104] More accountmodel debug --- src/libtomahawk/accounts/AccountModel.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index 95c5a62dd..64c04062e 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -66,7 +66,10 @@ AccountModel::loadData() // add all attica resolvers (installed or uninstalled) Attica::Content::List fromAttica = AtticaManager::instance()->resolvers(); foreach ( const Attica::Content& content, fromAttica ) + { + qDebug() << "Loading ATTICA ACCOUNT with content:" << content.id() << content.name(); m_accounts << new AccountModelNode( content ); + } // Add all non-attica manually installed resolvers foreach ( Account* acct, allAccounts ) @@ -430,7 +433,7 @@ AccountModel::accountAdded( Account* account ) bool thisIsTheOne = false; qDebug() << "Checking for added account's related factory or attica:" << n->factory << attica; if ( attica ) - qDebug() << n->atticaContent.id() << attica->atticaId(); + qDebug() << n->atticaContent.id() << n->atticaContent.name() << attica->atticaId(); if ( n->factory == factory ) { n->accounts << account; From e6f4674064fa43dba7e9c957120df83d999d133d Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Thu, 16 Feb 2012 23:21:37 -0500 Subject: [PATCH 084/104] Only remove rows from model if removing a manual resolver. Update otherwise --- src/libtomahawk/accounts/AccountModel.cpp | 25 +++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index 64c04062e..406ec0313 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -509,25 +509,38 @@ AccountModel::accountStateChanged( Account* account , Account::ConnectionState ) void AccountModel::accountRemoved( Account* account ) { - // Find the factory this belongs up, and update + // Find the row this belongs to and update/remove AccountFactory* factory = AccountManager::instance()->factoryForAccount( account ); for ( int i = 0; i < m_accounts.size(); i++ ) { AccountModelNode* n = m_accounts.at( i ); - if ( n->type == AccountModelNode::FactoryType && - n->factory == factory ) + bool found = false; + // Account in a factory, remove child and update + if ( ( n->type == AccountModelNode::FactoryType && n->factory == factory ) || + ( n->type == AccountModelNode::UniqueFactoryType && n->accounts.size() && n->accounts.first() == account ) ) { n->accounts.removeAll( account ); + found = true; + } + + // Attica account, just clear the account but leave the attica shell + if ( n->type == AccountModelNode::AtticaType && n->atticaAccount && n->atticaAccount == account ) + { + n->resolverAccount = 0; + found = true; + } + + if ( found ) + { const QModelIndex idx = index( i, 0, QModelIndex() ); emit dataChanged( idx, idx ); return; } - if ( ( n->type == AccountModelNode::UniqueFactoryType && n->accounts.size() && n->accounts.first() == account ) || - ( n->type == AccountModelNode::AtticaType && n->atticaAccount && n->atticaAccount == account ) || - ( n->type == AccountModelNode::ManualResolverType && n->resolverAccount && n->resolverAccount == account ) ) + // Manual resolver added, remove the row now + if ( n->type == AccountModelNode::ManualResolverType && n->resolverAccount && n->resolverAccount == account ) { beginRemoveRows( QModelIndex(), i, i ); m_accounts.removeAt( i ); From 0b452cc415610e9afae6ce299678fee61ce20d20 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 17 Feb 2012 11:31:33 -0500 Subject: [PATCH 085/104] more debug for account row removing --- src/libtomahawk/accounts/AccountModel.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index 406ec0313..d3f88cfdc 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -511,6 +511,7 @@ AccountModel::accountRemoved( Account* account ) { // Find the row this belongs to and update/remove AccountFactory* factory = AccountManager::instance()->factoryForAccount( account ); + qDebug() << "AccountModel got account removed:" << account->accountFriendlyName(); for ( int i = 0; i < m_accounts.size(); i++ ) { AccountModelNode* n = m_accounts.at( i ); @@ -533,6 +534,7 @@ AccountModel::accountRemoved( Account* account ) if ( found ) { + qDebug() << "Found account removed but we don't want to delete a row!" << i << n->type << n->factory; const QModelIndex idx = index( i, 0, QModelIndex() ); emit dataChanged( idx, idx ); @@ -542,6 +544,8 @@ AccountModel::accountRemoved( Account* account ) // Manual resolver added, remove the row now if ( n->type == AccountModelNode::ManualResolverType && n->resolverAccount && n->resolverAccount == account ) { + qDebug() << "Found account removed AND REMOVING IT FROM THE LIST!" << n->factory << n->type << n->accounts << i; + beginRemoveRows( QModelIndex(), i, i ); m_accounts.removeAt( i ); endRemoveRows(); From e3f4fdfdd85f6e415214b2ecdc973653582c9b74 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 17 Feb 2012 13:16:21 -0500 Subject: [PATCH 086/104] Some more work + debug to try to fix j's issue --- src/libtomahawk/AtticaManager.cpp | 14 ++++++++++++++ src/libtomahawk/AtticaManager.h | 2 ++ src/libtomahawk/accounts/AccountModel.cpp | 14 ++++++++++++-- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/libtomahawk/AtticaManager.cpp b/src/libtomahawk/AtticaManager.cpp index 96cd70fc6..e6a64bd60 100644 --- a/src/libtomahawk/AtticaManager.cpp +++ b/src/libtomahawk/AtticaManager.cpp @@ -125,6 +125,20 @@ AtticaManager::resolvers() const } +Content +AtticaManager::resolverForId( const QString& id ) const +{ + foreach ( const Attica::Content& c, m_resolvers ) + { + if ( c.id() == id ) + return c; + } + + return Content(); +} + + + AtticaManager::ResolverState AtticaManager::resolverState ( const Content& resolver ) const { diff --git a/src/libtomahawk/AtticaManager.h b/src/libtomahawk/AtticaManager.h index 88333cf54..3876583ed 100644 --- a/src/libtomahawk/AtticaManager.h +++ b/src/libtomahawk/AtticaManager.h @@ -71,6 +71,8 @@ public: bool resolversLoaded() const; Attica::Content::List resolvers() const; + Attica::Content resolverForId( const QString& id ) const; + ResolverState resolverState( const Attica::Content& resolver ) const; QPixmap iconForResolver( const Attica::Content& id ); // Looks up in icon cache diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index d3f88cfdc..9da527024 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -38,8 +38,6 @@ AccountModel::AccountModel( QObject* parent ) connect( AccountManager::instance(), SIGNAL( removed( Tomahawk::Accounts::Account* ) ), this, SLOT( accountRemoved( Tomahawk::Accounts::Account* ) ) ); connect( AccountManager::instance(), SIGNAL( stateChanged( Account* ,Accounts::Account::ConnectionState ) ), this, SLOT( accountStateChanged( Account*, Accounts::Account::ConnectionState ) ) ); - connect( AtticaManager::instance(), SIGNAL( resolverInstalled( QString ) ), this, SLOT( atticaInstalled( QString ) ) ); - loadData(); } @@ -319,20 +317,24 @@ AccountModel::setData( const QModelIndex& index, const QVariant& value, int role Attica::Content resolver = node->atticaContent; AtticaManager::ResolverState state = AtticaManager::instance()->resolverState( resolver ); + qDebug() << "Attica resolver was checked! Current state is:" << state << "and so.."; if ( state == AtticaManager::Installed && !node->resolverAccount ) { // Something is wrong, reinstall + qDebug() << "Found installed state but no resolver, uninstalling first"; AtticaManager::instance()->uninstallResolver( resolver ); state = AtticaManager::Uninstalled; } if ( state == AtticaManager::Installed ) { + qDebug() << "Already installed with resolver, just enabling"; acct = node->atticaAccount; break; } else { + qDebug() << "Kicked off fetch+install, now waiting"; m_waitingForAtticaInstall.insert( resolver.id() ); AtticaManager::instance()->installResolver( resolver ); @@ -441,8 +443,15 @@ AccountModel::accountAdded( Account* account ) } else if ( attica && n->atticaContent.id() == attica->atticaId() ) { + n->resolverAccount = attica; + n->atticaContent = AtticaManager::instance()->resolverForId( attica->atticaId() ); thisIsTheOne = true; + + if ( m_waitingForAtticaInstall.contains( attica->atticaId() ) ) + AccountManager::instance()->enableAccount( account ); + + m_waitingForAtticaInstall.remove( attica->atticaId() ); } if ( thisIsTheOne ) @@ -605,6 +614,7 @@ AccountModel::atticaInstalled( const QString& atticaId ) AccountManager::instance()->enableAccount( acct ); node->atticaAccount = acct; + node->atticaContent = AtticaManager::instance()->resolverForId( atticaId ); const QModelIndex idx = index( m_accounts.indexOf( node ), 0, QModelIndex() ); emit dataChanged( idx, idx ); } From 8cdce8e1ca989db27511bd259626b016029c0e60 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 17 Feb 2012 13:36:01 -0500 Subject: [PATCH 087/104] fix some typos, remove extra code --- src/libtomahawk/accounts/AccountModel.cpp | 61 ++--------------------- src/libtomahawk/accounts/AccountModel.h | 2 - 2 files changed, 3 insertions(+), 60 deletions(-) diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index 9da527024..662bbd071 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -318,7 +318,7 @@ AccountModel::setData( const QModelIndex& index, const QVariant& value, int role Attica::Content resolver = node->atticaContent; AtticaManager::ResolverState state = AtticaManager::instance()->resolverState( resolver ); qDebug() << "Attica resolver was checked! Current state is:" << state << "and so.."; - if ( state == AtticaManager::Installed && !node->resolverAccount ) + if ( state == AtticaManager::Installed && !node->atticaAccount ) { // Something is wrong, reinstall qDebug() << "Found installed state but no resolver, uninstalling first"; @@ -444,7 +444,7 @@ AccountModel::accountAdded( Account* account ) else if ( attica && n->atticaContent.id() == attica->atticaId() ) { - n->resolverAccount = attica; + n->atticaAccount = attica; n->atticaContent = AtticaManager::instance()->resolverForId( attica->atticaId() ); thisIsTheOne = true; @@ -537,7 +537,7 @@ AccountModel::accountRemoved( Account* account ) // Attica account, just clear the account but leave the attica shell if ( n->type == AccountModelNode::AtticaType && n->atticaAccount && n->atticaAccount == account ) { - n->resolverAccount = 0; + n->atticaAccount = 0; found = true; } @@ -565,61 +565,6 @@ AccountModel::accountRemoved( Account* account ) } -void -AccountModel::atticaInstalled( const QString& atticaId ) -{ - if ( !m_waitingForAtticaInstall.contains( atticaId ) ) - return; - - m_waitingForAtticaInstall.remove( atticaId ); - - // find associated Account*, set on to the saved resolver, and update state - AccountModelNode* node = 0; - AtticaResolverAccount* acct = 0; - - foreach ( AccountModelNode* n, m_accounts ) - { - if ( n->type == AccountModelNode::AtticaType && - n->atticaContent.id() == atticaId ) - { - node = n; - break; - } - } - - if ( !node ) - { - Q_ASSERT( false ); - return; // Couldn't find it?? - } - - foreach ( Account* acc, AccountManager::instance()->accounts( ResolverType ) ) - { - if ( AtticaResolverAccount* ra = qobject_cast< AtticaResolverAccount* >( acc ) ) - { - if ( ra->atticaId() == atticaId ) - { - acct = ra; - break; - } - } - } - - if ( !acct ) - { - qWarning() << "Got installed attica resolver but couldnt' find a resolver account for it??"; - return; - } - - AccountManager::instance()->enableAccount( acct ); - - node->atticaAccount = acct; - node->atticaContent = AtticaManager::instance()->resolverForId( atticaId ); - const QModelIndex idx = index( m_accounts.indexOf( node ), 0, QModelIndex() ); - emit dataChanged( idx, idx ); -} - - int AccountModel::rowCount( const QModelIndex& ) const { diff --git a/src/libtomahawk/accounts/AccountModel.h b/src/libtomahawk/accounts/AccountModel.h index cbdecf410..d06d0a147 100644 --- a/src/libtomahawk/accounts/AccountModel.h +++ b/src/libtomahawk/accounts/AccountModel.h @@ -100,8 +100,6 @@ private slots: void accountRemoved( Tomahawk::Accounts::Account* ); void accountStateChanged( Account*, Accounts::Account::ConnectionState ); - void atticaInstalled( const QString& atticaId ); - private: QList< AccountModelNode* > m_accounts; QSet< QString > m_waitingForAtticaInstall; From 443c554b366154e5e710e9854cee51939106ae6a Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sat, 18 Feb 2012 18:14:00 -0500 Subject: [PATCH 088/104] Rework some scriptresolver/pipeline interaction now that we haev accounts --- src/libtomahawk/AtticaManager.cpp | 2 - src/libtomahawk/accounts/ResolverAccount.cpp | 38 +++++++++-------- src/libtomahawk/accounts/ResolverAccount.h | 2 +- src/libtomahawk/tomahawksettings.cpp | 43 ++------------------ src/libtomahawk/tomahawksettings.h | 8 ---- src/tomahawkapp.cpp | 9 +--- 6 files changed, 27 insertions(+), 75 deletions(-) diff --git a/src/libtomahawk/AtticaManager.cpp b/src/libtomahawk/AtticaManager.cpp index e6a64bd60..b2b56ff92 100644 --- a/src/libtomahawk/AtticaManager.cpp +++ b/src/libtomahawk/AtticaManager.cpp @@ -409,7 +409,6 @@ AtticaManager::payloadFetched() m_resolverStates[ resolverId ].scriptPath = resolverPath; // Do the install / add to tomahawk - Tomahawk::Pipeline::instance()->addScriptResolver( resolverPath, true ); Tomahawk::Accounts::Account* resolver = Tomahawk::Accounts::ResolverAccountFactory::createFromPath( resolverPath, true ); Tomahawk::Accounts::AccountManager::instance()->addAccount( resolver ); @@ -547,7 +546,6 @@ AtticaManager::uninstallResolver( const Content& resolver ) } } - Tomahawk::Pipeline::instance()->removeScriptResolver( pathFromId( resolver.id() ) ); doResolverRemove( resolver.id() ); } diff --git a/src/libtomahawk/accounts/ResolverAccount.cpp b/src/libtomahawk/accounts/ResolverAccount.cpp index ac0e241a8..890ac75a3 100644 --- a/src/libtomahawk/accounts/ResolverAccount.cpp +++ b/src/libtomahawk/accounts/ResolverAccount.cpp @@ -86,20 +86,24 @@ ResolverAccount::ResolverAccount( const QString& accountId, const QString& path setConfiguration( configuration ); setEnabled( true ); - m_resolver = qobject_cast< ExternalResolverGui* >( Pipeline::instance()->addScriptResolver( path, true ) ); - connect( m_resolver, SIGNAL( changed() ), this, SLOT( resolverChanged() ) ); + m_resolver = QWeakPointer< ExternalResolverGui >( qobject_cast< ExternalResolverGui* >( Pipeline::instance()->addScriptResolver( path, true ) ) ); + connect( m_resolver.data(), SIGNAL( changed() ), this, SLOT( resolverChanged() ) ); // What resolver do we have here? Should only be types that are 'real' resolvers - Q_ASSERT ( m_resolver ); + Q_ASSERT ( m_resolver.data() ); - setAccountFriendlyName( m_resolver->name() ); + setAccountFriendlyName( m_resolver.data()->name() ); setTypes( AccountType( ResolverType ) ); } ResolverAccount::~ResolverAccount() { - delete m_resolver; + if ( m_resolver.isNull() ) + return; + + Pipeline::instance()->removeScriptResolver( m_resolver.data()->filePath() ); + delete m_resolver.data(); } @@ -107,11 +111,11 @@ ResolverAccount::~ResolverAccount() void ResolverAccount::authenticate() { + Q_ASSERT( !m_resolver.isNull() ); qDebug() << Q_FUNC_INFO << "Authenticating/starting resolver, exists?" << m_resolver; - Q_ASSERT( m_resolver ); - if ( !m_resolver->running() ) - m_resolver->start(); + if ( !m_resolver.data()->running() ) + m_resolver.data()->start(); emit connectionStateChanged( connectionState() ); } @@ -120,15 +124,15 @@ ResolverAccount::authenticate() bool ResolverAccount::isAuthenticated() const { - return m_resolver->running(); + return m_resolver.data()->running(); } void ResolverAccount::deauthenticate() { - if ( m_resolver->running() ) - m_resolver->stop(); + if ( m_resolver.data()->running() ) + m_resolver.data()->stop(); emit connectionStateChanged( connectionState() ); @@ -138,7 +142,7 @@ ResolverAccount::deauthenticate() Account::ConnectionState ResolverAccount::connectionState() const { - if ( m_resolver->running() ) + if ( m_resolver.data()->running() ) return Connected; else return Disconnected; @@ -148,7 +152,7 @@ ResolverAccount::connectionState() const QWidget* ResolverAccount::configurationWidget() { - return m_resolver->configUI(); + return m_resolver.data()->configUI(); } @@ -172,21 +176,21 @@ ResolverAccount::removeFromConfig() void ResolverAccount::saveConfig() { Account::saveConfig(); - m_resolver->saveConfig(); + m_resolver.data()->saveConfig(); } QString ResolverAccount::path() const { - return m_resolver->filePath(); + return m_resolver.data()->filePath(); } void ResolverAccount::resolverChanged() { - setAccountFriendlyName( m_resolver->name() ); + setAccountFriendlyName( m_resolver.data()->name() ); emit connectionStateChanged( connectionState() ); } @@ -220,7 +224,7 @@ AtticaResolverAccount::~AtticaResolverAccount() void AtticaResolverAccount::loadIcon() { - const QFileInfo fi( m_resolver->filePath() ); + const QFileInfo fi( m_resolver.data()->filePath() ); QDir codeDir = fi.absoluteDir(); codeDir.cd( "../images" ); diff --git a/src/libtomahawk/accounts/ResolverAccount.h b/src/libtomahawk/accounts/ResolverAccount.h index 899f087ea..04da6d283 100644 --- a/src/libtomahawk/accounts/ResolverAccount.h +++ b/src/libtomahawk/accounts/ResolverAccount.h @@ -85,7 +85,7 @@ private slots: protected: // Created by factory, when user installs a new resolver ResolverAccount( const QString& accountId, const QString& path ); - ExternalResolverGui* m_resolver; + QWeakPointer m_resolver; friend class ResolverAccountFactory; }; diff --git a/src/libtomahawk/tomahawksettings.cpp b/src/libtomahawk/tomahawksettings.cpp index 244a3b1b0..6991b0fbc 100644 --- a/src/libtomahawk/tomahawksettings.cpp +++ b/src/libtomahawk/tomahawksettings.cpp @@ -156,8 +156,8 @@ TomahawkSettings::doUpgrade( int oldVersion, int newVersion ) QStringList toremove; QStringList resolvers = resolverDir.entryList( QDir::Dirs | QDir::NoDotAndDotDot ); - QStringList listedResolvers = allScriptResolvers(); - QStringList enabledResolvers = enabledScriptResolvers(); + QStringList listedResolvers = value( "script/resolvers" ).toStringList(); + QStringList enabledResolvers = value( "script/loadedresolvers" ).toStringList(); foreach ( const QString& resolver, resolvers ) { foreach ( const QString& r, listedResolvers ) @@ -177,8 +177,8 @@ TomahawkSettings::doUpgrade( int oldVersion, int newVersion ) } } } - setAllScriptResolvers( listedResolvers ); - setEnabledScriptResolvers( enabledResolvers ); + setValue( "script/resolvers", listedResolvers ); + setValue( "script/loadedresolvers", enabledResolvers ); tDebug() << "UPGRADING AND DELETING:" << resolverDir.absolutePath(); TomahawkUtils::removeDirectory( resolverDir.absolutePath() ); } @@ -1004,41 +1004,6 @@ TomahawkSettings::setXmppBotPort( const int port ) } -void -TomahawkSettings::addScriptResolver(const QString& resolver) -{ - setValue( "script/resolvers", allScriptResolvers() << resolver ); -} - - -QStringList -TomahawkSettings::allScriptResolvers() const -{ - return value( "script/resolvers" ).toStringList(); -} - - -void -TomahawkSettings::setAllScriptResolvers( const QStringList& resolver ) -{ - setValue( "script/resolvers", resolver ); -} - - -QStringList -TomahawkSettings::enabledScriptResolvers() const -{ - return value( "script/loadedresolvers" ).toStringList(); -} - - -void -TomahawkSettings::setEnabledScriptResolvers( const QStringList& resolvers ) -{ - setValue( "script/loadedresolvers", resolvers ); -} - - QString TomahawkSettings::scriptDefaultPath() const { diff --git a/src/libtomahawk/tomahawksettings.h b/src/libtomahawk/tomahawksettings.h index 184e5ffcb..e52c2b80f 100644 --- a/src/libtomahawk/tomahawksettings.h +++ b/src/libtomahawk/tomahawksettings.h @@ -191,14 +191,6 @@ public: int xmppBotPort() const; void setXmppBotPort( const int port ); - /// Script resolver settings - QStringList allScriptResolvers() const; - void setAllScriptResolvers( const QStringList& resolvers ); - void addScriptResolver( const QString& resolver ); - QStringList enabledScriptResolvers() const; - void setEnabledScriptResolvers( const QStringList& resolvers ); - - QString scriptDefaultPath() const; void setScriptDefaultPath( const QString& path ); QString playlistDefaultPath() const; diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index 69714edd5..aa59a8cb1 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -423,7 +423,7 @@ TomahawkApp::registerMetaTypes() qRegisterMetaType< Tomahawk::InfoSystem::InfoRequestData >( "Tomahawk::InfoSystem::InfoRequestData" ); qRegisterMetaType< Tomahawk::InfoSystem::InfoSystemCache* >( "Tomahawk::InfoSystem::InfoSystemCache*" ); qRegisterMetaType< QList< Tomahawk::InfoSystem::InfoStringHash > >("QList< Tomahawk::InfoSystem::InfoStringHash > "); - + qRegisterMetaTypeStreamOperators< QList< Tomahawk::InfoSystem::InfoStringHash > >("QList< Tomahawk::InfoSystem::InfoStringHash > "); qRegisterMetaType< QPersistentModelIndex >( "QPersistentModelIndex" ); @@ -471,13 +471,6 @@ TomahawkApp::initPipeline() { // setup resolvers for local content, and (cached) remote collection content Pipeline::instance()->addResolver( new DatabaseResolver( 100 ) ); - // load script resolvers - QStringList enabled = TomahawkSettings::instance()->enabledScriptResolvers(); - foreach ( QString resolver, TomahawkSettings::instance()->allScriptResolvers() ) - { - const bool enable = enabled.contains( resolver ); - Pipeline::instance()->addScriptResolver( resolver, enable ); - } } From 3e81405086dfbbc40f7ae2f34a811805bee0c70b Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sat, 18 Feb 2012 18:15:13 -0500 Subject: [PATCH 089/104] Add ability to add infoplugins to infosystem also, add infoplugins from accounts that support them, and clean up adding new info plugins in infoworker --- src/libtomahawk/accounts/AccountManager.cpp | 7 ++ src/libtomahawk/accounts/ResolverAccount.cpp | 8 +- src/libtomahawk/infosystem/infosystem.cpp | 16 ++- src/libtomahawk/infosystem/infosystem.h | 10 +- .../infosystem/infosystemworker.cpp | 108 ++++++++---------- src/libtomahawk/infosystem/infosystemworker.h | 21 ++-- 6 files changed, 89 insertions(+), 81 deletions(-) diff --git a/src/libtomahawk/accounts/AccountManager.cpp b/src/libtomahawk/accounts/AccountManager.cpp index f99f146a6..c20cb0cfa 100644 --- a/src/libtomahawk/accounts/AccountManager.cpp +++ b/src/libtomahawk/accounts/AccountManager.cpp @@ -291,7 +291,14 @@ AccountManager::addAccount( Account* account ) if ( account->types() & Accounts::SipType ) m_accountsByAccountType[ Accounts::SipType ].append( account ); if ( account->types() & Accounts::InfoType ) + { m_accountsByAccountType[ Accounts::InfoType ].append( account ); + + if ( account->infoPlugin() ) + { + InfoSystem::InfoSystem::instance()->addInfoPlugin( account->infoPlugin() ); + } + } if ( account->types() & Accounts::ResolverType ) m_accountsByAccountType[ Accounts::ResolverType ].append( account ); diff --git a/src/libtomahawk/accounts/ResolverAccount.cpp b/src/libtomahawk/accounts/ResolverAccount.cpp index 890ac75a3..501add13f 100644 --- a/src/libtomahawk/accounts/ResolverAccount.cpp +++ b/src/libtomahawk/accounts/ResolverAccount.cpp @@ -67,13 +67,13 @@ ResolverAccount::ResolverAccount( const QString& accountId ) // We should have a valid saved path Q_ASSERT( !path.isEmpty() ); - m_resolver = qobject_cast< ExternalResolverGui* >( Pipeline::instance()->addScriptResolver( path, enabled() ) ); - connect( m_resolver, SIGNAL( changed() ), this, SLOT( resolverChanged() ) ); + m_resolver = QWeakPointer< ExternalResolverGui >( qobject_cast< ExternalResolverGui* >( Pipeline::instance()->addScriptResolver( path, enabled() ) ) ); + connect( m_resolver.data(), SIGNAL( changed() ), this, SLOT( resolverChanged() ) ); // What resolver do we have here? Should only be types that are 'real' resolvers - Q_ASSERT ( m_resolver ); + Q_ASSERT ( !m_resolver.isNull() ); - setAccountFriendlyName( m_resolver->name() ); + setAccountFriendlyName( m_resolver.data()->name() ); setTypes( AccountType( ResolverType ) ); } diff --git a/src/libtomahawk/infosystem/infosystem.cpp b/src/libtomahawk/infosystem/infosystem.cpp index 019a69a50..a16e28ecc 100644 --- a/src/libtomahawk/infosystem/infosystem.cpp +++ b/src/libtomahawk/infosystem/infosystem.cpp @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2012 Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -111,17 +112,17 @@ InfoSystem::init() connect( cache, SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), worker, SLOT( infoSlot( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), Qt::UniqueConnection ); - + connect( worker, SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), this, SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), Qt::UniqueConnection ); - + connect( worker, SIGNAL( finished( QString ) ), this, SIGNAL( finished( QString ) ), Qt::UniqueConnection ); - + connect( worker, SIGNAL( finished( QString, Tomahawk::InfoSystem::InfoType ) ), this, SIGNAL( finished( QString, Tomahawk::InfoSystem::InfoType ) ), Qt::UniqueConnection ); QMetaObject::invokeMethod( worker, "init", Qt::QueuedConnection, Q_ARG( Tomahawk::InfoSystem::InfoSystemCache*, cache ) ); - + m_inited = true; } @@ -195,6 +196,13 @@ InfoSystem::pushInfo( const QString &caller, const InfoTypeMap &input ) } +void +InfoSystem::addInfoPlugin( InfoPlugin* plugin ) +{ + QMetaObject::invokeMethod( m_infoSystemWorkerThreadController->worker(), "addInfoPlugin", Qt::QueuedConnection, Q_ARG( Tomahawk::InfoSystem::InfoPlugin*, plugin ) ); +} + + InfoSystemCacheThread::InfoSystemCacheThread( QObject *parent ) : QThread( parent ) { diff --git a/src/libtomahawk/infosystem/infosystem.h b/src/libtomahawk/infosystem/infosystem.h index 077821882..1b9b5f988 100644 --- a/src/libtomahawk/infosystem/infosystem.h +++ b/src/libtomahawk/infosystem/infosystem.h @@ -134,7 +134,7 @@ struct InfoRequestData { QVariantMap customData; uint timeoutMillis; bool allSources; - + InfoRequestData() : requestId( TomahawkUtils::infosystemRequestId() ) , internalId( TomahawkUtils::infosystemRequestId() ) @@ -145,7 +145,7 @@ struct InfoRequestData { , timeoutMillis( 10000 ) , allSources( false ) {} - + InfoRequestData( const quint64 rId, const QString &callr, const Tomahawk::InfoSystem::InfoType typ, const QVariant &inputvar, const QVariantMap &custom ) : requestId( rId ) , internalId( TomahawkUtils::infosystemRequestId() ) @@ -242,6 +242,9 @@ public: bool pushInfo( const QString &caller, const InfoType type, const QVariant &input ); bool pushInfo( const QString &caller, const InfoTypeMap &input ); + // InfoSystem takes ownership of InfoPlugins + void addInfoPlugin( InfoPlugin* plugin ); + signals: void info( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ); void finished( QString target ); @@ -249,7 +252,7 @@ signals: private slots: void init(); - + private: bool m_inited; InfoSystemCacheThread* m_infoSystemCacheThreadController; @@ -289,5 +292,6 @@ Q_DECLARE_METATYPE( Tomahawk::InfoSystem::InfoRequestData ); Q_DECLARE_METATYPE( Tomahawk::InfoSystem::InfoStringHash ); Q_DECLARE_METATYPE( Tomahawk::InfoSystem::InfoSystemCache* ); Q_DECLARE_METATYPE( QList< Tomahawk::InfoSystem::InfoStringHash > ); +Q_DECLARE_METATYPE( Tomahawk::InfoSystem::InfoPlugin* ); #endif // TOMAHAWK_INFOSYSTEM_H diff --git a/src/libtomahawk/infosystem/infosystemworker.cpp b/src/libtomahawk/infosystem/infosystemworker.cpp index 4a54d5cda..25947e223 100644 --- a/src/libtomahawk/infosystem/infosystemworker.cpp +++ b/src/libtomahawk/infosystem/infosystemworker.cpp @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2012 Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,7 +28,6 @@ #include "infoplugins/generic/musixmatchplugin.h" #include "infoplugins/generic/chartsplugin.h" #include "infoplugins/generic/spotifyPlugin.h" -#include "infoplugins/generic/lastfmplugin.h" #include "infoplugins/generic/musicbrainzPlugin.h" #include "infoplugins/generic/hypemPlugin.h" #include "utils/tomahawkutils.h" @@ -41,7 +41,6 @@ #include "infoplugins/unix/mprisplugin.h" #endif -#include "lastfm/NetworkAccessManager" #include "infoplugins/generic/RoviPlugin.h" namespace Tomahawk @@ -78,71 +77,56 @@ void InfoSystemWorker::init( Tomahawk::InfoSystem::InfoSystemCache* cache ) { tDebug() << Q_FUNC_INFO; + m_cache = cache; #ifndef ENABLE_HEADLESS - InfoPluginPtr enptr( new EchoNestPlugin() ); - m_plugins.append( enptr ); - registerInfoTypes( enptr, enptr.data()->supportedGetTypes(), enptr.data()->supportedPushTypes() ); - InfoPluginPtr mmptr( new MusixMatchPlugin() ); - m_plugins.append( mmptr ); - registerInfoTypes( mmptr, mmptr.data()->supportedGetTypes(), mmptr.data()->supportedPushTypes() ); - InfoPluginPtr mbptr( new MusicBrainzPlugin() ); - m_plugins.append( mbptr ); - registerInfoTypes( mbptr, mbptr.data()->supportedGetTypes(), mbptr.data()->supportedPushTypes() ); - InfoPluginPtr lfmptr( new LastFmPlugin() ); - m_plugins.append( lfmptr ); - registerInfoTypes( lfmptr, lfmptr.data()->supportedGetTypes(), lfmptr.data()->supportedPushTypes() ); - InfoPluginPtr sptr( new ChartsPlugin() ); - m_plugins.append( sptr ); - registerInfoTypes( sptr, sptr.data()->supportedGetTypes(), sptr.data()->supportedPushTypes() ); - InfoPluginPtr roviptr( new RoviPlugin() ); - m_plugins.append( roviptr ); - registerInfoTypes( roviptr, roviptr.data()->supportedGetTypes(), roviptr.data()->supportedPushTypes() ); - InfoPluginPtr spotptr( new SpotifyPlugin() ); - m_plugins.append( spotptr ); - registerInfoTypes( spotptr, spotptr.data()->supportedGetTypes(), spotptr.data()->supportedPushTypes() ); - InfoPluginPtr hypeptr( new hypemPlugin() ); - m_plugins.append( hypeptr ); - registerInfoTypes( hypeptr, hypeptr.data()->supportedGetTypes(), hypeptr.data()->supportedPushTypes() ); + addInfoPlugin( new EchoNestPlugin() ); + addInfoPlugin( new MusixMatchPlugin() ); + addInfoPlugin( new MusicBrainzPlugin() ); + addInfoPlugin( new ChartsPlugin() ); + addInfoPlugin( new RoviPlugin() ); + addInfoPlugin( new SpotifyPlugin() ); + addInfoPlugin( new hypemPlugin() ); #endif - #ifdef Q_WS_MAC - InfoPluginPtr admptr( new AdiumPlugin() ); - m_plugins.append( admptr ); - registerInfoTypes( admptr, admptr.data()->supportedGetTypes(), admptr.data()->supportedPushTypes() ); - #endif -#ifndef ENABLE_HEADLESS - #ifdef Q_WS_X11 - InfoPluginPtr fdonotifyptr( new FdoNotifyPlugin() ); - m_plugins.append( fdonotifyptr ); - registerInfoTypes( fdonotifyptr, fdonotifyptr.data()->supportedGetTypes(), fdonotifyptr.data()->supportedPushTypes() ); - InfoPluginPtr mprisptr( new MprisPlugin() ); - m_plugins.append( mprisptr ); - registerInfoTypes( mprisptr, mprisptr.data()->supportedGetTypes(), mprisptr.data()->supportedPushTypes() ); - #endif +#ifdef Q_WS_MAC + addInfoPlugin( new AdiumPlugin() ); #endif - Q_FOREACH( InfoPluginPtr plugin, m_plugins ) - { - connect( - plugin.data(), - SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), - this, - SLOT( infoSlot( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), - Qt::UniqueConnection - ); +#ifndef ENABLE_HEADLESS +#ifdef Q_WS_X11 + addInfoPlugin( new FdoNotifyPlugin() ); + addInfoPlugin( new MprisPlugin() ); +#endif +#endif +} - connect( - plugin.data(), - SIGNAL( getCachedInfo( Tomahawk::InfoSystem::InfoStringHash, qint64, Tomahawk::InfoSystem::InfoRequestData ) ), - cache, - SLOT( getCachedInfoSlot( Tomahawk::InfoSystem::InfoStringHash, qint64, Tomahawk::InfoSystem::InfoRequestData ) ) - ); - connect( - plugin.data(), - SIGNAL( updateCache( Tomahawk::InfoSystem::InfoStringHash, qint64, Tomahawk::InfoSystem::InfoType, QVariant ) ), - cache, - SLOT( updateCacheSlot( Tomahawk::InfoSystem::InfoStringHash, qint64, Tomahawk::InfoSystem::InfoType, QVariant ) ) - ); - } + +void +InfoSystemWorker::addInfoPlugin( InfoPlugin* plugin ) +{ + InfoPluginPtr weakptr( plugin ); + m_plugins.append( weakptr ); + registerInfoTypes( weakptr, weakptr.data()->supportedGetTypes(), weakptr.data()->supportedPushTypes() ); + + connect( + plugin, + SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), + this, + SLOT( infoSlot( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), + Qt::UniqueConnection + ); + + connect( + plugin, + SIGNAL( getCachedInfo( Tomahawk::InfoSystem::InfoStringHash, qint64, Tomahawk::InfoSystem::InfoRequestData ) ), + m_cache, + SLOT( getCachedInfoSlot( Tomahawk::InfoSystem::InfoStringHash, qint64, Tomahawk::InfoSystem::InfoRequestData ) ) + ); + connect( + plugin, + SIGNAL( updateCache( Tomahawk::InfoSystem::InfoStringHash, qint64, Tomahawk::InfoSystem::InfoType, QVariant ) ), + m_cache, + SLOT( updateCacheSlot( Tomahawk::InfoSystem::InfoStringHash, qint64, Tomahawk::InfoSystem::InfoType, QVariant ) ) + ); } diff --git a/src/libtomahawk/infosystem/infosystemworker.h b/src/libtomahawk/infosystem/infosystemworker.h index 45634c6a2..bf530114f 100644 --- a/src/libtomahawk/infosystem/infosystemworker.h +++ b/src/libtomahawk/infosystem/infosystemworker.h @@ -37,7 +37,9 @@ namespace Tomahawk { namespace InfoSystem { - +class InfoSystemCache; + + class DLLEXPORT InfoSystemWorker : public QObject { Q_OBJECT @@ -47,33 +49,36 @@ public: ~InfoSystemWorker(); void registerInfoTypes( const InfoPluginPtr &plugin, const QSet< InfoType > &getTypes, const QSet< InfoType > &pushTypes ); - QNetworkAccessManager* nam() const; - + signals: void info( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ); void finished( QString target ); void finished( QString target, Tomahawk::InfoSystem::InfoType type ); - + public slots: void init( Tomahawk::InfoSystem::InfoSystemCache* cache ); void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData ); void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input ); void infoSlot( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ); - + + void addInfoPlugin( InfoPlugin* plugin ); private slots: void checkTimeoutsTimerFired(); - + private: void checkFinished( const Tomahawk::InfoSystem::InfoRequestData &target ); QList< InfoPluginPtr > determineOrderedMatches( const InfoType type ) const; - + QHash< QString, QHash< InfoType, int > > m_dataTracker; QMultiMap< qint64, quint64 > m_timeRequestMapper; QHash< uint, bool > m_requestSatisfiedMap; QHash< uint, InfoRequestData* > m_savedRequestMap; - + + // NOTE Cache object lives in a different thread, do not call methods on it directly + InfoSystemCache* m_cache; + // For now, statically instantiate plugins; this is just somewhere to keep them QList< InfoPluginPtr > m_plugins; From 47e8f4ffc6a7285baf38672f3256b83068cd37c0 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Mon, 20 Feb 2012 00:58:38 -0500 Subject: [PATCH 090/104] Add a last.fm account w. resolver and infotype. Needs merging w/ attica still --- data/images/lastfm-icon.png | Bin 0 -> 3463 bytes resources.qrc | 1 + src/AccountDelegate.cpp | 11 +- src/libtomahawk/CMakeLists.txt | 5 + src/libtomahawk/accounts/Account.cpp | 5 + src/libtomahawk/accounts/Account.h | 5 +- src/libtomahawk/accounts/AccountManager.cpp | 16 +- src/libtomahawk/accounts/AccountModel.cpp | 62 +++++- src/libtomahawk/accounts/AccountModel.h | 3 +- src/libtomahawk/accounts/AccountModelNode.h | 17 +- src/libtomahawk/accounts/LastFmAccount.cpp | 194 ++++++++++++++++++ src/libtomahawk/accounts/LastFmAccount.h | 103 ++++++++++ src/libtomahawk/accounts/LastFmConfig.cpp | 134 ++++++++++++ src/libtomahawk/accounts/LastFmConfig.h | 53 +++++ src/libtomahawk/accounts/LastFmConfig.ui | 85 ++++++++ .../infoplugins/generic/lastfmplugin.cpp | 42 ++-- .../infoplugins/generic/lastfmplugin.h | 10 +- src/libtomahawk/infosystem/infosystem.cpp | 12 ++ src/libtomahawk/infosystem/infosystem.h | 3 +- src/libtomahawk/infosystem/infosystemworker.h | 3 +- src/libtomahawk/pipeline.cpp | 3 + src/libtomahawk/tomahawksettings.cpp | 78 ++----- src/libtomahawk/tomahawksettings.h | 13 -- .../widgets/infowidgets/ArtistInfoWidget_p.h | 5 - src/settingsdialog.cpp | 111 +--------- src/settingsdialog.h | 3 - src/stackedsettingsdialog.ui | 120 +---------- src/tomahawkapp.cpp | 7 +- 28 files changed, 758 insertions(+), 346 deletions(-) create mode 100644 data/images/lastfm-icon.png create mode 100644 src/libtomahawk/accounts/LastFmAccount.cpp create mode 100644 src/libtomahawk/accounts/LastFmAccount.h create mode 100644 src/libtomahawk/accounts/LastFmConfig.cpp create mode 100644 src/libtomahawk/accounts/LastFmConfig.h create mode 100644 src/libtomahawk/accounts/LastFmConfig.ui diff --git a/data/images/lastfm-icon.png b/data/images/lastfm-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ff605dae40536f51074e18506401c2ebbaf1d407 GIT binary patch literal 3463 zcmV;24S4d2P)^@RCt{2n|o|j_m#&#_s$)U$20a| zj~Q(9upMw6^NJG!;n7V&B-!Fffus>>)TDr#Y=T6!Le(xxnk?NcDkVzPq>(BTTD96H zQlQ}xA^`zPc!cHAWFfo~Y``x(w#RRK#xry0KK74!cpi8B08$9-SNd7kbAP|{JLfy+ zch33!?p(OTA&j735l{%^0@iO$qw7Ne=mlDUtAH}pfT0M;$j;85F?n3c50_}_+;UYZ z%hd&!Mb~aQ0(2exq9}Kww_FfSm$nMxiL=$`cLV?k7?Fcp-g2fUh;Z}sMqX&cNJ|DW*8zVzQ;J+tUoL*CX_9awxPy7&5{68~i&YZHu zFaO80^;Z@Ox{eNzm4#SPfMBo?dYnC9$C86yV?s(bi7(fD06eY_9 zRt-Rs&~DW{e?1TcG)aO`2y;lrlH(XnQ-lBjT@Sm55J`ErBlLLNbln8;1P~#Bq+0Pd zf)-f=FY`Z zUXD~yfM^Y$$Edx%gxqd|=g;Fkco6>?!!3UdT3n0%9Uvf*1w@7>Kroweu2@0dvSmnl zd1?D)l$Me;YZjxHE=3Q8=-ams&)aV!H#7`oHvqXm`Vsj*|2gI{V+`+0E*F+bldwPd zAkLL5@t;0T^V+ops;dqAClU}wY%`?C-5ji-kj9Rsbjuc8t5*+dd@=;HnVhOB?%J^f z$Ku6<7cPQ8(faiiu3MMZcq3RVD=GQ#L#+4TZzxwIm4p}p$v2Ifsj!gJ_unV;?z@Mr zR5C=Xm7?|Q8MSn2+IgJMJ;$geORib|xHsPfn=P$;eXumBlXOZFfnYK*;qA9E7Zeyy z9Jq3Yp1pes*3|)EE-WN__H1l3XCfpWp9z9M(W|fGuc^Uz>Qur#Q+76^Uw9!!z8(tE zxqUl*pMQ?h(}T%oBdf9!=Z}Akl#`Rt*X(jJ>WL?4|I1$zK35qe3k($mM?d{ES<|Ma ze6GndP3zawzGcfma*d#6<3_TkPNn3HH?R~JCz2pZj9a&kZx$~`R|Zb69S=T;$!1G5 zUe~#@Y8AbQ4<~%y{n=-9Y}-cpmMxf)NXS{R08bJDMrkl%38;iqVT#L060YZ-OEF&8 zb?Vlv!SmsVXqsl|Zr*d}xcKa|1e=;t#%JDj7rBo=p3vVqd2&iW|HX@RA3kg--(O!( z`_`?AdMOH$(`nd0Y~w)R0S}1e$mn%EM$MZ?hCwju+_j62Pd^>5x?bt#8<;%!!cer^xXn{bAUQrv3mw-Ot8p%r_ zXa4+@Np)Sv{f9pcyJqP5``_t4bcoy}S(&A!*k{h9_vA?c)L<}WY*s}D;;2z5-Q9+= zeKj@sYHEhmA;B9WipMPhJ#EyqS5~G73)I!&y?Ak0*(2JT-+$jwvAn9P1eZ>R$!4Sc z-FL~FGG#>brEPIpAfXOWBQ0V5n@nUT1u%fVuf7`b#NEe_6KrWok(Ik}A-c(g26P@d zf}Zqn1He9Q8q@yzS1Nb!X5#wwxSo0nYefaRBn^B1c>AJA$pR#GFgqNWtf`Lz{S6Jn zcK;YOjrP5J8T-?pCVZUXbdo(|2Hhu5;=6K%_T9S~T~%c$!dhI6wYV79;>7?cUN7Cp zj^Ww4lg@(&(N#75^d#B|!zhGI4u_$zU}xtwxnJA9eTMR!k316VQ~j%7(fid`X$^^o zWVe(5@WV`g=N<0dv4iXxGlr!{0s(Hf+Z)moqhze3#bP+IuBVR~gD!(pr;yv*QwezJ zA#_nh17xq4Q_Gf7|K58jzO)Z^Q(&7ok?DW>6Zwl4rPm=Y+rE`pSKMG;QC`nP2>Z z!wVL0w5p2pFTYIFwr$8=U50W@77HaWypSSGje56H7KkyVCc<~*?$uX0v~VFczxy3}QV9-_|AQZ( ziy~?$gzWPX=^ihf&04X;&eHMs#O{@+`E)e2TzjZ5< zUwSEJTRZ;ACu!Wdlg4e^(u@QI0m)|LzSm!8>|>AdNks*kEaPiwq4mH43KlL*=x(xD zxc{AZIJjhqq35MD)Cm4as!m3{tpgq~NYLu8uExE0uYqj>bN={8Caqi(ck&(fK zr=H@Uj~(N#Wy`SS=Hi+^A4Qf?fUQo#8)V}V4_(t}{`_-3U9yC~{p2SE`}$JkUf#Nu zkM6mLQyVtWZ?Iz=3UXf`=YRiuwmt9wo>QlWWedc`fLDskKAzB?J_Z=UK7KqC9(|NC zvu5EaE5qt?A(~96vW&mAmG0_l+P?gf#=U##iyW2?2ZG6jYvxP}=FKB-@?^40OR?tX zW3pNi1OY7+BGA!+x2cJ)ufN7~;sowPhfw(Mneur2PC$Gbj5`$N_WWgt0sh|u;;yeN27Fgx=m8qS z9YcUF0D_>x00I7xuJ`MZb@SBv#~~=03H5fj!2khWK3#3rVB$^G>mP=m3~PVTbDYt^;vnYlA=)Xwh4$ja3p{1 z=|i>E{|Wk$_`w!P&eht)pBv!(P z1OT|}`@LUY&dhGh&a@WfXsSyb;*r#?hLC9Df<3o>hhTp1qPzA@(Eo=d<6#)D&H|OA z@(LfCZZZGU7(pnriejNTS}{h%jf|Qhdg~*VHvm}>WWTPrv?5$Oqv literal 0 HcmV?d00001 diff --git a/resources.qrc b/resources.qrc index 9b9010880..134cccd5d 100644 --- a/resources.qrc +++ b/resources.qrc @@ -133,6 +133,7 @@ data/images/headphones-bigger.png data/images/no-album-no-case.png data/images/rdio.png + data/images/lastfm-icon.png data/sql/dbmigrate-27_to_28.sql diff --git a/src/AccountDelegate.cpp b/src/AccountDelegate.cpp index ba8342302..6fdb22e0f 100644 --- a/src/AccountDelegate.cpp +++ b/src/AccountDelegate.cpp @@ -75,10 +75,10 @@ AccountDelegate::AccountDelegate( QObject* parent ) QSize -AccountDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const +AccountDelegate::sizeHint( const QStyleOptionViewItem&, const QModelIndex& index ) const { AccountModel::RowType rowType = static_cast< AccountModel::RowType >( index.data( AccountModel::RowTypeRole ).toInt() ); - if ( rowType == AccountModel::TopLevelAccount || rowType == AccountModel::UniqueFactory ) + if ( rowType == AccountModel::TopLevelAccount || rowType == AccountModel::UniqueFactory || rowType == AccountModel::CustomAccount ) return QSize( 200, TOPLEVEL_ACCOUNT_HEIGHT ); else if ( rowType == AccountModel::TopLevelFactory ) { @@ -204,7 +204,6 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, rightEdge = drawAccountList( painter, opt, accts, rightEdge ); painter->restore(); - int centeredUnderAccounts = oldRightEdge - (oldRightEdge - rightEdge)/2 - (btnWidth/2); btnRect = QRect( opt.rect.right() - PADDING - btnWidth, opt.rect.bottom() - installMetrics.height() - 3*PADDING, btnWidth, installMetrics.height() + 2*PADDING ); } @@ -303,7 +302,6 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, { // rating stars const int rating = index.data( AccountModel::RatingRole ).toInt(); - const int ratingWidth = 5 * ( m_ratingStarPositive.width() + PADDING_BETWEEN_STARS ); // int runningEdge = opt.rect.right() - 2*PADDING - ratingWidth; int runningEdge = textRect.left(); @@ -414,7 +412,8 @@ AccountDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const QS m_configPressed = index; const AccountModel::RowType rowType = static_cast< AccountModel::RowType >( index.data( AccountModel::RowTypeRole ).toInt() ); - if ( rowType == AccountModel::TopLevelAccount ) + if ( rowType == AccountModel::TopLevelAccount || + rowType == AccountModel::CustomAccount ) { Account* acct = qobject_cast< Account* >( index.data( AccountModel::AccountData ).value< QObject* >() ); Q_ASSERT( acct ); // Should not be showing a config wrench if there is no account! @@ -445,8 +444,6 @@ AccountDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const QS m_configPressed = QModelIndex(); - const AccountModel::ItemState state = static_cast< AccountModel::ItemState >( index.data( AccountModel::StateRole ).toInt() ); - if ( checkRectForIndex( option, index ).contains( me->pos() ) ) { // Check box for this row diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index f443458ef..3ddce4215 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -308,6 +308,8 @@ set( libSources accounts/AccountModel.cpp accounts/AccountModelFilterProxy.cpp accounts/ResolverAccount.cpp + accounts/LastFmAccount.cpp + accounts/LastFmConfig.cpp sip/SipPlugin.cpp sip/SipHandler.cpp @@ -450,6 +452,8 @@ set( libHeaders accounts/AccountModel.h accounts/AccountModelFilterProxy.h accounts/ResolverAccount.h + accounts/LastFmAccount.h + accounts/LastFmConfig.h EchonestCatalogSynchronizer.h @@ -582,6 +586,7 @@ set( libUI ${libUI} playlist/queueview.ui context/ContextWidget.ui infobar/infobar.ui + accounts/LastFmConfig.ui ) include_directories( . ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/.. .. diff --git a/src/libtomahawk/accounts/Account.cpp b/src/libtomahawk/accounts/Account.cpp index 36a22ebef..6fdaf8315 100644 --- a/src/libtomahawk/accounts/Account.cpp +++ b/src/libtomahawk/accounts/Account.cpp @@ -35,6 +35,7 @@ accountTypeToString( AccountType type ) case ResolverType: return QObject::tr( "Music Finders" ); case InfoType: + case StatusPushType: return QObject::tr( "Status Updaters" ); } @@ -174,6 +175,8 @@ Account::setTypes( AccountTypes types ) m_types << "SipType"; if ( types & ResolverType ) m_types << "ResolverType"; + if ( types & StatusPushType ) + m_types << "StatusPushType"; syncConfig(); } @@ -189,6 +192,8 @@ Account::types() const types |= SipType; if ( m_types.contains( "ResolverType" ) ) types |= ResolverType; + if ( m_types.contains( "StatusPushTypeType" ) ) + types |= StatusPushType; return types; } diff --git a/src/libtomahawk/accounts/Account.h b/src/libtomahawk/accounts/Account.h index addc02184..d02bdceab 100644 --- a/src/libtomahawk/accounts/Account.h +++ b/src/libtomahawk/accounts/Account.h @@ -50,7 +50,8 @@ enum AccountType InfoType = 0x01, SipType = 0x02, - ResolverType = 0x04 + ResolverType = 0x04, + StatusPushType = 0x08 }; DLLEXPORT QString accountTypeToString( AccountType type ); @@ -88,7 +89,7 @@ public: virtual QWidget* configurationWidget() = 0; virtual void saveConfig() {} // called when the widget has been edited. save values from config widget, call sync() to write to disk account generic settings - QVariantHash credentials() { QMutexLocker locker( &m_mutex ); return m_credentials; } + QVariantHash credentials() const { QMutexLocker locker( &m_mutex ); return m_credentials; } QVariantMap acl() const { QMutexLocker locker( &m_mutex ); return m_acl; } virtual QWidget* aclWidget() = 0; diff --git a/src/libtomahawk/accounts/AccountManager.cpp b/src/libtomahawk/accounts/AccountManager.cpp index c20cb0cfa..6c5715113 100644 --- a/src/libtomahawk/accounts/AccountManager.cpp +++ b/src/libtomahawk/accounts/AccountManager.cpp @@ -21,6 +21,7 @@ #include "config.h" #include "sourcelist.h" #include "ResolverAccount.h" +#include "LastFmAccount.h" #include #include @@ -58,6 +59,9 @@ AccountManager::AccountManager( QObject *parent ) // We include the resolver factory manually, not in a plugin ResolverAccountFactory* f = new ResolverAccountFactory(); m_accountFactories[ f->factoryId() ] = f; + + LastFmAccountFactory* l = new LastFmAccountFactory(); + m_accountFactories[ l->factoryId() ] = l; } @@ -291,16 +295,14 @@ AccountManager::addAccount( Account* account ) if ( account->types() & Accounts::SipType ) m_accountsByAccountType[ Accounts::SipType ].append( account ); if ( account->types() & Accounts::InfoType ) - { m_accountsByAccountType[ Accounts::InfoType ].append( account ); - - if ( account->infoPlugin() ) - { - InfoSystem::InfoSystem::instance()->addInfoPlugin( account->infoPlugin() ); - } - } if ( account->types() & Accounts::ResolverType ) m_accountsByAccountType[ Accounts::ResolverType ].append( account ); + if ( account->types() & Accounts::StatusPushType ) + m_accountsByAccountType[ Accounts::StatusPushType ].append( account ); + + if ( account->infoPlugin() ) + InfoSystem::InfoSystem::instance()->addInfoPlugin( account->infoPlugin() ); emit added( account ); } diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index 662bbd071..6457c8837 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -59,6 +59,13 @@ AccountModel::loadData() qDebug() << "Creating factory node:" << fac->prettyName(); m_accounts << new AccountModelNode( fac ); + + // remove the accounts we are dealing with + foreach ( Account* acct, allAccounts ) + { + if ( AccountManager::instance()->factoryForAccount( acct ) == fac ) + allAccounts.removeAll( acct ); + } } // add all attica resolvers (installed or uninstalled) @@ -67,15 +74,26 @@ AccountModel::loadData() { qDebug() << "Loading ATTICA ACCOUNT with content:" << content.id() << content.name(); m_accounts << new AccountModelNode( content ); + + foreach ( Account* acct, AccountManager::instance()->accounts( Accounts::ResolverType ) ) + { + if ( AtticaResolverAccount* resolver = qobject_cast< AtticaResolverAccount* >( acct ) ) + { + if ( resolver->atticaId() == content.id() ) + { + allAccounts.removeAll( acct ); + } + } + } } - // Add all non-attica manually installed resolvers + // All other accounts we haven't dealt with yet foreach ( Account* acct, allAccounts ) { if ( qobject_cast< ResolverAccount* >( acct ) && !qobject_cast< AtticaResolverAccount* >( acct ) ) - { m_accounts << new AccountModelNode( qobject_cast< ResolverAccount* >( acct ) ); - } + else + m_accounts << new AccountModelNode( acct ); } endResetModel(); @@ -280,6 +298,41 @@ AccountModel::data( const QModelIndex& index, int role ) const } } } + case AccountModelNode::CustomAccountType: + { + Q_ASSERT( node->customAccount ); + Q_ASSERT( node->factory ); + + Account* account = node->customAccount; + switch ( role ) + { + case Qt::DisplayRole: + return account->accountFriendlyName(); + case Qt::DecorationRole: + return account->icon(); + case StateRole: + return ShippedWithTomahawk; + case Qt::ToolTipRole: + case DescriptionRole: + return node->factory->description(); + case CanRateRole: + return false; + case RowTypeRole: + return CustomAccount; + case AccountData: + return QVariant::fromValue< QObject* >( account ); + case HasConfig: + return account->configurationWidget() != 0; + case AccountTypeRole: + return QVariant::fromValue< AccountTypes >( account->types() ); + case Qt::CheckStateRole: + return account->enabled(); + case ConnectionStateRole: + return account->connectionState(); + default: + return QVariant(); + } + } } return QVariant(); @@ -345,6 +398,9 @@ AccountModel::setData( const QModelIndex& index, const QVariant& value, int role case AccountModelNode::ManualResolverType: acct = node->resolverAccount; break; + case AccountModelNode::CustomAccountType: + acct = node->customAccount; + break; default: ; }; diff --git a/src/libtomahawk/accounts/AccountModel.h b/src/libtomahawk/accounts/AccountModel.h index d06d0a147..4396dcd7a 100644 --- a/src/libtomahawk/accounts/AccountModel.h +++ b/src/libtomahawk/accounts/AccountModel.h @@ -70,7 +70,8 @@ public: enum RowType { TopLevelFactory, TopLevelAccount, - UniqueFactory + UniqueFactory, + CustomAccount }; enum ItemState { diff --git a/src/libtomahawk/accounts/AccountModelNode.h b/src/libtomahawk/accounts/AccountModelNode.h index 6b333a3b8..795e17b6f 100644 --- a/src/libtomahawk/accounts/AccountModelNode.h +++ b/src/libtomahawk/accounts/AccountModelNode.h @@ -36,13 +36,14 @@ namespace Accounts { * 1) AccountFactory* for all factories that have child accounts. Also a list of children * 2) Attica::Content for AtticaResolverAccounts (with associated AtticaResolverAccount*) (all synchrotron resolvers) * 3) ResolverAccount* for manually added resolvers (from file). + * 4) Account* for custom accounts. These may be hybrid infosystem/resolver/sip plugins or other special accounts * * These are the top-level items in tree. * * Top level nodes all look the same to the user. The only difference is that services that have login (and thus * can have multiple logins at once) allow a user to create multiple children with specific login information. * All other top level accounts (Account*, Attica::Content, ResolverAccount*) behave the same to the user, they can - * simply click "Install" or toggle on/off. + * simply toggle on/off. * */ @@ -51,7 +52,8 @@ struct AccountModelNode { FactoryType, UniqueFactoryType, AtticaType, - ManualResolverType + ManualResolverType, + CustomAccountType }; AccountModelNode* parent; NodeType type; @@ -67,6 +69,9 @@ struct AccountModelNode { /// 3. ResolverAccount* resolverAccount; + /// 4. + Account* customAccount; + // Construct in one of four ways. Then access the corresponding members explicit AccountModelNode( AccountFactory* fac ) : type( FactoryType ) { @@ -114,11 +119,19 @@ struct AccountModelNode { resolverAccount = ra; } + explicit AccountModelNode( Account* account ) : type( CustomAccountType ) + { + init(); + customAccount = account; + factory = AccountManager::instance()->factoryForAccount( account ); + } + void init() { factory = 0; atticaAccount = 0; resolverAccount = 0; + customAccount = 0; } }; diff --git a/src/libtomahawk/accounts/LastFmAccount.cpp b/src/libtomahawk/accounts/LastFmAccount.cpp new file mode 100644 index 000000000..4e97fcb95 --- /dev/null +++ b/src/libtomahawk/accounts/LastFmAccount.cpp @@ -0,0 +1,194 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2012, Leo Franchi + * + * 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 "LastFmAccount.h" +#include "LastFmConfig.h" + +#include "infosystem/infosystem.h" +#include "infosystem/infoplugins/generic/lastfmplugin.h" +#include "utils/tomahawkutils.h" +#include "resolvers/qtscriptresolver.h" + +using namespace Tomahawk; +using namespace InfoSystem; +using namespace Accounts; + +LastFmAccountFactory::LastFmAccountFactory() +{ + m_icon.load( RESPATH "images/lastfm-icon.png" ); +} + + +Account* +LastFmAccountFactory::createAccount( const QString& accountId ) +{ + return new LastFmAccount( accountId.isEmpty() ? generateId( factoryId() ) : accountId ); +} + + +QPixmap +LastFmAccountFactory::icon() const +{ + return m_icon; +} + + +LastFmAccount::LastFmAccount( const QString& accountId ) + : Account( accountId ) +{ + m_infoPlugin = new LastFmPlugin( this ); + + setAccountFriendlyName( "Last.Fm" ); + m_icon.load( RESPATH "images/lastfm-icon.png" ); +} + + +LastFmAccount::~LastFmAccount() +{ + delete m_infoPlugin; + delete m_resolver.data(); +} + + +void +LastFmAccount::authenticate() +{ + +} + + +void +LastFmAccount::deauthenticate() +{ + +} + + +QWidget* +LastFmAccount::configurationWidget() +{ + if ( m_configWidget.isNull() ) + m_configWidget = QWeakPointer( new LastFmConfig( this ) ); + + return m_configWidget.data(); +} + + +Account::ConnectionState +LastFmAccount::connectionState() const +{ + return m_authenticated ? Account::Connected : Account::Disconnected; +} + + +QPixmap +LastFmAccount::icon() const +{ + return m_icon; +} + + +InfoPlugin* +LastFmAccount::infoPlugin() +{ + return m_infoPlugin; +} + +bool +LastFmAccount::isAuthenticated() const +{ + return m_authenticated; +} + + +void +LastFmAccount::saveConfig() +{ + if ( !m_configWidget.isNull() ) + { + setUsername( m_configWidget.data()->username() ); + setPassword( m_configWidget.data()->password() ); + setScrobble( m_configWidget.data()->scrobble() ); + } + + m_infoPlugin->settingsChanged(); +} + + +QString +LastFmAccount::password() const +{ + return credentials().value( "password" ).toString(); +} + + +void +LastFmAccount::setPassword( const QString& password ) +{ + QVariantHash creds; + creds[ "password" ] = password; + setCredentials( creds ); +} + +QString +LastFmAccount::sessionKey() const +{ + return credentials().value( "sessionkey" ).toString(); +} + + +void +LastFmAccount::setSessionKey( const QString& sessionkey ) +{ + QVariantHash creds; + creds[ "sessionkey" ] = sessionkey; + setCredentials( creds ); +} + + +QString +LastFmAccount::username() const +{ + return credentials().value( "username" ).toString(); +} + + +void +LastFmAccount::setUsername( const QString& username ) +{ + QVariantHash creds; + creds[ "username" ] = username; + setCredentials( creds ); +} + + +bool +LastFmAccount::scrobble() const +{ + return configuration().value( "scrobble" ).toBool(); +} + + +void +LastFmAccount::setScrobble( bool scrobble ) +{ + QVariantHash conf; + conf[ "scrobble" ] = scrobble; + setConfiguration( conf ); +} + diff --git a/src/libtomahawk/accounts/LastFmAccount.h b/src/libtomahawk/accounts/LastFmAccount.h new file mode 100644 index 000000000..1ab607be4 --- /dev/null +++ b/src/libtomahawk/accounts/LastFmAccount.h @@ -0,0 +1,103 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2012, Leo Franchi + * + * 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 LASTFMACCOUNT_H +#define LASTFMACCOUNT_H + +#include "accounts/Account.h" + +#include + +class QtScriptResolver; + +namespace Tomahawk { +namespace InfoSystem { + class LastFmPlugin; +} + +namespace Accounts { + +class LastFmConfig; + +class LastFmAccountFactory : public AccountFactory +{ + Q_OBJECT +public: + LastFmAccountFactory(); + + virtual Account* createAccount(const QString& accountId = QString()); + virtual QString description() const { return tr( "Scrobble your tracks to last.fm, and find freely downloadable tracks to play" ); } + virtual QString factoryId() const { return "lastfmaccount"; } + virtual QString prettyName() const { return "Last.fm"; } + virtual AccountTypes types() const { return AccountTypes( InfoType | StatusPushType ); } + virtual bool allowUserCreation() const { return false; } + virtual QPixmap icon() const; + virtual bool isUnique() const { return true; } + +private: + QPixmap m_icon; +}; + +/** + * 3.Last.Fm account is special. It is both an attica resolver *and* a InfoPlugin. We always want the infoplugin, + * but the user can install the attica resolver on-demand. So we take care of both there. + * + */ +class LastFmAccount : public Account +{ + Q_OBJECT +public: + explicit LastFmAccount( const QString& accountId ); + ~LastFmAccount(); + + virtual void deauthenticate(); + virtual void authenticate(); + + virtual SipPlugin* sipPlugin() { return 0; } + virtual Tomahawk::InfoSystem::InfoPlugin* infoPlugin(); + + virtual bool isAuthenticated() const; + + virtual ConnectionState connectionState() const; + virtual QPixmap icon() const; + virtual QWidget* aclWidget() { return 0; } + virtual QWidget* configurationWidget(); + virtual void saveConfig(); + + QString username() const; + void setUsername( const QString& ); + QString password() const; + void setPassword( const QString& ); + QString sessionKey() const; + void setSessionKey( const QString& ); + bool scrobble() const; + void setScrobble( bool scrobble ); + +private: + bool m_authenticated; + QWeakPointer m_resolver; + Tomahawk::InfoSystem::LastFmPlugin* m_infoPlugin; + QWeakPointer m_configWidget; + QPixmap m_icon; +}; + + +} +} + +#endif // LASTFMACCOUNT_H diff --git a/src/libtomahawk/accounts/LastFmConfig.cpp b/src/libtomahawk/accounts/LastFmConfig.cpp new file mode 100644 index 000000000..70648d305 --- /dev/null +++ b/src/libtomahawk/accounts/LastFmConfig.cpp @@ -0,0 +1,134 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Leo Franchi + * + * 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 "LastFmConfig.h" + +#include "LastFmAccount.h" +#include +#include "ui_LastFmConfig.h" +#include "lastfm/ws.h" +#include "lastfm/XmlQuery" + +using namespace Tomahawk::Accounts; + +LastFmConfig::LastFmConfig( LastFmAccount* account ) + : QWidget( 0 ) + , m_account( account ) +{ + m_ui = new Ui_LastFmConfig; + m_ui->setupUi( this ); + + m_ui->username->setText( m_account->username() ); + m_ui->password->setText( m_account->password() ); + m_ui->enable->setChecked( m_account->scrobble() ); + + connect( m_ui->testLogin, SIGNAL( clicked( bool ) ), this, SLOT( testLogin( bool ) ) ); + +// #ifdef Q_WS_MAC // FIXME +// m_ui->testLogin->setVisible( false ); +// #endif +} + + +QString +LastFmConfig::password() const +{ + return m_ui->password->text(); +} + + +bool +LastFmConfig::scrobble() const +{ + return m_ui->enable->isChecked(); +} + + +QString +LastFmConfig::username() const +{ + return m_ui->username->text().trimmed(); +} + + +void +LastFmConfig::testLogin(bool ) +{ + m_ui->testLogin->setEnabled( false ); + m_ui->testLogin->setText( "Testing..." ); + + QString authToken = TomahawkUtils::md5( ( m_ui->username->text().toLower() + TomahawkUtils::md5( m_ui->password->text().toUtf8() ) ).toUtf8() ); + + // now authenticate w/ last.fm and get our session key + QMap query; + query[ "method" ] = "auth.getMobileSession"; + query[ "username" ] = m_ui->username->text().toLower(); + query[ "authToken" ] = authToken; + + // ensure they have up-to-date settings + lastfm::setNetworkAccessManager( TomahawkUtils::nam() ); + + QNetworkReply* authJob = lastfm::ws::post( query ); + + connect( authJob, SIGNAL( finished() ), SLOT( onLastFmFinished() ) ); +} + + +void +LastFmConfig::onLastFmFinished() +{ + QNetworkReply* authJob = dynamic_cast( sender() ); + if( !authJob ) + { + qDebug() << Q_FUNC_INFO << "No auth job returned!"; + return; + } + if( authJob->error() == QNetworkReply::NoError ) + { + lastfm::XmlQuery lfm = lastfm::XmlQuery( authJob->readAll() ); + + if( lfm.children( "error" ).size() > 0 ) + { + qDebug() << "ERROR from last.fm:" << lfm.text(); + m_ui->testLogin->setText( tr( "Failed" ) ); + m_ui->testLogin->setEnabled( true ); + } + else + { + m_ui->testLogin->setText( tr( "Success" ) ); + m_ui->testLogin->setEnabled( false ); + } + } + else + { + switch( authJob->error() ) + { + case QNetworkReply::ContentOperationNotPermittedError: + case QNetworkReply::AuthenticationRequiredError: + m_ui->testLogin->setText( tr( "Failed" ) ); + m_ui->testLogin->setEnabled( true ); + break; + + default: + qDebug() << "Couldn't get last.fm auth result"; + m_ui->testLogin->setText( tr( "Could not contact server" ) ); + m_ui->testLogin->setEnabled( true ); + return; + } + } +} diff --git a/src/libtomahawk/accounts/LastFmConfig.h b/src/libtomahawk/accounts/LastFmConfig.h new file mode 100644 index 000000000..a86d73f0e --- /dev/null +++ b/src/libtomahawk/accounts/LastFmConfig.h @@ -0,0 +1,53 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Leo Franchi + * + * 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 LASTFMCONFIG_H +#define LASTFMCONFIG_H + +#include + +class Ui_LastFmConfig; + +namespace Tomahawk { +namespace Accounts { + +class LastFmAccount; + +class LastFmConfig : public QWidget +{ + Q_OBJECT +public: + explicit LastFmConfig( LastFmAccount* account ); + + QString username() const; + QString password() const; + bool scrobble() const; + +public slots: + void testLogin( bool ); + void onLastFmFinished(); + +private: + LastFmAccount* m_account; + Ui_LastFmConfig* m_ui; +}; + +} +} + +#endif // LASTFMCONFIG_H diff --git a/src/libtomahawk/accounts/LastFmConfig.ui b/src/libtomahawk/accounts/LastFmConfig.ui new file mode 100644 index 000000000..c0a0ece12 --- /dev/null +++ b/src/libtomahawk/accounts/LastFmConfig.ui @@ -0,0 +1,85 @@ + + + LastFmConfig + + + + 0 + 0 + 400 + 178 + + + + Form + + + + + + + + + :/data/images/lastfm-icon.png + + + Qt::AlignCenter + + + + + + + + + Qt::LeftToRight + + + Scrobble tracks to Last.fm + + + + + + + + + Username: + + + + + + + + + + Password: + + + + + + + QLineEdit::Password + + + + + + + + + Test Login + + + + + + + + + + + + diff --git a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp index 99f58d815..b2d5b7a32 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp @@ -26,34 +26,37 @@ #include "album.h" #include "typedefs.h" #include "audio/audioengine.h" -#include "tomahawksettings.h" #include "utils/tomahawkutils.h" #include "utils/logger.h" +#include "accounts/LastFmAccount.h" #include #include #include +using namespace Tomahawk::Accounts; using namespace Tomahawk::InfoSystem; -LastFmPlugin::LastFmPlugin() +LastFmPlugin::LastFmPlugin( LastFmAccount* account ) : InfoPlugin() + , m_account( account ) , m_scrobbler( 0 ) { m_supportedGetTypes << InfoAlbumCoverArt << InfoArtistImages << InfoArtistSimilars << InfoArtistSongs << InfoChart << InfoChartCapabilities; m_supportedPushTypes << InfoSubmitScrobble << InfoSubmitNowPlaying << InfoLove << InfoUnLove; // Flush session key cache - TomahawkSettings::instance()->setLastFmSessionKey( QByteArray() ); + // TODO WHY FLUSH +// m_account->setSessionKey( QByteArray() ); lastfm::ws::ApiKey = "7194b85b6d1f424fe1668173a78c0c4a"; lastfm::ws::SharedSecret = "ba80f1df6d27ae63e9cb1d33ccf2052f"; - lastfm::ws::Username = TomahawkSettings::instance()->lastFmUsername(); + lastfm::ws::Username = m_account->username(); lastfm::setNetworkAccessManager( TomahawkUtils::nam() ); - m_pw = TomahawkSettings::instance()->lastFmPassword(); + m_pw = m_account->password(); //HACK work around a bug in liblastfm---it doesn't create its config dir, so when it // tries to write the track cache, it fails silently. until we have a fixed version, do this @@ -69,9 +72,6 @@ LastFmPlugin::LastFmPlugin() m_badUrls << QUrl( "http://cdn.last.fm/flatness/catalogue/noimage" ); - connect( TomahawkSettings::instance(), SIGNAL( changed() ), - SLOT( settingsChanged() ), Qt::QueuedConnection ); - QTimer::singleShot( 0, this, SLOT( settingsChanged() ) ); } @@ -693,23 +693,23 @@ LastFmPlugin::artistImagesReturned() void LastFmPlugin::settingsChanged() { - if ( !m_scrobbler && TomahawkSettings::instance()->scrobblingEnabled() ) + if ( !m_scrobbler && m_account->enabled() ) { // can simply create the scrobbler - lastfm::ws::Username = TomahawkSettings::instance()->lastFmUsername(); - m_pw = TomahawkSettings::instance()->lastFmPassword(); + lastfm::ws::Username = m_account->username(); + m_pw = m_account->password(); createScrobbler(); } - else if ( m_scrobbler && !TomahawkSettings::instance()->scrobblingEnabled() ) + else if ( m_scrobbler && !m_account->enabled() ) { delete m_scrobbler; m_scrobbler = 0; } - else if ( TomahawkSettings::instance()->lastFmUsername() != lastfm::ws::Username || - TomahawkSettings::instance()->lastFmPassword() != m_pw ) + else if ( m_account->username() != lastfm::ws::Username || + m_account->password() != m_pw ) { - lastfm::ws::Username = TomahawkSettings::instance()->lastFmUsername(); - m_pw = TomahawkSettings::instance()->lastFmPassword(); + lastfm::ws::Username = m_account->username(); + m_pw = m_account->password(); // credentials have changed, have to re-create scrobbler for them to take effect if ( m_scrobbler ) { @@ -739,16 +739,16 @@ LastFmPlugin::onAuthenticated() if ( lfm.children( "error" ).size() > 0 ) { tLog() << "Error from authenticating with Last.fm service:" << lfm.text(); - TomahawkSettings::instance()->setLastFmSessionKey( QByteArray() ); + m_account->setSessionKey( QByteArray() ); } else { lastfm::ws::SessionKey = lfm[ "session" ][ "key" ].text(); - TomahawkSettings::instance()->setLastFmSessionKey( lastfm::ws::SessionKey.toLatin1() ); + m_account->setSessionKey( lastfm::ws::SessionKey.toLatin1() ); // qDebug() << "Got session key from last.fm"; - if ( TomahawkSettings::instance()->scrobblingEnabled() ) + if ( m_account->enabled() ) m_scrobbler = new lastfm::Audioscrobbler( "thk" ); } } @@ -764,7 +764,7 @@ LastFmPlugin::onAuthenticated() void LastFmPlugin::createScrobbler() { - if ( TomahawkSettings::instance()->lastFmSessionKey().isEmpty() ) // no session key, so get one + if ( m_account->sessionKey().isEmpty() ) // no session key, so get one { qDebug() << "LastFmPlugin::createScrobbler Session key is empty"; QString authToken = TomahawkUtils::md5( ( lastfm::ws::Username.toLower() + TomahawkUtils::md5( m_pw.toUtf8() ) ).toUtf8() ); @@ -780,7 +780,7 @@ LastFmPlugin::createScrobbler() else { qDebug() << "LastFmPlugin::createScrobbler Already have session key"; - lastfm::ws::SessionKey = TomahawkSettings::instance()->lastFmSessionKey(); + lastfm::ws::SessionKey = m_account->sessionKey(); m_scrobbler = new lastfm::Audioscrobbler( "thk" ); } diff --git a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.h b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.h index 4850fb44c..00b133a58 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.h +++ b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.h @@ -32,6 +32,11 @@ class QNetworkReply; namespace Tomahawk { +namespace Accounts +{ + class LastFmAccount; +} + namespace InfoSystem { @@ -40,7 +45,7 @@ class LastFmPlugin : public InfoPlugin Q_OBJECT public: - LastFmPlugin(); + LastFmPlugin( Accounts::LastFmAccount* account ); virtual ~LastFmPlugin(); public slots: @@ -74,6 +79,7 @@ private: void dataError( Tomahawk::InfoSystem::InfoRequestData requestData ); + Accounts::LastFmAccount* m_account; QList parseTrackList( QNetworkReply * reply ); lastfm::MutableTrack m_track; @@ -88,3 +94,5 @@ private: } #endif // LASTFMPLUGIN_H + +class A; diff --git a/src/libtomahawk/infosystem/infosystem.cpp b/src/libtomahawk/infosystem/infosystem.cpp index a16e28ecc..877a3b345 100644 --- a/src/libtomahawk/infosystem/infosystem.cpp +++ b/src/libtomahawk/infosystem/infosystem.cpp @@ -46,6 +46,9 @@ InfoSystem* InfoSystem::s_instance = 0; InfoSystem* InfoSystem::instance() { + if ( !s_instance ) + s_instance = new InfoSystem( 0 ); + return s_instance; } @@ -101,6 +104,9 @@ void InfoSystem::init() { tDebug() << Q_FUNC_INFO; + if ( m_inited ) + return; + if ( !m_infoSystemCacheThreadController->cache() || !m_infoSystemWorkerThreadController->worker() ) { QTimer::singleShot( 0, this, SLOT( init() ) ); @@ -199,6 +205,12 @@ InfoSystem::pushInfo( const QString &caller, const InfoTypeMap &input ) void InfoSystem::addInfoPlugin( InfoPlugin* plugin ) { + // Init is not complete (waiting for worker th read to start and create worker object) so keep trying till then + if ( !m_inited || !m_infoSystemWorkerThreadController->worker() ) + { + QMetaObject::invokeMethod( this, "addInfoPlugin", Qt::QueuedConnection, Q_ARG( Tomahawk::InfoSystem::InfoPlugin*, plugin ) ); + return; + } QMetaObject::invokeMethod( m_infoSystemWorkerThreadController->worker(), "addInfoPlugin", Qt::QueuedConnection, Q_ARG( Tomahawk::InfoSystem::InfoPlugin*, plugin ) ); } diff --git a/src/libtomahawk/infosystem/infosystem.h b/src/libtomahawk/infosystem/infosystem.h index 1b9b5f988..a8f0fda66 100644 --- a/src/libtomahawk/infosystem/infosystem.h +++ b/src/libtomahawk/infosystem/infosystem.h @@ -242,8 +242,9 @@ public: bool pushInfo( const QString &caller, const InfoType type, const QVariant &input ); bool pushInfo( const QString &caller, const InfoTypeMap &input ); +public slots: // InfoSystem takes ownership of InfoPlugins - void addInfoPlugin( InfoPlugin* plugin ); + void addInfoPlugin( Tomahawk::InfoSystem::InfoPlugin* plugin ); signals: void info( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ); diff --git a/src/libtomahawk/infosystem/infosystemworker.h b/src/libtomahawk/infosystem/infosystemworker.h index bf530114f..12c4d1ae8 100644 --- a/src/libtomahawk/infosystem/infosystemworker.h +++ b/src/libtomahawk/infosystem/infosystemworker.h @@ -62,7 +62,8 @@ public slots: void infoSlot( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ); - void addInfoPlugin( InfoPlugin* plugin ); + void addInfoPlugin( Tomahawk::InfoSystem::InfoPlugin* plugin ); + private slots: void checkTimeoutsTimerFired(); diff --git a/src/libtomahawk/pipeline.cpp b/src/libtomahawk/pipeline.cpp index 0fdc9c563..2b25caa14 100644 --- a/src/libtomahawk/pipeline.cpp +++ b/src/libtomahawk/pipeline.cpp @@ -164,6 +164,9 @@ Pipeline::removeScriptResolver( const QString& scriptPath ) QWeakPointer< ExternalResolver > r; foreach ( QWeakPointer< ExternalResolver > res, m_scriptResolvers ) { + if ( res.isNull() ) + continue; + if ( res.data()->filePath() == scriptPath ) r = res; } diff --git a/src/libtomahawk/tomahawksettings.cpp b/src/libtomahawk/tomahawksettings.cpp index 6991b0fbc..21ca03c00 100644 --- a/src/libtomahawk/tomahawksettings.cpp +++ b/src/libtomahawk/tomahawksettings.cpp @@ -296,6 +296,28 @@ TomahawkSettings::doUpgrade( int oldVersion, int newVersion ) } + // Add a Last.Fm account since we now moved the infoplugin into the account + const QString accountKey = QString( "lastfmaccount_%1" ).arg( QUuid::createUuid().toString().mid( 1, 8 ) ); + accounts << accountKey; + const QString lfmUsername = value( "lastfm/username" ).toString(); + const QString lfmPassword = value( "lastfm/password" ).toString(); + const bool scrobble = value( "lastfm/enablescrobbling", false ).toBool(); + beginGroup( "accounts/" + accountKey ); +// setValue( "enabled", false ); + setValue( "autoconnect", true ); + setValue( "types", QStringList() << "ResolverType" << "StatusPushType" ); + QVariantHash credentials; + credentials[ "username" ] = lfmUsername; + credentials[ "password" ] = lfmPassword; + credentials[ "session" ] = value( "lastfm/session" ).toString(); + setValue( "credentials", credentials ); + QVariantHash configuration; + configuration[ "scrobble" ] = scrobble; + setValue( "configuration", configuration ); + endGroup(); + + remove( "lastfm" ); + remove( "script/resolvers" ); remove( "script/loadedresolvers" ); @@ -892,62 +914,6 @@ TomahawkSettings::setExternalPort(int externalPort) } -QString -TomahawkSettings::lastFmPassword() const -{ - return value( "lastfm/password" ).toString(); -} - - -void -TomahawkSettings::setLastFmPassword( const QString& password ) -{ - setValue( "lastfm/password", password ); -} - - -QByteArray -TomahawkSettings::lastFmSessionKey() const -{ - return value( "lastfm/session" ).toByteArray(); -} - - -void -TomahawkSettings::setLastFmSessionKey( const QByteArray& key ) -{ - setValue( "lastfm/session", key ); -} - - -QString -TomahawkSettings::lastFmUsername() const -{ - return value( "lastfm/username" ).toString(); -} - - -void -TomahawkSettings::setLastFmUsername( const QString& username ) -{ - setValue( "lastfm/username", username ); -} - - -bool -TomahawkSettings::scrobblingEnabled() const -{ - return value( "lastfm/enablescrobbling", false ).toBool(); -} - - -void -TomahawkSettings::setScrobblingEnabled( bool enable ) -{ - setValue( "lastfm/enablescrobbling", enable ); -} - - QString TomahawkSettings::xmppBotServer() const { diff --git a/src/libtomahawk/tomahawksettings.h b/src/libtomahawk/tomahawksettings.h index e52c2b80f..52788b15c 100644 --- a/src/libtomahawk/tomahawksettings.h +++ b/src/libtomahawk/tomahawksettings.h @@ -165,19 +165,6 @@ public: QStringList aclEntries() const; void setAclEntries( const QStringList &entries ); - /// Last.fm settings - bool scrobblingEnabled() const; /// false by default - void setScrobblingEnabled( bool enable ); - - QString lastFmUsername() const; - void setLastFmUsername( const QString& username ); - - QString lastFmPassword() const; - void setLastFmPassword( const QString& password ); - - QByteArray lastFmSessionKey() const; - void setLastFmSessionKey( const QByteArray& key ); - /// XMPP Component Settings QString xmppBotServer() const; void setXmppBotServer( const QString &server ); diff --git a/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget_p.h b/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget_p.h index 91b673a6a..42adc2efe 100644 --- a/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget_p.h +++ b/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget_p.h @@ -87,11 +87,6 @@ public slots: } signals: - void repeatModeChanged( Tomahawk::PlaylistInterface::RepeatMode mode ); - void shuffleModeChanged( bool enabled ); - - void trackCountChanged( unsigned int tracks ); - void sourceTrackCountChanged( unsigned int tracks ); void nextTrackReady(); private slots: diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index f784f34ae..bcd2c997b 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -30,11 +30,6 @@ #include #include -#ifdef LIBLASTFM_FOUND -#include -#include -#endif - #include "AtticaManager.h" #include "tomahawkapp.h" #include "tomahawksettings.h" @@ -168,21 +163,11 @@ SettingsDialog::SettingsDialog( QWidget *parent ) } // NOW PLAYING -#ifdef Q_WS_MAC - ui->checkBoxEnableAdium->setChecked( s->nowPlayingEnabled() ); -#else - ui->checkBoxEnableAdium->hide(); -#endif - - // LAST FM - ui->checkBoxEnableLastfm->setChecked( s->scrobblingEnabled() ); - ui->lineEditLastfmUsername->setText( s->lastFmUsername() ); - ui->lineEditLastfmPassword->setText(s->lastFmPassword() ); - connect( ui->pushButtonTestLastfmLogin, SIGNAL( clicked( bool) ), SLOT( testLastFmLogin() ) ); - -#ifdef Q_WS_MAC // FIXME - ui->pushButtonTestLastfmLogin->setVisible( false ); -#endif +// #ifdef Q_WS_MAC +// ui->checkBoxEnableAdium->setChecked( s->nowPlayingEnabled() ); +// #else +// ui->checkBoxEnableAdium->hide(); +// #endif connect( ui->proxyButton, SIGNAL( clicked() ), SLOT( showProxySettings() ) ); connect( ui->checkBoxStaticPreferred, SIGNAL( toggled(bool) ), SLOT( toggleUpnp(bool) ) ); @@ -217,11 +202,7 @@ SettingsDialog::~SettingsDialog() s->setScannerTime( ui->scannerTimeSpinBox->value() ); s->setEnableEchonestCatalogs( ui->enableEchonestCatalog->isChecked() ); - s->setNowPlayingEnabled( ui->checkBoxEnableAdium->isChecked() ); - - s->setScrobblingEnabled( ui->checkBoxEnableLastfm->isChecked() ); - s->setLastFmUsername( ui->lineEditLastfmUsername->text() ); - s->setLastFmPassword( ui->lineEditLastfmPassword->text() ); +// s->setNowPlayingEnabled( ui->checkBoxEnableAdium->isChecked() ); s->applyChanges(); s->sync(); @@ -265,13 +246,6 @@ SettingsDialog::createIcons() musicButton->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled ); maxlen = qMax( fm.width( musicButton->text() ), maxlen ); - QListWidgetItem *lastfmButton = new QListWidgetItem( ui->listWidget ); - lastfmButton->setIcon( QIcon( RESPATH "images/lastfm-settings.png" ) ); - lastfmButton->setText( tr( "Last.fm" ) ); - lastfmButton->setTextAlignment( Qt::AlignHCenter ); - lastfmButton->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled ); - maxlen = qMax( fm.width( lastfmButton->text() ), maxlen ); - QListWidgetItem *advancedButton = new QListWidgetItem( ui->listWidget ); advancedButton->setIcon( QIcon( RESPATH "images/advanced-settings.png" ) ); advancedButton->setText( tr( "Advanced" ) ); @@ -282,7 +256,6 @@ SettingsDialog::createIcons() maxlen += 15; // padding accountsButton->setSizeHint( QSize( maxlen, 60 ) ); musicButton->setSizeHint( QSize( maxlen, 60 ) ); - lastfmButton->setSizeHint( QSize( maxlen, 60 ) ); advancedButton->setSizeHint( QSize( maxlen, 60 ) ); #ifndef Q_WS_MAC @@ -362,78 +335,6 @@ SettingsDialog::updateScanOptionsView() } -void -SettingsDialog::testLastFmLogin() -{ -#ifdef LIBLASTFM_FOUND - ui->pushButtonTestLastfmLogin->setEnabled( false ); - ui->pushButtonTestLastfmLogin->setText( "Testing..." ); - - QString authToken = TomahawkUtils::md5( ( ui->lineEditLastfmUsername->text().toLower() + TomahawkUtils::md5( ui->lineEditLastfmPassword->text().toUtf8() ) ).toUtf8() ); - - // now authenticate w/ last.fm and get our session key - QMap query; - query[ "method" ] = "auth.getMobileSession"; - query[ "username" ] = ui->lineEditLastfmUsername->text().toLower(); - query[ "authToken" ] = authToken; - - // ensure they have up-to-date settings - lastfm::setNetworkAccessManager( TomahawkUtils::nam() ); - - QNetworkReply* authJob = lastfm::ws::post( query ); - - connect( authJob, SIGNAL( finished() ), SLOT( onLastFmFinished() ) ); -#endif -} - - -void -SettingsDialog::onLastFmFinished() -{ -#ifdef LIBLASTFM_FOUND - QNetworkReply* authJob = dynamic_cast( sender() ); - if( !authJob ) - { - qDebug() << Q_FUNC_INFO << "No auth job returned!"; - return; - } - if( authJob->error() == QNetworkReply::NoError ) - { - lastfm::XmlQuery lfm = lastfm::XmlQuery( authJob->readAll() ); - - if( lfm.children( "error" ).size() > 0 ) - { - qDebug() << "ERROR from last.fm:" << lfm.text(); - ui->pushButtonTestLastfmLogin->setText( tr( "Failed" ) ); - ui->pushButtonTestLastfmLogin->setEnabled( true ); - } - else - { - ui->pushButtonTestLastfmLogin->setText( tr( "Success" ) ); - ui->pushButtonTestLastfmLogin->setEnabled( false ); - } - } - else - { - switch( authJob->error() ) - { - case QNetworkReply::ContentOperationNotPermittedError: - case QNetworkReply::AuthenticationRequiredError: - ui->pushButtonTestLastfmLogin->setText( tr( "Failed" ) ); - ui->pushButtonTestLastfmLogin->setEnabled( true ); - break; - - default: - qDebug() << "Couldn't get last.fm auth result"; - ui->pushButtonTestLastfmLogin->setText( tr( "Could not contact server" ) ); - ui->pushButtonTestLastfmLogin->setEnabled( true ); - return; - } - } -#endif -} - - void SettingsDialog::accountsFilterChanged( int ) { diff --git a/src/settingsdialog.h b/src/settingsdialog.h index dc61925d7..ca146efb3 100644 --- a/src/settingsdialog.h +++ b/src/settingsdialog.h @@ -86,9 +86,6 @@ private slots: void toggleUpnp( bool preferStaticEnabled ); void showProxySettings(); - void testLastFmLogin(); - void onLastFmFinished(); - void accountsFilterChanged( int ); void createAccountFromFactory( Tomahawk::Accounts::AccountFactory* ); diff --git a/src/stackedsettingsdialog.ui b/src/stackedsettingsdialog.ui index 78c36c9f5..ab707c2b5 100644 --- a/src/stackedsettingsdialog.ui +++ b/src/stackedsettingsdialog.ui @@ -85,7 +85,7 @@ - 0 + 2 @@ -98,6 +98,9 @@ Internet Sources + + 2 + @@ -221,119 +224,6 @@ - - - - 0 - - - - - Now Playing Information - - - - - - Applications to update with currently playing track: - - - - - - - - - - - Adium - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - Qt::LeftToRight - - - Scrobble tracks to Last.fm - - - - - - - - - Username: - - - - - - - - - - Password: - - - - - - - QLineEdit::Password - - - - - - - - - Test Login - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - @@ -582,4 +472,4 @@ -
+ \ No newline at end of file diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index aa59a8cb1..192256915 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -219,13 +219,13 @@ TomahawkApp::init() connect( m_shortcutHandler.data(), SIGNAL( mute() ), m_audioEngine.data(), SLOT( mute() ) ); } + tDebug() << "Init InfoSystem."; + m_infoSystem = QWeakPointer( Tomahawk::InfoSystem::InfoSystem::instance() ); + 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 ) ); - Echonest::Config::instance()->setNetworkAccessManager( TomahawkUtils::nam() ); #ifndef ENABLE_HEADLESS EchonestGenerator::setupCatalogs(); @@ -422,6 +422,7 @@ TomahawkApp::registerMetaTypes() qRegisterMetaType< Tomahawk::InfoSystem::InfoType >( "Tomahawk::InfoSystem::InfoType" ); qRegisterMetaType< Tomahawk::InfoSystem::InfoRequestData >( "Tomahawk::InfoSystem::InfoRequestData" ); qRegisterMetaType< Tomahawk::InfoSystem::InfoSystemCache* >( "Tomahawk::InfoSystem::InfoSystemCache*" ); + qRegisterMetaType< Tomahawk::InfoSystem::InfoPlugin* >( "Tomahawk::InfoSystem::InfoPlugin*" ); qRegisterMetaType< QList< Tomahawk::InfoSystem::InfoStringHash > >("QList< Tomahawk::InfoSystem::InfoStringHash > "); qRegisterMetaTypeStreamOperators< QList< Tomahawk::InfoSystem::InfoStringHash > >("QList< Tomahawk::InfoSystem::InfoStringHash > "); From 502db675107e441a9c25c8e9f8ebc36f90bd36f2 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Mon, 20 Feb 2012 15:45:43 -0500 Subject: [PATCH 091/104] don't crash on exit --- src/libtomahawk/accounts/LastFmAccount.cpp | 8 ++++---- src/libtomahawk/accounts/LastFmAccount.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libtomahawk/accounts/LastFmAccount.cpp b/src/libtomahawk/accounts/LastFmAccount.cpp index 4e97fcb95..758130fb2 100644 --- a/src/libtomahawk/accounts/LastFmAccount.cpp +++ b/src/libtomahawk/accounts/LastFmAccount.cpp @@ -51,7 +51,7 @@ LastFmAccountFactory::icon() const LastFmAccount::LastFmAccount( const QString& accountId ) : Account( accountId ) { - m_infoPlugin = new LastFmPlugin( this ); + m_infoPlugin = QWeakPointer< LastFmPlugin >( new LastFmPlugin( this ) ); setAccountFriendlyName( "Last.Fm" ); m_icon.load( RESPATH "images/lastfm-icon.png" ); @@ -60,7 +60,7 @@ LastFmAccount::LastFmAccount( const QString& accountId ) LastFmAccount::~LastFmAccount() { - delete m_infoPlugin; + delete m_infoPlugin.data(); delete m_resolver.data(); } @@ -106,7 +106,7 @@ LastFmAccount::icon() const InfoPlugin* LastFmAccount::infoPlugin() { - return m_infoPlugin; + return m_infoPlugin.data(); } bool @@ -126,7 +126,7 @@ LastFmAccount::saveConfig() setScrobble( m_configWidget.data()->scrobble() ); } - m_infoPlugin->settingsChanged(); + m_infoPlugin.data()->settingsChanged(); } diff --git a/src/libtomahawk/accounts/LastFmAccount.h b/src/libtomahawk/accounts/LastFmAccount.h index 1ab607be4..0dc9d4c79 100644 --- a/src/libtomahawk/accounts/LastFmAccount.h +++ b/src/libtomahawk/accounts/LastFmAccount.h @@ -91,7 +91,7 @@ public: private: bool m_authenticated; QWeakPointer m_resolver; - Tomahawk::InfoSystem::LastFmPlugin* m_infoPlugin; + QWeakPointer m_infoPlugin; QWeakPointer m_configWidget; QPixmap m_icon; }; From 61b55ab156f47ffd01ed8ab4df2ebe032c9e201b Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Mon, 13 Feb 2012 21:34:02 -0500 Subject: [PATCH 092/104] shrink spacing --- src/stackedsettingsdialog.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stackedsettingsdialog.ui b/src/stackedsettingsdialog.ui index ab707c2b5..dacee0c24 100644 --- a/src/stackedsettingsdialog.ui +++ b/src/stackedsettingsdialog.ui @@ -472,4 +472,4 @@ - \ No newline at end of file + From 01fbbb6683edbf1833ea02f302f94f1b8c85b5ee Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Mon, 20 Feb 2012 18:00:21 -0500 Subject: [PATCH 093/104] osx button size tweaks --- src/AccountDelegate.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/AccountDelegate.cpp b/src/AccountDelegate.cpp index 6fdb22e0f..4af815b76 100644 --- a/src/AccountDelegate.cpp +++ b/src/AccountDelegate.cpp @@ -205,6 +205,9 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, painter->restore(); btnRect = QRect( opt.rect.right() - PADDING - btnWidth, opt.rect.bottom() - installMetrics.height() - 3*PADDING, btnWidth, installMetrics.height() + 2*PADDING ); +#ifdef Q_WS_MAC + btnRect.adjust( -4, 0, 4, 0 ); +#endif } leftEdge = btnRect.left(); @@ -242,6 +245,9 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, else btnRect = QRect( opt.rect.right() - PADDING - btnWidth, center - ( installMetrics.height() + 4 ) / 2, btnWidth, installMetrics.height() + 2*PADDING ); +#ifdef Q_WS_MAC + btnRect.adjust( -4, 2, 4, -2 ); +#endif leftEdge = btnRect.left(); m_cachedButtonRects[ index ] = btnRect; From 27cde20dbf669306a1b790cab8bf0f27ae6eb164 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Mon, 20 Feb 2012 23:06:49 -0500 Subject: [PATCH 094/104] Fix Add Account button in factory config on OSX, and a few other osx tweaks --- src/AccountFactoryWrapper.cpp | 1 - src/libtomahawk/accounts/LastFmConfig.ui | 5 ++++- src/settingsdialog.cpp | 7 +++++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/AccountFactoryWrapper.cpp b/src/AccountFactoryWrapper.cpp index 0bf60f634..f5f270b06 100644 --- a/src/AccountFactoryWrapper.cpp +++ b/src/AccountFactoryWrapper.cpp @@ -141,7 +141,6 @@ AccountFactoryWrapper::buttonClicked( QAbstractButton* button ) { m_createAccount = true; emit createAccount( m_factory ); -// accept(); return; } else diff --git a/src/libtomahawk/accounts/LastFmConfig.ui b/src/libtomahawk/accounts/LastFmConfig.ui index c0a0ece12..5cdf0e5e8 100644 --- a/src/libtomahawk/accounts/LastFmConfig.ui +++ b/src/libtomahawk/accounts/LastFmConfig.ui @@ -7,13 +7,16 @@ 0 0 400 - 178 + 220 Form + + 4 + diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index bcd2c997b..ddd954efa 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -437,6 +437,13 @@ SettingsDialog::openAccountFactoryConfig( AccountFactory* factory ) void SettingsDialog::createAccountFromFactory( AccountFactory* factory ) { +#ifdef Q_WS_MAC + // On mac we need to close the dialog we came from before showing another dialog + Q_ASSERT( sender() && qobject_cast< AccountFactoryWrapper* >( sender() ) ); + AccountFactoryWrapper* dialog = qobject_cast< AccountFactoryWrapper* >( sender() ); + dialog->accept(); +#endif + //if exited with OK, create it, if not, delete it immediately! Account* account = factory->createAccount(); bool added = false; From d0b6d092553de7b19be5f9e226601310b3363504 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Thu, 23 Feb 2012 23:35:26 -0600 Subject: [PATCH 095/104] Add first round of integration for custom attica accounts --- src/libtomahawk/AtticaManager.cpp | 45 ++++++++++++++-- src/libtomahawk/AtticaManager.h | 20 ++++++- src/libtomahawk/accounts/AccountModel.cpp | 24 ++++++--- src/libtomahawk/accounts/LastFmAccount.cpp | 61 ++++++++++++++++++++++ src/libtomahawk/accounts/LastFmAccount.h | 12 +++-- src/libtomahawk/tomahawksettings.cpp | 2 +- 6 files changed, 148 insertions(+), 16 deletions(-) diff --git a/src/libtomahawk/AtticaManager.cpp b/src/libtomahawk/AtticaManager.cpp index b2b56ff92..bdfbeb770 100644 --- a/src/libtomahawk/AtticaManager.cpp +++ b/src/libtomahawk/AtticaManager.cpp @@ -202,6 +202,38 @@ AtticaManager::userHasRated( const Content& c ) const } +bool +AtticaManager::hasCustomAccountForAttica( const QString &id ) const +{ + // Only last.fm at the moment contains a custom account + if ( id == "lastfm" ) + return true; + + return false; +} + + +Tomahawk::Accounts::Account* +AtticaManager::customAccountForAttica( const QString &id ) const +{ + return m_customAccounts.value( id ); +} + + +void +AtticaManager::registerCustomAccount( const QString &atticaId, Tomahawk::Accounts::Account *account ) +{ + m_customAccounts.insert( atticaId, account ); +} + + +AtticaManager::Resolver +AtticaManager::resolverData(const QString &atticaId) const +{ + return m_resolverStates.value( atticaId ); +} + + void AtticaManager::providerAdded( const Provider& provider ) { @@ -324,7 +356,7 @@ AtticaManager::syncServerData() void -AtticaManager::installResolver( const Content& resolver ) +AtticaManager::installResolver( const Content& resolver, bool autoCreateAccount ) { Q_ASSERT( !resolver.id().isNull() ); @@ -338,6 +370,7 @@ AtticaManager::installResolver( const Content& resolver ) ItemJob< DownloadItem >* job = m_resolverProvider.downloadLink( resolver.id() ); connect( job, SIGNAL( finished( Attica::BaseJob* ) ), this, SLOT( resolverDownloadFinished( Attica::BaseJob* ) ) ); job->setProperty( "resolverId", resolver.id() ); + job->setProperty( "createAccount", autoCreateAccount ); job->start(); } @@ -373,6 +406,7 @@ AtticaManager::resolverDownloadFinished ( BaseJob* j ) QNetworkReply* reply = TomahawkUtils::nam()->get( QNetworkRequest( url ) ); connect( reply, SIGNAL( finished() ), this, SLOT( payloadFetched() ) ); reply->setProperty( "resolverId", job->property( "resolverId" ) ); + reply->setProperty( "createAccount", job->property( "createAccount" ) ); } else { @@ -408,9 +442,12 @@ AtticaManager::payloadFetched() // update with absolute, not relative, path m_resolverStates[ resolverId ].scriptPath = resolverPath; - // Do the install / add to tomahawk - Tomahawk::Accounts::Account* resolver = Tomahawk::Accounts::ResolverAccountFactory::createFromPath( resolverPath, true ); - Tomahawk::Accounts::AccountManager::instance()->addAccount( resolver ); + if ( reply->property( "createAccount" ).toBool() ) + { + // Do the install / add to tomahawk + Tomahawk::Accounts::Account* resolver = Tomahawk::Accounts::ResolverAccountFactory::createFromPath( resolverPath, true ); + Tomahawk::Accounts::AccountManager::instance()->addAccount( resolver ); + } m_resolverStates[ resolverId ].state = Installed; TomahawkSettingsGui::instanceGui()->setAtticaResolverStates( m_resolverStates ); diff --git a/src/libtomahawk/AtticaManager.h b/src/libtomahawk/AtticaManager.h index 3876583ed..0b6fcfef6 100644 --- a/src/libtomahawk/AtticaManager.h +++ b/src/libtomahawk/AtticaManager.h @@ -31,6 +31,12 @@ #include #include +namespace Tomahawk { +namespace Accounts { +class Account; +} +} + class DLLEXPORT AtticaManager : public QObject { Q_OBJECT @@ -83,8 +89,18 @@ public: void uploadRating( const Attica::Content& c ); bool userHasRated( const Attica::Content& c ) const; + /** + If the resolver coming from libattica has a native custom c++ account + as well. For example the last.fm account. + */ + bool hasCustomAccountForAttica( const QString& id ) const; + Tomahawk::Accounts::Account* customAccountForAttica( const QString& id ) const; + void registerCustomAccount( const QString& atticaId, Tomahawk::Accounts::Account* account ); + + AtticaManager::Resolver resolverData( const QString& atticaId ) const; + public slots: - void installResolver( const Attica::Content& resolver ); + void installResolver( const Attica::Content& resolver, bool autoCreateAccount = true ); void upgradeResolver( const Attica::Content& resolver ); signals: @@ -116,6 +132,8 @@ private: Attica::Content::List m_resolvers; StateHash m_resolverStates; + QMap< QString, Tomahawk::Accounts::Account* > m_customAccounts; + static AtticaManager* s_instance; }; diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index 6457c8837..17c1a14b6 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -73,15 +73,23 @@ AccountModel::loadData() foreach ( const Attica::Content& content, fromAttica ) { qDebug() << "Loading ATTICA ACCOUNT with content:" << content.id() << content.name(); - m_accounts << new AccountModelNode( content ); - - foreach ( Account* acct, AccountManager::instance()->accounts( Accounts::ResolverType ) ) + if ( AtticaManager::instance()->hasCustomAccountForAttica( content.id() ) ) { - if ( AtticaResolverAccount* resolver = qobject_cast< AtticaResolverAccount* >( acct ) ) + Account* acct = AtticaManager::instance()->customAccountForAttica( content.id() ); + m_accounts << new AccountModelNode( acct ); + allAccounts.removeAll( acct ); + } else + { + m_accounts << new AccountModelNode( content ); + + foreach ( Account* acct, AccountManager::instance()->accounts( Accounts::ResolverType ) ) { - if ( resolver->atticaId() == content.id() ) + if ( AtticaResolverAccount* resolver = qobject_cast< AtticaResolverAccount* >( acct ) ) { - allAccounts.removeAll( acct ); + if ( resolver->atticaId() == content.id() ) + { + allAccounts.removeAll( acct ); + } } } } @@ -90,6 +98,8 @@ AccountModel::loadData() // All other accounts we haven't dealt with yet foreach ( Account* acct, allAccounts ) { + Q_ASSERT( !qobject_cast< AtticaResolverAccount* >( acct ) ); // This should be caught above in the attica list + if ( qobject_cast< ResolverAccount* >( acct ) && !qobject_cast< AtticaResolverAccount* >( acct ) ) m_accounts << new AccountModelNode( qobject_cast< ResolverAccount* >( acct ) ); else @@ -326,7 +336,7 @@ AccountModel::data( const QModelIndex& index, int role ) const case AccountTypeRole: return QVariant::fromValue< AccountTypes >( account->types() ); case Qt::CheckStateRole: - return account->enabled(); + return account->enabled() ? Qt::Checked : Qt::Unchecked; case ConnectionStateRole: return account->connectionState(); default: diff --git a/src/libtomahawk/accounts/LastFmAccount.cpp b/src/libtomahawk/accounts/LastFmAccount.cpp index 758130fb2..fae2f3132 100644 --- a/src/libtomahawk/accounts/LastFmAccount.cpp +++ b/src/libtomahawk/accounts/LastFmAccount.cpp @@ -23,6 +23,9 @@ #include "infosystem/infoplugins/generic/lastfmplugin.h" #include "utils/tomahawkutils.h" #include "resolvers/qtscriptresolver.h" +#include "AtticaManager.h" +#include "pipeline.h" +#include "accounts/AccountManager.h" using namespace Tomahawk; using namespace InfoSystem; @@ -55,6 +58,18 @@ LastFmAccount::LastFmAccount( const QString& accountId ) setAccountFriendlyName( "Last.Fm" ); m_icon.load( RESPATH "images/lastfm-icon.png" ); + + AtticaManager::instance()->registerCustomAccount( "lastfm", this ); + + connect( AtticaManager::instance(), SIGNAL( resolverInstalled( QString ) ), this, SLOT( resolverInstalled( QString ) ) ); + + const Attica::Content res = AtticaManager::instance()->resolverForId( "lastfm" ); + const AtticaManager::ResolverState state = AtticaManager::instance()->resolverState( res ); + + if ( state == AtticaManager::Installed ) + { + hookupResolver(); + } } @@ -68,14 +83,28 @@ LastFmAccount::~LastFmAccount() void LastFmAccount::authenticate() { + const Attica::Content res = AtticaManager::instance()->resolverForId( "lastfm" ); + const AtticaManager::ResolverState state = AtticaManager::instance()->resolverState( res ); + if ( state == AtticaManager::Installed ) + { + hookupResolver(); + } else + { + AtticaManager::instance()->installResolver( res, false ); + } + + emit connectionStateChanged( connectionState() ); } void LastFmAccount::deauthenticate() { + if ( m_resolver.data()->running() ) + m_resolver.data()->stop(); + emit connectionStateChanged( connectionState() ); } @@ -192,3 +221,35 @@ LastFmAccount::setScrobble( bool scrobble ) setConfiguration( conf ); } + +void +LastFmAccount::resolverInstalled( const QString &resolverId ) +{ + if ( resolverId == "lastfm" ) + { + // We requested this install, so we want to launch it + hookupResolver(); + AccountManager::instance()->enableAccount( this ); + } +} + +void +LastFmAccount::resolverChanged() +{ + emit connectionStateChanged( connectionState() ); +} + + +void +LastFmAccount::hookupResolver() +{ + // If there is a last.fm resolver from attica installed, create the corresponding ExternalResolver* and hook up to it + const Attica::Content res = AtticaManager::instance()->resolverForId( "lastfm" ); + const AtticaManager::ResolverState state = AtticaManager::instance()->resolverState( res ); + Q_ASSERT( state == AtticaManager::Installed ); + + const AtticaManager::Resolver data = AtticaManager::instance()->resolverData( res.id() ); + + m_resolver = QWeakPointer< ExternalResolverGui >( qobject_cast< ExternalResolverGui* >( Pipeline::instance()->addScriptResolver( data.scriptPath, enabled() ) ) ); + connect( m_resolver.data(), SIGNAL( changed() ), this, SLOT( resolverChanged() ) ); +} diff --git a/src/libtomahawk/accounts/LastFmAccount.h b/src/libtomahawk/accounts/LastFmAccount.h index 0dc9d4c79..015afce8e 100644 --- a/src/libtomahawk/accounts/LastFmAccount.h +++ b/src/libtomahawk/accounts/LastFmAccount.h @@ -23,9 +23,9 @@ #include -class QtScriptResolver; - namespace Tomahawk { +class ExternalResolverGui; + namespace InfoSystem { class LastFmPlugin; } @@ -88,9 +88,15 @@ public: bool scrobble() const; void setScrobble( bool scrobble ); +private slots: + void resolverInstalled( const QString& resolverId ); + + void resolverChanged(); private: + void hookupResolver(); + bool m_authenticated; - QWeakPointer m_resolver; + QWeakPointer m_resolver; QWeakPointer m_infoPlugin; QWeakPointer m_configWidget; QPixmap m_icon; diff --git a/src/libtomahawk/tomahawksettings.cpp b/src/libtomahawk/tomahawksettings.cpp index 21ca03c00..aa9baa5eb 100644 --- a/src/libtomahawk/tomahawksettings.cpp +++ b/src/libtomahawk/tomahawksettings.cpp @@ -303,7 +303,7 @@ TomahawkSettings::doUpgrade( int oldVersion, int newVersion ) const QString lfmPassword = value( "lastfm/password" ).toString(); const bool scrobble = value( "lastfm/enablescrobbling", false ).toBool(); beginGroup( "accounts/" + accountKey ); -// setValue( "enabled", false ); + setValue( "enabled", enabledResolvers.contains( "lastfm" ) == true ); setValue( "autoconnect", true ); setValue( "types", QStringList() << "ResolverType" << "StatusPushType" ); QVariantHash credentials; From ac42abda7ffd9dd92e064146b4aa210a6cf9e571 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 24 Feb 2012 10:46:46 -0600 Subject: [PATCH 096/104] Add a last.fm account on fresh config --- src/libtomahawk/accounts/AccountModel.cpp | 8 ++++++-- src/libtomahawk/tomahawksettings.cpp | 10 ++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index 17c1a14b6..4b7f66aad 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -76,8 +76,12 @@ AccountModel::loadData() if ( AtticaManager::instance()->hasCustomAccountForAttica( content.id() ) ) { Account* acct = AtticaManager::instance()->customAccountForAttica( content.id() ); - m_accounts << new AccountModelNode( acct ); - allAccounts.removeAll( acct ); + Q_ASSERT( acct ); + if ( acct ) + { + m_accounts << new AccountModelNode( acct ); + allAccounts.removeAll( acct ); + } } else { m_accounts << new AccountModelNode( content ); diff --git a/src/libtomahawk/tomahawksettings.cpp b/src/libtomahawk/tomahawksettings.cpp index aa9baa5eb..11f45aa03 100644 --- a/src/libtomahawk/tomahawksettings.cpp +++ b/src/libtomahawk/tomahawksettings.cpp @@ -82,6 +82,16 @@ TomahawkSettings::doInitialSetup() { // by default we add a local network resolver addAccount( "sipzeroconf_autocreated" ); + + // Add a last.fm account for scrobbling and infosystem + const QString accountKey = QString( "lastfmaccount_%1" ).arg( QUuid::createUuid().toString().mid( 1, 8 ) ); + addAccount( accountKey ); + + beginGroup( "accounts/" + accountKey ); + setValue( "enabled", false ); + setValue( "autoconnect", true ); + setValue( "types", QStringList() << "ResolverType" << "StatusPushType" ); + endGroup(); } From 55d7fe9e53edeaebe8706a065a19a0b47c83caf4 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 24 Feb 2012 11:00:36 -0600 Subject: [PATCH 097/104] Remove debugging aid --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 4ad4ca4d4..f25a34a58 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -124,7 +124,7 @@ main( int argc, char *argv[] ) #endif #ifndef ENABLE_HEADLESS - // new BreakPad( QDir::tempPath(), TomahawkSettings::instance()->crashReporterEnabled() ); + new BreakPad( QDir::tempPath(), TomahawkSettings::instance()->crashReporterEnabled() ); #endif KDSingleApplicationGuard guard( &a, KDSingleApplicationGuard::AutoKillOtherInstances ); From b51480f122a376681413e12defe5d828b62f3cad Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 24 Feb 2012 11:30:22 -0600 Subject: [PATCH 098/104] Fix unchecking of unique factories --- src/libtomahawk/accounts/AccountModel.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index 4b7f66aad..8f3869378 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -368,15 +368,22 @@ AccountModel::setData( const QModelIndex& index, const QVariant& value, int role switch ( node->type ) { case AccountModelNode::UniqueFactoryType: - if ( node->accounts.isEmpty() ) + { + const Qt::CheckState state = static_cast< Qt::CheckState >( value.toInt() ); + if ( node->accounts.isEmpty() && state == Qt::Checked ) { // No account for this unique factory, create it // Don't add it to node->accounts here, slot attached to accountmanager::accountcreated will do it for us acct = node->factory->createAccount(); AccountManager::instance()->addAccount( acct ); TomahawkSettings::instance()->addAccount( acct->accountId() ); + } else if ( !node->accounts.isEmpty() ) + { + Q_ASSERT( node->accounts.size() == 1 ); + acct = node->accounts.first(); } break; + } case AccountModelNode::AtticaType: { // This may or may not be installed. if it's not installed yet, install it, then go ahead and enable it From ea47a5556d3d6301a2900c177f3f28c6aa8c0392 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 24 Feb 2012 16:49:14 -0600 Subject: [PATCH 099/104] better assert --- src/libtomahawk/accounts/AccountModel.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index 8f3869378..ad3c93d8e 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -370,8 +370,9 @@ AccountModel::setData( const QModelIndex& index, const QVariant& value, int role case AccountModelNode::UniqueFactoryType: { const Qt::CheckState state = static_cast< Qt::CheckState >( value.toInt() ); - if ( node->accounts.isEmpty() && state == Qt::Checked ) + if ( node->accounts.isEmpty() ) { + Q_ASSERT( state == Qt::Checked ); // How could we have a checked unique factory w/ no account?? // No account for this unique factory, create it // Don't add it to node->accounts here, slot attached to accountmanager::accountcreated will do it for us acct = node->factory->createAccount(); From b2247febc1f89cdcc38bf322434c51e59be7cf67 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 24 Feb 2012 18:52:16 -0600 Subject: [PATCH 100/104] Fix last.fm rsolver part of lastfm account --- src/libtomahawk/AtticaManager.h | 19 ++++++++++++----- src/libtomahawk/accounts/AccountManager.cpp | 4 +--- src/libtomahawk/accounts/AccountModel.cpp | 19 ++++++++++++++--- src/libtomahawk/accounts/AccountModelNode.h | 4 ++++ src/libtomahawk/accounts/LastFmAccount.cpp | 23 ++++++++++++++++----- src/libtomahawk/accounts/LastFmAccount.h | 8 +++++-- 6 files changed, 59 insertions(+), 18 deletions(-) diff --git a/src/libtomahawk/AtticaManager.h b/src/libtomahawk/AtticaManager.h index 0b6fcfef6..62ba665e8 100644 --- a/src/libtomahawk/AtticaManager.h +++ b/src/libtomahawk/AtticaManager.h @@ -26,16 +26,12 @@ #include #include "dllmacro.h" +#include "accounts/Account.h" #include #include #include -namespace Tomahawk { -namespace Accounts { -class Account; -} -} class DLLEXPORT AtticaManager : public QObject { @@ -137,6 +133,19 @@ private: static AtticaManager* s_instance; }; +class DLLEXPORT CustomAtticaAccount : public Tomahawk::Accounts::Account +{ + Q_OBJECT +public: + virtual ~CustomAtticaAccount() {} + + virtual Attica::Content atticaContent() const = 0; + +protected: + // No, you can't. + CustomAtticaAccount( const QString& id ) : Tomahawk::Accounts::Account( id ) {} +}; + Q_DECLARE_METATYPE( Attica::Content ); #endif // ATTICAMANAGER_H diff --git a/src/libtomahawk/accounts/AccountManager.cpp b/src/libtomahawk/accounts/AccountManager.cpp index 6c5715113..bef708937 100644 --- a/src/libtomahawk/accounts/AccountManager.cpp +++ b/src/libtomahawk/accounts/AccountManager.cpp @@ -215,8 +215,6 @@ AccountManager::connectAll() { acc->authenticate(); m_enabledAccounts << acc; -// if ( acc->types() & Accounts::SipType && acc->sipPlugin() ) -// acc->sipPlugin()->connectPlugin(); } m_connected = true; @@ -409,4 +407,4 @@ AccountManager::onStateChanged( Account::ConnectionState state ) }; -}; \ No newline at end of file +}; diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index ad3c93d8e..32748ecac 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -318,6 +318,12 @@ AccountModel::data( const QModelIndex& index, int role ) const Q_ASSERT( node->factory ); Account* account = node->customAccount; + // This is sort of ugly. CustomAccounts are pure Account*, but we know that + // some might also be linked to attica resolvers (not always). If that is the case + // they have a Attica::Content set on the node, so we use that to display some + // extra metadata and rating + const bool hasAttica = !node->atticaContent.id().isEmpty(); + switch ( role ) { case Qt::DisplayRole: @@ -328,9 +334,15 @@ AccountModel::data( const QModelIndex& index, int role ) const return ShippedWithTomahawk; case Qt::ToolTipRole: case DescriptionRole: - return node->factory->description(); + return hasAttica ? node->atticaContent.description() : node->factory->description(); case CanRateRole: - return false; + return hasAttica; + case AuthorRole: + return hasAttica ? node->atticaContent.author() : QString(); + case RatingRole: + return hasAttica ? node->atticaContent.rating() / 20 : 0; // rating is out of 100 + case DownloadCounterRole: + return hasAttica ? node->atticaContent.downloads() : QVariant(); case RowTypeRole: return CustomAccount; case AccountData: @@ -378,7 +390,8 @@ AccountModel::setData( const QModelIndex& index, const QVariant& value, int role acct = node->factory->createAccount(); AccountManager::instance()->addAccount( acct ); TomahawkSettings::instance()->addAccount( acct->accountId() ); - } else if ( !node->accounts.isEmpty() ) + } + else { Q_ASSERT( node->accounts.size() == 1 ); acct = node->accounts.first(); diff --git a/src/libtomahawk/accounts/AccountModelNode.h b/src/libtomahawk/accounts/AccountModelNode.h index 795e17b6f..042d913cf 100644 --- a/src/libtomahawk/accounts/AccountModelNode.h +++ b/src/libtomahawk/accounts/AccountModelNode.h @@ -22,6 +22,7 @@ #include "Account.h" #include "AccountManager.h" #include "ResolverAccount.h" +#include "AtticaManager.h" #include @@ -124,6 +125,9 @@ struct AccountModelNode { init(); customAccount = account; factory = AccountManager::instance()->factoryForAccount( account ); + + if ( CustomAtticaAccount* customAtticaAccount = qobject_cast< CustomAtticaAccount* >( account ) ) + atticaContent = customAtticaAccount->atticaContent(); } void init() diff --git a/src/libtomahawk/accounts/LastFmAccount.cpp b/src/libtomahawk/accounts/LastFmAccount.cpp index fae2f3132..b22cafd9c 100644 --- a/src/libtomahawk/accounts/LastFmAccount.cpp +++ b/src/libtomahawk/accounts/LastFmAccount.cpp @@ -52,7 +52,7 @@ LastFmAccountFactory::icon() const LastFmAccount::LastFmAccount( const QString& accountId ) - : Account( accountId ) + : CustomAtticaAccount( accountId ) { m_infoPlugin = QWeakPointer< LastFmPlugin >( new LastFmPlugin( this ) ); @@ -86,13 +86,19 @@ LastFmAccount::authenticate() const Attica::Content res = AtticaManager::instance()->resolverForId( "lastfm" ); const AtticaManager::ResolverState state = AtticaManager::instance()->resolverState( res ); - if ( state == AtticaManager::Installed ) + qDebug() << "Last.FM account authenticating..."; + if ( m_resolver.isNull() && state == AtticaManager::Installed ) { hookupResolver(); - } else + } + else if ( m_resolver.isNull() ) { AtticaManager::instance()->installResolver( res, false ); } + else + { + m_resolver.data()->start(); + } emit connectionStateChanged( connectionState() ); } @@ -121,7 +127,7 @@ LastFmAccount::configurationWidget() Account::ConnectionState LastFmAccount::connectionState() const { - return m_authenticated ? Account::Connected : Account::Disconnected; + return m_resolver.data()->running() ? Account::Connected : Account::Disconnected; } @@ -141,7 +147,7 @@ LastFmAccount::infoPlugin() bool LastFmAccount::isAuthenticated() const { - return m_authenticated; + return !m_resolver.isNull() && m_resolver.data()->running(); } @@ -253,3 +259,10 @@ LastFmAccount::hookupResolver() m_resolver = QWeakPointer< ExternalResolverGui >( qobject_cast< ExternalResolverGui* >( Pipeline::instance()->addScriptResolver( data.scriptPath, enabled() ) ) ); connect( m_resolver.data(), SIGNAL( changed() ), this, SLOT( resolverChanged() ) ); } + + +Attica::Content +LastFmAccount::atticaContent() const +{ + return AtticaManager::instance()->resolverForId( "lastfm" ); +} diff --git a/src/libtomahawk/accounts/LastFmAccount.h b/src/libtomahawk/accounts/LastFmAccount.h index 015afce8e..3e7aaf651 100644 --- a/src/libtomahawk/accounts/LastFmAccount.h +++ b/src/libtomahawk/accounts/LastFmAccount.h @@ -20,6 +20,9 @@ #define LASTFMACCOUNT_H #include "accounts/Account.h" +#include "AtticaManager.h" + +#include #include @@ -58,7 +61,7 @@ private: * but the user can install the attica resolver on-demand. So we take care of both there. * */ -class LastFmAccount : public Account +class LastFmAccount : public CustomAtticaAccount { Q_OBJECT public: @@ -88,6 +91,8 @@ public: bool scrobble() const; void setScrobble( bool scrobble ); + Attica::Content atticaContent() const; + private slots: void resolverInstalled( const QString& resolverId ); @@ -95,7 +100,6 @@ private slots: private: void hookupResolver(); - bool m_authenticated; QWeakPointer m_resolver; QWeakPointer m_infoPlugin; QWeakPointer m_configWidget; From 540db2860e811dce0b5366a548e20697410f5ad8 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sat, 25 Feb 2012 11:59:47 -0500 Subject: [PATCH 101/104] fix a crash --- src/libtomahawk/accounts/LastFmAccount.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libtomahawk/accounts/LastFmAccount.cpp b/src/libtomahawk/accounts/LastFmAccount.cpp index b22cafd9c..f4ade6a5f 100644 --- a/src/libtomahawk/accounts/LastFmAccount.cpp +++ b/src/libtomahawk/accounts/LastFmAccount.cpp @@ -127,7 +127,7 @@ LastFmAccount::configurationWidget() Account::ConnectionState LastFmAccount::connectionState() const { - return m_resolver.data()->running() ? Account::Connected : Account::Disconnected; + return (!m_resolver.isNull() && m_resolver.data()->running()) ? Account::Connected : Account::Disconnected; } From 91546d0684bbdf4f7ceaf8a2700500e809e57a21 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Mon, 27 Feb 2012 19:48:47 -0500 Subject: [PATCH 102/104] Fix some bugs in ze last.fm account --- src/libtomahawk/accounts/Account.cpp | 2 +- src/libtomahawk/accounts/LastFmAccount.cpp | 6 +++--- .../infosystem/infoplugins/generic/lastfmplugin.cpp | 10 +++++----- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/libtomahawk/accounts/Account.cpp b/src/libtomahawk/accounts/Account.cpp index 6fdaf8315..baeda84bc 100644 --- a/src/libtomahawk/accounts/Account.cpp +++ b/src/libtomahawk/accounts/Account.cpp @@ -192,7 +192,7 @@ Account::types() const types |= SipType; if ( m_types.contains( "ResolverType" ) ) types |= ResolverType; - if ( m_types.contains( "StatusPushTypeType" ) ) + if ( m_types.contains( "StatusPushType" ) ) types |= StatusPushType; return types; diff --git a/src/libtomahawk/accounts/LastFmAccount.cpp b/src/libtomahawk/accounts/LastFmAccount.cpp index f4ade6a5f..2b61666ee 100644 --- a/src/libtomahawk/accounts/LastFmAccount.cpp +++ b/src/libtomahawk/accounts/LastFmAccount.cpp @@ -175,7 +175,7 @@ LastFmAccount::password() const void LastFmAccount::setPassword( const QString& password ) { - QVariantHash creds; + QVariantHash creds = credentials(); creds[ "password" ] = password; setCredentials( creds ); } @@ -190,7 +190,7 @@ LastFmAccount::sessionKey() const void LastFmAccount::setSessionKey( const QString& sessionkey ) { - QVariantHash creds; + QVariantHash creds = credentials(); creds[ "sessionkey" ] = sessionkey; setCredentials( creds ); } @@ -206,7 +206,7 @@ LastFmAccount::username() const void LastFmAccount::setUsername( const QString& username ) { - QVariantHash creds; + QVariantHash creds = credentials(); creds[ "username" ] = username; setCredentials( creds ); } diff --git a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp index f55456a65..0b9caa4f6 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp @@ -706,14 +706,14 @@ LastFmPlugin::artistImagesReturned() void LastFmPlugin::settingsChanged() { - if ( !m_scrobbler && m_account->enabled() ) + if ( !m_scrobbler && m_account->scrobble() ) { // can simply create the scrobbler - lastfm::ws::Username = m_account->username(); - m_pw = m_account->password(); + lastfm::ws::Username = m_account->username(); + m_pw = m_account->password(); createScrobbler(); } - else if ( m_scrobbler && !m_account->enabled() ) + else if ( m_scrobbler && !m_account->scrobble() ) { delete m_scrobbler; m_scrobbler = 0; @@ -761,7 +761,7 @@ LastFmPlugin::onAuthenticated() m_account->setSessionKey( lastfm::ws::SessionKey.toLatin1() ); // qDebug() << "Got session key from last.fm"; - if ( m_account->enabled() ) + if ( m_account->scrobble() ) m_scrobbler = new lastfm::Audioscrobbler( "thk" ); } } From 91e307b261149cca163b30a08291a04897f1faa2 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Mon, 27 Feb 2012 19:48:56 -0500 Subject: [PATCH 103/104] fix duplicate delete --- src/tomahawkapp.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index c5194ff26..669a3383d 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -309,9 +309,6 @@ TomahawkApp::~TomahawkApp() if ( !m_audioEngine.isNull() ) delete m_audioEngine.data(); - if ( !m_infoSystem.isNull() ) - delete m_infoSystem.data(); - delete Tomahawk::Accounts::AccountManager::instance(); #ifndef ENABLE_HEADLESS From 28785522392442bb54b7910ea65630fcc876ec38 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 2 Mar 2012 16:23:45 -0500 Subject: [PATCH 104/104] Fix various bugs in attica<->account bridge and bump config version --- src/libtomahawk/AtticaManager.cpp | 1 + src/libtomahawk/accounts/Account.cpp | 7 +++++++ src/libtomahawk/accounts/Account.h | 2 +- src/libtomahawk/accounts/AccountModel.cpp | 6 ++++++ src/libtomahawk/accounts/ResolverAccount.cpp | 6 +++++- src/libtomahawk/tomahawksettings.cpp | 2 +- src/libtomahawk/tomahawksettings.h | 2 +- 7 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/libtomahawk/AtticaManager.cpp b/src/libtomahawk/AtticaManager.cpp index 03af93824..f532c4e37 100644 --- a/src/libtomahawk/AtticaManager.cpp +++ b/src/libtomahawk/AtticaManager.cpp @@ -447,6 +447,7 @@ AtticaManager::payloadFetched() // Do the install / add to tomahawk Tomahawk::Accounts::Account* resolver = Tomahawk::Accounts::ResolverAccountFactory::createFromPath( resolverPath, true ); Tomahawk::Accounts::AccountManager::instance()->addAccount( resolver ); + TomahawkSettings::instance()->addAccount( resolver->accountId() ); } m_resolverStates[ resolverId ].state = Installed; diff --git a/src/libtomahawk/accounts/Account.cpp b/src/libtomahawk/accounts/Account.cpp index baeda84bc..208cc7bac 100644 --- a/src/libtomahawk/accounts/Account.cpp +++ b/src/libtomahawk/accounts/Account.cpp @@ -55,6 +55,13 @@ Account::Account( const QString& accountId ) loadFromConfig( accountId ); } + +Account::~Account() +{ + sync(); +} + + QWidget* Account::configurationWidget() { diff --git a/src/libtomahawk/accounts/Account.h b/src/libtomahawk/accounts/Account.h index d02bdceab..73a7dedee 100644 --- a/src/libtomahawk/accounts/Account.h +++ b/src/libtomahawk/accounts/Account.h @@ -73,7 +73,7 @@ public: enum ConnectionState { Disconnected, Connecting, Connected, Disconnecting }; explicit Account( const QString &accountId ); - virtual ~Account() {} + virtual ~Account(); QString accountServiceName() const { QMutexLocker locker( &m_mutex ); return m_accountServiceName; } // e.g. "Twitter", "Last.fm" QString accountFriendlyName() const { QMutexLocker locker( &m_mutex ); return m_accountFriendlyName; } // e.g. screen name on the service, JID, etc. diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index 32748ecac..5775e1d24 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -422,6 +422,12 @@ AccountModel::setData( const QModelIndex& index, const QVariant& value, int role } else { + if ( m_waitingForAtticaInstall.contains( resolver.id() ) ) + { + // in progress, ignore + return true; + } + qDebug() << "Kicked off fetch+install, now waiting"; m_waitingForAtticaInstall.insert( resolver.id() ); diff --git a/src/libtomahawk/accounts/ResolverAccount.cpp b/src/libtomahawk/accounts/ResolverAccount.cpp index 501add13f..f1010e6ad 100644 --- a/src/libtomahawk/accounts/ResolverAccount.cpp +++ b/src/libtomahawk/accounts/ResolverAccount.cpp @@ -200,6 +200,8 @@ ResolverAccount::resolverChanged() AtticaResolverAccount::AtticaResolverAccount( const QString& accountId ) : ResolverAccount( accountId ) { + TomahawkSettings::instance()->setValue( QString( "accounts/%1/atticaresolver" ).arg( accountId ), true ); + m_atticaId = configuration().value( "atticaId" ).toString(); loadIcon(); } @@ -209,9 +211,11 @@ AtticaResolverAccount::AtticaResolverAccount( const QString& accountId, const QS , m_atticaId( atticaId ) { QVariantHash conf = configuration(); - conf[ "atticaid" ] = atticaId; + conf[ "atticaId" ] = atticaId; setConfiguration( conf ); + TomahawkSettings::instance()->setValue( QString( "accounts/%1/atticaresolver" ).arg( accountId ), true ); + loadIcon(); } diff --git a/src/libtomahawk/tomahawksettings.cpp b/src/libtomahawk/tomahawksettings.cpp index 4651e97fb..aaf1ae8d8 100644 --- a/src/libtomahawk/tomahawksettings.cpp +++ b/src/libtomahawk/tomahawksettings.cpp @@ -203,7 +203,7 @@ TomahawkSettings::doUpgrade( int oldVersion, int newVersion ) { // 0.3.0 contained a bug which prevent indexing local files. Force a reindex. QTimer::singleShot( 0, this, SLOT( updateIndex() ) ); - } else if ( oldVersion == 5 ) + } else if ( oldVersion == 6 ) { // Migrate to accounts from sipplugins. // collect old connected and enabled sip plugins diff --git a/src/libtomahawk/tomahawksettings.h b/src/libtomahawk/tomahawksettings.h index 52788b15c..1a1d67100 100644 --- a/src/libtomahawk/tomahawksettings.h +++ b/src/libtomahawk/tomahawksettings.h @@ -27,7 +27,7 @@ #include "dllmacro.h" -#define TOMAHAWK_SETTINGS_VERSION 6 +#define TOMAHAWK_SETTINGS_VERSION 7 /** * Convenience wrapper around QSettings for tomahawk-specific config