1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-06 14:16:32 +02:00

some work

This commit is contained in:
Leo Franchi
2011-11-28 13:17:27 -05:00
parent cef9c620dc
commit 328d055ee1
24 changed files with 556 additions and 652 deletions

235
src/AccountDelegate.cpp Normal file
View File

@@ -0,0 +1,235 @@
/*
Copyright (C) 2011 Leo Franchi <leo.franchi@kdab.com>
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 "AccountDelegate.h"
#include <QApplication>
#include <QPainter>
#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* >() ) );
}

View File

@@ -16,31 +16,40 @@
*/ */
#ifndef SIPCONFIGDELEGATE_H #ifndef ACCOUNTDELEGATE_H
#define SIPCONFIGDELEGATE_H #define ACCOUNTDELEGATE_H
#include "configdelegatebase.h" #include "configdelegatebase.h"
class SipPlugin; namespace Tomahawk
class SipPluginFactory; {
class SipConfigDelegate : public ConfigDelegateBase namespace Accounts
{
class Account;
class AccountDelegate : public ConfigDelegateBase
{ {
Q_OBJECT Q_OBJECT
public: public:
SipConfigDelegate( QObject* parent = 0); AccountDelegate( QObject* parent = 0);
virtual void paint ( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const; 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 bool editorEvent ( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index );
virtual QSize sizeHint ( const QStyleOptionViewItem& option, const QModelIndex& index ) const; 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 QRect configRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const;
virtual QList<int> extraCheckRoles() const { return QList<int>() << (int)AccountModel::BasicCapabilityRole; }
private slots: private slots:
void askedForEdit( const QModelIndex& idx ); void askedForEdit( const QModelIndex& idx );
signals: signals:
void sipFactoryClicked( SipPluginFactory* ); void openConfig( Account* );
void openConfig( SipPlugin* );
}; };
#endif // SIPCONFIGDELEGATE_H }
}
#endif // ACCOUNTDELEGATE_H

View File

@@ -71,7 +71,7 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui}
settingsdialog.cpp settingsdialog.cpp
diagnosticsdialog.cpp diagnosticsdialog.cpp
configdelegatebase.cpp configdelegatebase.cpp
sipconfigdelegate.cpp AccountDelegate.cpp
resolverconfigdelegate.cpp resolverconfigdelegate.cpp
settingslistdelegate.cpp settingslistdelegate.cpp
resolversmodel.cpp resolversmodel.cpp
@@ -122,7 +122,7 @@ SET( tomahawkHeadersGui ${tomahawkHeadersGui}
diagnosticsdialog.h diagnosticsdialog.h
configdelegatebase.h configdelegatebase.h
resolverconfigdelegate.h resolverconfigdelegate.h
sipconfigdelegate.h AccountDelegate.h
settingslistdelegate.h settingslistdelegate.h
resolversmodel.h resolversmodel.h
delegateconfigwrapper.h delegateconfigwrapper.h

View File

@@ -52,7 +52,7 @@ TwitterAccount::TwitterAccount( const QString &accountId )
QSet< AccountType > types; QSet< AccountType > types;
types << InfoType << SipType; types << InfoType << SipType;
setTypes( types ); setTypes( types );
m_configWidget = QWeakPointer< TwitterConfigWidget >( new TwitterConfigWidget( this, 0 ) ); m_configWidget = QWeakPointer< TwitterConfigWidget >( new TwitterConfigWidget( this, 0 ) );
connect( m_configWidget.data(), SIGNAL( twitterAuthed( bool ) ), SLOT( configDialogAuthedSignalSlot( bool ) ) ); connect( m_configWidget.data(), SIGNAL( twitterAuthed( bool ) ), SLOT( configDialogAuthedSignalSlot( bool ) ) );
@@ -93,9 +93,9 @@ TwitterAccount::sipPlugin()
void void
TwitterAccount::authenticate() 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"; qDebug() << "TwitterSipPlugin has empty Twitter credentials; not connecting";
return; return;
@@ -154,7 +154,9 @@ TwitterAccount::connectAuthVerifyReply( const QTweetUser &user )
else else
{ {
tDebug() << "TwitterAccount successfully authenticated to Twitter as user " << user.screenName(); 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(); sync();
emit nowAuthenticated( m_twitterAuth, user ); emit nowAuthenticated( m_twitterAuth, user );
} }

View File

@@ -56,10 +56,9 @@ class DLLEXPORT TwitterAccount : public Account
public: public:
TwitterAccount( const QString &accountId ); TwitterAccount( const QString &accountId );
virtual ~TwitterAccount(); virtual ~TwitterAccount();
QIcon icon() const { return QIcon( ":/twitter-icon.png" ); } QIcon icon() const { return QIcon( ":/twitter-icon.png" ); }
bool canSelfAuthenticate() const { return true; }
void authenticate(); void authenticate();
void deauthenticate(); void deauthenticate();
bool isAuthenticated() const { return m_isAuthenticated; } bool isAuthenticated() const { return m_isAuthenticated; }
@@ -82,7 +81,7 @@ signals:
private slots: private slots:
void configDialogAuthedSignalSlot( bool authed ); void configDialogAuthedSignalSlot( bool authed );
void connectAuthVerifyReply( const QTweetUser &user ); void connectAuthVerifyReply( const QTweetUser &user );
private: private:
bool m_isAuthenticated; bool m_isAuthenticated;
QWeakPointer< TomahawkOAuthTwitter > m_twitterAuth; QWeakPointer< TomahawkOAuthTwitter > m_twitterAuth;

View File

@@ -59,7 +59,6 @@ public:
QIcon icon() const { return QIcon( ":/xmpp-icon.png" ); } QIcon icon() const { return QIcon( ":/xmpp-icon.png" ); }
bool canSelfAuthenticate() const { return false; }
void authenticate(); void authenticate();
void deauthenticate(); void deauthenticate();
bool isAuthenticated() const { return m_isAuthenticated; } bool isAuthenticated() const { return m_isAuthenticated; }
@@ -77,7 +76,7 @@ private:
bool m_isAuthenticated; bool m_isAuthenticated;
QWeakPointer< QWidget > m_configWidget; QWeakPointer< QWidget > m_configWidget;
QWeakPointer< XmppSipPlugin > m_xmppSipPlugin; QWeakPointer< XmppSipPlugin > m_xmppSipPlugin;
// for settings access // for settings access
friend class XmppConfigWidget; friend class XmppConfigWidget;

View File

@@ -25,6 +25,8 @@
#include "utils/tomahawkutils.h" #include "utils/tomahawkutils.h"
#include "utils/logger.h" #include "utils/logger.h"
#define ROW_HEIGHT 50
ConfigDelegateBase::ConfigDelegateBase ( QObject* parent ) ConfigDelegateBase::ConfigDelegateBase ( QObject* parent )
: QStyledItemDelegate ( parent ) : QStyledItemDelegate ( parent )
{ {
@@ -36,23 +38,7 @@ QSize
ConfigDelegateBase::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const ConfigDelegateBase::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const
{ {
int width = QStyledItemDelegate::sizeHint( option, index ).width(); 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 void
@@ -94,17 +80,24 @@ ConfigDelegateBase::editorEvent ( QEvent* event, QAbstractItemModel* model, cons
m_configPressed = QModelIndex(); m_configPressed = QModelIndex();
QMouseEvent* me = static_cast< QMouseEvent* >( event ); QMouseEvent* me = static_cast< QMouseEvent* >( event );
if( me->button() != Qt::LeftButton || !checkRectForIndex( option, index ).contains( me->pos() ) ) QList<int> roles = QList<int>() << (int)Qt::CheckStateRole;
return false; roles.append( extraCheckRoles() );
// eat the double click events inside the check rect foreach ( int role, roles )
if( event->type() == QEvent::MouseButtonDblClick ) { {
return true; 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 ) { } else if( event->type() == QEvent::MouseButtonPress ) {
QMouseEvent* me = static_cast< QMouseEvent* >( event ); QMouseEvent* me = static_cast< QMouseEvent* >( event );

View File

@@ -36,10 +36,11 @@ public:
virtual bool editorEvent ( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index ); 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 // 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 // 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 QRect configRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const = 0;
virtual QList<int> extraCheckRoles() const { return QList<int>(); }
signals: signals:
void configPressed( const QModelIndex& idx ); void configPressed( const QModelIndex& idx );

View File

@@ -59,12 +59,12 @@ set( libSources
EchonestCatalogSynchronizer.cpp EchonestCatalogSynchronizer.cpp
accounts/accountmanager.cpp accounts/AccountManager.cpp
accounts/account.cpp accounts/Account.cpp
accounts/AccountModel.cpp
sip/SipPlugin.cpp sip/SipPlugin.cpp
sip/SipHandler.cpp sip/SipHandler.cpp
sip/SipModel.cpp
sip/sipinfo.cpp sip/sipinfo.cpp
audio/audioengine.cpp audio/audioengine.cpp
@@ -284,14 +284,14 @@ set( libHeaders
album.h album.h
playlist.h playlist.h
accounts/account.h accounts/Account.h
accounts/accountmanager.h accounts/AccountManager.h
accounts/AccountModel.h
EchonestCatalogSynchronizer.h EchonestCatalogSynchronizer.h
sip/SipPlugin.h sip/SipPlugin.h
sip/SipHandler.h sip/SipHandler.h
sip/SipModel.h
sip/sipinfo.h sip/sipinfo.h
audio/audioengine.h audio/audioengine.h
@@ -484,7 +484,7 @@ set( libHeaders
set( libHeaders_NoMOC set( libHeaders_NoMOC
viewpage.h viewpage.h
accounts/account.h accounts/Account.h
infosystem/infoplugins/unix/imageconverter.h infosystem/infoplugins/unix/imageconverter.h

View File

@@ -1,6 +1,7 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
* *
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org> * Copyright 2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* Copyright 2011, Leo Franchi <lfranchi@kde.org?
* *
* Tomahawk is free software: you can redistribute it and/or modify * Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@@ -16,7 +17,7 @@
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>. * along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "account.h" #include "Account.h"
namespace Tomahawk namespace Tomahawk
{ {
@@ -24,6 +25,16 @@ namespace Tomahawk
namespace Accounts 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* QWidget*
Account::configurationWidget() Account::configurationWidget()
{ {
@@ -77,9 +88,4 @@ void
Account::refreshProxy() Account::refreshProxy()
{ {
}
}
} }

View File

@@ -1,6 +1,7 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
* *
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org> * Copyright 2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* Copyright 2011, Leo Franchi <lfranchi@kde.org?
* *
* Tomahawk is free software: you can redistribute it and/or modify * Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@@ -39,7 +40,7 @@ namespace InfoSystem
{ {
class InfoPlugin; class InfoPlugin;
} }
namespace Accounts namespace Accounts
{ {
@@ -54,13 +55,12 @@ inline QString generateId( const QString &factoryId )
class DLLEXPORT Account : public QObject class DLLEXPORT Account : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit Account( const QString &accountId ) enum AuthErrorCode { AuthError, ConnectionError };
: QObject() enum ConnectionState { Disconnected, Connecting, Connected, Disconnecting };
, m_enabled( false )
, m_autoConnect( false ) explicit Account( const QString &accountId );
, m_accountId( accountId ) {}
virtual ~Account() {} virtual ~Account() {}
virtual QString accountServiceName() const { QMutexLocker locker( &m_mutex ); return m_accountServiceName; } // e.g. "Twitter", "Last.fm" virtual QString accountServiceName() const { QMutexLocker locker( &m_mutex ); return m_accountServiceName; } // e.g. "Twitter", "Last.fm"
@@ -79,11 +79,13 @@ public:
virtual QIcon icon() const = 0; virtual QIcon icon() const = 0;
virtual bool canSelfAuthenticate() const = 0;
virtual void authenticate() = 0; virtual void authenticate() = 0;
virtual void deauthenticate() = 0; virtual void deauthenticate() = 0;
virtual ConnectionState connectionState() = 0;
virtual bool isAuthenticated() const = 0; virtual bool isAuthenticated() const = 0;
virtual QString errorMessage() const { QMutexLocker locker( &m_mutex ); return m_cachedError; }
virtual Tomahawk::InfoSystem::InfoPlugin* infoPlugin() = 0; virtual Tomahawk::InfoSystem::InfoPlugin* infoPlugin() = 0;
virtual SipPlugin* sipPlugin() = 0; virtual SipPlugin* sipPlugin() = 0;
@@ -129,13 +131,16 @@ public:
} }
virtual void refreshProxy() = 0; virtual void refreshProxy() = 0;
virtual void sync() { QMutexLocker locker( &m_mutex ); syncConfig(); }; virtual void sync() { QMutexLocker locker( &m_mutex ); syncConfig(); };
signals: signals:
void error( int errorId, const QString& errorStr );
void connectionStateChanged( Tomahawk::Accounts::Account::ConnectionState state );
void configurationChanged(); void configurationChanged();
void authenticated( bool ); void authenticated( bool );
protected: protected:
virtual void loadFromConfig( const QString &accountId ) virtual void loadFromConfig( const QString &accountId )
{ {
@@ -167,8 +172,14 @@ protected:
s->sync(); s->sync();
} }
private slots:
void onConnectionStateChanged( Tomahawk::Accounts::Account::ConnectionState );
void onError( int,QString );
private:
QString m_accountServiceName; QString m_accountServiceName;
QString m_accountFriendlyName; QString m_accountFriendlyName;
QString m_cachedError;
bool m_enabled; bool m_enabled;
bool m_autoConnect; bool m_autoConnect;
QString m_accountId; QString m_accountId;
@@ -203,4 +214,4 @@ public:
Q_DECLARE_INTERFACE( Tomahawk::Accounts::AccountFactory, "tomahawk.AccountFactory/1.0" ) Q_DECLARE_INTERFACE( Tomahawk::Accounts::AccountFactory, "tomahawk.AccountFactory/1.0" )
#endif #endif

View File

@@ -16,7 +16,7 @@
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>. * along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "accountmanager.h" #include "AccountManager.h"
#include "config.h" #include "config.h"
#include <QtCore/QLibrary> #include <QtCore/QLibrary>
@@ -48,13 +48,14 @@ AccountManager::AccountManager( QObject *parent )
loadPluginFactories( findPluginFactories() ); loadPluginFactories( findPluginFactories() );
} }
AccountManager::~AccountManager() AccountManager::~AccountManager()
{ {
disconnectAll();
qDeleteAll( m_accounts );
} }
QStringList QStringList
AccountManager::findPluginFactories() AccountManager::findPluginFactories()
{ {
@@ -187,8 +188,8 @@ AccountManager::addAccountPlugin( Account* account )
foreach( AccountType type, account->types() ) foreach( AccountType type, account->types() )
m_accountsByAccountType[ type ].append( account ); m_accountsByAccountType[ type ].append( account );
//TODO:?
//emit pluginAdded( account ); emit accountAdded( account );
} }

View File

@@ -25,7 +25,7 @@
#include "dllmacro.h" #include "dllmacro.h"
#include "infosystem/infosystem.h" #include "infosystem/infosystem.h"
#include "sip/SipPlugin.h" #include "sip/SipPlugin.h"
#include "account.h" #include "Account.h"
namespace Tomahawk namespace Tomahawk
{ {
@@ -36,10 +36,10 @@ namespace Accounts
class DLLEXPORT AccountManager : public QObject class DLLEXPORT AccountManager : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
static AccountManager* instance(); static AccountManager* instance();
explicit AccountManager( QObject *parent ); explicit AccountManager( QObject *parent );
virtual ~AccountManager(); virtual ~AccountManager();
@@ -51,12 +51,24 @@ public:
void addAccountPlugin( Account* account ); void addAccountPlugin( Account* account );
Account* loadPlugin( const QString &accountId ); Account* loadPlugin( const QString &accountId );
QString factoryFromId( const QString& accountId ) const; QString factoryFromId( const QString& accountId ) const;
QList< Account* > getAccounts() { return m_accounts; }; QList< Account* > accounts() const { return m_accounts; };
QList< Account* > getAccounts( Tomahawk::Accounts::AccountType type ) { return m_accountsByAccountType[ type ]; } 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: private:
QList< Account* > m_accounts; QList< Account* > m_accounts;
QList< Account* > m_enabledAccounts;
QList< Account* > m_connectedAccounts;
bool m_connected;
QHash< AccountType, QList< Account* > > m_accountsByAccountType; QHash< AccountType, QList< Account* > > m_accountsByAccountType;
QHash< QString, AccountFactory* > m_accountFactories; QHash< QString, AccountFactory* > m_accountFactories;
@@ -67,4 +79,4 @@ private:
}; };
#endif #endif

View File

@@ -0,0 +1,153 @@
/*
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 "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;
}
}
}

View File

@@ -1,5 +1,4 @@
/* /*
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 2011 Leo Franchi <lfranchi@kde.org> Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
@@ -21,43 +20,57 @@
#define SIPMODEL_H #define SIPMODEL_H
#include "dllmacro.h" #include "dllmacro.h"
#include "sip/SipPlugin.h"
#include <QModelIndex> #include <QModelIndex>
#include <QStringList> #include <QStringList>
class SipPlugin; namespace Tomahawk
{
namespace Accounts
{
class DLLEXPORT SipModel : public QAbstractItemModel class Account;
class DLLEXPORT AccountModel : public QAbstractListModel
{ {
Q_OBJECT Q_OBJECT
public: public:
enum Roles { enum BasicCapabilities
PluginName = Qt::UserRole + 15, {
ConnectionStateRole = Qt::UserRole + 17, NoCapabilities = 0,
HasConfig = Qt::UserRole + 18, SipCapability = 0x1,
FactoryRole = Qt::UserRole + 19, ResolverCapability = 0x2
ErrorString = Qt::UserRole + 20,
FactoryItemRole = Qt::UserRole + 21,
FactoryItemIcon = Qt::UserRole + 22,
SipPluginData = Qt::UserRole + 23,
SipPluginFactoryData = Qt::UserRole + 24
}; };
explicit SipModel( QObject* parent = 0 ); enum Roles {
virtual ~SipModel(); 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 QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const;
virtual int rowCount( const QModelIndex& parent = QModelIndex() ) 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 Qt::ItemFlags flags(const QModelIndex& index) 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);
private slots: private slots:
void pluginAdded( SipPlugin* p ); void accountAdded( Tomahawk::Accounts::Account* p );
void pluginRemoved( SipPlugin* p ); void accountRemoved( Tomahawk::Accounts::Account* p );
void pluginStateChanged( SipPlugin* p ); void accountStateChanged( Tomahawk::Accounts::Account::ConnectionState );
}; };
}
}
#endif // SIPMODEL_H #endif // SIPMODEL_H

View File

@@ -223,6 +223,7 @@ void
DatabaseWorker::logOp( DatabaseCommandLoggable* command ) DatabaseWorker::logOp( DatabaseCommandLoggable* command )
{ {
TomahawkSqlQuery oplogquery = m_dbimpl->newquery(); 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) " oplogquery.prepare( "INSERT INTO oplog(source, guid, command, singleton, compressed, json) "
"VALUES(?, ?, ?, ?, ?, ?)" ); "VALUES(?, ?, ?, ?, ?, ?)" );

View File

@@ -1,6 +1,7 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
* *
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org> * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
* *
* Tomahawk is free software: you can redistribute it and/or modify * Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@@ -32,7 +33,7 @@
#include "sourcelist.h" #include "sourcelist.h"
#include "tomahawksettings.h" #include "tomahawksettings.h"
#include "utils/logger.h" #include "utils/logger.h"
#include "accounts/accountmanager.h" #include "accounts/AccountManager.h"
#include "config.h" #include "config.h"
@@ -62,8 +63,6 @@ SipHandler::SipHandler( QObject* parent )
SipHandler::~SipHandler() SipHandler::~SipHandler()
{ {
qDebug() << Q_FUNC_INFO; qDebug() << Q_FUNC_INFO;
disconnectAll();
qDeleteAll( m_allPlugins );
} }
@@ -174,7 +173,7 @@ void
SipHandler::loadFromAccountManager() SipHandler::loadFromAccountManager()
{ {
tDebug() << Q_FUNC_INFO; 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 ) foreach( Tomahawk::Accounts::Account* account, accountList )
{ {
tDebug() << Q_FUNC_INFO << "adding plugin " << account->accountId(); tDebug() << Q_FUNC_INFO << "adding plugin " << account->accountId();

View File

@@ -1,6 +1,7 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
* *
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org> * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
* *
* Tomahawk is free software: you can redistribute it and/or modify * Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * 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 connectPlugin( const QString &pluginId = QString() );
void disconnectPlugin( const QString &pluginId = QString() ); void disconnectPlugin( const QString &pluginId = QString() );
void connectAll();
void disconnectAll();
void toggleConnect(); void toggleConnect();
@@ -105,11 +104,6 @@ private:
void loadPluginFactory( const QString& path ); void loadPluginFactory( const QString& path );
QString factoryFromId( const QString& pluginId ) const; 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 //TODO: move this to source
QHash<QString, SipInfo> m_peersSipInfos; QHash<QString, SipInfo> m_peersSipInfos;
QHash<QString, QPixmap> m_usernameAvatars; QHash<QString, QPixmap> m_usernameAvatars;

View File

@@ -1,227 +0,0 @@
/*
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 "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 );
}

View File

@@ -29,10 +29,6 @@ SipPlugin::SipPlugin( Tomahawk::Accounts::Account *account, QObject* parent )
: QObject( parent ) : QObject( parent )
, m_account( account ) , 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 ) ) );
} }

View File

@@ -26,7 +26,7 @@
#include <QString> #include <QString>
#include <QNetworkProxy> #include <QNetworkProxy>
#include "accounts/account.h" #include "accounts/Account.h"
#ifndef ENABLE_HEADLESS #ifndef ENABLE_HEADLESS
#include <QMenu> #include <QMenu>
#endif #endif
@@ -40,9 +40,6 @@ class DLLEXPORT SipPlugin : public QObject
Q_OBJECT Q_OBJECT
public: public:
enum SipErrorCode { AuthError, ConnectionError }; // Placeholder for errors, to be defined
enum ConnectionState { Disconnected, Connecting, Connected, Disconnecting };
SipPlugin(); SipPlugin();
explicit SipPlugin( Tomahawk::Accounts::Account *account, QObject* parent = 0 ); explicit SipPlugin( Tomahawk::Accounts::Account *account, QObject* parent = 0 );
virtual ~SipPlugin(); virtual ~SipPlugin();
@@ -53,8 +50,6 @@ public:
virtual bool isValid() const = 0; virtual bool isValid() const = 0;
virtual const QString friendlyName() const; virtual const QString friendlyName() const;
virtual const QString serviceName() const; virtual const QString serviceName() const;
virtual ConnectionState connectionState() const = 0;
virtual QString errorMessage() const;
#ifndef ENABLE_HEADLESS #ifndef ENABLE_HEADLESS
virtual QMenu* menu(); virtual QMenu* menu();
#endif #endif
@@ -76,9 +71,6 @@ public slots:
virtual void refreshProxy(); virtual void refreshProxy();
signals: signals:
void error( int, const QString& );
void stateChanged( SipPlugin::ConnectionState state );
void peerOnline( const QString& ); void peerOnline( const QString& );
void peerOffline( const QString& ); void peerOffline( const QString& );
void msgReceived( const QString& from, const QString& msg ); void msgReceived( const QString& from, const QString& msg );
@@ -99,17 +91,13 @@ signals:
void dataError( bool ); void dataError( bool );
private slots: private slots:
void onError( int, const QString& );
void onStateChange( SipPlugin::ConnectionState state );
void onPeerOnline( const QString &peerId ); void onPeerOnline( const QString &peerId );
void onPeerOffline( const QString &peerId ); void onPeerOffline( const QString &peerId );
protected: protected:
Tomahawk::Accounts::Account *m_account; Tomahawk::Accounts::Account *m_account;
private: private:
QString m_cachedError;
QStringList m_peersOnline; QStringList m_peersOnline;
}; };

View File

@@ -51,7 +51,7 @@
#include "network/servent.h" #include "network/servent.h"
#include "playlist/dynamic/widgets/LoadingSpinner.h" #include "playlist/dynamic/widgets/LoadingSpinner.h"
#include "sip/SipHandler.h" #include "sip/SipHandler.h"
#include "sip/SipModel.h" #include "sip/AccountModel.h"
#include "utils/logger.h" #include "utils/logger.h"
#include "ui_proxydialog.h" #include "ui_proxydialog.h"
@@ -417,7 +417,7 @@ SettingsDialog::testLastFmLogin()
// ensure they have up-to-date settings // ensure they have up-to-date settings
lastfm::setNetworkAccessManager( TomahawkUtils::nam() ); lastfm::setNetworkAccessManager( TomahawkUtils::nam() );
QNetworkReply* authJob = lastfm::ws::post( query ); QNetworkReply* authJob = lastfm::ws::post( query );
connect( authJob, SIGNAL( finished() ), SLOT( onLastFmFinished() ) ); connect( authJob, SIGNAL( finished() ), SLOT( onLastFmFinished() ) );
@@ -877,7 +877,7 @@ ProxyDialog::saveSettings()
qDebug() << Q_FUNC_INFO; qDebug() << Q_FUNC_INFO;
QNetworkProxy::ProxyType type = static_cast< QNetworkProxy::ProxyType>( m_backwardMap[ ui->typeBox->currentIndex() ] ); QNetworkProxy::ProxyType type = static_cast< QNetworkProxy::ProxyType>( m_backwardMap[ ui->typeBox->currentIndex() ] );
//First set settings //First set settings
TomahawkSettings* s = TomahawkSettings::instance(); TomahawkSettings* s = TomahawkSettings::instance();
s->setProxyHost( ui->hostLineEdit->text() ); s->setProxyHost( ui->hostLineEdit->text() );
@@ -890,7 +890,7 @@ ProxyDialog::saveSettings()
s->setProxyType( type ); s->setProxyType( type );
s->setProxyDns( ui->checkBoxUseProxyForDns->checkState() == Qt::Checked ); s->setProxyDns( ui->checkBoxUseProxyForDns->checkState() == Qt::Checked );
s->sync(); s->sync();
TomahawkUtils::NetworkProxyFactory* proxyFactory = TomahawkUtils::proxyFactory(); TomahawkUtils::NetworkProxyFactory* proxyFactory = TomahawkUtils::proxyFactory();
tDebug() << Q_FUNC_INFO << "Got proxyFactory: " << proxyFactory; tDebug() << Q_FUNC_INFO << "Got proxyFactory: " << proxyFactory;
if ( type == QNetworkProxy::NoProxy ) if ( type == QNetworkProxy::NoProxy )

View File

@@ -1,282 +0,0 @@
/*
Copyright (C) 2011 Leo Franchi <leo.franchi@kdab.com>
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 "sipconfigdelegate.h"
#include <QApplication>
#include <QPainter>
#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* >() ) );
}

View File

@@ -211,7 +211,7 @@ TomahawkApp::init()
tDebug() << "Init AccountManager."; tDebug() << "Init AccountManager.";
m_accountManager = QWeakPointer< Tomahawk::Accounts::AccountManager >( new Tomahawk::Accounts::AccountManager( this ) ); m_accountManager = QWeakPointer< Tomahawk::Accounts::AccountManager >( new Tomahawk::Accounts::AccountManager( this ) );
Tomahawk::Accounts::AccountManager::instance()->loadFromConfig(); Tomahawk::Accounts::AccountManager::instance()->loadFromConfig();
tDebug() << "Init InfoSystem."; tDebug() << "Init InfoSystem.";
m_infoSystem = QWeakPointer<Tomahawk::InfoSystem::InfoSystem>( new Tomahawk::InfoSystem::InfoSystem( this ) ); m_infoSystem = QWeakPointer<Tomahawk::InfoSystem::InfoSystem>( new Tomahawk::InfoSystem::InfoSystem( this ) );
@@ -505,7 +505,8 @@ void
TomahawkApp::initSIP() TomahawkApp::initSIP()
{ {
tDebug() << Q_FUNC_INFO; 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(); tDebug() << Q_FUNC_INFO << "testing account with name " << account->accountServiceName();
if ( account->configurationWidget() && account->configuration().isEmpty() ) if ( account->configurationWidget() && account->configuration().isEmpty() )
@@ -513,7 +514,7 @@ TomahawkApp::initSIP()
if ( !account->enabled() ) if ( !account->enabled() )
account->setEnabled( true ); 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 //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" ) ) if ( !arguments().contains( "--nosip" ) )
{ {