1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-04-20 07:52:30 +02:00

Initial work towards SIP Factoryizing. Migrates and stuff, too. Config dialog unfinished.

This commit is contained in:
Leo Franchi 2011-04-25 21:55:26 -04:00
parent 3f740ce4a0
commit 8d777ff6a9
27 changed files with 1104 additions and 480 deletions

View File

@ -46,7 +46,7 @@ macro_log_feature(LIBECHONEST_FOUND "Echonest" "Qt library for communicating wit
macro_optional_find_package(CLucene 0.9.23)
macro_log_feature(CLucene_FOUND "CLucene" "The open-source, C++ search engine" "http://clucene.sf.net" TRUE "" "CLucene is used for indexing the collection")
macro_optional_find_package(QJSON 0.7.0)
macro_optional_find_package(QJSON)
macro_log_feature(QJSON_FOUND "QJson" "Qt library that maps JSON data to QVariant objects" "http://qjson.sf.net" TRUE "" "libqjson is used for encoding communication between Tomahawk instances")
macro_optional_find_package(Taglib 1.6.0)

View File

@ -82,7 +82,7 @@ public:
void init();
static TomahawkApp* instance();
SipHandler* sipHandler() { return m_sipHandler; }
SipHandler* sipHandler();
XMPPBot* xmppBot() { return m_xmppBot; }
#ifndef TOMAHAWK_HEADLESS
@ -119,7 +119,6 @@ private:
Database* m_database;
ScanManager *m_scanManager;
AudioEngine* m_audioEngine;
SipHandler* m_sipHandler;
Servent* m_servent;
Tomahawk::InfoSystem::InfoSystem* m_infoSystem;
XMPPBot* m_xmppBot;

View File

@ -31,6 +31,7 @@ set( libSources
sip/SipPlugin.cpp
sip/SipHandler.cpp
sip/SipModel.cpp
audio/audioengine.cpp
@ -187,6 +188,7 @@ set( libHeaders
sip/SipPlugin.h
sip/SipHandler.h
sip/SipModel.h
audio/audioengine.h

View File

@ -42,6 +42,8 @@ SipHandler* SipHandler::s_instance = 0;
SipHandler* SipHandler::instance()
{
if( s_instance == 0 )
s_instance = new SipHandler( 0 );
return s_instance;
}
@ -51,7 +53,7 @@ SipHandler::SipHandler( QObject* parent )
{
s_instance = this;
loadPlugins( findPlugins() );
loadPluginFactories( findPluginFactories() );
connect( TomahawkSettings::instance(), SIGNAL( changed() ), SLOT( onSettingsChanged() ) );
}
@ -59,14 +61,7 @@ SipHandler::SipHandler( QObject* parent )
SipHandler::~SipHandler()
{
disconnectPlugins();
}
QList< SipPlugin* >
SipHandler::plugins() const
{
return m_plugins;
disconnectAll();
}
const QPixmap SipHandler::avatar( const QString& name ) const
@ -95,7 +90,7 @@ SipHandler::onSettingsChanged()
QStringList
SipHandler::findPlugins()
SipHandler::findPluginFactories()
{
QStringList paths;
QList< QDir > pluginDirs;
@ -137,7 +132,7 @@ SipHandler::findPlugins()
void
SipHandler::loadPlugins( const QStringList& paths )
SipHandler::loadPluginFactories( const QStringList& paths )
{
foreach ( QString fileName, paths )
{
@ -145,13 +140,69 @@ SipHandler::loadPlugins( const QStringList& paths )
continue;
qDebug() << "Trying to load plugin:" << fileName;
loadPlugin( fileName );
loadPluginFactory( fileName );
}
}
SipPlugin*
SipHandler::createPlugin( const QString& factoryName )
{
Q_ASSERT( m_pluginFactories.contains( factoryName ) );
SipPlugin* sip = m_pluginFactories[ factoryName ]->createPlugin();
hookUpPlugin( 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 );
hookUpPlugin( sip );
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::loadPlugin( const QString& path )
SipHandler::hookUpPlugin( SipPlugin* sip )
{
QObject::connect( sip, SIGNAL( peerOnline( QString ) ), SLOT( onPeerOnline( QString ) ) );
QObject::connect( sip, SIGNAL( peerOffline( QString ) ), SLOT( onPeerOffline( QString ) ) );
QObject::connect( sip, SIGNAL( msgReceived( QString, QString ) ), SLOT( onMessage( 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 ) ) );
m_allPlugins << sip;
emit pluginAdded( sip );
}
void
SipHandler::loadPluginFactory( const QString& path )
{
QPluginLoader loader( path );
QObject* plugin = loader.instance();
@ -160,37 +211,24 @@ SipHandler::loadPlugin( const QString& path )
qDebug() << "Error loading plugin:" << loader.errorString();
}
SipPlugin* sip = qobject_cast<SipPlugin*>(plugin);
if ( sip )
SipPluginFactory* sipfactory = qobject_cast<SipPluginFactory*>(plugin);
if ( sipfactory )
{
if ( pluginLoaded( sip->name() ) )
{
qDebug() << "Plugin" << sip->name() << "already loaded! Not loading:" << loader.fileName();
return;
}
qDebug() << "Loaded plugin:" << loader.fileName();
QObject::connect( sip, SIGNAL( peerOnline( QString ) ), SLOT( onPeerOnline( QString ) ) );
QObject::connect( sip, SIGNAL( peerOffline( QString ) ), SLOT( onPeerOffline( QString ) ) );
QObject::connect( sip, SIGNAL( msgReceived( QString, QString ) ), SLOT( onMessage( QString, QString ) ) );
QObject::connect( sip, SIGNAL( connected() ), SIGNAL( connected() ) );
QObject::connect( sip, SIGNAL( disconnected() ), SIGNAL( disconnected() ) );
QObject::connect( sip, SIGNAL( error( int, QString ) ), SLOT( onError( int, QString ) ) );
QObject::connect( sip, SIGNAL( avatarReceived( QString, QPixmap ) ), SLOT( onAvatarReceived( QString, QPixmap ) ) );
QObject::connect( sip, SIGNAL( avatarReceived( QPixmap ) ), SLOT( onAvatarReceived( QPixmap ) ) );
m_plugins << sip;
qDebug() << "Loaded plugin factory:" << loader.fileName() << sipfactory->factoryId() << sipfactory->prettyName();
m_pluginFactories[ sipfactory->factoryId() ] = sipfactory;
} else
{
qDebug() << "Loaded invalid plugin.." << loader.fileName();
}
}
bool
SipHandler::pluginLoaded( const QString& name ) const
SipHandler::pluginLoaded( const QString& pluginId ) const
{
foreach( SipPlugin* plugin, m_plugins )
foreach( SipPlugin* plugin, m_allPlugins )
{
if ( plugin->name() == name )
if ( plugin->pluginId() == pluginId )
return true;
}
@ -201,15 +239,75 @@ SipHandler::pluginLoaded( const QString& name ) const
void
SipHandler::checkSettings()
{
foreach( SipPlugin* sip, m_plugins )
foreach( SipPlugin* sip, m_allPlugins )
{
sip->checkSettings();
}
}
void
SipHandler::loadFromConfig( bool startup )
{
QStringList pluginIds = TomahawkSettings::instance()->enabledSipPlugins();
foreach( const QString& pluginId, pluginIds )
{
QString pluginFactory = factoryFromId( pluginId );
if( m_pluginFactories.contains( pluginFactory ) )
{
SipPlugin* p = loadPlugin( pluginId );
p->connectPlugin( startup );
m_enabledPlugins << p;
}
}
m_connected = true;
}
void
SipHandler::connectPlugins( bool startup, const QString &pluginName )
SipHandler::connectAll()
{
foreach( SipPlugin* sip, m_enabledPlugins )
{
sip->connectPlugin();
}
m_connected = true;
}
void
SipHandler::disconnectAll()
{
foreach( SipPlugin* p, m_connectedPlugins )
p->disconnectPlugin();
SourceList::instance()->removeAllRemote();
m_connected = false;
}
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( bool startup, const QString &pluginId )
{
#ifndef TOMAHAWK_HEADLESS
if ( !TomahawkSettings::instance()->acceptedLegalWarning() )
@ -226,33 +324,49 @@ SipHandler::connectPlugins( bool startup, const QString &pluginName )
TomahawkSettings::instance()->setAcceptedLegalWarning( true );
}
#endif
foreach( SipPlugin* sip, m_plugins )
foreach( SipPlugin* sip, m_allPlugins )
{
if ( pluginName.isEmpty() || ( !pluginName.isEmpty() && sip->name() == pluginName ) )
if ( sip->pluginId() == pluginId )
{
Q_ASSERT( m_enabledPlugins.contains( sip ) ); // make sure the plugin we're connecting is enabled. should always be the case
sip->connectPlugin( startup );
}
if ( pluginName.isEmpty() )
{
m_connected = true;
}
}
}
void
SipHandler::disconnectPlugins( const QString &pluginName )
SipHandler::disconnectPlugin( const QString &pluginName )
{
foreach( SipPlugin* sip, m_plugins )
foreach( SipPlugin* sip, m_connectedPlugins )
{
if ( pluginName.isEmpty() || ( !pluginName.isEmpty() && sip->name() == pluginName ) )
if ( sip->name() == pluginName )
sip->disconnectPlugin();
}
}
if ( pluginName.isEmpty() )
{
SourceList::instance()->removeAllRemote();
m_connected = false;
}
QList< SipPlugin* >
SipHandler::allPlugins() const
{
return m_allPlugins;
}
QList< SipPlugin* >
SipHandler::enabledPlugins() const
{
return m_enabledPlugins;
}
QList< SipPlugin* >
SipHandler::connectedPlugins() const
{
return m_connectedPlugins;
}
QList< SipPluginFactory* >
SipHandler::pluginFactories() const
{
return m_pluginFactories.values();
}
@ -260,9 +374,9 @@ void
SipHandler::toggleConnect()
{
if( m_connected )
disconnectPlugins();
disconnectAll();
else
connectPlugins();
connectAll();
}
@ -368,20 +482,43 @@ SipHandler::onMessage( const QString& from, const QString& msg )
void
SipHandler::onError( int code, const QString& msg )
{
qWarning() << "Failed to connect to SIP:" << code << msg;
SipPlugin* sip = qobject_cast< SipPlugin* >( sender() );
Q_ASSERT( sip );
qWarning() << "Failed to connect to SIP:" << sip->accountName() << code << msg;
if ( code == SipPlugin::AuthError )
{
emit authError();
emit authError( sip );
}
else
{
SipPlugin* sip = qobject_cast<SipPlugin*>(sender());
QTimer::singleShot( 10000, sip, SLOT( connectPlugin() ) );
}
}
void SipHandler::onAvatarReceived( const QString& from, const QPixmap& avatar )
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.removeAll( sip );
emit disconnected( sip );
}
emit stateChanged( sip, state );
}
void
SipHandler::onAvatarReceived( const QString& from, const QPixmap& avatar )
{
qDebug() << Q_FUNC_INFO << "Set avatar on source for " << from;
Q_ASSERT(!avatar.isNull());
@ -413,8 +550,16 @@ void SipHandler::onAvatarReceived( const QString& from, const QPixmap& avatar )
}
}
void SipHandler::onAvatarReceived( const QPixmap& avatar )
void
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 )
{
return pluginId.split( "_" ).first();
}

