mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-09 07:36:48 +02:00
Step one in the pivot
This commit is contained in:
@@ -470,7 +470,7 @@ AccountDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const QS
|
|||||||
else if ( m_cachedButtonRects.contains( index ) && m_cachedButtonRects[ index ].contains( me->pos() ) )
|
else if ( m_cachedButtonRects.contains( index ) && m_cachedButtonRects[ index ].contains( me->pos() ) )
|
||||||
{
|
{
|
||||||
// Install/create/etc button for this row
|
// Install/create/etc button for this row
|
||||||
model->setData( index, true, AccountModel::ButtonClickedRole );
|
model->setData( index, true, AccountModel::AddAccountButtonRole );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -30,8 +30,7 @@ using namespace Tomahawk;
|
|||||||
using namespace Accounts;
|
using namespace Accounts;
|
||||||
|
|
||||||
AccountModel::AccountModel( QObject* parent )
|
AccountModel::AccountModel( QObject* parent )
|
||||||
: QAbstractItemModel( parent )
|
: QAbstractListModel( parent )
|
||||||
, m_rootItem( 0 )
|
|
||||||
{
|
{
|
||||||
loadData();
|
loadData();
|
||||||
}
|
}
|
||||||
@@ -41,9 +40,8 @@ AccountModel::loadData()
|
|||||||
{
|
{
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
|
|
||||||
delete m_rootItem;
|
qDeleteAll( m_accounts );
|
||||||
|
|
||||||
m_rootItem = new AccountModelNode();
|
|
||||||
// Add all factories
|
// Add all factories
|
||||||
QList< AccountFactory* > factories = AccountManager::instance()->factories();
|
QList< AccountFactory* > factories = AccountManager::instance()->factories();
|
||||||
QList< Account* > allAccounts = AccountManager::instance()->accounts();
|
QList< Account* > allAccounts = AccountManager::instance()->accounts();
|
||||||
@@ -53,20 +51,20 @@ AccountModel::loadData()
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
qDebug() << "Creating factory node:" << fac->prettyName();
|
qDebug() << "Creating factory node:" << fac->prettyName();
|
||||||
new AccountModelNode( m_rootItem, fac );
|
m_accounts << new AccountModelNode( fac );
|
||||||
}
|
}
|
||||||
|
|
||||||
// add all attica resolvers (installed or uninstalled)
|
// add all attica resolvers (installed or uninstalled)
|
||||||
Attica::Content::List fromAttica = AtticaManager::instance()->resolvers();
|
Attica::Content::List fromAttica = AtticaManager::instance()->resolvers();
|
||||||
foreach ( const Attica::Content& content, fromAttica )
|
foreach ( const Attica::Content& content, fromAttica )
|
||||||
new AccountModelNode( m_rootItem, content );
|
m_accounts << new AccountModelNode( content );
|
||||||
|
|
||||||
// Add all non-attica manually installed resolvers
|
// Add all non-attica manually installed resolvers
|
||||||
foreach ( Account* acct, allAccounts )
|
foreach ( Account* acct, allAccounts )
|
||||||
{
|
{
|
||||||
if ( qobject_cast< ResolverAccount* >( acct ) && !qobject_cast< AtticaResolverAccount* >( acct ) )
|
if ( qobject_cast< ResolverAccount* >( acct ) && !qobject_cast< AtticaResolverAccount* >( acct ) )
|
||||||
{
|
{
|
||||||
new AccountModelNode( m_rootItem, qobject_cast< ResolverAccount* >( acct ) );
|
m_accounts << new AccountModelNode( qobject_cast< ResolverAccount* >( acct ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,173 +84,140 @@ AccountModel::data( const QModelIndex& index, int role ) const
|
|||||||
if ( !hasIndex( index.row(), index.column(), index.parent() ) )
|
if ( !hasIndex( index.row(), index.column(), index.parent() ) )
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
||||||
const AccountModelNode* node = nodeFromIndex( index );
|
const AccountModelNode* node = m_accounts.at( index.row() );
|
||||||
if ( node->parent == m_rootItem ) {
|
// This is a top-level item. 3 cases
|
||||||
// This is a top-level item. 3 cases
|
|
||||||
Q_ASSERT( node->type != AccountModelNode::AccountType ); // must not be of this type, these should be children (other branch of if)
|
|
||||||
|
|
||||||
switch ( node->type )
|
switch ( node->type )
|
||||||
|
{
|
||||||
|
case AccountModelNode::FactoryType:
|
||||||
{
|
{
|
||||||
case AccountModelNode::FactoryType:
|
AccountFactory* fac = node->factory;
|
||||||
{
|
Q_ASSERT( fac );
|
||||||
AccountFactory* fac = node->factory;
|
|
||||||
Q_ASSERT( fac );
|
|
||||||
|
|
||||||
|
switch ( role )
|
||||||
|
{
|
||||||
|
case Qt::DisplayRole:
|
||||||
|
return fac->prettyName();
|
||||||
|
case Qt::DecorationRole:
|
||||||
|
return fac->icon();
|
||||||
|
case StateRole:
|
||||||
|
return ShippedWithTomahawk;
|
||||||
|
case DescriptionRole:
|
||||||
|
return fac->description();
|
||||||
|
case RowTypeRole:
|
||||||
|
return TopLevelFactory;
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case AccountModelNode::AtticaType:
|
||||||
|
{
|
||||||
|
Attica::Content c = node->atticaContent;
|
||||||
|
Q_ASSERT( !c.id().isNull() );
|
||||||
|
|
||||||
|
switch( role )
|
||||||
|
{
|
||||||
|
case Qt::DisplayRole:
|
||||||
|
return c.name();
|
||||||
|
case Qt::DecorationRole:
|
||||||
|
return QVariant::fromValue< QPixmap >( AtticaManager::instance()->iconForResolver( c ) );
|
||||||
|
case StateRole:
|
||||||
|
return (int)AtticaManager::instance()->resolverState( c );
|
||||||
|
case DescriptionRole:
|
||||||
|
return c.description();
|
||||||
|
case AuthorRole:
|
||||||
|
return c.author();
|
||||||
|
case RowTypeRole:
|
||||||
|
return TopLevelAccount;
|
||||||
|
case RatingRole:
|
||||||
|
return c.rating() / 20; // rating is out of 100
|
||||||
|
case DownloadCounterRole:
|
||||||
|
return c.downloads();
|
||||||
|
case VersionRole:
|
||||||
|
return c.version();
|
||||||
|
case UserHasRatedRole:
|
||||||
|
return AtticaManager::instance()->userHasRated( c );
|
||||||
|
default:
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
AtticaResolverAccount* atticaAcct = node->atticaAccount;
|
||||||
|
if ( atticaAcct )
|
||||||
|
{
|
||||||
|
// If the resolver is installed or on disk, we expose some additional data
|
||||||
switch ( role )
|
switch ( role )
|
||||||
{
|
{
|
||||||
case Qt::DisplayRole:
|
case HasConfig:
|
||||||
return fac->prettyName();
|
return atticaAcct->configurationWidget() != 0;
|
||||||
case Qt::DecorationRole:
|
case Qt::CheckStateRole:
|
||||||
return fac->icon();
|
return atticaAcct->enabled() ? Qt::Checked : Qt::Unchecked;
|
||||||
case StateRole:
|
case AccountData:
|
||||||
return ShippedWithTomahawk;
|
return QVariant::fromValue< QObject* >( atticaAcct );
|
||||||
case DescriptionRole:
|
case ConnectionStateRole:
|
||||||
return fac->description();
|
return atticaAcct->connectionState();
|
||||||
case RowTypeRole:
|
|
||||||
return TopLevelFactory;
|
|
||||||
default:
|
|
||||||
return QVariant();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case AccountModelNode::AtticaType:
|
|
||||||
{
|
|
||||||
Attica::Content c = node->atticaContent;
|
|
||||||
Q_ASSERT( !c.id().isNull() );
|
|
||||||
|
|
||||||
switch( role )
|
|
||||||
{
|
|
||||||
case Qt::DisplayRole:
|
|
||||||
return c.name();
|
|
||||||
case Qt::DecorationRole:
|
|
||||||
return QVariant::fromValue< QPixmap >( AtticaManager::instance()->iconForResolver( c ) );
|
|
||||||
case StateRole:
|
|
||||||
return (int)AtticaManager::instance()->resolverState( c );
|
|
||||||
case DescriptionRole:
|
|
||||||
return c.description();
|
|
||||||
case AuthorRole:
|
|
||||||
return c.author();
|
|
||||||
case RowTypeRole:
|
|
||||||
return TopLevelAccount;
|
|
||||||
case RatingRole:
|
|
||||||
return c.rating() / 20; // rating is out of 100
|
|
||||||
case DownloadCounterRole:
|
|
||||||
return c.downloads();
|
|
||||||
case VersionRole:
|
|
||||||
return c.version();
|
|
||||||
case UserHasRatedRole:
|
|
||||||
return AtticaManager::instance()->userHasRated( c );
|
|
||||||
default:
|
default:
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
AtticaResolverAccount* atticaAcct = node->atticaAccount;
|
|
||||||
if ( atticaAcct )
|
|
||||||
{
|
|
||||||
// If the resolver is installed or on disk, we expose some additional data
|
|
||||||
switch ( role )
|
|
||||||
{
|
|
||||||
case HasConfig:
|
|
||||||
return atticaAcct->configurationWidget() != 0;
|
|
||||||
case Qt::CheckStateRole:
|
|
||||||
return atticaAcct->enabled() ? Qt::Checked : Qt::Unchecked;
|
|
||||||
case AccountData:
|
|
||||||
return QVariant::fromValue< QObject* >( atticaAcct );
|
|
||||||
case ConnectionStateRole:
|
|
||||||
return atticaAcct->connectionState();
|
|
||||||
default:
|
|
||||||
;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return QVariant();
|
|
||||||
}
|
}
|
||||||
case AccountModelNode::ManualResolverType:
|
return QVariant();
|
||||||
case AccountModelNode::UniqueFactoryType:
|
|
||||||
{
|
|
||||||
Account* acct = 0;
|
|
||||||
if ( node->type == AccountModelNode::ManualResolverType )
|
|
||||||
acct = node->resolverAccount;
|
|
||||||
else if ( node->type == AccountModelNode::UniqueFactoryType )
|
|
||||||
acct = node->account;
|
|
||||||
|
|
||||||
// If there's no account*, then it means it's a unique factory that hasn't been created
|
|
||||||
if ( !acct )
|
|
||||||
{
|
|
||||||
Q_ASSERT( node->type == AccountModelNode::UniqueFactoryType );
|
|
||||||
Q_ASSERT( node->factory );
|
|
||||||
|
|
||||||
switch( role )
|
|
||||||
{
|
|
||||||
case Qt::DisplayRole:
|
|
||||||
return node->factory->prettyName();
|
|
||||||
case Qt::DecorationRole:
|
|
||||||
return node->factory->icon();
|
|
||||||
case DescriptionRole:
|
|
||||||
return node->factory->description();
|
|
||||||
case RowTypeRole:
|
|
||||||
return TopLevelFactory;
|
|
||||||
case StateRole:
|
|
||||||
return Uninstalled;
|
|
||||||
default:
|
|
||||||
return QVariant();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch ( role )
|
|
||||||
{
|
|
||||||
case Qt::DisplayRole:
|
|
||||||
return acct->accountFriendlyName();
|
|
||||||
case Qt::DecorationRole:
|
|
||||||
return acct->icon();
|
|
||||||
case DescriptionRole:
|
|
||||||
return node->type == AccountModelNode::ManualResolverType ? QString() : node->factory->description();
|
|
||||||
case Qt::CheckStateRole:
|
|
||||||
return acct->enabled() ? Qt::Checked : Qt::Unchecked;
|
|
||||||
case AccountData:
|
|
||||||
return QVariant::fromValue< QObject* >( acct );
|
|
||||||
case RowTypeRole:
|
|
||||||
return TopLevelAccount;
|
|
||||||
case ConnectionStateRole:
|
|
||||||
return acct->connectionState();
|
|
||||||
case HasConfig:
|
|
||||||
return acct->configurationWidget() != 0;
|
|
||||||
case StateRole:
|
|
||||||
return Installed;
|
|
||||||
default:
|
|
||||||
return QVariant();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case AccountModelNode::AccountType:
|
|
||||||
Q_ASSERT( false ); // Should not be here---all account nodes should be children of top level nodes
|
|
||||||
}
|
}
|
||||||
}
|
case AccountModelNode::ManualResolverType:
|
||||||
else
|
case AccountModelNode::UniqueFactoryType:
|
||||||
{
|
|
||||||
// This is a child account* of an accountfactory*
|
|
||||||
Q_ASSERT( node->type == AccountModelNode::AccountType );
|
|
||||||
Q_ASSERT( node->children.isEmpty() );
|
|
||||||
Q_ASSERT( node->account );
|
|
||||||
|
|
||||||
Account* acc = node->account;
|
|
||||||
switch ( role )
|
|
||||||
{
|
{
|
||||||
case RowTypeRole:
|
Account* acct = 0;
|
||||||
return ChildAccount;
|
if ( node->type == AccountModelNode::ManualResolverType )
|
||||||
case Qt::DisplayRole:
|
acct = node->resolverAccount;
|
||||||
return acc->accountFriendlyName();
|
else if ( node->type == AccountModelNode::UniqueFactoryType )
|
||||||
case ConnectionStateRole:
|
acct = node->accounts.first();
|
||||||
return acc->connectionState();
|
|
||||||
case HasConfig:
|
// If there's no account*, then it means it's a unique factory that hasn't been created
|
||||||
return ( acc->configurationWidget() != 0 );
|
if ( !acct )
|
||||||
case ErrorString:
|
{
|
||||||
return acc->errorMessage();
|
Q_ASSERT( node->type == AccountModelNode::UniqueFactoryType );
|
||||||
case Qt::CheckStateRole:
|
Q_ASSERT( node->factory );
|
||||||
return acc->enabled() ? Qt::Checked : Qt::Unchecked;
|
|
||||||
case AccountData:
|
switch( role )
|
||||||
return QVariant::fromValue< QObject* >( acc );
|
{
|
||||||
default:
|
case Qt::DisplayRole:
|
||||||
return QVariant();
|
return node->factory->prettyName();
|
||||||
|
case Qt::DecorationRole:
|
||||||
|
return node->factory->icon();
|
||||||
|
case DescriptionRole:
|
||||||
|
return node->factory->description();
|
||||||
|
case RowTypeRole:
|
||||||
|
return TopLevelFactory;
|
||||||
|
case StateRole:
|
||||||
|
return Uninstalled;
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch ( role )
|
||||||
|
{
|
||||||
|
case Qt::DisplayRole:
|
||||||
|
return acct->accountFriendlyName();
|
||||||
|
case Qt::DecorationRole:
|
||||||
|
return acct->icon();
|
||||||
|
case DescriptionRole:
|
||||||
|
return node->type == AccountModelNode::ManualResolverType ? QString() : node->factory->description();
|
||||||
|
case Qt::CheckStateRole:
|
||||||
|
return acct->enabled() ? Qt::Checked : Qt::Unchecked;
|
||||||
|
case AccountData:
|
||||||
|
return QVariant::fromValue< QObject* >( acct );
|
||||||
|
case RowTypeRole:
|
||||||
|
return TopLevelAccount;
|
||||||
|
case ConnectionStateRole:
|
||||||
|
return acct->connectionState();
|
||||||
|
case HasConfig:
|
||||||
|
return acct->configurationWidget() != 0;
|
||||||
|
case StateRole:
|
||||||
|
return Installed;
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,32 +232,54 @@ AccountModel::setData( const QModelIndex& index, const QVariant& value, int role
|
|||||||
if ( !index.isValid() || !hasIndex( index.row(), index.column(), index.parent() ) )
|
if ( !index.isValid() || !hasIndex( index.row(), index.column(), index.parent() ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
AccountModelNode* node = nodeFromIndex( index );
|
AccountModelNode* node = m_accounts.at( index.row() );
|
||||||
|
|
||||||
if ( role == CheckboxClickedRole )
|
if ( role == CheckboxClickedRole )
|
||||||
{
|
{
|
||||||
// All checkboxes are for turning on/off an account. So we can just do that
|
|
||||||
Q_ASSERT( node->account || node->resolverAccount || node->atticaAccount );
|
|
||||||
Q_ASSERT( node->type != AccountModelNode::FactoryType );
|
|
||||||
|
|
||||||
Account* acct = 0;
|
Account* acct = 0;
|
||||||
switch ( node->type )
|
switch ( node->type )
|
||||||
{
|
{
|
||||||
case AccountModelNode::AccountType:
|
|
||||||
case AccountModelNode::UniqueFactoryType:
|
case AccountModelNode::UniqueFactoryType:
|
||||||
acct = node->account;
|
Q_ASSERT( node->accounts.size() == 1 );
|
||||||
|
acct = node->accounts.first();
|
||||||
break;
|
break;
|
||||||
case AccountModelNode::AtticaType:
|
case AccountModelNode::AtticaType:
|
||||||
acct = node->atticaAccount;
|
{
|
||||||
break;
|
// This may or may not be installed. if it's not installed yet, install it, then go ahead and enable it
|
||||||
|
Q_ASSERT( node->atticaContent.isValid() );
|
||||||
|
|
||||||
|
Attica::Content resolver = node->atticaContent;
|
||||||
|
AtticaManager::ResolverState state = AtticaManager::instance()->resolverState( resolver );
|
||||||
|
if ( state == AtticaManager::Installed )
|
||||||
|
{
|
||||||
|
acct = node->atticaAccount;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
connect( AtticaManager::instance(), SIGNAL( resolverInstalled( QString ) ), this, SLOT( atticaInstalled( QString ) ) );
|
||||||
|
m_waitingForAtticaInstall.insert( resolver.id() );
|
||||||
|
|
||||||
|
AtticaManager::instance()->installResolver( resolver );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
case AccountModelNode::ManualResolverType:
|
case AccountModelNode::ManualResolverType:
|
||||||
acct = node->resolverAccount;
|
acct = node->resolverAccount;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
;
|
;
|
||||||
};
|
};
|
||||||
Q_ASSERT( acct );
|
|
||||||
|
|
||||||
|
if ( node->type == AccountModelNode::FactoryType )
|
||||||
|
{
|
||||||
|
// TODO handle overall on/off
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_ASSERT( acct );
|
||||||
Qt::CheckState state = static_cast< Qt::CheckState >( value.toInt() );
|
Qt::CheckState state = static_cast< Qt::CheckState >( value.toInt() );
|
||||||
|
|
||||||
if ( state == Qt::Checked && !acct->enabled() )
|
if ( state == Qt::Checked && !acct->enabled() )
|
||||||
@@ -307,69 +294,15 @@ AccountModel::setData( const QModelIndex& index, const QVariant& value, int role
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The install/create/remove/etc button was clicked. Handle it properly depending on this item
|
// The install/create/remove/etc button was clicked. Handle it properly depending on this item
|
||||||
if ( role == ButtonClickedRole )
|
if ( role == AddAccountButtonRole )
|
||||||
{
|
{
|
||||||
switch ( node->type )
|
Q_ASSERT( node->type == AccountModelNode::FactoryType );
|
||||||
{
|
// Make a new account of this factory type
|
||||||
case AccountModelNode::FactoryType:
|
emit createAccount( node->factory );
|
||||||
case AccountModelNode::UniqueFactoryType:
|
|
||||||
{
|
|
||||||
Q_ASSERT( node->factory );
|
|
||||||
|
|
||||||
// Make a new account of this factory type
|
|
||||||
emit createAccount( node->factory );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case AccountModelNode::AccountType:
|
|
||||||
case AccountModelNode::ManualResolverType:
|
|
||||||
{
|
|
||||||
Q_ASSERT( node->account || node->resolverAccount );
|
|
||||||
Account* acct = node->type == AccountModelNode::AccountType ? node->account : node->resolverAccount;
|
|
||||||
|
|
||||||
// This is a child account, and the remove button was just hit. Remove it!
|
|
||||||
// OR this is a manually added resolver, and
|
|
||||||
// the only thing we can do with a manual resolver is remove it completely from the list
|
|
||||||
AccountManager::instance()->removeAccount( acct );
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case AccountModelNode::AtticaType:
|
|
||||||
{
|
|
||||||
// This is an attica resolver, may be installed or not. Handle it properly
|
|
||||||
Q_ASSERT( node->atticaContent.isValid() );
|
|
||||||
|
|
||||||
Attica::Content resolver = node->atticaContent;
|
|
||||||
AtticaManager::ResolverState state = AtticaManager::instance()->resolverState( resolver );
|
|
||||||
if ( role == Qt::EditRole )
|
|
||||||
{
|
|
||||||
switch( state )
|
|
||||||
{
|
|
||||||
case AtticaManager::Uninstalled:
|
|
||||||
// install
|
|
||||||
AtticaManager::instance()->installResolver( resolver );
|
|
||||||
break;
|
|
||||||
case AtticaManager::Installing:
|
|
||||||
case AtticaManager::Upgrading:
|
|
||||||
// Do nothing, busy
|
|
||||||
break;
|
|
||||||
case AtticaManager::Installed:
|
|
||||||
// Uninstall
|
|
||||||
AtticaManager::instance()->uninstallResolver( resolver );
|
|
||||||
break;
|
|
||||||
case AtticaManager::NeedsUpgrade:
|
|
||||||
AtticaManager::instance()->upgradeResolver( resolver );
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
//FIXME -- this handles e.g. Failed
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
emit dataChanged( index, index );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ( role == RatingRole )
|
if ( role == RatingRole )
|
||||||
{
|
{
|
||||||
// We only support rating Attica resolvers for the moment.
|
// We only support rating Attica resolvers for the moment.
|
||||||
@@ -398,30 +331,16 @@ AccountModel::accountAdded( Account* account )
|
|||||||
{
|
{
|
||||||
// Find the factory this belongs up, and update
|
// Find the factory this belongs up, and update
|
||||||
AccountFactory* factory = AccountManager::instance()->factoryForAccount( account );
|
AccountFactory* factory = AccountManager::instance()->factoryForAccount( account );
|
||||||
for ( int i = 0; i < m_rootItem->children.size(); i++ )
|
for ( int i = 0; i < m_accounts.size(); i++ )
|
||||||
{
|
{
|
||||||
AccountModelNode* n = m_rootItem->children.at( i );
|
AccountModelNode* n = m_accounts.at( i );
|
||||||
if ( n->factory == factory )
|
if ( n->factory == factory )
|
||||||
{
|
{
|
||||||
if ( factory->isUnique() )
|
n->accounts << account;
|
||||||
{
|
const QModelIndex idx = index( i, 0, QModelIndex() );
|
||||||
Q_ASSERT( n->type == AccountModelNode::UniqueFactoryType );
|
dataChanged( idx, idx );
|
||||||
n->account = account;
|
|
||||||
const QModelIndex idx = index( i, 0, QModelIndex() );
|
|
||||||
emit dataChanged( idx, idx );
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Q_ASSERT( n->type == AccountModelNode::FactoryType );
|
|
||||||
// This is our parent
|
|
||||||
beginInsertRows( index( i, 0, QModelIndex() ), n->children.size(), n->children.size() );
|
|
||||||
new AccountModelNode( n, account );
|
|
||||||
endInsertRows();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -434,12 +353,24 @@ AccountModel::accountAdded( Account* account )
|
|||||||
if ( attica->atticaId() == c.id() )
|
if ( attica->atticaId() == c.id() )
|
||||||
{
|
{
|
||||||
// This is us. Create the row
|
// This is us. Create the row
|
||||||
// const int count = m_rootItem->children.size()
|
const int count = m_accounts.size();
|
||||||
// beginInsertRows( QModelIndex(), );
|
beginInsertRows( QModelIndex(), count, count );
|
||||||
// new AccountModelNode( );
|
m_accounts << new AccountModelNode( c );
|
||||||
|
endInsertRows();
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ok, just a plain resolver. add it at the end
|
||||||
|
if ( ResolverAccount* resolver = qobject_cast< ResolverAccount* >( account ) )
|
||||||
|
{
|
||||||
|
const int count = m_accounts.size();
|
||||||
|
beginInsertRows( QModelIndex(), count, count );
|
||||||
|
m_accounts << new AccountModelNode( resolver );
|
||||||
|
endInsertRows();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -448,15 +379,14 @@ AccountModel::accountStateChanged( Account* account , Account::ConnectionState )
|
|||||||
{
|
{
|
||||||
// Find the factory this belongs up, and update
|
// Find the factory this belongs up, and update
|
||||||
AccountFactory* factory = AccountManager::instance()->factoryForAccount( account );
|
AccountFactory* factory = AccountManager::instance()->factoryForAccount( account );
|
||||||
for ( int i = 0; i < m_rootItem->children.size(); i++ )
|
for ( int i = 0; i < m_accounts.size(); i++ )
|
||||||
{
|
{
|
||||||
AccountModelNode* n = m_rootItem->children.at( i );
|
AccountModelNode* n = m_accounts.at( i );
|
||||||
if ( n->type != AccountModelNode::FactoryType )
|
if ( n->type != AccountModelNode::FactoryType )
|
||||||
{
|
{
|
||||||
// If this is not a non-unique factory, it has as top-level account, so find that and update it
|
// If this is not a non-unique factory, it has as top-level account, so find that and update it
|
||||||
// For each type that this node could be, check the corresponding data
|
// For each type that this node could be, check the corresponding data
|
||||||
if ( ( n->type == AccountModelNode::UniqueFactoryType && n->account && n->account == account ) ||
|
if ( ( n->type == AccountModelNode::UniqueFactoryType && n->accounts.size() && n->accounts.first() == account ) ||
|
||||||
( n->type == AccountModelNode::AccountType && n->account == account ) ||
|
|
||||||
( n->type == AccountModelNode::AtticaType && n->atticaAccount && n->atticaAccount == account ) ||
|
( n->type == AccountModelNode::AtticaType && n->atticaAccount && n->atticaAccount == account ) ||
|
||||||
( n->type == AccountModelNode::ManualResolverType && n->resolverAccount && n->resolverAccount == account ) )
|
( n->type == AccountModelNode::ManualResolverType && n->resolverAccount && n->resolverAccount == account ) )
|
||||||
{
|
{
|
||||||
@@ -466,14 +396,13 @@ AccountModel::accountStateChanged( Account* account , Account::ConnectionState )
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for ( int k = 0; k < n->children.size(); k++ )
|
for ( int k = 0; k < n->accounts.size(); k++ )
|
||||||
{
|
{
|
||||||
AccountModelNode* childAccount = n->children.at( k );
|
Account* childAccount = n->accounts.at( k );
|
||||||
Q_ASSERT( childAccount->type == AccountModelNode::AccountType );
|
|
||||||
if ( childAccount->account == account )
|
if ( childAccount == account )
|
||||||
{
|
{
|
||||||
const QModelIndex parent = index( i, 0, QModelIndex() );
|
const QModelIndex idx = index( i, 0, QModelIndex() );
|
||||||
const QModelIndex idx = index( k, 0, parent );
|
|
||||||
emit dataChanged( idx, idx );
|
emit dataChanged( idx, idx );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -488,96 +417,44 @@ AccountModel::accountRemoved( Account* account )
|
|||||||
{
|
{
|
||||||
// Find the factory this belongs up, and update
|
// Find the factory this belongs up, and update
|
||||||
AccountFactory* factory = AccountManager::instance()->factoryForAccount( account );
|
AccountFactory* factory = AccountManager::instance()->factoryForAccount( account );
|
||||||
for ( int i = 0; i < m_rootItem->children.size(); i++ )
|
for ( int i = 0; i < m_accounts.size(); i++ )
|
||||||
{
|
{
|
||||||
AccountModelNode* n = m_rootItem->children.at( i );
|
AccountModelNode* n = m_accounts.at( i );
|
||||||
if ( n->factory == factory )
|
|
||||||
|
if ( n->type == AccountModelNode::FactoryType &&
|
||||||
|
n->factory == factory )
|
||||||
{
|
{
|
||||||
if ( factory->isUnique() )
|
n->accounts.removeAll( account );
|
||||||
{
|
const QModelIndex idx = index( i, 0, QModelIndex() );
|
||||||
Q_ASSERT( n->type == AccountModelNode::UniqueFactoryType );
|
emit dataChanged( idx, idx );
|
||||||
n->account = account;
|
|
||||||
const QModelIndex idx = index( i, 0, QModelIndex() );
|
return;
|
||||||
emit dataChanged( idx, idx );
|
}
|
||||||
}
|
|
||||||
else
|
if ( ( n->type == AccountModelNode::UniqueFactoryType && n->accounts.size() && n->accounts.first() == account ) ||
|
||||||
{
|
( n->type == AccountModelNode::AtticaType && n->atticaAccount && n->atticaAccount == account ) ||
|
||||||
Q_ASSERT( n->type == AccountModelNode::FactoryType );
|
( n->type == AccountModelNode::ManualResolverType && n->resolverAccount && n->resolverAccount == account ) )
|
||||||
// This is our parent
|
{
|
||||||
beginInsertRows( index( i, 0, QModelIndex() ), n->children.size(), n->children.size() );
|
beginRemoveRows( QModelIndex(), i, i );
|
||||||
new AccountModelNode( n, account );
|
m_accounts.removeAt( i );
|
||||||
endInsertRows();
|
endRemoveRows();
|
||||||
}
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
void
|
||||||
AccountModel::columnCount( const QModelIndex& parent ) const
|
AccountModel::atticaInstalled( const QString& atticaId )
|
||||||
{
|
{
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
AccountModel::rowCount( const QModelIndex& parent ) const
|
AccountModel::rowCount( const QModelIndex& ) const
|
||||||
{
|
{
|
||||||
if ( !parent.isValid() )
|
return m_accounts.size();
|
||||||
{
|
|
||||||
return m_rootItem->children.count();
|
|
||||||
}
|
|
||||||
|
|
||||||
// If it's a top-level item, return child count. Only factories will have any.
|
|
||||||
return nodeFromIndex( parent )->children.count();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QModelIndex
|
|
||||||
AccountModel::parent( const QModelIndex& child ) const
|
|
||||||
{
|
|
||||||
if ( !child.isValid() )
|
|
||||||
{
|
|
||||||
return QModelIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
AccountModelNode* node = nodeFromIndex( child );
|
|
||||||
AccountModelNode* parent = node->parent;
|
|
||||||
|
|
||||||
// top level, none
|
|
||||||
if( parent == m_rootItem )
|
|
||||||
return QModelIndex();
|
|
||||||
|
|
||||||
// child Account* of an AccountFactory*
|
|
||||||
Q_ASSERT( m_rootItem->children.contains( parent ) );
|
|
||||||
return createIndex( m_rootItem->children.indexOf( parent ), 0, parent );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QModelIndex
|
|
||||||
AccountModel::index( int row, int column, const QModelIndex& parent ) const
|
|
||||||
{
|
|
||||||
if( row < 0 || column < 0 )
|
|
||||||
return QModelIndex();
|
|
||||||
|
|
||||||
if( hasIndex( row, column, parent ) )
|
|
||||||
{
|
|
||||||
AccountModelNode *parentNode = nodeFromIndex( parent );
|
|
||||||
AccountModelNode *childNode = parentNode->children.at( row );
|
|
||||||
return createIndex( row, column, childNode );
|
|
||||||
}
|
|
||||||
|
|
||||||
return QModelIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
AccountModelNode*
|
|
||||||
AccountModel::nodeFromIndex( const QModelIndex& idx ) const
|
|
||||||
{
|
|
||||||
if( !idx.isValid() )
|
|
||||||
return m_rootItem;
|
|
||||||
|
|
||||||
Q_ASSERT( idx.internalPointer() );
|
|
||||||
|
|
||||||
return reinterpret_cast< AccountModelNode* >( idx.internalPointer() );
|
|
||||||
}
|
|
||||||
|
@@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
#include "Account.h"
|
#include "Account.h"
|
||||||
|
|
||||||
#include <QAbstractItemModel>
|
#include <QAbstractListModel>
|
||||||
|
|
||||||
|
|
||||||
namespace Tomahawk {
|
namespace Tomahawk {
|
||||||
@@ -32,7 +32,7 @@ namespace Accounts {
|
|||||||
|
|
||||||
class AccountModelNode;
|
class AccountModelNode;
|
||||||
|
|
||||||
class DLLEXPORT AccountModel : public QAbstractItemModel
|
class DLLEXPORT AccountModel : public QAbstractListModel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ public:
|
|||||||
AccountData = Qt::UserRole + 28, // raw plugin
|
AccountData = Qt::UserRole + 28, // raw plugin
|
||||||
|
|
||||||
CheckboxClickedRole = Qt::UserRole + 29, // the checkbox for this row was toggled
|
CheckboxClickedRole = Qt::UserRole + 29, // the checkbox for this row was toggled
|
||||||
ButtonClickedRole = Qt::UserRole + 30, // the generic install/create/remove/etc/ button was clicked
|
AddAccountButtonRole = Qt::UserRole + 30, // the add account button
|
||||||
};
|
};
|
||||||
|
|
||||||
enum RowType {
|
enum RowType {
|
||||||
@@ -81,11 +81,8 @@ public:
|
|||||||
explicit AccountModel( QObject* parent = 0 );
|
explicit AccountModel( QObject* parent = 0 );
|
||||||
|
|
||||||
virtual QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const;
|
virtual QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const;
|
||||||
virtual int columnCount( const QModelIndex& parent = QModelIndex() ) const;
|
|
||||||
virtual int rowCount( const QModelIndex& parent = QModelIndex() ) const;
|
virtual int rowCount( const QModelIndex& parent = QModelIndex() ) const;
|
||||||
virtual QModelIndex parent( const QModelIndex& child ) const;
|
virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole);
|
||||||
virtual QModelIndex index( int row, int column, const QModelIndex& parent = QModelIndex() ) const;
|
|
||||||
virtual bool setData( const QModelIndex& index, const QVariant& value, int role = Qt::EditRole );
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void createAccount( Tomahawk::Accounts::AccountFactory* factory );
|
void createAccount( Tomahawk::Accounts::AccountFactory* factory );
|
||||||
@@ -95,11 +92,12 @@ private slots:
|
|||||||
void accountRemoved( Tomahawk::Accounts::Account* );
|
void accountRemoved( Tomahawk::Accounts::Account* );
|
||||||
void accountStateChanged( Account*, Accounts::Account::ConnectionState );
|
void accountStateChanged( Account*, Accounts::Account::ConnectionState );
|
||||||
|
|
||||||
|
void atticaInstalled( const QString& atticaId );
|
||||||
private:
|
private:
|
||||||
AccountModelNode* nodeFromIndex( const QModelIndex& index ) const;
|
|
||||||
void loadData();
|
void loadData();
|
||||||
|
|
||||||
AccountModelNode* m_rootItem;
|
QList< AccountModelNode* > m_accounts;
|
||||||
|
QSet< QString > m_waitingForAtticaInstall;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -33,11 +33,9 @@ namespace Accounts {
|
|||||||
* Node for account tree.
|
* Node for account tree.
|
||||||
*
|
*
|
||||||
* Basically a union with possible types:
|
* Basically a union with possible types:
|
||||||
* 1) AccountFactory* for accounts that are not unique (jabber, google, twitter)
|
* 1) AccountFactory* for all factories that have child accounts. Also a list of children
|
||||||
* 2) Account* for accounts that are associated with an AccountFactory (children of AccountFactory)
|
* 2) Attica::Content for AtticaResolverAccounts (with associated AtticaResolverAccount*) (all synchrotron resolvers)
|
||||||
* 3) Attica::Content for AtticaResolverAccounts (with associated AtticaResolverAccount*) (all synchrotron resolvers)
|
* 3) ResolverAccount* for manually added resolvers (from file).
|
||||||
* 4) ResolverAccount* for manually added resolvers (from file).
|
|
||||||
* 5) AccountFactory* + Account* for factories that are unique
|
|
||||||
*
|
*
|
||||||
* These are the top-level items in tree.
|
* These are the top-level items in tree.
|
||||||
*
|
*
|
||||||
@@ -52,29 +50,25 @@ struct AccountModelNode {
|
|||||||
enum NodeType {
|
enum NodeType {
|
||||||
FactoryType,
|
FactoryType,
|
||||||
UniqueFactoryType,
|
UniqueFactoryType,
|
||||||
AccountType,
|
|
||||||
AtticaType,
|
AtticaType,
|
||||||
ManualResolverType
|
ManualResolverType
|
||||||
};
|
};
|
||||||
AccountModelNode* parent;
|
AccountModelNode* parent;
|
||||||
NodeType type;
|
NodeType type;
|
||||||
QList< AccountModelNode* > children; // list of children accounts (actually existing and configured accounts)
|
|
||||||
|
|
||||||
/// 1.
|
/// 1, 4
|
||||||
AccountFactory* factory;
|
AccountFactory* factory;
|
||||||
|
QList< Account* > accounts; // list of children accounts (actually existing and configured accounts)
|
||||||
|
|
||||||
/// 2.
|
/// 2.
|
||||||
Account* account;
|
|
||||||
|
|
||||||
/// 3.
|
|
||||||
Attica::Content atticaContent;
|
Attica::Content atticaContent;
|
||||||
AtticaResolverAccount* atticaAccount;
|
AtticaResolverAccount* atticaAccount;
|
||||||
|
|
||||||
/// 4.
|
/// 3.
|
||||||
ResolverAccount* resolverAccount;
|
ResolverAccount* resolverAccount;
|
||||||
|
|
||||||
// Construct in one of four ways. Then access the corresponding members
|
// Construct in one of four ways. Then access the corresponding members
|
||||||
explicit AccountModelNode( AccountModelNode* p, AccountFactory* fac ) : parent( p ), type( FactoryType )
|
explicit AccountModelNode( AccountFactory* fac ) : type( FactoryType )
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
factory = fac;
|
factory = fac;
|
||||||
@@ -88,26 +82,12 @@ struct AccountModelNode {
|
|||||||
if ( AccountManager::instance()->factoryForAccount( acct ) == fac )
|
if ( AccountManager::instance()->factoryForAccount( acct ) == fac )
|
||||||
{
|
{
|
||||||
qDebug() << "Found account for factory:" << acct->accountFriendlyName();
|
qDebug() << "Found account for factory:" << acct->accountFriendlyName();
|
||||||
if ( fac->isUnique() )
|
accounts.append( acct );
|
||||||
{
|
|
||||||
account = acct;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
new AccountModelNode( this, acct );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AccountModelNode( AccountModelNode* p, Account* acct ) : parent( p ), type( AccountType )
|
explicit AccountModelNode( Attica::Content cnt ) : type( AtticaType )
|
||||||
{
|
|
||||||
init();
|
|
||||||
account = acct;
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit AccountModelNode( AccountModelNode* p, Attica::Content cnt ) : parent( p ), type( AtticaType )
|
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
atticaContent = cnt;
|
atticaContent = cnt;
|
||||||
@@ -128,26 +108,15 @@ struct AccountModelNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit AccountModelNode( AccountModelNode* p, ResolverAccount* ra ) : parent( p ), type( ManualResolverType )
|
explicit AccountModelNode( ResolverAccount* ra ) : type( ManualResolverType )
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
resolverAccount = ra;
|
resolverAccount = ra;
|
||||||
}
|
}
|
||||||
|
|
||||||
AccountModelNode() : parent( 0 ) {}
|
|
||||||
|
|
||||||
~AccountModelNode()
|
|
||||||
{
|
|
||||||
qDeleteAll( children );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void init()
|
void init()
|
||||||
{
|
{
|
||||||
parent->children.append( this );
|
|
||||||
|
|
||||||
factory = 0;
|
factory = 0;
|
||||||
account = 0;
|
|
||||||
atticaAccount = 0;
|
atticaAccount = 0;
|
||||||
resolverAccount = 0;
|
resolverAccount = 0;
|
||||||
}
|
}
|
||||||
|
@@ -113,7 +113,6 @@ SettingsDialog::SettingsDialog( QWidget *parent )
|
|||||||
m_accountModel = new AccountModel( this );
|
m_accountModel = new AccountModel( this );
|
||||||
|
|
||||||
ui->accountsView->setModel( m_accountModel );
|
ui->accountsView->setModel( m_accountModel );
|
||||||
ui->accountsView->expandAll();
|
|
||||||
|
|
||||||
connect( m_accountModel, SIGNAL( createAccount( Tomahawk::Accounts::AccountFactory* ) ), this, SLOT( createAccountFromFactory( Tomahawk::Accounts::AccountFactory* ) ) );
|
connect( m_accountModel, SIGNAL( createAccount( Tomahawk::Accounts::AccountFactory* ) ), this, SLOT( createAccountFromFactory( Tomahawk::Accounts::AccountFactory* ) ) );
|
||||||
|
|
||||||
|
@@ -127,26 +127,7 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QTreeView" name="accountsView">
|
<widget class="QListView" name="accountsView"/>
|
||||||
<property name="indentation">
|
|
||||||
<number>6</number>
|
|
||||||
</property>
|
|
||||||
<property name="rootIsDecorated">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="uniformRowHeights">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="animated">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="headerHidden">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="expandsOnDoubleClick">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||||
|
Reference in New Issue
Block a user