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

Add multi-account config widget and hook things up

This commit is contained in:
Leo Franchi
2012-02-09 23:16:18 -05:00
parent 0dd4823a23
commit ecccf87992
12 changed files with 709 additions and 86 deletions

View File

@@ -71,8 +71,6 @@ AccountDelegate::AccountDelegate( QObject* parent )
m_defaultCover = m_defaultCover.scaled( ICONSIZE, ICONSIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation );
m_cachedIcons[ "sipplugin-online" ] = QPixmap( RESPATH "images/sipplugin-online.png" ).scaled( STATUS_ICON_SIZE, STATUS_ICON_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation );
m_cachedIcons[ "sipplugin-offline" ] = QPixmap( RESPATH "images/sipplugin-offline.png" ).scaled( STATUS_ICON_SIZE, STATUS_ICON_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation );
}
@@ -381,9 +379,28 @@ AccountDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const QS
{
m_configPressed = index;
Account* acct = qobject_cast< Account* >( index.data( AccountModel::AccountData ).value< QObject* >() );
Q_ASSERT( acct ); // Should not be showing a config wrench if there is no account!
emit openConfig( acct );
const AccountModel::RowType rowType = static_cast< AccountModel::RowType >( index.data( AccountModel::RowTypeRole ).toInt() );
if ( rowType == AccountModel::TopLevelAccount )
{
Account* acct = qobject_cast< Account* >( index.data( AccountModel::AccountData ).value< QObject* >() );
Q_ASSERT( acct ); // Should not be showing a config wrench if there is no account!
emit openConfig( acct );
}
else if ( rowType == AccountModel::TopLevelFactory )
{
AccountFactory* fac = qobject_cast< AccountFactory* >( index.data( AccountModel::AccountData ).value< QObject* >() );
Q_ASSERT( fac ); // Should not be showing a config wrench if there is no account!
emit openConfig( fac );
}
else if ( rowType == AccountModel::UniqueFactory )
{
const QList< Account* > accts = index.data( AccountModel::ChildrenOfFactoryRole ).value< QList< Tomahawk::Accounts::Account* > >();
Q_ASSERT( !accts.isEmpty() ); // If there's no account, why is there a config widget for this factory?
Q_ASSERT( accts.size() == 1 );
emit openConfig( accts.first() );
}
return true;
}
} else if ( event->type() == QEvent::MouseButtonRelease || event->type() == QEvent::MouseButtonDblClick )
@@ -395,13 +412,7 @@ AccountDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const QS
m_configPressed = QModelIndex();
const AccountModel::ItemState state = static_cast< AccountModel::ItemState >( index.data( AccountModel::StateRole ).toInt() );
const bool canCheck = ( state == AccountModel::Installed || state == AccountModel::ShippedWithTomahawk );
if ( !canCheck )
return false;
// A few options. First, could be the checkbox on/off.
// second, could be the install/uninstall/create button
// third could be the config button
if ( checkRectForIndex( option, index ).contains( me->pos() ) )
{
// Check box for this row
@@ -525,7 +536,6 @@ AccountDelegate::drawStatus( QPainter* painter, const QPointF& rightTopEdge, Acc
painter->drawPixmap( connectIconRect, p );
int leftEdge = connectIconRect.x();
// For now, disable text next to icon
if ( drawText )
{
int width = painter->fontMetrics().width( statusText );
@@ -557,7 +567,7 @@ AccountDelegate::drawConfigWrench ( QPainter* painter, QStyleOptionViewItemV4& o
// draw it the same size as the check belox
topt.font = opt.font;
topt.icon = QIcon( RESPATH "images/configure.png" );
topt.iconSize = QSize( 16, 16 );
topt.iconSize = QSize( 14, 14 );
topt.subControls = QStyle::SC_ToolButton;
topt.activeSubControls = QStyle::SC_None;
topt.features = QStyleOptionToolButton::None;

View File

@@ -44,6 +44,7 @@ protected:
signals:
void update( const QModelIndex& idx );
void openConfig( Tomahawk::Accounts::Account* );
void openConfig( Tomahawk::Accounts::AccountFactory* );
private:
void drawRoundedButton( QPainter* painter, const QRect& buttonRect ) const;
@@ -56,7 +57,6 @@ private:
QRect checkRectForIndex( const QStyleOptionViewItem &option, const QModelIndex &idx ) const;
QMap< QString, QPixmap > m_cachedIcons;
QPixmap m_offlineIcon, m_onlineIcon, m_defaultCover, m_onHoverStar, m_ratingStarPositive, m_ratingStarNegative, m_removeIcon;
int m_hoveringOver;
QPersistentModelIndex m_hoveringItem, m_configPressed;

View File

@@ -0,0 +1,137 @@
/* === This file is part of Tomahawk Player - <http://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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tomahawk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#include "AccountFactoryWrapper.h"
#include "accounts/Account.h"
#include <accounts/AccountManager.h>
#include "AccountFactoryWrapperDelegate.h"
#include "delegateconfigwrapper.h"
#include "ui_AccountFactoryWrapper.h"
using namespace Tomahawk::Accounts;
AccountFactoryWrapper::AccountFactoryWrapper( AccountFactory* factory, QWidget* parent )
: QDialog( parent, Qt::Sheet )
, m_factory( factory )
, m_ui( new Ui_AccountFactoryWrapper )
, m_createAccount( false )
{
m_ui->setupUi( this );
setWindowTitle( factory->prettyName() );
m_ui->factoryIcon->setPixmap( factory->icon() );
m_ui->factoryDescription->setText( factory->description() );
m_addButton = m_ui->buttonBox->addButton( tr( "Add Account" ), QDialogButtonBox::ActionRole );
AccountFactoryWrapperDelegate* del = new AccountFactoryWrapperDelegate( m_ui->accountsList );
m_ui->accountsList->setItemDelegate( del );
connect( del, SIGNAL( openConfig( Tomahawk::Accounts::Account* ) ), this, SLOT( openAccountConfig( Tomahawk::Accounts::Account* ) ) );
connect( del, SIGNAL( removeAccount( Tomahawk::Accounts::Account* ) ), this, SLOT( removeAccount( Tomahawk::Accounts::Account* ) ) );
load();
connect( m_ui->buttonBox, SIGNAL( rejected() ), this, SLOT( reject() ) );
connect( m_ui->buttonBox, SIGNAL( accepted() ), this, SLOT( accept() ) );
connect( m_ui->buttonBox, SIGNAL( clicked( QAbstractButton*) ), this, SLOT( buttonClicked() ) );
#ifdef Q_OS_MAC
setContentsMargins( 0, 0, 0, 0 );
m_ui->verticalLayout->setSpacing( 4 );
#endif
}
void
AccountFactoryWrapper::load()
{
m_ui->accountsList->clear();
foreach ( Account* acc, AccountManager::instance()->accounts() )
{
if ( AccountManager::instance()->factoryForAccount( acc ) == m_factory )
{
QTreeWidgetItem* item = new QTreeWidgetItem( m_ui->accountsList );
item->setData( 0, AccountRole, QVariant::fromValue< QObject *>( acc ) );
}
}
const int height = m_ui->accountsList->model()->rowCount( QModelIndex() ) * ACCOUNT_ROW_HEIGHT + 7;
m_ui->accountsList->setFixedHeight( height );
}
void
AccountFactoryWrapper::openAccountConfig( Account* account )
{
if( account->configurationWidget() )
{
#ifndef Q_WS_MAC
DelegateConfigWrapper dialog( account->configurationWidget(), QString("%1 Configuration" ).arg( account->accountFriendlyName() ), this );
QWeakPointer< DelegateConfigWrapper > watcher( &dialog );
int ret = dialog.exec();
if( !watcher.isNull() && ret == QDialog::Accepted )
{
// send changed config to resolver
account->saveConfig();
}
#else
// on osx a sheet needs to be non-modal
DelegateConfigWrapper* dialog = new DelegateConfigWrapper( account->configurationWidget(), QString("%1 Configuration" ).arg( account->accountFriendlyName() ), this, Qt::Sheet );
dialog->setProperty( "accountplugin", QVariant::fromValue< QObject* >( account ) );
connect( dialog, SIGNAL( finished( int ) ), this, SLOT( accountConfigClosed( int ) ) );
dialog->show();
#endif
}
}
void
AccountFactoryWrapper::accountConfigClosed( int value )
{
if( value == QDialog::Accepted )
{
DelegateConfigWrapper* dialog = qobject_cast< DelegateConfigWrapper* >( sender() );
Account* account = qobject_cast< Account* >( dialog->property( "accountplugin" ).value< QObject* >() );
account->saveConfig();
}
}
void
AccountFactoryWrapper::removeAccount( Tomahawk::Accounts::Account* acct )
{
AccountManager::instance()->removeAccount( acct );
load();
}
void
AccountFactoryWrapper::buttonClicked( QAbstractButton* button )
{
if ( button == m_addButton )
{
m_createAccount = true;
emit createAccount( m_factory );
accept();
return;
}
else
reject();
}

View File

@@ -0,0 +1,67 @@
/* === This file is part of Tomahawk Player - <http://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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tomahawk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ACCOUNTFACTORYWRAPPER_H
#define ACCOUNTFACTORYWRAPPER_H
#include <QDialog>
class QAbstractButton;
namespace Tomahawk {
namespace Accounts {
class AccountFactory;
class Account;
}
}
class Ui_AccountFactoryWrapper;
// class AccountFactoryWrapper_
class AccountFactoryWrapper : public QDialog
{
Q_OBJECT
public:
enum ExtraRoles {
AccountRole = Qt::UserRole + 140
};
explicit AccountFactoryWrapper( Tomahawk::Accounts::AccountFactory* factory, QWidget* parent = 0 );
bool doCreateAccount() const { return m_createAccount; }
signals:
void createAccount( Tomahawk::Accounts::AccountFactory* factory );
public slots:
void openAccountConfig( Tomahawk::Accounts::Account* );
void accountConfigClosed( int value );
void removeAccount( Tomahawk::Accounts::Account* );
private slots:
void buttonClicked( QAbstractButton* );
private:
void load();
Tomahawk::Accounts::AccountFactory* m_factory;
Ui_AccountFactoryWrapper* m_ui;
QPushButton* m_addButton;
bool m_createAccount;
};
#endif // ACCOUNTFACTORYWRAPPER_H

View File

@@ -0,0 +1,110 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AccountFactoryWrapper</class>
<widget class="QDialog" name="AccountFactoryWrapper">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>507</width>
<height>298</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="factoryIcon">
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="factoryDescription">
<property name="text">
<string>Description goes here</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QTreeWidget" name="accountsList">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="autoScroll">
<bool>false</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerItem</enum>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="headerHidden">
<bool>true</bool>
</property>
<property name="expandsOnDoubleClick">
<bool>false</bool>
</property>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,166 @@
/* === This file is part of Tomahawk Player - <http://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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tomahawk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#include "AccountFactoryWrapperDelegate.h"
#include "accounts/Account.h"
#include "AccountFactoryWrapper.h"
#include "utils/tomahawkutils.h"
#include <QApplication>
#include <QPainter>
#include <QMouseEvent>
using namespace Tomahawk::Accounts;
#define ICON_SIZE 15
#define CONFIG_WRENCH_SIZE 20
#define PADDING 4
AccountFactoryWrapperDelegate::AccountFactoryWrapperDelegate( QObject* parent )
: QStyledItemDelegate( parent )
{
m_removePixmap.load( RESPATH "images/list-remove.png" );
m_onlineIcon.load( RESPATH "images/sipplugin-online.png" );
m_offlineIcon.load( RESPATH "images/sipplugin-offline.png" );
m_removePixmap = m_removePixmap.scaled( ICON_SIZE, ICON_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation );
m_onlineIcon = m_onlineIcon.scaled( ICON_SIZE, ICON_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation );
m_offlineIcon = m_offlineIcon.scaled( ICON_SIZE, ICON_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation );
m_configIcon.addFile( RESPATH "images/configure.png", QSize( CONFIG_WRENCH_SIZE - 8, CONFIG_WRENCH_SIZE - 8 ) );
}
void
AccountFactoryWrapperDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
QStyleOptionViewItemV4 opt = option;
initStyleOption( &opt, index );
const int center = opt.rect.height() / 2 + opt.rect.top();
const int topIcon = center - ICON_SIZE/2;
// draw the background
const QWidget* w = opt.widget;
QStyle* style = w ? w->style() : QApplication::style();
style->drawPrimitive( QStyle::PE_PanelItemViewItem, &opt, painter, w );
Account* acc = qobject_cast< Account* >( index.data( AccountFactoryWrapper::AccountRole ).value< QObject* >() );
Q_ASSERT( acc );
// name on left
painter->drawText( opt.rect.adjusted( PADDING, PADDING, -PADDING, -PADDING ), Qt::AlignLeft | Qt::AlignVCenter, acc->accountFriendlyName() );
// remove, config, status on right
const QRect pmRect( opt.rect.right() - PADDING - m_removePixmap.width(), topIcon, ICON_SIZE, ICON_SIZE );
painter->drawPixmap( pmRect, m_removePixmap );
m_cachedButtonRects[ index ] = pmRect;
const QRect confRect( pmRect.left() - PADDING - CONFIG_WRENCH_SIZE, center - CONFIG_WRENCH_SIZE/2, CONFIG_WRENCH_SIZE, CONFIG_WRENCH_SIZE );
QStyleOptionToolButton topt;
topt.rect = confRect;
topt.pos = confRect.topLeft();
topt.font = opt.font;
topt.icon = m_configIcon;
topt.iconSize = QSize( CONFIG_WRENCH_SIZE - 8, CONFIG_WRENCH_SIZE - 8 );
topt.subControls = QStyle::SC_ToolButton;
topt.activeSubControls = QStyle::SC_None;
topt.features = QStyleOptionToolButton::None;
bool pressed = ( m_configPressed == opt.index );
topt.state = pressed ? QStyle::State_On : QStyle::State_Raised;
if( opt.state & QStyle::State_MouseOver || pressed )
topt.state |= QStyle::State_HasFocus;
style->drawComplexControl( QStyle::CC_ToolButton, &topt, painter, w );
m_cachedConfigRects[ index ] = confRect;
QPixmap p;
QString statusText;
Account::ConnectionState state = acc->connectionState();
if ( state == Account::Connected )
{
p = m_onlineIcon;
statusText = tr( "Online" );
}
else if ( state == Account::Connecting )
{
p = m_offlineIcon;
statusText = tr( "Connecting..." );
}
else
{
p = m_offlineIcon;
statusText = tr( "Offline" );
}
const QRect connectIconRect( confRect.left() - PADDING - ICON_SIZE, topIcon, ICON_SIZE, ICON_SIZE );
painter->drawPixmap( connectIconRect, p );
int width = painter->fontMetrics().width( statusText );
painter->drawText( QRect( connectIconRect.left() - PADDING - width, center - painter->fontMetrics().height()/2, width, painter->fontMetrics().height() ), statusText );
}
QSize
AccountFactoryWrapperDelegate::sizeHint(const QStyleOptionViewItem&, const QModelIndex&) const
{
return QSize( 200, ACCOUNT_ROW_HEIGHT );
}
bool
AccountFactoryWrapperDelegate::editorEvent( QEvent* event, QAbstractItemModel*, const QStyleOptionViewItem&, const QModelIndex& index )
{
if ( event->type() != QEvent::MouseButtonPress &&
event->type() != QEvent::MouseButtonRelease &&
event->type() != QEvent::MouseButtonDblClick &&
event->type() != QEvent::MouseMove )
return false;
if ( event->type() == QEvent::MouseButtonPress )
{
// Show the config wrench as depressed on click
QMouseEvent* me = static_cast< QMouseEvent* >( event );
if ( me->button() == Qt::LeftButton && m_cachedConfigRects.contains( index ) && m_cachedConfigRects[ index ].contains( me->pos() ) )
{
m_configPressed = index;
Account* acct = qobject_cast< Account* >( index.data( AccountFactoryWrapper::AccountRole ).value< QObject* >() );
Q_ASSERT( acct ); // Should not be showing a config wrench if there is no account!
emit openConfig( acct );
return true;
}
} else if ( event->type() == QEvent::MouseButtonRelease || event->type() == QEvent::MouseButtonDblClick )
{
QMouseEvent* me = static_cast< QMouseEvent* >( event );
if ( m_configPressed.isValid() )
emit update( m_configPressed );
m_configPressed = QModelIndex();
if ( m_cachedButtonRects.contains( index ) && m_cachedButtonRects[ index ].contains( me->pos() ) )
{
Account* acct = qobject_cast< Account* >( index.data( AccountFactoryWrapper::AccountRole ).value< QObject* >() );
emit removeAccount( acct );
return true;
}
}
return false;
}

View File

@@ -0,0 +1,58 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2010-2012, 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tomahawk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ACCOUNTFACTORYWRAPPERDELEGATE_H
#define ACCOUNTFACTORYWRAPPERDELEGATE_H
#include <QStyledItemDelegate>
#define ACCOUNT_ROW_HEIGHT 20
namespace Tomahawk {
namespace Accounts {
class Account;
}
}
class AccountFactoryWrapperDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
explicit AccountFactoryWrapperDelegate( QObject* parent = 0 );
virtual void paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const;
virtual QSize sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const;
virtual bool editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index);
signals:
void update( const QModelIndex& );
void openConfig( Tomahawk::Accounts::Account* );
void removeAccount( Tomahawk::Accounts::Account* );
private:
QPixmap m_removePixmap, m_offlineIcon, m_onlineIcon;
QIcon m_configIcon;
QModelIndex m_configPressed;
mutable QHash< QPersistentModelIndex, QRect > m_cachedButtonRects;
mutable QHash< QPersistentModelIndex, QRect > m_cachedConfigRects;
};
#endif // ACCOUNTFACTORYWRAPPERDELEGATE_H

View File

@@ -78,6 +78,8 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui}
settingslistdelegate.cpp
tomahawkwindow.cpp
LoadXSPFDialog.cpp
AccountFactoryWrapper.cpp
AccountFactoryWrapperDelegate.cpp
)
SET( tomahawkHeaders ${tomahawkHeaders}
@@ -121,6 +123,8 @@ SET( tomahawkHeadersGui ${tomahawkHeadersGui}
delegateconfigwrapper.h
tomahawkwindow.h
LoadXSPFDialog.h
AccountFactoryWrapper.h
AccountFactoryWrapperDelegate.h
)
SET( tomahawkUI ${tomahawkUI}
@@ -132,6 +136,8 @@ SET( tomahawkUI ${tomahawkUI}
audiocontrols.ui
LoadXSPFDialog.ui
AccountFactoryWrapper.ui
)
INCLUDE_DIRECTORIES(

View File

@@ -28,7 +28,7 @@ class DelegateConfigWrapper : public QDialog
{
Q_OBJECT
public:
DelegateConfigWrapper( QWidget* conf, const QString& title, QWidget* parent, Qt::WindowFlags flags = 0 ) : QDialog( parent, flags ), m_widget( conf )
DelegateConfigWrapper( QWidget* conf, const QString& title, QWidget* parent, Qt::WindowFlags flags = 0 ) : QDialog( parent, flags ), m_widget( conf ), m_deleted( false )
{
m_widget->setWindowFlags( Qt::Sheet );
#ifdef Q_WS_MAC
@@ -39,11 +39,11 @@ public:
v->setContentsMargins( 0, 0, 0, 0 );
v->addWidget( m_widget );
QDialogButtonBox* buttons = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this );
m_okButton = buttons->button( QDialogButtonBox::Ok );
connect( buttons, SIGNAL( clicked( QAbstractButton*) ), this, SLOT( closed( QAbstractButton* ) ) );
m_buttons = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this );
m_okButton = m_buttons->button( QDialogButtonBox::Ok );
connect( m_buttons, SIGNAL( clicked( QAbstractButton*) ), this, SLOT( closed( QAbstractButton* ) ) );
connect( this, SIGNAL( rejected() ), this, SLOT( rejected() ) );
v->addWidget( buttons );
v->addWidget( m_buttons );
setLayout( v );
@@ -62,6 +62,14 @@ public:
~DelegateConfigWrapper() {}
void setShowDelete( bool del )
{
if ( del )
m_deleteButton = m_buttons->addButton( tr( "Delete Account" ), QDialogButtonBox::DestructiveRole );
}
bool deleted() const { return m_deleted; }
public slots:
void toggleOkButton( bool dataError )
{
@@ -78,6 +86,11 @@ public slots:
QDialogButtonBox* buttons = qobject_cast< QDialogButtonBox* >( sender() );
if( buttons->standardButton( b ) == QDialogButtonBox::Ok )
done( QDialog::Accepted );
else if ( b == m_deleteButton )
{
m_deleted = true;
emit deleted();
}
else
done( QDialog::Rejected );
}
@@ -100,9 +113,14 @@ public slots:
show();
}
signals:
void closedWithDelete();
private:
QDialogButtonBox* m_buttons;
QWidget* m_widget;
QPushButton* m_okButton;
QPushButton *m_okButton, *m_deleteButton;
bool m_deleted;
};
#endif

View File

@@ -72,6 +72,7 @@ AccountModel::loadData()
connect ( AccountManager::instance(), SIGNAL( removed( Tomahawk::Accounts::Account* ) ), this, SLOT( accountRemoved( Tomahawk::Accounts::Account* ) ) );
connect ( AccountManager::instance(), SIGNAL( stateChanged( Account* ,Accounts::Account::ConnectionState ) ), this, SLOT( accountStateChanged( Account*, Accounts::Account::ConnectionState ) ) );
connect( AtticaManager::instance(), SIGNAL( resolverInstalled( QString ) ), this, SLOT( atticaInstalled( QString ) ) );
}
@@ -175,7 +176,12 @@ AccountModel::data( const QModelIndex& index, int role ) const
case AccountModelNode::UniqueFactoryType:
{
if ( role == RowTypeRole )
return UniqueFactory;
{
if ( node->type == AccountModelNode::ManualResolverType )
return TopLevelAccount;
else
return UniqueFactory;
}
Account* acct = 0;
if ( node->type == AccountModelNode::ManualResolverType )
@@ -270,7 +276,6 @@ AccountModel::setData( const QModelIndex& index, const QVariant& value, int role
}
else
{
connect( AtticaManager::instance(), SIGNAL( resolverInstalled( QString ) ), this, SLOT( atticaInstalled( QString ) ) );
m_waitingForAtticaInstall.insert( resolver.id() );
AtticaManager::instance()->installResolver( resolver );
@@ -461,7 +466,54 @@ AccountModel::accountRemoved( Account* account )
void
AccountModel::atticaInstalled( const QString& atticaId )
{
if ( !m_waitingForAtticaInstall.contains( atticaId ) )
return;
m_waitingForAtticaInstall.remove( atticaId );
// find associated Account*, set on to the saved resolver, and update state
AccountModelNode* node = 0;
AtticaResolverAccount* acct = 0;
foreach ( AccountModelNode* n, m_accounts )
{
if ( n->type == AccountModelNode::AtticaType &&
n->atticaContent.id() == atticaId )
{
node = n;
break;
}
}
if ( !node )
{
Q_ASSERT( false );
return; // Couldn't find it??
}
foreach ( Account* acc, AccountManager::instance()->accounts( ResolverType ) )
{
if ( AtticaResolverAccount* ra = qobject_cast< AtticaResolverAccount* >( acc ) )
{
if ( ra->atticaId() == atticaId )
{
acct = ra;
break;
}
}
}
if ( !acct )
{
qWarning() << "Got installed attica resolver but couldnt' find a resolver account for it??";
return;
}
AccountManager::instance()->enableAccount( acct );
node->atticaAccount = acct;
const QModelIndex idx = index( m_accounts.indexOf( node ), 0, QModelIndex() );
emit dataChanged( idx, idx );
}

View File

@@ -53,6 +53,7 @@
#include "accounts/Account.h"
#include "accounts/AccountManager.h"
#include "utils/logger.h"
#include "AccountFactoryWrapper.h"
#include "ui_proxydialog.h"
#include "ui_stackedsettingsdialog.h"
@@ -105,8 +106,10 @@ SettingsDialog::SettingsDialog( QWidget *parent )
ui->accountsView->setItemDelegate( accountDelegate );
ui->accountsView->setContextMenuPolicy( Qt::CustomContextMenu );
ui->accountsView->setVerticalScrollMode( QAbstractItemView::ScrollPerPixel );
ui->accountsView->setMouseTracking( true );
connect( accountDelegate, SIGNAL( openConfig( Tomahawk::Accounts::Account* ) ), this, SLOT( openAccountConfig( Tomahawk::Accounts::Account* ) ) );
connect( accountDelegate, SIGNAL( openConfig( Tomahawk::Accounts::AccountFactory* ) ), this, SLOT( openAccountFactoryConfig( Tomahawk::Accounts::AccountFactory* ) ) );
connect( accountDelegate, SIGNAL( update( QModelIndex ) ), ui->accountsView, SLOT( update( QModelIndex ) ) );
connect( ui->accountsView, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( accountContextMenuRequest( QPoint ) ) );
@@ -425,20 +428,6 @@ SettingsDialog::onLastFmFinished()
}
void
SettingsDialog::accountInstalled(Account* account)
{
// m_resolversModel->atticaResolverInstalled( resolverId );
}
void
SettingsDialog::accountUninstalled(const QString& acct)
{
// m_resolversModel->removeResolver( AtticaManager::instance()->pathFromId( resolverId ) );
}
void
SettingsDialog::accountsSelectionChanged()
{
@@ -454,15 +443,20 @@ SettingsDialog::accountsSelectionChanged()
void
SettingsDialog::openAccountConfig( Account* account )
SettingsDialog::openAccountConfig( Account* account, bool showDelete )
{
if( account->configurationWidget() )
{
#ifndef Q_WS_MAC
DelegateConfigWrapper dialog( account->configurationWidget(), QString("%1 Configuration" ).arg( account->accountFriendlyName() ), this );
dialog.setShowDelete( showDelete );
QWeakPointer< DelegateConfigWrapper > watcher( &dialog );
int ret = dialog.exec();
if( !watcher.isNull() && ret == QDialog::Accepted )
if ( !watcher.isNull() && dialog.deleted() )
{
AccountManager::instance()->removeAccount( account );
}
else if( !watcher.isNull() && ret == QDialog::Accepted )
{
// send changed config to resolver
account->saveConfig();
@@ -470,8 +464,10 @@ SettingsDialog::openAccountConfig( Account* account )
#else
// on osx a sheet needs to be non-modal
DelegateConfigWrapper* dialog = new DelegateConfigWrapper( account->configurationWidget(), QString("%1 Configuration" ).arg( account->accountFriendlyName() ), this, Qt::Sheet );
dialog->setShowDelete( showDelete );
dialog->setProperty( "accountplugin", QVariant::fromValue< QObject* >( account ) );
connect( dialog, SIGNAL( finished( int ) ), this, SLOT( accountConfigClosed( int ) ) );
connect( dialog, SIGNAL( closedWithDelete() ), this, SLOT( accountConfigDelete() ) );
dialog->show();
#endif
@@ -491,6 +487,54 @@ SettingsDialog::accountConfigClosed( int value )
}
void
SettingsDialog::accountConfigDelete()
{
DelegateConfigWrapper* dialog = qobject_cast< DelegateConfigWrapper* >( sender() );
Account* account = qobject_cast< Account* >( dialog->property( "accountplugin" ).value< QObject* >() );
Q_ASSERT( account );
AccountManager::instance()->removeAccount( account );
sender()->deleteLater();
}
void
SettingsDialog::openAccountFactoryConfig( AccountFactory* factory )
{
QList< Account* > accts;
foreach ( Account* acct, AccountManager::instance()->accounts() )
{
if ( AccountManager::instance()->factoryForAccount( acct ) == factory )
accts << acct;
if ( accts.size() > 1 )
break;
}
Q_ASSERT( accts.size() > 0 ); // Shouldn't have a config wrench if there are no accounts!
if ( accts.size() == 1 )
{
// If there's just one, open the config directly w/ the delete button. Otherwise open the multi dialog
openAccountConfig( accts.first() );
return;
}
#ifndef Q_WS_MAC
AccountFactoryWrapper dialog( factory, this );
QWeakPointer< AccountFactoryWrapper > watcher( &dialog );
int ret = dialog.exec();
if ( !watcher.isNull() && dialog.doCreateAccount() )
createAccountFromFactory( factory );
#else
// on osx a sheet needs to be non-modal
AccountFactoryWrapper* dialog = new AccountFactoryWrapper( factory, this );
connect( dialog, SIGNAL( createAccount( Tomahawk::Accounts::AccountFactory ) ), this, SLOT( createAccountFromFactory( Tomahawk::Accounts::AccountFactory* ) ) );
dialog->show();
#endif
}
void
SettingsDialog::createAccountFromFactory( AccountFactory* factory )
{
@@ -568,47 +612,6 @@ SettingsDialog::handleAccountAdded( Account* account, bool added )
}
void
SettingsDialog::accountContextMenuRequest( const QPoint& p )
{
QModelIndex idx = ui->accountsView->indexAt( p );
// if it's an account, allow to delete
if( idx.isValid() )
{
// QList< QAction* > acts;
// acts << new QAction( tr( "Delete Service" ), this );
// acts.first()->setProperty( "accountplugin", idx.data( AccountModel::AccountData ) );
// connect( acts.first(), SIGNAL( triggered( bool ) ), this, SLOT( onAccountRowDeleted( bool ) ) );
// QMenu::exec( acts, ui->accountsView->mapToGlobal( p ) );
}
}
void
SettingsDialog::onAccountRowDeleted( bool )
{
Account* account = qobject_cast< Account* >( qobject_cast< QAction* >( sender() )->property( "accountplugin" ).value< QObject* >() );
AccountManager::instance()->removeAccount( account );
}
void
SettingsDialog::accountDeleted( bool )
{
QModelIndexList indexes = ui->accountsView->selectionModel()->selectedIndexes();
// if it's an account, allow to delete
foreach( const QModelIndex& idx, indexes )
{
if( idx.isValid() )
{
// Account* account = qobject_cast< Account* >( idx.data( AccountModel::AccountData ).value< QObject* >() );
// AccountManager::instance()->removeAccount( account );
}
}
}
void
SettingsDialog::requiresRestart()
{

View File

@@ -88,18 +88,14 @@ private slots:
void testLastFmLogin();
void onLastFmFinished();
void openAccountConfig( Tomahawk::Accounts::Account* );
void createAccountFromFactory( Tomahawk::Accounts::AccountFactory* );
void accountContextMenuRequest( const QPoint& );
void accountDeleted( bool );
void onAccountRowDeleted( bool );
void accountsSelectionChanged();
void accountInstalled( Tomahawk::Accounts::Account* account );
void accountUninstalled( const QString& acct );
void openAccountConfig( Tomahawk::Accounts::Account*, bool showDelete = false );
void openAccountFactoryConfig( Tomahawk::Accounts::AccountFactory* );
void accountConfigClosed( int value );
void accountConfigDelete();
void accountCreateConfigClosed( int value );
void updateScanOptionsView();