View File

@ -38,28 +38,50 @@ public:
SipHandler( QObject* parent );
~SipHandler();
QList< SipPlugin* > plugins() const;
QList< SipPluginFactory* > pluginFactories() const;
QList< SipPlugin* > allPlugins() const;
QList< SipPlugin* > enabledPlugins() const;
QList< SipPlugin* > connectedPlugins() const;
void loadFromConfig( bool startup = false );
const QPixmap avatar( const QString& name ) const;
public slots:
void addContact( const QString& id ) { qDebug() << Q_FUNC_INFO << id; }
void checkSettings();
void connectPlugins( bool startup = false, const QString &pluginName = QString() );
void disconnectPlugins( const QString &pluginName = QString() );
void enablePlugin( SipPlugin* p );
void disablePlugin( SipPlugin* p );
void connectPlugin( bool startup = false, const QString &pluginId = QString() );
void disconnectPlugin( const QString &pluginId = QString() );
void connectAll();
void disconnectAll();
void toggleConnect();
// 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();
void disconnected();
void authError();
void connected( SipPlugin* );
void disconnected( SipPlugin* );
void authError( SipPlugin* );
void stateChanged( SipPlugin* p, SipPlugin::ConnectionState state );
void pluginAdded( SipPlugin* p );
void pluginRemoved( SipPlugin* p );
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();
@ -73,13 +95,18 @@ private slots:
private:
static SipHandler *s_instance;
QStringList findPlugins();
bool pluginLoaded( const QString& name ) const;
QStringList findPluginFactories();
bool pluginLoaded( const QString& pluginId ) const;
void hookUpPlugin( SipPlugin* p );
void loadPlugins( const QStringList& paths );
void loadPlugin( const QString& path );
void loadPluginFactories( const QStringList& paths );
void loadPluginFactory( const QString& path );
QString factoryFromId( const QString& pluginId );
QList< SipPlugin* > m_plugins;
QHash< QString, SipPluginFactory* > m_pluginFactories;
QList< SipPlugin* > m_allPlugins;
QList< SipPlugin* > m_enabledPlugins;
QList< SipPlugin* > m_connectedPlugins;
bool m_connected;

View File

@ -0,0 +1,140 @@
/*
Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 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 <http://www.gnu.org/licenses/>.
*/
#include "SipModel.h"
#include "tomahawksettings.h"
#include "tomahawk/tomahawkapp.h"
#include "sip/SipHandler.h"
SipModel::SipModel( QObject* parent )
: QAbstractListModel( parent )
{
connect( SipHandler::instance(), SIGNAL( stateChanged( SipPlugin*, SipPlugin::ConnectionState ) ), this, SLOT( pluginStateChanged( SipPlugin* ) ) );
}
SipModel::~SipModel()
{
}
QVariant
SipModel::data( const QModelIndex& index, int role ) const
{
if( !index.isValid() )
return QVariant();
if( 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();
}
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:
{
p->accountName();
}
case SipModel::ConnectionStateRole:
return p->connectionState();
case SipModel::HasConfig:
return ( p->configWidget() == 0 );
case SipModel::FactoryRole:
return false;
case Qt::CheckStateRole:
return SipHandler::instance()->enabledPlugins().contains( p ) ? Qt::Checked : Qt::Unchecked;
default:
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 && !SipHandler::instance()->enabledPlugins().contains( p ) ) {
SipHandler::instance()->enablePlugin( p );
} else if( state == Qt::Unchecked ) {
SipHandler::instance()->disablePlugin( p );
}
dataChanged( index, index );
return true;
}
return false;
}
int
SipModel::rowCount( const QModelIndex& parent ) const
{
return SipHandler::instance()->allPlugins().size() + 1;
}
int
SipModel::columnCount(const QModelIndex& parent) const
{
return 1;
}
Qt::ItemFlags
SipModel::flags( const QModelIndex& index ) const
{
return QAbstractItemModel::flags( index ) | Qt::ItemIsUserCheckable;
}
void
SipModel::pluginAdded( SipPlugin* 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 );
}
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 );
}

View File

@ -0,0 +1,56 @@
/*
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 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 <http://www.gnu.org/licenses/>.
*/
#ifndef SIPMODEL_H
#define SIPMODEL_H
#include "dllmacro.h"
#include <QModelIndex>
#include <QStringList>
class SipPlugin;
class DLLEXPORT SipModel : public QAbstractListModel
{
Q_OBJECT
public:
enum Roles {
PluginName = Qt::UserRole + 15,
ConnectionStateRole = Qt::UserRole + 17,
HasConfig = Qt::UserRole + 18,
FactoryRole = Qt::UserRole + 19
};
explicit SipModel( QObject* parent = 0 );
virtual ~SipModel();
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 );
};
#endif // SIPMODEL_H

View File

@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
@ -16,7 +16,28 @@
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#include <sip/SipPlugin.h>
#include "sip/SipPlugin.h"
#include <QUuid>
QString
SipPluginFactory::generateId()
{
QString uniq = QUuid::createUuid().toString().mid( 1, 8 );
return factoryId() + "_" + uniq;
}
SipPlugin::SipPlugin( const QString& pluginId, QObject* parent )
: QObject( parent )
, m_pluginId( pluginId )
{
}
QString SipPlugin::pluginId() const
{
return m_pluginId;
}
QMenu*

View File

@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
@ -25,19 +25,44 @@
#include "dllmacro.h"
class SipPlugin;
class DLLEXPORT SipPluginFactory : public QObject
{
Q_OBJECT
public:
SipPluginFactory() {}
virtual ~SipPluginFactory() {}
// display name for plugin
virtual QString prettyName() = 0;
// internal name
virtual QString factoryId() = 0;
virtual SipPlugin* createPlugin( const QString& pluginId = QString() ) = 0;
protected:
QString generateId();
};
class DLLEXPORT SipPlugin : public QObject
{
Q_OBJECT
public:
enum SipErrorCode { AuthError, ConnectionError }; // Placeholder for errors, to be defined
enum ConnectionState { Disconnected, Connecting, Connected };
explicit SipPlugin( const QString& pluginId, QObject* parent = 0 );
virtual ~SipPlugin() {}
virtual bool isValid() = 0;
virtual const QString name() = 0;
virtual const QString friendlyName() = 0;
virtual const QString accountName() = 0;
// 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 ConnectionState connectionState() const = 0;
virtual QMenu* menu();
virtual QWidget* configWidget();
@ -51,8 +76,7 @@ public slots:
signals:
void error( int, const QString& );
void connected();
void disconnected();
void stateChanged( SipPlugin::ConnectionState state );
void peerOnline( const QString& );
void peerOffline( const QString& );
@ -67,8 +91,11 @@ signals:
void addMenu( QMenu* menu );
void removeMenu( QMenu* menu );
private:
QString m_pluginId;
};
Q_DECLARE_INTERFACE( SipPlugin, "tomahawk.Sip/1.0" )
Q_DECLARE_INTERFACE( SipPluginFactory, "tomahawk.SipFactory/1.0" )
#endif

View File

