mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-04-14 13:01:53 +02:00
Some more work on the config UI
This commit is contained in:
parent
2380838347
commit
eb8a4f6711
@ -79,6 +79,8 @@
|
||||
<file>./data/images/add.png</file>
|
||||
<file>./data/images/recently-played.png</file>
|
||||
<file>./data/images/supercollection.png</file>
|
||||
<file>./data/images/sipplugin-online.png</file>
|
||||
<file>./data/images/sipplugin-offline.png</file>
|
||||
<file>./data/topbar-radiobuttons.css</file>
|
||||
<file>./data/icons/tomahawk-icon-16x16.png</file>
|
||||
<file>./data/icons/tomahawk-icon-32x32.png</file>
|
||||
|
@ -64,6 +64,8 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui}
|
||||
tomahawktrayicon.cpp
|
||||
audiocontrols.cpp
|
||||
settingsdialog.cpp
|
||||
configdelegatebase.cpp
|
||||
sipconfigdelegate.cpp
|
||||
resolverconfigdelegate.cpp
|
||||
resolversmodel.cpp
|
||||
tomahawkwindow.cpp
|
||||
@ -104,7 +106,9 @@ SET( tomahawkHeadersGui ${tomahawkHeadersGui}
|
||||
tomahawktrayicon.h
|
||||
audiocontrols.h
|
||||
settingsdialog.h
|
||||
configdelegatebase.h
|
||||
resolverconfigdelegate.h
|
||||
sipconfigdelegate.h
|
||||
resolversmodel.h
|
||||
resolverconfigwrapper.h
|
||||
tomahawkwindow.h
|
||||
|
@ -195,8 +195,6 @@ SipHandler::hookUpPlugin( SipPlugin* sip )
|
||||
QObject::connect( sip, SIGNAL( avatarReceived( QString, QPixmap ) ), SLOT( onAvatarReceived( QString, QPixmap ) ) );
|
||||
QObject::connect( sip, SIGNAL( avatarReceived( QPixmap ) ), SLOT( onAvatarReceived( QPixmap ) ) );
|
||||
|
||||
m_allPlugins << sip;
|
||||
|
||||
emit pluginAdded( sip );
|
||||
}
|
||||
|
||||
@ -248,16 +246,21 @@ SipHandler::checkSettings()
|
||||
void
|
||||
SipHandler::loadFromConfig( bool startup )
|
||||
{
|
||||
QStringList pluginIds = TomahawkSettings::instance()->enabledSipPlugins();
|
||||
QStringList pluginIds = TomahawkSettings::instance()->sipPlugins();
|
||||
QStringList enabled = TomahawkSettings::instance()->enabledSipPlugins();
|
||||
foreach( const QString& pluginId, pluginIds )
|
||||
{
|
||||
QString pluginFactory = factoryFromId( pluginId );
|
||||
if( m_pluginFactories.contains( pluginFactory ) )
|
||||
{
|
||||
SipPlugin* p = loadPlugin( pluginId );
|
||||
p->connectPlugin( startup );
|
||||
m_allPlugins << p;
|
||||
|
||||
m_enabledPlugins << p;
|
||||
if ( enabled.contains( pluginId ) )
|
||||
{
|
||||
p->connectPlugin( startup );
|
||||
m_enabledPlugins << p;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_connected = true;
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include "sip/SipHandler.h"
|
||||
|
||||
SipModel::SipModel( QObject* parent )
|
||||
: QAbstractListModel( parent )
|
||||
: QAbstractItemModel( parent )
|
||||
{
|
||||
connect( SipHandler::instance(), SIGNAL( stateChanged( SipPlugin*, SipPlugin::ConnectionState ) ), this, SLOT( pluginStateChanged( SipPlugin* ) ) );
|
||||
}
|
||||
@ -56,15 +56,15 @@ SipModel::data( const QModelIndex& index, int role ) const
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
case SipModel::PluginName:
|
||||
{
|
||||
p->accountName();
|
||||
}
|
||||
return p->accountName();
|
||||
case SipModel::ConnectionStateRole:
|
||||
return p->connectionState();
|
||||
case SipModel::HasConfig:
|
||||
return ( p->configWidget() == 0 );
|
||||
case SipModel::FactoryRole:
|
||||
return false;
|
||||
case Qt::DecorationRole:
|
||||
return p->icon();
|
||||
case Qt::CheckStateRole:
|
||||
return SipHandler::instance()->enabledPlugins().contains( p ) ? Qt::Checked : Qt::Unchecked;
|
||||
default:
|
||||
@ -94,11 +94,44 @@ SipModel::setData( const QModelIndex& index, const QVariant& value, int role )
|
||||
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();
|
||||
|
||||
// it's a child of the Add Account, e.g. a factory
|
||||
if( hasIndex( row, column, parent ) ) {
|
||||
createIndex( row, column, 1 /* magic */ );
|
||||
}
|
||||
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
QModelIndex
|
||||
SipModel::parent( const QModelIndex& child ) const
|
||||
{
|
||||
if( !child.isValid() )
|
||||
return QModelIndex();
|
||||
|
||||
if( child.internalId() == 1 ) {
|
||||
return createIndex( SipHandler::instance()->allPlugins().size() - 1, 0, 0 );
|
||||
}
|
||||
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
int
|
||||
SipModel::rowCount( const QModelIndex& parent ) const
|
||||
{
|
||||
return SipHandler::instance()->allPlugins().size() + 1;
|
||||
if( !parent.isValid() ) { // top level item
|
||||
if( parent.row() == SipHandler::instance()->allPlugins().count() ) { // last row, this is the factory
|
||||
return SipHandler::instance()->pluginFactories().count();
|
||||
} else {
|
||||
return SipHandler::instance()->allPlugins().size() + 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
class SipPlugin;
|
||||
|
||||
class DLLEXPORT SipModel : public QAbstractListModel
|
||||
class DLLEXPORT SipModel : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
@ -35,12 +35,15 @@ public:
|
||||
PluginName = Qt::UserRole + 15,
|
||||
ConnectionStateRole = Qt::UserRole + 17,
|
||||
HasConfig = Qt::UserRole + 18,
|
||||
FactoryRole = Qt::UserRole + 19
|
||||
FactoryRole = Qt::UserRole + 19,
|
||||
ErrorString = Qt::UserRole + 20
|
||||
};
|
||||
|
||||
explicit SipModel( QObject* parent = 0 );
|
||||
virtual ~SipModel();
|
||||
|
||||
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;
|
||||
|
@ -52,3 +52,15 @@ SipPlugin::configWidget()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
QString
|
||||
SipPlugin::errorMessage() const
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
|
||||
QIcon
|
||||
SipPlugin::icon() const
|
||||
{
|
||||
return QIcon();
|
||||
}
|
||||
|
@ -35,9 +35,9 @@ public:
|
||||
virtual ~SipPluginFactory() {}
|
||||
|
||||
// display name for plugin
|
||||
virtual QString prettyName() = 0;
|
||||
virtual QString prettyName() const = 0;
|
||||
// internal name
|
||||
virtual QString factoryId() = 0;
|
||||
virtual QString factoryId() const = 0;
|
||||
virtual SipPlugin* createPlugin( const QString& pluginId = QString() ) = 0;
|
||||
|
||||
protected:
|
||||
@ -63,8 +63,10 @@ public:
|
||||
virtual const QString friendlyName() const = 0;
|
||||
virtual const QString accountName() const = 0;
|
||||
virtual ConnectionState connectionState() const = 0;
|
||||
virtual QString errorMessage() const;
|
||||
virtual QMenu* menu();
|
||||
virtual QWidget* configWidget();
|
||||
virtual QIcon icon() const;
|
||||
|
||||
public slots:
|
||||
virtual bool connectPlugin( bool startup = false ) = 0;
|
||||
|
@ -29,10 +29,9 @@
|
||||
#define PADDING 4
|
||||
|
||||
ResolverConfigDelegate::ResolverConfigDelegate( QObject* parent )
|
||||
: QStyledItemDelegate( parent )
|
||||
, m_configPressed( false )
|
||||
: ConfigDelegateBase( parent )
|
||||
{
|
||||
|
||||
connect( this, SIGNAL( configPressed( QModelIndex ) ), this, SLOT( onConfigPressed( QModelIndex ) ) );
|
||||
}
|
||||
|
||||
void
|
||||
@ -61,36 +60,32 @@ ResolverConfigDelegate::paint( QPainter* painter, const QStyleOptionViewItem& op
|
||||
style->drawPrimitive( QStyle::PE_PanelItemViewItem, &opt, painter, w );
|
||||
|
||||
int rightSplit = itemRect.width();
|
||||
int rectW = opt.rect.height() - 4 * PADDING;
|
||||
int rectW = 24;
|
||||
QRect confRect = QRect( rightSplit - rectW - 2 * PADDING, 2 * PADDING + top, rectW, rectW );
|
||||
|
||||
// if the resolver has a config widget, paint it first (right-aligned)
|
||||
if( index.data( ResolversModel::HasConfig ).toBool() ) {
|
||||
// draw it the same size as the check belox
|
||||
QStyleOptionToolButton topt;
|
||||
topt.font = opt.font;
|
||||
topt.icon = QIcon( RESPATH "images/configure.png" );
|
||||
topt.iconSize = QSize( 16, 16 );
|
||||
topt.rect = confRect;
|
||||
topt.subControls = QStyle::SC_ToolButton;
|
||||
topt.activeSubControls = QStyle::SC_None;
|
||||
topt.features = QStyleOptionToolButton::None;
|
||||
topt.pos = confRect.topLeft();
|
||||
topt.state = m_configPressed ? QStyle::State_On : QStyle::State_Raised;
|
||||
if( opt.state & QStyle::State_MouseOver || m_configPressed )
|
||||
topt.state |= QStyle::State_HasFocus;
|
||||
style->drawComplexControl( QStyle::CC_ToolButton, &topt, painter, w );
|
||||
|
||||
drawConfigWrench( painter, opt, topt );
|
||||
}
|
||||
|
||||
// draw check
|
||||
confRect.moveTo( 2 * PADDING, 2 * PADDING + top );
|
||||
opt.rect = confRect;
|
||||
opt.checkState == Qt::Checked ? opt.state |= QStyle::State_On : opt.state |= QStyle::State_Off;
|
||||
style->drawPrimitive( QStyle::PE_IndicatorViewItemCheck, &opt, painter, w );
|
||||
QRect checkRect = confRect;
|
||||
checkRect.moveTo( 2 * PADDING, 2 * PADDING + top );
|
||||
opt.rect = checkRect;
|
||||
drawCheckBox( opt, painter, w );
|
||||
itemRect.setX( opt.rect.topRight().x() + PADDING );
|
||||
|
||||
painter->save();
|
||||
painter->setFont( name );
|
||||
QRect textRect = itemRect.adjusted( PADDING, PADDING, -PADDING, -PADDING );
|
||||
|
||||
if( index.data( ResolversModel::HasConfig ).toBool() )
|
||||
textRect.setRight( confRect.topLeft().x() - PADDING );
|
||||
|
||||
textRect.setBottom( itemRect.height() / 2 + top );
|
||||
QString nameStr = bfm.elidedText( index.data( ResolversModel::ResolverName ).toString(),Qt::ElideRight, textRect.width() );
|
||||
painter->drawText( textRect, nameStr );
|
||||
@ -106,71 +101,8 @@ ResolverConfigDelegate::paint( QPainter* painter, const QStyleOptionViewItem& op
|
||||
|
||||
}
|
||||
|
||||
QSize
|
||||
ResolverConfigDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const
|
||||
void
|
||||
ResolverConfigDelegate::onConfigPressed( const QModelIndex& idx )
|
||||
{
|
||||
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, 3 * PADDING + bfm.height() + sfm.height() );
|
||||
}
|
||||
|
||||
bool
|
||||
ResolverConfigDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index)
|
||||
{
|
||||
// qDebug() << "EDITOR EVENT!" << ( event->type() == QEvent::MouseButtonRelease );
|
||||
|
||||
QStyleOptionViewItemV4 viewOpt( option );
|
||||
initStyleOption( &viewOpt, index );
|
||||
const QWidget* w = viewOpt.widget;
|
||||
QStyle* style = w ? w->style() : QApplication::style();
|
||||
int top = viewOpt.rect.top();
|
||||
|
||||
if( event->type() == QEvent::MouseButtonRelease || event->type() == QEvent::MouseButtonDblClick ) {
|
||||
m_configPressed = false;
|
||||
|
||||
int rectW = option.rect.height() - 4 * PADDING;
|
||||
QRect checkRect = QRect( 2 * PADDING, 2 * PADDING + top, rectW, rectW );
|
||||
QMouseEvent* me = static_cast< QMouseEvent* >( event );
|
||||
if( me->button() != Qt::LeftButton || !checkRect.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( 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 ) {
|
||||
int rightSplit = viewOpt.rect.width();
|
||||
int rectW = viewOpt.rect.height() - 4 * PADDING;
|
||||
QRect confRect = QRect( rightSplit - rectW - 2 * PADDING, 2 * PADDING + top, rectW, rectW );
|
||||
|
||||
QMouseEvent* me = static_cast< QMouseEvent* >( event );
|
||||
if( me->button() == Qt::LeftButton && confRect.contains( me->pos() ) ) {
|
||||
m_configPressed = true;
|
||||
|
||||
emit openConfig( index.data( ResolversModel::ResolverPath ).toString() );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return QStyledItemDelegate::editorEvent( event, model, option, index );
|
||||
emit openConfig( idx.data( ResolversModel::ResolverPath ).toString() );
|
||||
}
|
||||
|
@ -20,23 +20,21 @@
|
||||
#ifndef RESOLVERCONFIGDELEGATE_H
|
||||
#define RESOLVERCONFIGDELEGATE_H
|
||||
|
||||
#include <QStyledItemDelegate>
|
||||
#include "configdelegatebase.h"
|
||||
|
||||
|
||||
class ResolverConfigDelegate : public QStyledItemDelegate
|
||||
class ResolverConfigDelegate : public ConfigDelegateBase
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ResolverConfigDelegate(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 );
|
||||
|
||||
private slots:
|
||||
void onConfigPressed ( const QModelIndex& );
|
||||
|
||||
signals:
|
||||
void openConfig( const QString& resolverPath );
|
||||
|
||||
private:
|
||||
bool m_configPressed;
|
||||
};
|
||||
|
||||
#endif // RESOLVERCONFIGDELEGATE_H
|
||||
|
@ -165,12 +165,6 @@ ScriptResolver::handleMsg( const QByteArray& msg )
|
||||
rp->setMimetype( TomahawkUtils::extensionToMimetype( m.value( "extension" ).toString() ) );
|
||||
Q_ASSERT( !rp->mimetype().isEmpty() );
|
||||
}
|
||||
if ( m.contains( "year" ) )
|
||||
{
|
||||
QVariantMap attr;
|
||||
attr[ "releaseyear" ] = m.value( "year" );
|
||||
rp->setAttributes( attr );
|
||||
}
|
||||
|
||||
results << rp;
|
||||
}
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "resolversmodel.h"
|
||||
#include "resolverconfigwrapper.h"
|
||||
#include "sip/SipModel.h"
|
||||
#include "sipconfigdelegate.h"
|
||||
|
||||
static QString
|
||||
md5( const QByteArray& src )
|
||||
@ -70,9 +71,9 @@ SettingsDialog::SettingsDialog( QWidget *parent )
|
||||
ui->checkBoxUpnp->setEnabled( !s->preferStaticHostPort() );
|
||||
|
||||
// SIP PLUGINS
|
||||
// SipPluginDelegate* ad = new SipPluginDelegate( this );
|
||||
// ui->accountsView->setItemDelegate( ad );
|
||||
// connect( ad, SIGNAL( openConfig( QString ) ), this, SLOT( openSipPluginConfig( QString ) ) );
|
||||
SipConfigDelegate* sipdel = new SipConfigDelegate( this );
|
||||
ui->accountsView->setItemDelegate( sipdel );
|
||||
// connect( sipdel, SIGNAL( openConfig( SipPlugin* ) ), this, SLOT( openSipPluginConfig( SipPlugin* ) ) );
|
||||
m_sipModel = new SipModel( this );
|
||||
ui->accountsView->setModel( m_sipModel );
|
||||
|
||||
|
@ -31,7 +31,20 @@
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_20">
|
||||
<item>
|
||||
<widget class="QListView" name="accountsView"/>
|
||||
<widget class="QTreeView" name="accountsView">
|
||||
<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>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
Loading…
x
Reference in New Issue
Block a user