1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-03-19 15:29:42 +01: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
#define SIPCONFIGDELEGATE_H
#ifndef ACCOUNTDELEGATE_H
#define ACCOUNTDELEGATE_H
#include "configdelegatebase.h"
class SipPlugin;
class SipPluginFactory;
class SipConfigDelegate : public ConfigDelegateBase
namespace Tomahawk
{
namespace Accounts
{
class Account;
class AccountDelegate : public ConfigDelegateBase
{
Q_OBJECT
public:
SipConfigDelegate( QObject* parent = 0);
AccountDelegate( QObject* parent = 0);
virtual void paint ( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const;
virtual bool editorEvent ( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index );
virtual QSize sizeHint ( const QStyleOptionViewItem& option, const QModelIndex& index ) const;
virtual QRect checkRectForIndex( const QStyleOptionViewItem &option, const QModelIndex &idx ) const;
virtual QRect checkRectForIndex( const QStyleOptionViewItem &option, const QModelIndex &idx, int role ) const;
virtual QRect configRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const;
virtual QList<int> extraCheckRoles() const { return QList<int>() << (int)AccountModel::BasicCapabilityRole; }
private slots:
void askedForEdit( const QModelIndex& idx );
signals:
void sipFactoryClicked( SipPluginFactory* );
void openConfig( SipPlugin* );
void openConfig( Account* );
};
#endif // SIPCONFIGDELEGATE_H
}
}
#endif // ACCOUNTDELEGATE_H

View File

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

View File

@ -52,7 +52,7 @@ TwitterAccount::TwitterAccount( const QString &accountId )
QSet< AccountType > types;
types << InfoType << SipType;
setTypes( types );
m_configWidget = QWeakPointer< TwitterConfigWidget >( new TwitterConfigWidget( this, 0 ) );
connect( m_configWidget.data(), SIGNAL( twitterAuthed( bool ) ), SLOT( configDialogAuthedSignalSlot( bool ) ) );
@ -93,9 +93,9 @@ TwitterAccount::sipPlugin()
void
TwitterAccount::authenticate()
{
tDebug() << Q_FUNC_INFO << "credentials: " << m_credentials.keys();
tDebug() << Q_FUNC_INFO << "credentials: " << credentials().keys();
if ( m_credentials[ "oauthtoken" ].toString().isEmpty() || m_credentials[ "oauthtokensecret" ].toString().isEmpty() )
if ( credentials[ "oauthtoken" ].toString().isEmpty() || credentials()[ "oauthtokensecret" ].toString().isEmpty() )
{
qDebug() << "TwitterSipPlugin has empty Twitter credentials; not connecting";
return;
@ -154,7 +154,9 @@ TwitterAccount::connectAuthVerifyReply( const QTweetUser &user )
else
{
tDebug() << "TwitterAccount successfully authenticated to Twitter as user " << user.screenName();
m_configuration[ "screenname" ] = user.screenName();
QVariantHash config = configuration();
config[ "screenname" ] = user.screenName();
setConfiguration( config );
sync();
emit nowAuthenticated( m_twitterAuth, user );
}

View File

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

View File

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

View File

@ -25,6 +25,8 @@
#include "utils/tomahawkutils.h"
#include "utils/logger.h"
#define ROW_HEIGHT 50
ConfigDelegateBase::ConfigDelegateBase ( QObject* parent )
: QStyledItemDelegate ( parent )
{
@ -36,23 +38,7 @@ QSize
ConfigDelegateBase::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const
{
int width = QStyledItemDelegate::sizeHint( option, index ).width();
QStyleOptionViewItemV4 opt = option;
initStyleOption( &opt, index );
QFont name = opt.font;
name.setPointSize( name.pointSize() + 2 );
name.setBold( true );
QFont path = opt.font;
path.setItalic( true );
path.setPointSize( path.pointSize() - 1 );
QFontMetrics bfm( name );
QFontMetrics sfm( path );
return QSize( width, 2 * PADDING + bfm.height() + sfm.height() );
return QSize( width, ROW_HEIGHT );
}
void
@ -94,17 +80,24 @@ ConfigDelegateBase::editorEvent ( QEvent* event, QAbstractItemModel* model, cons
m_configPressed = QModelIndex();
QMouseEvent* me = static_cast< QMouseEvent* >( event );
if( me->button() != Qt::LeftButton || !checkRectForIndex( option, index ).contains( me->pos() ) )
return false;
QList<int> roles = QList<int>() << (int)Qt::CheckStateRole;
roles.append( extraCheckRoles() );
// eat the double click events inside the check rect
if( event->type() == QEvent::MouseButtonDblClick ) {
return true;
foreach ( int role, roles )
{
if( me->button() != Qt::LeftButton || !checkRectForIndex( option, index, role ).contains( me->pos() ) )
return false;
// eat the double click events inside the check rect
if( event->type() == QEvent::MouseButtonDblClick ) {
return true;
}
Qt::CheckState curState = static_cast< Qt::CheckState >( index.data( role ).toInt() );
Qt::CheckState newState = curState == Qt::Checked ? Qt::Unchecked : Qt::Checked;
return model->setData( index, newState, role );
}
Qt::CheckState curState = static_cast< Qt::CheckState >( index.data( Qt::CheckStateRole ).toInt() );
Qt::CheckState newState = curState == Qt::Checked ? Qt::Unchecked : Qt::Checked;
return model->setData( index, newState, Qt::CheckStateRole );
} else if( event->type() == QEvent::MouseButtonPress ) {
QMouseEvent* me = static_cast< QMouseEvent* >( event );

View File

@ -36,10 +36,11 @@ public:
virtual bool editorEvent ( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index );
// if you want to use a checkbox, you need to have this say where to paint it
virtual QRect checkRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const = 0;
virtual QRect checkRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx, int role ) const = 0;
// if you want to use a config wrench, you need to have this say where to paint it
virtual QRect configRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const = 0;
virtual QList<int> extraCheckRoles() const { return QList<int>(); }
signals:
void configPressed( const QModelIndex& idx );

View File

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

View File

@ -1,6 +1,7 @@
/* === 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
* 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/>.
*/
#include "account.h"
#include "Account.h"
namespace Tomahawk
{
@ -24,6 +25,16 @@ namespace Tomahawk
namespace Accounts
{
Account::Account( const QString& accountId )
: QObject()
, m_enabled( false )
, m_autoConnect( false )
, m_accountId( accountId )
{
connect( this, SIGNAL( error( int, QString ) ), this, SLOT( onError( int,QString ) ) );
connect( this, SIGNAL( connectionStateChanged( Tomahawk::Accounts::Account::ConnectionState ) ) , this, SLOT( onConnectionStateChanged( Tomahawk::Accounts::Account::ConnectionState ) ) );
}
QWidget*
Account::configurationWidget()
{
@ -77,9 +88,4 @@ void
Account::refreshProxy()
{
}
}
}

View File

@ -1,6 +1,7 @@
/* === 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
* it under the terms of the GNU General Public License as published by
@ -39,7 +40,7 @@ namespace InfoSystem
{
class InfoPlugin;
}
namespace Accounts
{
@ -54,13 +55,12 @@ inline QString generateId( const QString &factoryId )
class DLLEXPORT Account : public QObject
{
Q_OBJECT
public:
explicit Account( const QString &accountId )
: QObject()
, m_enabled( false )
, m_autoConnect( false )
, m_accountId( accountId ) {}
enum AuthErrorCode { AuthError, ConnectionError };
enum ConnectionState { Disconnected, Connecting, Connected, Disconnecting };
explicit Account( const QString &accountId );
virtual ~Account() {}
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 bool canSelfAuthenticate() const = 0;
virtual void authenticate() = 0;
virtual void deauthenticate() = 0;
virtual ConnectionState connectionState() = 0;
virtual bool isAuthenticated() const = 0;
virtual QString errorMessage() const { QMutexLocker locker( &m_mutex ); return m_cachedError; }
virtual Tomahawk::InfoSystem::InfoPlugin* infoPlugin() = 0;
virtual SipPlugin* sipPlugin() = 0;
@ -129,13 +131,16 @@ public:
}
virtual void refreshProxy() = 0;
virtual void sync() { QMutexLocker locker( &m_mutex ); syncConfig(); };
signals:
void error( int errorId, const QString& errorStr );
void connectionStateChanged( Tomahawk::Accounts::Account::ConnectionState state );
void configurationChanged();
void authenticated( bool );
protected:
virtual void loadFromConfig( const QString &accountId )
{
@ -167,8 +172,14 @@ protected:
s->sync();
}
private slots:
void onConnectionStateChanged( Tomahawk::Accounts::Account::ConnectionState );
void onError( int,QString );
private:
QString m_accountServiceName;
QString m_accountFriendlyName;
QString m_cachedError;
bool m_enabled;
bool m_autoConnect;
QString m_accountId;
@ -203,4 +214,4 @@ public:
Q_DECLARE_INTERFACE( Tomahawk::Accounts::AccountFactory, "tomahawk.AccountFactory/1.0" )
#endif
#endif

View File

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

View File

@ -25,7 +25,7 @@
#include "dllmacro.h"
#include "infosystem/infosystem.h"
#include "sip/SipPlugin.h"
#include "account.h"
#include "Account.h"
namespace Tomahawk
{
@ -36,10 +36,10 @@ namespace Accounts
class DLLEXPORT AccountManager : public QObject
{
Q_OBJECT
public:
static AccountManager* instance();
explicit AccountManager( QObject *parent );
virtual ~AccountManager();
@ -51,12 +51,24 @@ public:
void addAccountPlugin( Account* account );
Account* loadPlugin( const QString &accountId );
QString factoryFromId( const QString& accountId ) const;
QList< Account* > getAccounts() { return m_accounts; };
QList< Account* > getAccounts( Tomahawk::Accounts::AccountType type ) { return m_accountsByAccountType[ type ]; }
QList< Account* > accounts() const { return m_accounts; };
QList< Account* > accounts( Tomahawk::Accounts::AccountType type ) const { return m_accountsByAccountType[ type ]; }
public slots:
void connectAll();
void disconnectAll();
signals:
void accountAdded( Tomahawk::Accounts::Account* );
void accountRemoved( Tomahawk::Accounts::Account* );
private:
QList< Account* > m_accounts;
QList< Account* > m_enabledAccounts;
QList< Account* > m_connectedAccounts;
bool m_connected;
QHash< AccountType, QList< Account* > > m_accountsByAccountType;
QHash< QString, AccountFactory* > m_accountFactories;
@ -67,4 +79,4 @@ private:
};
#endif
#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>
This program is free software: you can redistribute it and/or modify
@ -21,43 +20,57 @@
#define SIPMODEL_H
#include "dllmacro.h"
#include "sip/SipPlugin.h"
#include <QModelIndex>
#include <QStringList>
class SipPlugin;
namespace Tomahawk
{
namespace Accounts
{
class DLLEXPORT SipModel : public QAbstractItemModel
class Account;
class DLLEXPORT AccountModel : public QAbstractListModel
{
Q_OBJECT
public:
enum Roles {
PluginName = Qt::UserRole + 15,
ConnectionStateRole = Qt::UserRole + 17,
HasConfig = Qt::UserRole + 18,
FactoryRole = Qt::UserRole + 19,
ErrorString = Qt::UserRole + 20,
FactoryItemRole = Qt::UserRole + 21,
FactoryItemIcon = Qt::UserRole + 22,
SipPluginData = Qt::UserRole + 23,
SipPluginFactoryData = Qt::UserRole + 24
enum BasicCapabilities
{
NoCapabilities = 0,
SipCapability = 0x1,
ResolverCapability = 0x2
};
explicit SipModel( QObject* parent = 0 );
virtual ~SipModel();
enum Roles {
AccountName = Qt::UserRole + 15,
AccountIcon = Qt::UserRole + 16,
HeadlineText = Qt::UserRole + 17,
DescText = Qt::UserRole + 18,
BasicCapabilityRole = Qt::UserRole + 19,
ConnectionStateRole = Qt::UserRole + 20,
HasConfig = Qt::UserRole + 21,
ErrorString = Qt::UserRole + 22,
AccountData = Qt::UserRole + 23 // raw plugin
};
explicit AccountModel( QObject* parent = 0 );
virtual ~AccountModel();
virtual QModelIndex index ( int row, int column, const QModelIndex& parent = QModelIndex() ) const;
virtual QModelIndex parent ( const QModelIndex& child ) const;
virtual QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const;
virtual int rowCount( const QModelIndex& parent = QModelIndex() ) const;
virtual int columnCount( const QModelIndex& parent ) const;
virtual Qt::ItemFlags flags(const QModelIndex& index) const;
virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole);
private slots:
void pluginAdded( SipPlugin* p );
void pluginRemoved( SipPlugin* p );
void pluginStateChanged( SipPlugin* p );
void accountAdded( Tomahawk::Accounts::Account* p );
void accountRemoved( Tomahawk::Accounts::Account* p );
void accountStateChanged( Tomahawk::Accounts::Account::ConnectionState );
};
}
}
#endif // SIPMODEL_H

View File

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

View File

@ -1,6 +1,7 @@
/* === This file is part of Tomahawk Player - <http://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
* it under the terms of the GNU General Public License as published by
@ -32,7 +33,7 @@
#include "sourcelist.h"
#include "tomahawksettings.h"
#include "utils/logger.h"
#include "accounts/accountmanager.h"
#include "accounts/AccountManager.h"
#include "config.h"
@ -62,8 +63,6 @@ SipHandler::SipHandler( QObject* parent )
SipHandler::~SipHandler()
{
qDebug() << Q_FUNC_INFO;
disconnectAll();
qDeleteAll( m_allPlugins );
}
@ -174,7 +173,7 @@ void
SipHandler::loadFromAccountManager()
{
tDebug() << Q_FUNC_INFO;
QList< Tomahawk::Accounts::Account* > accountList = Tomahawk::Accounts::AccountManager::instance()->getAccounts( Tomahawk::Accounts::SipType );
QList< Tomahawk::Accounts::Account* > accountList = Tomahawk::Accounts::AccountManager::instance()->accounts( Tomahawk::Accounts::SipType );
foreach( Tomahawk::Accounts::Account* account, accountList )
{
tDebug() << Q_FUNC_INFO << "adding plugin " << account->accountId();

View File

@ -1,6 +1,7 @@
/* === This file is part of Tomahawk Player - <http://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
* it under the terms of the GNU General Public License as published by
@ -60,8 +61,6 @@ public slots:
void connectPlugin( const QString &pluginId = QString() );
void disconnectPlugin( const QString &pluginId = QString() );
void connectAll();
void disconnectAll();
void toggleConnect();
@ -105,11 +104,6 @@ private:
void loadPluginFactory( const QString& path );
QString factoryFromId( const QString& pluginId ) const;
QList< SipPlugin* > m_allPlugins;
QList< SipPlugin* > m_enabledPlugins;
QList< SipPlugin* > m_connectedPlugins;
bool m_connected;
//TODO: move this to source
QHash<QString, SipInfo> m_peersSipInfos;
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 )
, 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 <QNetworkProxy>
#include "accounts/account.h"
#include "accounts/Account.h"
#ifndef ENABLE_HEADLESS
#include <QMenu>
#endif
@ -40,9 +40,6 @@ class DLLEXPORT SipPlugin : public QObject
Q_OBJECT
public:
enum SipErrorCode { AuthError, ConnectionError }; // Placeholder for errors, to be defined
enum ConnectionState { Disconnected, Connecting, Connected, Disconnecting };
SipPlugin();
explicit SipPlugin( Tomahawk::Accounts::Account *account, QObject* parent = 0 );
virtual ~SipPlugin();
@ -53,8 +50,6 @@ public:
virtual bool isValid() const = 0;
virtual const QString friendlyName() const;
virtual const QString serviceName() const;
virtual ConnectionState connectionState() const = 0;
virtual QString errorMessage() const;
#ifndef ENABLE_HEADLESS
virtual QMenu* menu();
#endif
@ -76,9 +71,6 @@ public slots:
virtual void refreshProxy();
signals:
void error( int, const QString& );
void stateChanged( SipPlugin::ConnectionState state );
void peerOnline( const QString& );
void peerOffline( const QString& );
void msgReceived( const QString& from, const QString& msg );
@ -99,17 +91,13 @@ signals:
void dataError( bool );
private slots:
void onError( int, const QString& );
void onStateChange( SipPlugin::ConnectionState state );
void onPeerOnline( const QString &peerId );
void onPeerOffline( const QString &peerId );
protected:
Tomahawk::Accounts::Account *m_account;
private:
QString m_cachedError;
QStringList m_peersOnline;
};

View File

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

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.";
m_accountManager = QWeakPointer< Tomahawk::Accounts::AccountManager >( new Tomahawk::Accounts::AccountManager( this ) );
Tomahawk::Accounts::AccountManager::instance()->loadFromConfig();
tDebug() << "Init InfoSystem.";
m_infoSystem = QWeakPointer<Tomahawk::InfoSystem::InfoSystem>( new Tomahawk::InfoSystem::InfoSystem( this ) );
@ -505,7 +505,8 @@ void
TomahawkApp::initSIP()
{
tDebug() << Q_FUNC_INFO;
foreach ( Tomahawk::Accounts::Account* account, Tomahawk::Accounts::AccountManager::instance()->getAccounts() )
// TODO debugging hack only
foreach ( Tomahawk::Accounts::Account* account, Tomahawk::Accounts::AccountManager::instance()->accounts() )
{
tDebug() << Q_FUNC_INFO << "testing account with name " << account->accountServiceName();
if ( account->configurationWidget() && account->configuration().isEmpty() )
@ -513,7 +514,7 @@ TomahawkApp::initSIP()
if ( !account->enabled() )
account->setEnabled( true );
}
//FIXME: jabber autoconnect is really more, now that there is sip -- should be renamed and/or split out of jabber-specific settings
if ( !arguments().contains( "--nosip" ) )
{