@ -25,8 +25,9 @@
#include <QDir>
#include <QDebug>
#include "sip/SipHandler.h"
#define VERSION 2
#define VERSION 3
TomahawkSettings* TomahawkSettings::s_instance = 0;
@ -53,11 +54,15 @@ TomahawkSettings::TomahawkSettings( QObject* parent )
<< "new:" << VERSION
<< "Doing upgrade, if any...";
int current = value( "configversion" ).toUInt();
while( current < VERSION )
{
doUpgrade( current, current + 1 );
current++;
}
// insert upgrade code here as required
setValue( "configversion", VERSION );
if( contains( "script/resolvers") ) {
setValue( "script/loadedresolvers", value( "script/resolvers" ) );
}
}
}
@ -67,6 +72,72 @@ TomahawkSettings::~TomahawkSettings()
s_instance = 0;
}
void
TomahawkSettings::doUpgrade( int oldVersion, int newVersion )
{
Q_UNUSED( newVersion );
if( oldVersion == 1 )
{
qDebug() << "Migrating config from verson 1 to 2: script resolver config name";
if( contains( "script/resolvers" ) ) {
setValue( "script/loadedresolvers", value( "script/resolvers" ) );
remove( "script/resolvers" );
}
} else if( oldVersion == 2 )
{
qDebug() << "Migrating config from version 2 to 3: Converting jabber and twitter accounts to new SIP Factory approach";
// migrate old accounts to new system. only jabber and twitter, and max one each. create a new plugin for each if needed
// not pretty as we hardcode a plugin id and assume that we know how the config layout is, but hey, this is migration after all
if( contains( "jabber/username" ) && contains( "jabber/password" ) )
{
setValue( "sipjabber_legacy/username", value( "jabber/username" ) );
setValue( "sipjabber_legacy/password", value( "jabber/password" ) );
setValue( "sipjabber_legacy/autoconnect", value( "jabber/autoconnect" ) );
setValue( "sipjabber_legacy/port", value( "jabber/port" ) );
setValue( "sipjabber_legacy/server", value( "jabber/server" ) );
addSipPlugin( "sipjabber_legacy" );
remove( "jabber/username" );
remove( "jabber/password" );
remove( "jabber/autoconnect" );
remove( "jabber/server" );
remove( "jabber/port" );
// will be auto-added in the appropriate places
// SipPlugin* p = SipHandler::instance()->loadPlugin( "sipjabber_legacy" );
// SipHandler::instance()->enablePlugin( p );
}
if( contains( "twitter/ScreenName" ) && contains( "twitter/OAuthToken" ) )
{
setValue( "siptwitter_legacy/ScreenName", value( "twitter/ScreenName" ) );
setValue( "siptwitter_legacy/OAuthToken", value( "twitter/OAuthToken" ) );
setValue( "siptwitter_legacy/OAuthTokenSecret", value( "twitter/OAuthTokenSecret" ) );
setValue( "siptwitter_legacy/CachedFriendsSinceID", value( "twitter/CachedFriendsSinceID" ) );
setValue( "siptwitter_legacy/CachedMentionsSinceID", value( "twitter/CachedMentionsSinceID" ) );
setValue( "siptwitter_legacy/CachedDirectMessagesSinceID", value( "twitter/CachedDirectMessagesSinceID" ) );
setValue( "siptwitter_legacy/CachedPeers", value( "twitter/CachedPeers" ) );
setValue( "siptwitter_legacy/AutoConnect", value( "jabber/autoconnect" ) );
addSipPlugin( "siptwitter_legacy" );
remove( "twitter/ScreenName" );
remove( "twitter/OAuthToken" );
remove( "twitter/OAuthTokenSecret" );
remove( "twitter/CachedFriendsSinceID" );
remove( "twitter/CachedMentionsSinceID" );
remove( "twitter/CachedDirectMessagesSinceID" );
// SipPlugin* p = SipHandler::instance()->loadPlugin( "siptwitter_legacy" );
// SipHandler::instance()->enablePlugin( p );
}
// create a zeroconf plugin too
addSipPlugin( "sipzeroconf_legacy" );
// SipPlugin* p = SipHandler::instance()->createPlugin( "sipzeroconf" );
// SipHandler::instance()->enablePlugin( p );
}
}
QStringList
TomahawkSettings::scannerPaths()
@ -306,76 +377,63 @@ TomahawkSettings::appendRecentlyPlayedPlaylist( const Tomahawk::playlist_ptr& pl
setValue( "playlists/recentlyPlayed", playlist_guids );
}
bool
TomahawkSettings::jabberAutoConnect() const
QStringList
TomahawkSettings::sipPlugins() const
{
return value( "jabber/autoconnect", true ).toBool();
return value( "sip/allplugins", QStringList() ).toStringList();
}
void
TomahawkSettings::setJabberAutoConnect( bool autoconnect )
TomahawkSettings::setSipPlugins( const QStringList& plugins )
{
setValue( "jabber/autoconnect", autoconnect );
setValue( "sip/allplugins", plugins );
}
unsigned int
TomahawkSettings::jabberPort() const
QStringList
TomahawkSettings::enabledSipPlugins() const
{
return value( "jabber/port", 5222 ).toUInt();
return value( "sip/enabledplugins", QStringList() ).toStringList();
}
void
TomahawkSettings::setJabberPort( int port )
TomahawkSettings::setEnabledSipPlugins( const QStringList& list )
{
if ( port < 0 )
return;
setValue( "jabber/port", port );
setValue( "sip/enabledplugins", list );
}
QString
TomahawkSettings::jabberServer() const
{
return value( "jabber/server" ).toString();
}
void
TomahawkSettings::setJabberServer( const QString& server )
TomahawkSettings::enableSipPlugin( const QString& pluginId )
{
setValue( "jabber/server", server );
QStringList list = enabledSipPlugins();
list << pluginId;
setEnabledSipPlugins( list );
}
QString
TomahawkSettings::jabberUsername() const
{
return value( "jabber/username" ).toString();
}
void
TomahawkSettings::setJabberUsername( const QString& username )
TomahawkSettings::disableSipPlugin( const QString& pluginId )
{
setValue( "jabber/username", username );
QStringList list = enabledSipPlugins();
list.removeAll( pluginId );
setEnabledSipPlugins( list );
}
QString
TomahawkSettings::jabberPassword() const
{
return value( "jabber/password" ).toString();
}
void
TomahawkSettings::setJabberPassword( const QString& pw )
TomahawkSettings::addSipPlugin( const QString& pluginId, bool enable )
{
setValue( "jabber/password", pw );
QStringList list = sipPlugins();
list << pluginId;
setSipPlugins( list );
if ( enable )
enableSipPlugin( pluginId );
}
void
TomahawkSettings::removeSipPlugin( const QString& pluginId )
{
QStringList list = sipPlugins();
list.removeAll( pluginId );
setSipPlugins( list );
}
@ -477,90 +535,6 @@ TomahawkSettings::setLastFmUsername( const QString& username )
setValue( "lastfm/username", username );
}
QString
TomahawkSettings::twitterScreenName() const
{
return value( "twitter/ScreenName" ).toString();
}
void
TomahawkSettings::setTwitterScreenName( const QString& screenName )
{
setValue( "twitter/ScreenName", screenName );
}
QString
TomahawkSettings::twitterOAuthToken() const
{
return value( "twitter/OAuthToken" ).toString();
}
void
TomahawkSettings::setTwitterOAuthToken( const QString& oauthtoken )
{
setValue( "twitter/OAuthToken", oauthtoken );
}
QString
TomahawkSettings::twitterOAuthTokenSecret() const
{
return value( "twitter/OAuthTokenSecret" ).toString();
}
void
TomahawkSettings::setTwitterOAuthTokenSecret( const QString& oauthtokensecret )
{
setValue( "twitter/OAuthTokenSecret", oauthtokensecret );
}
qint64
TomahawkSettings::twitterCachedFriendsSinceId() const
{
return value( "twitter/CachedFriendsSinceID", 0 ).toLongLong();
}
void
TomahawkSettings::setTwitterCachedFriendsSinceId( qint64 cachedId )
{
setValue( "twitter/CachedFriendsSinceID", cachedId );
}
qint64
TomahawkSettings::twitterCachedMentionsSinceId() const
{
return value( "twitter/CachedMentionsSinceID", 0 ).toLongLong();
}
void
TomahawkSettings::setTwitterCachedMentionsSinceId( qint64 cachedId )
{
setValue( "twitter/CachedMentionsSinceID", cachedId );
}
qint64
TomahawkSettings::twitterCachedDirectMessagesSinceId() const
{
return value( "twitter/CachedDirectMessagesSinceID", 0 ).toLongLong();
}
void
TomahawkSettings::setTwitterCachedDirectMessagesSinceId( qint64 cachedId )
{
setValue( "twitter/CachedDirectMessagesSinceID", cachedId );
}
QHash<QString, QVariant>
TomahawkSettings::twitterCachedPeers() const
{
return value( "twitter/CachedPeers", QHash<QString, QVariant>() ).toHash();
}
void
TomahawkSettings::setTwitterCachedPeers( const QHash<QString, QVariant> &cachedPeers )
{
setValue( "twitter/CachedPeers", cachedPeers );
}
bool
TomahawkSettings::scrobblingEnabled() const
{

View File

@ -68,21 +68,19 @@ public:
QList<Tomahawk::playlist_ptr> recentlyPlayedPlaylists() const;
void appendRecentlyPlayedPlaylist( const Tomahawk::playlist_ptr& playlist );
/// Jabber settings
bool jabberAutoConnect() const; /// true by default
void setJabberAutoConnect( bool autoconnect = false );
/// SIP plugins
// all plugins we know about. loaded, unloaded, enabled, disabled.
void setSipPlugins( const QStringList& plugins );
QStringList sipPlugins() const;
QString jabberUsername() const;
void setJabberUsername( const QString& username );
// just the enabled sip plugins.
void setEnabledSipPlugins( const QStringList& list );
QStringList enabledSipPlugins() const;
void enableSipPlugin( const QString& pluginId );
void disableSipPlugin( const QString& pluginId );
QString jabberPassword() const;
void setJabberPassword( const QString& pw );
QString jabberServer() const;
void setJabberServer( const QString& server );
unsigned int jabberPort() const; // default is 5222
void setJabberPort( int port );
void addSipPlugin( const QString& pluginId, bool enable = true );
void removeSipPlugin( const QString& pluginId );
/// Network settings
enum ExternalAddressMode { Lan, Upnp };
@ -134,28 +132,6 @@ public:
QByteArray lastFmSessionKey() const;
void setLastFmSessionKey( const QByteArray& key );
/// Twitter settings
QString twitterScreenName() const;
void setTwitterScreenName( const QString& screenName );
QString twitterOAuthToken() const;
void setTwitterOAuthToken( const QString& oauthtoken );
QString twitterOAuthTokenSecret() const;
void setTwitterOAuthTokenSecret( const QString& oauthtokensecret );
qint64 twitterCachedFriendsSinceId() const;
void setTwitterCachedFriendsSinceId( qint64 sinceid );
qint64 twitterCachedMentionsSinceId() const;
void setTwitterCachedMentionsSinceId( qint64 sinceid );
qint64 twitterCachedDirectMessagesSinceId() const;
void setTwitterCachedDirectMessagesSinceId( qint64 sinceid );
QHash<QString, QVariant> twitterCachedPeers() const;
void setTwitterCachedPeers( const QHash<QString, QVariant> &cachedPeers );
/// XMPP Component Settings
QString xmppBotServer() const;
void setXmppBotServer( const QString &server );
@ -181,6 +157,8 @@ signals:
void changed();
private:
void doUpgrade( int oldVersion, int newVersion );
static TomahawkSettings* s_instance;
};

View File

@ -43,6 +43,7 @@
#include "resolverconfigdelegate.h"
#include "resolversmodel.h"
#include "resolverconfigwrapper.h"
#include "sip/SipModel.h"
static QString
md5( const QByteArray& src )
@ -57,6 +58,8 @@ SettingsDialog::SettingsDialog( QWidget *parent )
, m_proxySettings( this )
, m_rejected( false )
, m_testLastFmQuery( 0 )
, m_sipModel( 0 )
, m_resolversModel( 0 )
{
ui->setupUi( this );
TomahawkSettings* s = TomahawkSettings::instance();
@ -66,28 +69,24 @@ SettingsDialog::SettingsDialog( QWidget *parent )
ui->checkBoxUpnp->setChecked( s->externalAddressMode() == TomahawkSettings::Upnp );
ui->checkBoxUpnp->setEnabled( !s->preferStaticHostPort() );
// JABBER
ui->checkBoxJabberAutoConnect->setChecked( s->jabberAutoConnect() );
ui->jabberUsername->setText( s->jabberUsername() );
ui->jabberPassword->setText( s->jabberPassword() );
ui->jabberServer->setText( s->jabberServer() );
ui->jabberPort->setValue( s->jabberPort() );
// SIP PLUGINS
// SipPluginDelegate* ad = new SipPluginDelegate( this );
// ui->accountsView->setItemDelegate( ad );
// connect( ad, SIGNAL( openConfig( QString ) ), this, SLOT( openSipPluginConfig( QString ) ) );
m_sipModel = new SipModel( this );
ui->accountsView->setModel( m_sipModel );
// ui->checkBoxJabberAutoConnect->setChecked( s->jabberAutoConnect() );
// ui->jabberUsername->setText( s->jabberUsername() );
// ui->jabberPassword->setText( s->jabberPassword() );
// ui->jabberServer->setText( s->jabberServer() );
// ui->jabberPort->setValue( s->jabberPort() );
ui->staticHostName->setText( s->externalHostname() );
ui->staticPort->setValue( s->externalPort() );
ui->proxyButton->setVisible( false );
// SIP PLUGINS
foreach(SipPlugin *plugin, APP->sipHandler()->plugins())
{
if(plugin->configWidget())
{
qDebug() << "Adding configWidget for " << plugin->name();
ui->tabWidget->addTab(plugin->configWidget(), plugin->friendlyName());
}
}
// MUSIC SCANNER
//FIXME: MULTIPLECOLLECTIONDIRS
if ( s->scannerPaths().count() )
@ -131,12 +130,6 @@ SettingsDialog::~SettingsDialog()
s->setPreferStaticHostPort( ui->checkBoxStaticPreferred->checkState() == Qt::Checked );
s->setExternalAddressMode( ui->checkBoxUpnp->checkState() == Qt::Checked ? TomahawkSettings::Upnp : TomahawkSettings::Lan );
s->setJabberAutoConnect( ui->checkBoxJabberAutoConnect->checkState() == Qt::Checked );
s->setJabberUsername( ui->jabberUsername->text() );
s->setJabberPassword( ui->jabberPassword->text() );
s->setJabberServer( ui->jabberServer->text() );
s->setJabberPort( ui->jabberPort->value() );
s->setExternalHostname( ui->staticHostName->text() );
s->setExternalPort( ui->staticPort->value() );

View File

@ -21,6 +21,7 @@
#include <QDialog>
class SipModel;
class ResolversModel;
class QNetworkReply;
@ -80,6 +81,7 @@ private:
ProxyDialog m_proxySettings;
bool m_rejected;
QNetworkReply* m_testLastFmQuery;
SipModel* m_sipModel;
ResolversModel* m_resolversModel;
};

View File

@ -23,8 +23,18 @@
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>4</number>
<number>0</number>
</property>
<widget class="QWidget" name="tabFriends">
<attribute name="title">
<string>Accounts</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_20">
<item>
<widget class="QListView" name="accountsView"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="tabJabber">
<attribute name="title">
<string>Jabber</string>

View File

@ -27,10 +27,18 @@
#include <QLineEdit>
#include <QMessageBox>
JabberPlugin::JabberPlugin()
: p( 0 )
SipPlugin*
JabberFactory::createPlugin( const QString& pluginId )
{
return new JabberPlugin( pluginId.isEmpty() ? generateId() : pluginId );
}
JabberPlugin::JabberPlugin( const QString& pluginId )
: SipPlugin( pluginId )
, p( 0 )
, m_menu( 0 )
, m_addFriendAction( 0 )
, m_state( Disconnected )
{
}
@ -47,21 +55,21 @@ JabberPlugin::setProxy( QNetworkProxy* proxy )
const QString
JabberPlugin::name()
JabberPlugin::name() const
{
return QString( MYNAME );
}
const QString
JabberPlugin::friendlyName()
JabberPlugin::friendlyName() const
{
return QString( "Jabber" );
}
const QString
JabberPlugin::accountName()
JabberPlugin::accountName() const
{
return TomahawkSettings::instance()->jabberUsername();
return TomahawkSettings::instance()->value( pluginId() + "/username" ).toString();
}
QMenu*
@ -75,13 +83,13 @@ JabberPlugin::connectPlugin( bool startup )
{
qDebug() << Q_FUNC_INFO;
if ( startup && !TomahawkSettings::instance()->jabberAutoConnect() )
if ( startup && !readAutoConnect() )
return false;
QString jid = m_currentUsername = TomahawkSettings::instance()->jabberUsername();
QString server = m_currentServer = TomahawkSettings::instance()->jabberServer();
QString password = m_currentPassword = TomahawkSettings::instance()->jabberPassword();
unsigned int port = m_currentPort = TomahawkSettings::instance()->jabberPort();
QString jid = m_currentUsername = accountName();
QString server = m_currentServer = readServer();
QString password = m_currentPassword = readPassword();
unsigned int port = m_currentPort = readPort();
QStringList splitJid = jid.split( '@', QString::SkipEmptyParts );
if ( splitJid.size() < 2 )
@ -110,6 +118,8 @@ JabberPlugin::connectPlugin( bool startup )
QObject::connect( p, SIGNAL( avatarReceived( QString, QPixmap ) ), SIGNAL( avatarReceived( QString, QPixmap ) ) );
QObject::connect( p, SIGNAL( avatarReceived( QPixmap ) ), SIGNAL( avatarReceived( QPixmap) ) );
m_state = Connecting;
emit stateChanged( m_state );
return true;
}
@ -140,7 +150,9 @@ JabberPlugin::onConnected()
emit addMenu( m_menu );
}
emit connected();
m_state = Connected;
emit stateChanged( m_state );
}
void
@ -154,7 +166,9 @@ JabberPlugin::onDisconnected()
m_addFriendAction = 0; // deleted by menu
}
emit disconnected();
m_state = Disconnected;
emit stateChanged( m_state );
}
void
@ -182,6 +196,9 @@ JabberPlugin::onAuthError( int code, const QString& msg )
Q_ASSERT(false);
break;
}
m_state = Disconnected;
emit stateChanged( m_state );
}
void
@ -223,25 +240,56 @@ void
JabberPlugin::checkSettings()
{
bool reconnect = false;
if ( m_currentUsername != TomahawkSettings::instance()->jabberUsername() )
if ( m_currentUsername != accountName() )
reconnect = true;
if ( m_currentPassword != TomahawkSettings::instance()->jabberPassword() )
if ( m_currentPassword != readPassword() )
reconnect = true;
if ( m_currentServer != TomahawkSettings::instance()->jabberServer() )
if ( m_currentServer != readServer() )
reconnect = true;
if ( m_currentPort != TomahawkSettings::instance()->jabberPort() )
if ( m_currentPort != readPort() )
reconnect = true;
m_currentUsername = TomahawkSettings::instance()->jabberUsername();
m_currentPassword = TomahawkSettings::instance()->jabberPassword();
m_currentServer = TomahawkSettings::instance()->jabberServer();
m_currentPort = TomahawkSettings::instance()->jabberPort();
m_currentUsername = accountName();
m_currentPassword = readPassword();
m_currentServer = readServer();
m_currentPort = readPort();
if ( reconnect && ( p || TomahawkSettings::instance()->jabberAutoConnect() ) )
if ( reconnect && ( p || readAutoConnect() ) )
{
disconnectPlugin();
connectPlugin( false );
}
}
Q_EXPORT_PLUGIN2( sip, JabberPlugin )
QString
JabberPlugin::readPassword()
{
return TomahawkSettings::instance()->value( pluginId() + "/password" ).toString();
}
int
JabberPlugin::readPort()
{
return TomahawkSettings::instance()->value( pluginId() + "/port", 5222 ).toInt();
}
QString
JabberPlugin::readServer()
{
return TomahawkSettings::instance()->value( pluginId() + "/server" ).toString();
}
bool
JabberPlugin::readAutoConnect()
{
return TomahawkSettings::instance()->value( pluginId() + "/autoconnect", true ).toBool();
}
SipPlugin::ConnectionState
JabberPlugin::connectionState() const
{
return m_state;
}
Q_EXPORT_PLUGIN2( sipfactory, JabberFactory )

View File

@ -27,20 +27,34 @@
#define MYNAME "SIPJREEN"
class SIPDLLEXPORT JabberFactory : public SipPluginFactory
{
Q_OBJECT
Q_INTERFACES( SipPluginFactory )
public:
JabberFactory() {}
virtual ~JabberFactory() {}
virtual QString prettyName() { return "Jabber"; }
virtual QString factoryId() { return "sipjabber"; }
virtual SipPlugin* createPlugin( const QString& pluginId );
};
class SIPDLLEXPORT JabberPlugin : public SipPlugin
{
Q_OBJECT
Q_INTERFACES( SipPlugin )
public:
JabberPlugin();
JabberPlugin( const QString& pluginId );
virtual ~JabberPlugin();
//FIXME: Make this more correct
virtual bool isValid() { return true; }
virtual const QString name();
virtual const QString friendlyName();
virtual const QString accountName();
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();
void setProxy( QNetworkProxy* proxy );
@ -60,6 +74,11 @@ private slots:
void onAuthError(int code, const QString &msg);
private:
QString readPassword();
QString readServer();
bool readAutoConnect();
int readPort();
Jabber_p* p;
QMenu* m_menu;
QAction* m_addFriendAction;
@ -68,6 +87,7 @@ private:
QString m_currentPassword;
QString m_currentServer;
unsigned int m_currentPort;
ConnectionState m_state;
};
#endif

View File

@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
@ -35,10 +35,16 @@
static QString s_gotTomahawkRegex = QString( "^(@[a-zA-Z0-9]+ )?(Got Tomahawk\\?) (\\{[a-fA-F0-9\\-]+\\}) (.*)$" );
TwitterPlugin::TwitterPlugin()
: SipPlugin()
SipPlugin*
TwitterFactory::createPlugin( const QString& pluginId )
{
return new TwitterPlugin( pluginId.isEmpty() ? generateId() : pluginId );
}
TwitterPlugin::TwitterPlugin( const QString& pluginId )
: SipPlugin( pluginId )
, m_isAuthed( false )
, m_isOnline( false )
, m_checkTimer( this )
, m_connectTimer( this )
, m_cachedFriendsSinceId( 0 )
@ -48,6 +54,7 @@ TwitterPlugin::TwitterPlugin()
, m_keyCache()
, m_finishedFriends( false )
, m_finishedMentions( false )
, m_state( Disconnected )
, m_configWidget( 0 )
{
qDebug() << Q_FUNC_INFO;
@ -66,42 +73,49 @@ TwitterPlugin::configDialogAuthedSignalSlot( bool authed )
m_isAuthed = authed;
if ( !authed )
{
TomahawkSettings::instance()->setTwitterScreenName( QString() );
TomahawkSettings::instance()->setTwitterOAuthToken( QString() );
TomahawkSettings::instance()->setTwitterOAuthTokenSecret( QString() );
setTwitterScreenName( QString() );
setTwitterOAuthToken( QString() );
setTwitterOAuthTokenSecret( QString() );
}
}
bool
TwitterPlugin::isValid()
TwitterPlugin::isValid() const
{
return m_isAuthed;
}
const QString
TwitterPlugin::name()
TwitterPlugin::name() const
{
return QString( MYNAME );
}
const QString
TwitterPlugin::friendlyName()
TwitterPlugin::friendlyName() const
{
return tr("Twitter");
}
const QString
TwitterPlugin::accountName()
TwitterPlugin::accountName() const
{
return QString( TomahawkSettings::instance()->twitterScreenName() );
return twitterScreenName();
}
SipPlugin::ConnectionState
TwitterPlugin::connectionState() const
{
return m_state;
}
QWidget* TwitterPlugin::configWidget()
{
m_configWidget = new TwitterConfigWidget( this );
m_configWidget = new TwitterConfigWidget( this, 0 );
connect( m_configWidget, SIGNAL( twitterAuthed(bool) ), SLOT( configDialogAuthedSignalSlot(bool) ) );
return m_configWidget;
}
@ -110,9 +124,7 @@ TwitterPlugin::connectPlugin( bool /*startup*/ )
{
qDebug() << Q_FUNC_INFO;
TomahawkSettings *settings = TomahawkSettings::instance();
m_cachedPeers = settings->twitterCachedPeers();
m_cachedPeers = twitterCachedPeers();
QList<QString> peerlist = m_cachedPeers.keys();
qStableSort( peerlist.begin(), peerlist.end() );
foreach( QString screenName, peerlist )
@ -122,20 +134,23 @@ TwitterPlugin::connectPlugin( bool /*startup*/ )
qDebug() << "TwitterPlugin : " << screenName << ", key " << prop << ", value " << ( cachedPeer[prop].canConvert< QString >() ? cachedPeer[prop].toString() : QString::number( cachedPeer[prop].toInt() ) );
QMetaObject::invokeMethod( this, "registerOffer", Q_ARG( QString, screenName ), QGenericArgument( "QHash< QString, QVariant >", (const void*)&cachedPeer ) );
}
if ( settings->twitterOAuthToken().isEmpty() || settings->twitterOAuthTokenSecret().isEmpty() )
if ( twitterOAuthToken().isEmpty() || twitterOAuthTokenSecret().isEmpty() )
{
qDebug() << "TwitterPlugin 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 &) ) );
credVerifier->verify();
m_state = Connecting;
emit stateChanged( m_state );
}
return true;
}
@ -145,15 +160,13 @@ TwitterPlugin::refreshTwitterAuth()
if( !m_twitterAuth.isNull() )
delete m_twitterAuth.data();
m_twitterAuth = QWeakPointer<TomahawkOAuthTwitter>( new TomahawkOAuthTwitter( this ) );
if( m_twitterAuth.isNull() )
return false;
TomahawkSettings *settings = TomahawkSettings::instance();
m_twitterAuth.data()->setNetworkAccessManager( TomahawkUtils::nam() );
m_twitterAuth.data()->setOAuthToken( settings->twitterOAuthToken().toLatin1() );
m_twitterAuth.data()->setOAuthTokenSecret( settings->twitterOAuthTokenSecret().toLatin1() );
m_twitterAuth.data()->setOAuthToken( twitterOAuthToken().toLatin1() );
m_twitterAuth.data()->setOAuthTokenSecret( twitterOAuthTokenSecret().toLatin1() );
return true;
}
@ -178,7 +191,8 @@ TwitterPlugin::disconnectPlugin()
delete m_twitterAuth.data();
m_cachedPeers.empty();
m_isOnline = false;
m_state = Disconnected;
emit stateChanged( m_state );
}
void
@ -188,6 +202,8 @@ TwitterPlugin::connectAuthVerifyReply( const QTweetUser &user )
{
qDebug() << "TwitterPlugin could not authenticate to Twitter";
m_isAuthed = false;
m_state = Disconnected;
emit stateChanged( m_state );
}
else
{
@ -195,7 +211,7 @@ TwitterPlugin::connectAuthVerifyReply( const QTweetUser &user )
m_isAuthed = true;
if ( !m_twitterAuth.isNull() )
{
TomahawkSettings::instance()->setTwitterScreenName( user.screenName() );
setTwitterScreenName( user.screenName() );
m_friendsTimeline = QWeakPointer<QTweetFriendsTimeline>( new QTweetFriendsTimeline( m_twitterAuth.data(), this ) );
m_mentions = QWeakPointer<QTweetMentions>( new QTweetMentions( m_twitterAuth.data(), this ) );
m_directMessages = QWeakPointer<QTweetDirectMessages>( new QTweetDirectMessages( m_twitterAuth.data(), this ) );
@ -207,7 +223,8 @@ TwitterPlugin::connectAuthVerifyReply( const QTweetUser &user )
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_isOnline = true;
m_state = Connected;
emit stateChanged( m_state );
m_connectTimer.start();
m_checkTimer.start();
QMetaObject::invokeMethod( this, "checkTimerFired", Qt::AutoConnection );
@ -225,6 +242,8 @@ TwitterPlugin::connectAuthVerifyReply( const QTweetUser &user )
{
qDebug() << "TwitterPlugin auth pointer was null!";
m_isAuthed = false;
m_state = Disconnected;
emit stateChanged( m_state );
}
}
}
@ -237,18 +256,18 @@ TwitterPlugin::checkTimerFired()
return;
if ( m_cachedFriendsSinceId == 0 )
m_cachedFriendsSinceId = TomahawkSettings::instance()->twitterCachedFriendsSinceId();
m_cachedFriendsSinceId = twitterCachedFriendsSinceId();
qDebug() << "TwitterPlugin looking at friends timeline since id " << m_cachedFriendsSinceId;
if ( !m_friendsTimeline.isNull() )
m_friendsTimeline.data()->fetch( m_cachedFriendsSinceId, 0, 800 );
m_friendsTimeline.data()->fetch( m_cachedFriendsSinceId, 0, 800 );
if ( m_cachedMentionsSinceId == 0 )
m_cachedMentionsSinceId = TomahawkSettings::instance()->twitterCachedMentionsSinceId();
m_cachedMentionsSinceId = twitterCachedMentionsSinceId();
qDebug() << "TwitterPlugin looking at mentions timeline since id " << m_cachedMentionsSinceId;
if ( !m_mentions.isNull() )
m_mentions.data()->fetch( m_cachedMentionsSinceId, 0, 800 );
}
@ -259,7 +278,7 @@ TwitterPlugin::connectTimerFired()
if ( !isValid() || m_cachedPeers.isEmpty() || m_twitterAuth.isNull() )
return;
QString myScreenName = TomahawkSettings::instance()->twitterScreenName();
QString myScreenName = twitterScreenName();
QList<QString> peerlist = m_cachedPeers.keys();
qStableSort( peerlist.begin(), peerlist.end() );
foreach( QString screenName, peerlist )
@ -271,20 +290,20 @@ TwitterPlugin::connectTimerFired()
peerData["lastseen"] = QDateTime::currentMSecsSinceEpoch();
m_cachedPeers[screenName] = peerData;
}
if ( QDateTime::currentMSecsSinceEpoch() - peerData["lastseen"].toLongLong() > 1209600000 ) // 2 weeks
{
qDebug() << "Aging peer " << screenName << " out of cache";
m_cachedPeers.remove( screenName );
continue;
}
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)";
continue;
}
QMetaObject::invokeMethod( this, "registerOffer", Q_ARG( QString, screenName ), QGenericArgument( "QHash< QString, QVariant >", (const void*)&peerData ) );
}
}
@ -292,7 +311,7 @@ TwitterPlugin::connectTimerFired()
void
TwitterPlugin::parseGotTomahawk( const QRegExp &regex, const QString &screenName, const QString &text )
{
QString myScreenName = TomahawkSettings::instance()->twitterScreenName();
QString myScreenName = twitterScreenName();
qDebug() << "TwitterPlugin 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 ) )
@ -300,7 +319,7 @@ TwitterPlugin::parseGotTomahawk( const QRegExp &regex, const QString &screenName
qDebug() << "TwitterPlugin skipping mention because it's directed @someone that isn't us";
return;
}
QString node;
for ( int i = 0; i < regex.captureCount(); ++i )
{
@ -318,13 +337,13 @@ TwitterPlugin::parseGotTomahawk( const QRegExp &regex, const QString &screenName
}
else
qDebug() << "TwitterPlugin parsed node " << node << " out of the tweet";
if ( screenName == myScreenName && node == Database::instance()->dbid() )
{
qDebug() << "My screen name and my dbid found; ignoring";
return;
}
QHash< QString, QVariant > peerData;
if( m_cachedPeers.contains( screenName ) )
{
@ -341,14 +360,14 @@ TwitterPlugin::friendsTimelineStatuses( const QList< QTweetStatus > &statuses )
{
qDebug() << Q_FUNC_INFO;
QRegExp regex( s_gotTomahawkRegex, Qt::CaseSensitive, QRegExp::RegExp2 );
QString myScreenName = TomahawkSettings::instance()->twitterScreenName();
QString myScreenName = twitterScreenName();
QHash< QString, QTweetStatus > latestHash;
foreach ( QTweetStatus status, statuses )
{
if ( !regex.exactMatch( status.text() ) )
continue;
if ( !latestHash.contains( status.user().screenName() ) )
latestHash[status.user().screenName()] = status;
else
@ -357,7 +376,7 @@ TwitterPlugin::friendsTimelineStatuses( const QList< QTweetStatus > &statuses )
latestHash[status.user().screenName()] = status;
}
}
foreach( QTweetStatus status, latestHash.values() )
{
if ( status.id() > m_cachedFriendsSinceId )
@ -366,9 +385,9 @@ TwitterPlugin::friendsTimelineStatuses( const QList< QTweetStatus > &statuses )
qDebug() << "TwitterPlugin checking mention from " << status.user().screenName() << " with content " << status.text();
parseGotTomahawk( regex, status.user().screenName(), status.text() );
}
TomahawkSettings::instance()->setTwitterCachedFriendsSinceId( m_cachedFriendsSinceId );
setTwitterCachedFriendsSinceId( m_cachedFriendsSinceId );
m_finishedFriends = true;
QMetaObject::invokeMethod( this, "pollDirectMessages", Qt::AutoConnection );
}
@ -378,13 +397,13 @@ TwitterPlugin::mentionsStatuses( const QList< QTweetStatus > &statuses )
{
qDebug() << Q_FUNC_INFO;
QRegExp regex( s_gotTomahawkRegex, Qt::CaseSensitive, QRegExp::RegExp2 );
QHash< QString, QTweetStatus > latestHash;
foreach ( QTweetStatus status, statuses )
{
if ( !regex.exactMatch( status.text() ) )
continue;
if ( !latestHash.contains( status.user().screenName() ) )
latestHash[status.user().screenName()] = status;
else
@ -393,18 +412,18 @@ TwitterPlugin::mentionsStatuses( const QList< QTweetStatus > &statuses )
latestHash[status.user().screenName()] = status;
}
}
foreach( QTweetStatus status, latestHash.values() )
{
if ( status.id() > m_cachedMentionsSinceId )
m_cachedMentionsSinceId = status.id();
qDebug() << "TwitterPlugin checking mention from " << status.user().screenName() << " with content " << status.text();
parseGotTomahawk( regex, status.user().screenName(), status.text() );
}
TomahawkSettings::instance()->setTwitterCachedMentionsSinceId( m_cachedMentionsSinceId );
setTwitterCachedMentionsSinceId( m_cachedMentionsSinceId );
m_finishedMentions = true;
QMetaObject::invokeMethod( this, "pollDirectMessages", Qt::AutoConnection );
}
@ -414,18 +433,18 @@ TwitterPlugin::pollDirectMessages()
{
if ( !m_finishedMentions || !m_finishedFriends )
return;
m_finishedFriends = false;
m_finishedMentions = false;
if ( !isValid() )
return;
if ( m_cachedDirectMessagesSinceId == 0 )
m_cachedDirectMessagesSinceId = TomahawkSettings::instance()->twitterCachedDirectMessagesSinceId();
m_cachedDirectMessagesSinceId = twitterCachedDirectMessagesSinceId();
qDebug() << "TwitterPlugin looking for direct messages since id " << m_cachedDirectMessagesSinceId;
if ( !m_directMessages.isNull() )
m_directMessages.data()->fetch( m_cachedDirectMessagesSinceId, 0, 800 );
}
@ -434,10 +453,10 @@ void
TwitterPlugin::directMessages( const QList< QTweetDMStatus > &messages )
{
qDebug() << Q_FUNC_INFO;
QRegExp regex( s_gotTomahawkRegex, Qt::CaseSensitive, QRegExp::RegExp2 );
QString myScreenName = TomahawkSettings::instance()->twitterScreenName();
QString myScreenName = twitterScreenName();
QHash< QString, QTweetDMStatus > latestHash;
foreach ( QTweetDMStatus status, messages )
{
@ -454,7 +473,7 @@ TwitterPlugin::directMessages( const QList< QTweetDMStatus > &messages )
if ( port == 0 )
continue;
}
if ( !latestHash.contains( status.senderScreenName() ) )
latestHash[status.senderScreenName()] = status;
else
@ -463,13 +482,13 @@ TwitterPlugin::directMessages( const QList< QTweetDMStatus > &messages )
latestHash[status.senderScreenName()] = status;
}
}
foreach( QTweetDMStatus status, latestHash.values() )
{
qDebug() << "TwitterPlugin checking direct message from " << status.senderScreenName() << " with content " << status.text();
if ( status.id() > m_cachedDirectMessagesSinceId )
m_cachedDirectMessagesSinceId = status.id();
if ( regex.exactMatch( status.text() ) )
parseGotTomahawk( regex, status.sender().screenName(), status.text() );
else
@ -490,12 +509,12 @@ TwitterPlugin::directMessages( const QList< QTweetDMStatus > &messages )
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];
QHash< QString, QVariant > peerData = ( m_cachedPeers.contains( status.senderScreenName() ) ) ?
m_cachedPeers[status.senderScreenName()].toHash() :
QHash< QString, QVariant >();
peerData["host"] = QVariant::fromValue< QString >( host );
peerData["port"] = QVariant::fromValue< int >( port );
peerData["pkey"] = QVariant::fromValue< QString >( pkey );
@ -513,7 +532,7 @@ TwitterPlugin::directMessages( const QList< QTweetDMStatus > &messages )
}
}
TomahawkSettings::instance()->setTwitterCachedDirectMessagesSinceId( m_cachedDirectMessagesSinceId );
setTwitterCachedDirectMessagesSinceId( m_cachedDirectMessagesSinceId );
}
void
@ -569,7 +588,7 @@ TwitterPlugin::registerOffer( const QString &screenName, const QHash< QString, Q
qDebug() << "TwitterPlugin 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";
@ -586,12 +605,12 @@ TwitterPlugin::registerOffer( const QString &screenName, const QHash< QString, Q
{
_peerData["lastseen"] = QString::number( QDateTime::currentMSecsSinceEpoch() );
m_cachedPeers[screenName] = QVariant::fromValue< QHash< QString, QVariant > >( _peerData );
TomahawkSettings::instance()->setTwitterCachedPeers( m_cachedPeers );
setTwitterCachedPeers( m_cachedPeers );
}
if ( m_isOnline && _peerData.contains( "host" ) && _peerData.contains( "port" ) && _peerData.contains( "pkey" ) )
if ( m_state == Connected && _peerData.contains( "host" ) && _peerData.contains( "port" ) && _peerData.contains( "pkey" ) )
QMetaObject::invokeMethod( this, "makeConnection", Q_ARG( QString, screenName ), QGenericArgument( "QHash< QString, QVariant >", (const void*)&_peerData ) );
}
void
@ -632,7 +651,7 @@ TwitterPlugin::directMessagePosted( const QTweetDMStatus& message )
{
qDebug() << Q_FUNC_INFO;
qDebug() << "TwitterPlugin sent message to " << message.recipientScreenName() << " containing: " << message.text();
}
void
@ -658,4 +677,89 @@ TwitterPlugin::checkSettings()
connectPlugin( false );
}
Q_EXPORT_PLUGIN2( sip, TwitterPlugin )
QString
TwitterPlugin::twitterScreenName() const
{
return TomahawkSettings::instance()->value( pluginId() + "/ScreenName" ).toString();
}
void
TwitterPlugin::setTwitterScreenName( const QString& screenName )
{
TomahawkSettings::instance()->setValue( pluginId() + "/ScreenName", screenName );
}
QString
TwitterPlugin::twitterOAuthToken() const
{
return TomahawkSettings::instance()->value( pluginId() + "/OAuthToken" ).toString();
}
void
TwitterPlugin::setTwitterOAuthToken( const QString& oauthtoken )
{
TomahawkSettings::instance()->setValue( pluginId() + "/OAuthToken", oauthtoken );
}
QString
TwitterPlugin::twitterOAuthTokenSecret() const
{
return TomahawkSettings::instance()->value( pluginId() + "/OAuthTokenSecret" ).toString();
}
void
TwitterPlugin::setTwitterOAuthTokenSecret( const QString& oauthtokensecret )
{
TomahawkSettings::instance()->setValue( pluginId() + "/OAuthTokenSecret", oauthtokensecret );
}
qint64
TwitterPlugin::twitterCachedFriendsSinceId() const
{
return TomahawkSettings::instance()->value( pluginId() + "/CachedFriendsSinceID", 0 ).toLongLong();
}
void
TwitterPlugin::setTwitterCachedFriendsSinceId( qint64 cachedId )
{
TomahawkSettings::instance()->setValue( pluginId() + "/CachedFriendsSinceID", cachedId );
}
qint64
TwitterPlugin::twitterCachedMentionsSinceId() const
{
return TomahawkSettings::instance()->value( pluginId() + "/CachedMentionsSinceID", 0 ).toLongLong();
}
void
TwitterPlugin::setTwitterCachedMentionsSinceId( qint64 cachedId )
{
TomahawkSettings::instance()->setValue( pluginId() + "/CachedMentionsSinceID", cachedId );
}
qint64
TwitterPlugin::twitterCachedDirectMessagesSinceId() const
{
return TomahawkSettings::instance()->value( pluginId() + "/CachedDirectMessagesSinceID", 0 ).toLongLong();
}
void
TwitterPlugin::setTwitterCachedDirectMessagesSinceId( qint64 cachedId )
{
TomahawkSettings::instance()->setValue( pluginId() + "/CachedDirectMessagesSinceID", cachedId );
}
QHash<QString, QVariant>
TwitterPlugin::twitterCachedPeers() const
{
return TomahawkSettings::instance()->value( pluginId() + "/CachedPeers", QHash<QString, QVariant>() ).toHash();
}
void
TwitterPlugin::setTwitterCachedPeers( const QHash<QString, QVariant> &cachedPeers )
{
TomahawkSettings::instance()->setValue( pluginId() + "/CachedPeers", cachedPeers );
}
Q_EXPORT_PLUGIN2( sipfactory, TwitterFactory )

View File

@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
@ -40,21 +40,34 @@
#define MYNAME "SIPTWITTER"
class SIPDLLEXPORT TwitterFactory : public SipPluginFactory
{
Q_OBJECT
Q_INTERFACES( SipPluginFactory )
public:
TwitterFactory() {}
virtual ~TwitterFactory() {}
virtual QString prettyName() { return "Twitter"; }
virtual QString factoryId() { return "siptwitter"; }
virtual SipPlugin* createPlugin( const QString& pluginId = QString() );
};
class SIPDLLEXPORT TwitterPlugin : public SipPlugin
{
Q_OBJECT
Q_INTERFACES( SipPlugin )
public:
TwitterPlugin();
TwitterPlugin( const QString& pluginId );
virtual ~TwitterPlugin() {}
virtual bool isValid();
virtual const QString name();
virtual const QString accountName();
virtual const QString friendlyName();
virtual bool isValid() const;
virtual const QString name() const;
virtual const QString accountName() const;
virtual const QString friendlyName() const;
virtual ConnectionState connectionState() const;
virtual QWidget* configWidget();
public slots:
@ -98,6 +111,21 @@ private slots:
private:
bool refreshTwitterAuth();
void parseGotTomahawk( const QRegExp &regex, const QString &screenName, const QString &text );
// handle per-plugin config
QString twitterScreenName() const;
void setTwitterScreenName( const QString& screenName );
QString twitterOAuthToken() const;
void setTwitterOAuthToken( const QString& oauthtoken );
QString twitterOAuthTokenSecret() const;
void setTwitterOAuthTokenSecret( const QString& oauthtokensecret );
qint64 twitterCachedFriendsSinceId() const;
void setTwitterCachedFriendsSinceId( qint64 sinceid );
qint64 twitterCachedMentionsSinceId() const;
void setTwitterCachedMentionsSinceId( qint64 sinceid );
qint64 twitterCachedDirectMessagesSinceId() const;
void setTwitterCachedDirectMessagesSinceId( qint64 sinceid );
QHash<QString, QVariant> twitterCachedPeers() const;
void setTwitterCachedPeers( const QHash<QString, QVariant> &cachedPeers );
QWeakPointer< TomahawkOAuthTwitter > m_twitterAuth;
QWeakPointer< QTweetFriendsTimeline > m_friendsTimeline;
@ -105,8 +133,8 @@ private:
QWeakPointer< QTweetDirectMessages > m_directMessages;
QWeakPointer< QTweetDirectMessageNew > m_directMessageNew;
QWeakPointer< QTweetDirectMessageDestroy > m_directMessageDestroy;
bool m_isAuthed;
bool m_isOnline;
QTimer m_checkTimer;
QTimer m_connectTimer;
qint64 m_cachedFriendsSinceId;
@ -116,8 +144,12 @@ private:
QSet<QString> m_keyCache;
bool m_finishedFriends;
bool m_finishedMentions;
ConnectionState m_state;
TwitterConfigWidget *m_configWidget;
// for settings access
friend class TwitterConfigWidget;
};
#endif

View File

@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
@ -17,6 +17,7 @@
*/
#include "twitterconfigwidget.h"
#include "twitter.h"
#include "ui_twitterconfigwidget.h"
#include "tomahawksettings.h"
@ -30,7 +31,7 @@
#include <QMessageBox>
TwitterConfigWidget::TwitterConfigWidget( SipPlugin* plugin, QWidget *parent ) :
TwitterConfigWidget::TwitterConfigWidget( TwitterPlugin* plugin, QWidget *parent ) :
QWidget( parent ),
ui( new Ui::TwitterConfigWidget ),
m_plugin( plugin )
@ -47,9 +48,8 @@ TwitterConfigWidget::TwitterConfigWidget( SipPlugin* plugin, QWidget *parent ) :
ui->twitterTweetComboBox->setCurrentIndex( 0 );
ui->twitterUserTweetLineEdit->setReadOnly( true );
ui->twitterUserTweetLineEdit->setEnabled( false );
TomahawkSettings* s = TomahawkSettings::instance();
if ( s->twitterOAuthToken().isEmpty() || s->twitterOAuthTokenSecret().isEmpty() || s->twitterScreenName().isEmpty() )
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" ) );
@ -58,12 +58,12 @@ TwitterConfigWidget::TwitterConfigWidget( SipPlugin* plugin, QWidget *parent ) :
ui->twitterTweetGotTomahawkButton->setVisible( false );
ui->twitterUserTweetLineEdit->setVisible( false );
ui->twitterTweetComboBox->setVisible( false );
emit twitterAuthed( false );
}
else
{
ui->twitterStatusLabel->setText( tr( "Status: Credentials saved for %1" ).arg( s->twitterScreenName() ) );
ui->twitterStatusLabel->setText( tr( "Status: Credentials saved for %1" ).arg( m_plugin->twitterScreenName() ) );
ui->twitterAuthenticateButton->setText( tr( "De-authenticate" ) );
ui->twitterInstructionsInfoLabel->setVisible( true );
ui->twitterGlobalTweetLabel->setVisible( true );
@ -97,11 +97,10 @@ TwitterConfigWidget::authenticateTwitter()
TomahawkOAuthTwitter *twitAuth = new TomahawkOAuthTwitter( this );
twitAuth->setNetworkAccessManager( TomahawkUtils::nam() );
twitAuth->authorizePin();
TomahawkSettings* s = TomahawkSettings::instance();
s->setTwitterOAuthToken( twitAuth->oauthToken() );
s->setTwitterOAuthTokenSecret( twitAuth->oauthTokenSecret() );
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 ) ) );
@ -119,12 +118,11 @@ TwitterConfigWidget::authenticateVerifyReply( const QTweetUser &user )
return;
}
TomahawkSettings* s = TomahawkSettings::instance();
s->setTwitterScreenName( user.screenName() );
s->setTwitterCachedFriendsSinceId( 0 );
s->setTwitterCachedMentionsSinceId( 0 );
ui->twitterStatusLabel->setText( tr( "Status: Credentials saved for %1" ).arg( s->twitterScreenName() ) );
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->twitterInstructionsInfoLabel->setVisible( true );
ui->twitterGlobalTweetLabel->setVisible( true );
@ -133,7 +131,7 @@ TwitterConfigWidget::authenticateVerifyReply( const QTweetUser &user )
ui->twitterTweetComboBox->setVisible( true );
m_plugin->connectPlugin( false );
emit twitterAuthed( true );
}
@ -151,11 +149,10 @@ void
TwitterConfigWidget::deauthenticateTwitter()
{
qDebug() << Q_FUNC_INFO;
TomahawkSettings* s = TomahawkSettings::instance();
s->setTwitterOAuthToken( QString() );
s->setTwitterOAuthTokenSecret( QString() );
s->setTwitterScreenName( QString() );
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->twitterInstructionsInfoLabel->setVisible( false );
@ -163,7 +160,7 @@ TwitterConfigWidget::deauthenticateTwitter()
ui->twitterTweetGotTomahawkButton->setVisible( false );
ui->twitterUserTweetLineEdit->setVisible( false );
ui->twitterTweetComboBox->setVisible( false );
emit twitterAuthed( false );
}
@ -181,7 +178,7 @@ TwitterConfigWidget::tweetComboBoxIndexChanged( int index )
ui->twitterUserTweetLineEdit->setReadOnly( false );
ui->twitterUserTweetLineEdit->setEnabled( true );
}
if( ui->twitterTweetComboBox->currentText() == tr( "Direct Message" ) ) //FIXME: use data!
ui->twitterTweetGotTomahawkButton->setText( tr( "Send Message!" ) );
else
@ -192,16 +189,15 @@ void
TwitterConfigWidget::startPostGotTomahawkStatus()
{
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";
TomahawkSettings* s = TomahawkSettings::instance();
if ( s->twitterOAuthToken().isEmpty() || s->twitterOAuthTokenSecret().isEmpty() || s->twitterScreenName().isEmpty() )
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 );
@ -209,8 +205,8 @@ TwitterConfigWidget::startPostGotTomahawkStatus()
}
TomahawkOAuthTwitter *twitAuth = new TomahawkOAuthTwitter( this );
twitAuth->setNetworkAccessManager( TomahawkUtils::nam() );
twitAuth->setOAuthToken( s->twitterOAuthToken().toLatin1() );
twitAuth->setOAuthTokenSecret( s->twitterOAuthTokenSecret().toLatin1() );
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();
@ -225,12 +221,11 @@ TwitterConfigWidget::postGotTomahawkStatusAuthVerifyReply( const QTweetUser &use
emit twitterAuthed( false );
return;
}
TomahawkSettings* s = TomahawkSettings::instance();
s->setTwitterScreenName( user.screenName() );
m_plugin->setTwitterScreenName( user.screenName() );
TomahawkOAuthTwitter *twitAuth = new TomahawkOAuthTwitter( this );
twitAuth->setNetworkAccessManager( TomahawkUtils::nam() );
twitAuth->setOAuthToken( s->twitterOAuthToken().toLatin1() );
twitAuth->setOAuthTokenSecret( s->twitterOAuthTokenSecret().toLatin1() );
twitAuth->setOAuthToken( m_plugin->twitterOAuthToken().toLatin1() );
twitAuth->setOAuthTokenSecret( m_plugin->twitterOAuthTokenSecret().toLatin1() );
if ( m_postGTtype != "Direct Message" )
{
QTweetStatusUpdate *statUpdate = new QTweetStatusUpdate( twitAuth, this );

View File

@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
@ -28,6 +28,7 @@
#include <QWidget>
class TwitterPlugin;
namespace Ui {
class TwitterConfigWidget;
@ -38,12 +39,12 @@ class TwitterConfigWidget : public QWidget
Q_OBJECT
public:
explicit TwitterConfigWidget( SipPlugin* plugin = 0, QWidget *parent = 0 );
explicit TwitterConfigWidget( TwitterPlugin* plugin = 0, QWidget *parent = 0 );
~TwitterConfigWidget();
signals:
void twitterAuthed( bool authed );
private slots:
void authDeauthTwitter();
void startPostGotTomahawkStatus();
@ -58,9 +59,9 @@ private slots:
private:
void authenticateTwitter();
void deauthenticateTwitter();
Ui::TwitterConfigWidget *ui;
SipPlugin *m_plugin;
TwitterPlugin *m_plugin;
QString m_postGTtype;
};

View File

@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
@ -20,24 +20,39 @@
#include <QtPlugin>
SipPlugin*
ZeroconfFactory::createPlugin( const QString& pluginId )
{
return new ZeroconfPlugin( pluginId.isEmpty() ? generateId() : pluginId );
}
const QString
ZeroconfPlugin::name()
ZeroconfPlugin::name() const
{
return QString( MYNAME );
}
const QString
ZeroconfPlugin::accountName()
ZeroconfPlugin::accountName() const
{
return QString();
}
const QString
ZeroconfPlugin::friendlyName()
ZeroconfPlugin::friendlyName() const
{
return QString( "Zeroconf" );
}
SipPlugin::ConnectionState
ZeroconfPlugin::connectionState() const
{
return m_state;
}
bool
ZeroconfPlugin::connectPlugin( bool /*startup*/ )
{
@ -47,7 +62,7 @@ ZeroconfPlugin::connectPlugin( bool /*startup*/ )
SLOT( lanHostFound( QString, int, QString, QString ) ) );
m_zeroconf->advertise();
m_isOnline = true;
m_state = Connected;
foreach( const QStringList& nodeSet, m_cachedNodes )
{
@ -61,7 +76,7 @@ ZeroconfPlugin::connectPlugin( bool /*startup*/ )
void
ZeroconfPlugin::disconnectPlugin()
{
m_isOnline = false;
m_state = Disconnected;
delete m_zeroconf;
m_zeroconf = 0;
@ -75,7 +90,7 @@ ZeroconfPlugin::lanHostFound( const QString& host, int port, const QString& name
qDebug() << "Found LAN host:" << host << port << nodeid;
if ( !m_isOnline )
if ( m_state != Connected )
{
qDebug() << "Not online, so not connecting.";
QStringList nodeSet;
@ -83,11 +98,11 @@ ZeroconfPlugin::lanHostFound( const QString& host, int port, const QString& name
m_cachedNodes.append( nodeSet );
return;
}
if ( !Servent::instance()->connectedToSession( nodeid ) )
Servent::instance()->connectToPeer( host, port, "whitelist", name, nodeid );
else
qDebug() << "Already connected to" << host;
}
Q_EXPORT_PLUGIN2( sip, ZeroconfPlugin )
Q_EXPORT_PLUGIN2( sipfactory, ZeroconfFactory )

View File

@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
@ -24,17 +24,30 @@
#include "../sipdllmacro.h"
#define MYNAME "SIPZEROCONF"
#define MYNAME "Local Netwrok"
class SIPDLLEXPORT ZeroconfFactory : public SipPluginFactory
{
Q_OBJECT
Q_INTERFACES( SipPluginFactory )
public:
ZeroconfFactory() {}
virtual ~ZeroconfFactory() {}
virtual QString factoryId() { return "sipzeroconf"; }
virtual QString prettyName() { return "Local Network"; }
virtual SipPlugin* createPlugin ( const QString& pluginId = QString() );
};
class SIPDLLEXPORT ZeroconfPlugin : public SipPlugin
{
Q_OBJECT
Q_INTERFACES( SipPlugin )
public:
ZeroconfPlugin()
: m_zeroconf( 0 )
, m_isOnline( false )
ZeroconfPlugin( const QString& pluginId )
: SipPlugin( pluginId )
, m_zeroconf( 0 )
, m_state( Disconnected )
, m_cachedNodes()
{
qDebug() << Q_FUNC_INFO;
@ -44,11 +57,12 @@ public:
{
qDebug() << Q_FUNC_INFO;
}
virtual bool isValid() { return true; }
virtual const QString name();
virtual const QString friendlyName();
virtual const QString accountName();
virtual const QString name() const;
virtual const QString friendlyName() const;
virtual const QString accountName() const;
virtual ConnectionState connectionState() const;
virtual bool isValid() const { return true; };
public slots:
virtual bool connectPlugin( bool startup );
@ -77,7 +91,7 @@ private slots:
private:
TomahawkZeroconf* m_zeroconf;
bool m_isOnline;
ConnectionState m_state;
QVector<QStringList> m_cachedNodes;
};

View File

@ -404,14 +404,12 @@ SourceDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, co
CollectionItem* colItem = qobject_cast< CollectionItem* >( item );
Q_ASSERT( colItem );
bool status = !( !colItem || colItem->source().isNull() || !colItem->source()->isOnline() );
QPixmap avatar( RESPATH "images/user-avatar.png" );
QString tracks;
QString name = index.data().toString();
int figWidth = 0;
QRect iconRect = option.rect.adjusted( 4, 6, -option.rect.width() + option.rect.height() - 12 + 4, -6 );
QPixmap avatar = index.data( Qt::DecorationRole ).value< QIcon >().pixmap( iconRect.size() );
if ( status && colItem && !colItem->source().isNull() )
{
tracks = QString::number( colItem->source()->trackCount() );
@ -421,6 +419,7 @@ SourceDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, co
name = colItem->source()->friendlyName();
}
QRect iconRect = option.rect.adjusted( 4, 6, -option.rect.width() + option.rect.height() - 12 + 4, -6 );
painter->drawPixmap( iconRect, avatar.scaledToHeight( iconRect.height(), Qt::SmoothTransformation ) );

View File

@ -147,7 +147,6 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] )
, m_database( 0 )
, m_scanManager( 0 )
, m_audioEngine( 0 )
, m_sipHandler( 0 )
, m_servent( 0 )
, m_shortcutHandler( 0 )
, m_mainwindow( 0 )
@ -166,13 +165,13 @@ TomahawkApp::init()
{
qsrand( QTime( 0, 0, 0 ).secsTo( QTime::currentTime() ) );
#ifdef TOMAHAWK_HEADLESS
#ifdef TOMAHAWK_HEADLESS
m_headless = true;
#else
#else
m_mainwindow = 0;
m_headless = arguments().contains( "--headless" );
setWindowIcon( QIcon( RESPATH "icons/tomahawk-icon-128x128.png" ) );
#endif
#endif
registerMetaTypes();
@ -193,12 +192,12 @@ TomahawkApp::init()
GeneratorFactory::registerFactory( "echonest", new EchonestFactory );
// Register shortcut handler for this platform
#ifdef Q_WS_MAC
#ifdef Q_WS_MAC
m_shortcutHandler = new MacShortcutHandler( this );
Tomahawk::setShortcutHandler( static_cast<MacShortcutHandler*>( m_shortcutHandler) );
Tomahawk::setApplicationHandler( this );
#endif
#endif
// Connect up shortcuts
if ( m_shortcutHandler )
@ -249,9 +248,9 @@ TomahawkApp::init()
QNetworkProxy::setApplicationProxy( *TomahawkUtils::proxy() );
qDebug() << "Init SIP system.";
m_sipHandler = new SipHandler( this );
#ifndef TOMAHAWK_HEADLESS
#ifndef TOMAHAWK_HEADLESS
if ( !m_headless )
{
qDebug() << "Init MainWindow.";
@ -259,7 +258,7 @@ TomahawkApp::init()
m_mainwindow->setWindowTitle( "Tomahawk" );
m_mainwindow->show();
}
#endif
#endif
qDebug() << "Init Local Collection.";
initLocalCollection();
@ -294,7 +293,6 @@ TomahawkApp::~TomahawkApp()
}
m_scriptResolvers.clear();
delete m_sipHandler;
delete m_servent;
delete m_scanManager;
#ifndef TOMAHAWK_HEADLESS
@ -321,6 +319,11 @@ TomahawkApp::audioControls()
}
#endif
SipHandler*
TomahawkApp::sipHandler()
{
return SipHandler::instance();
}
void
TomahawkApp::registerMetaTypes()
@ -492,15 +495,15 @@ TomahawkApp::setupSIP()
qDebug() << Q_FUNC_INFO;
//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" ) && TomahawkSettings::instance()->jabberAutoConnect() )
if( !arguments().contains( "--nosip" ) )
{
#ifdef GLOOX_FOUND
#ifdef GLOOX_FOUND
m_xmppBot = new XMPPBot( this );
#endif
#endif
qDebug() << "Connecting SIP classes";
m_sipHandler->connectPlugins( true );
// m_sipHandler->setProxy( *TomahawkUtils::proxy() );
SipHandler::instance()->loadFromConfig( true );
// SipHandler::instance()->setProxy( *TomahawkUtils::proxy() );
}
}

View File

@ -172,11 +172,14 @@ TomahawkWindow::TomahawkWindow( QWidget* parent )
m_backAvailable->setToolTip( tr( "Go back one page" ) );
m_forwardAvailable = toolbar->addAction( QIcon( RESPATH "images/forward.png" ), tr( "Forward" ), ViewManager::instance(), SLOT( historyForward() ) );
m_forwardAvailable->setToolTip( tr( "Go forward one page" ) );
toolbar->addAction( QIcon( RESPATH "images/home.png" ), tr( "Home" ), ViewManager::instance(), SLOT( showWelcomePage() ) );
statusBar()->addPermanentWidget( m_audioControls, 1 );
// propagate sip menu
foreach( SipPlugin *plugin, APP->sipHandler()->plugins() )
connect( SipHandler::instance(), SIGNAL( pluginAdded( SipPlugin* ) ), this, SLOT( onSipPluginAdded( SiPlugin* ) ) );
connect( SipHandler::instance(), SIGNAL( pluginRemoved( SipPlugin* ) ), this, SLOT( onSipPluginRemoved( SiPlugin* ) ) );
foreach( SipPlugin *plugin, APP->sipHandler()->allPlugins() )
{
connect( plugin, SIGNAL( addMenu( QMenu* ) ), this, SLOT( pluginMenuAdded( QMenu* ) ) );
connect( plugin, SIGNAL( removeMenu( QMenu* ) ), this, SLOT( pluginMenuRemoved( QMenu* ) ) );
@ -471,6 +474,19 @@ TomahawkWindow::onSipDisconnected()
ui->actionToggleConnect->setText( tr( "Go &online" ) );
}
void
TomahawkWindow::onSipPluginAdded( SipPlugin* p )
{
connect( p, SIGNAL( addMenu( QMenu* ) ), this, SLOT( pluginMenuAdded( QMenu* ) ) );
connect( p, SIGNAL( removeMenu( QMenu* ) ), this, SLOT( pluginMenuRemoved( QMenu* ) ) );
}
void
TomahawkWindow::onSipPluginRemoved( SipPlugin* p )
{
Q_UNUSED( p );
}
void
TomahawkWindow::onSipError()

View File

@ -27,6 +27,7 @@
#include "result.h"
class SipPlugin;
class SourceTreeView;
class QAction;
@ -81,6 +82,8 @@ private slots:
void showAboutTomahawk();
void checkForUpdates();
void onSipPluginAdded( SipPlugin* p );
void onSipPluginRemoved( SipPlugin* p );
private:
void loadSettings();
void saveSettings();

2
thirdparty/jreen vendored

@ -1 +1 @@
Subproject commit f7281d6616b5490eee92e4ddb2171d3d4e958f3c
Subproject commit 040ca3f3cb9b30b4845fc23054c833fda4717460