mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-03-18 23:09:42 +01:00
Work to add setData to the model, and hook up model to some signals
This commit is contained in:
parent
daa6b7b841
commit
34dbc50b3a
@ -20,6 +20,7 @@
|
||||
|
||||
#include <QApplication>
|
||||
#include <QPainter>
|
||||
#include <QMouseEvent>
|
||||
|
||||
#include "accounts/AccountModel.h"
|
||||
#include "accounts/Account.h"
|
||||
@ -50,7 +51,7 @@ using namespace Tomahawk;
|
||||
using namespace Accounts;
|
||||
|
||||
AccountDelegate::AccountDelegate( QObject* parent )
|
||||
: ConfigDelegateBase ( parent )
|
||||
: QStyledItemDelegate ( parent )
|
||||
, m_widestTextWidth( 0 )
|
||||
{
|
||||
|
||||
@ -87,12 +88,6 @@ AccountDelegate::AccountDelegate( QObject* parent )
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
AccountDelegate::editorEvent ( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index )
|
||||
{
|
||||
return ConfigDelegateBase::editorEvent( event, model, option, index );
|
||||
}
|
||||
|
||||
|
||||
QSize
|
||||
AccountDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const
|
||||
@ -125,131 +120,6 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option,
|
||||
paintChild( painter, opt, index );
|
||||
|
||||
return;
|
||||
|
||||
// const QRect itemRect = opt.rect;
|
||||
// const int top = itemRect.top();
|
||||
// const int mid = itemRect.height() / 2;
|
||||
// const int quarter = mid - ( itemRect.height() / 4 );
|
||||
//
|
||||
// // one line bold for account name
|
||||
// // space below it for online/offline status
|
||||
// // checkbox, icon, name/status, features, config icon
|
||||
// QFont name = opt.font;
|
||||
// name.setPointSize( name.pointSize() + 2 );
|
||||
// name.setBold( true );
|
||||
//
|
||||
// QFont smallFont = opt.font;
|
||||
// smallFont.setPointSize( smallFont.pointSize() - 1 );
|
||||
// QFontMetrics smallFontFM( smallFont );
|
||||
//
|
||||
// // 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 + WRENCH_SIZE + 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< QPixmap >().isNull() ) {
|
||||
QRect prect = QRect( iconLeftEdge, pos + top, ICONSIZE, ICONSIZE );
|
||||
|
||||
painter->save();
|
||||
painter->drawPixmap( prect, index.data( Qt::DecorationRole ).value< QPixmap >().scaled( prect.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation ) );
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
// name
|
||||
painter->save();
|
||||
painter->setFont( name );
|
||||
QFontMetrics namefm( name );
|
||||
// pos will the top-left point of the text rect
|
||||
pos = quarter - ( namefm.height() / 2 ) + top;
|
||||
const QString nameStr = index.data( AccountModel::AccountName ).toString();
|
||||
const int titleWidth = namefm.width( nameStr );
|
||||
const QRect nameRect( textLeftEdge, pos, titleWidth, namefm.height() );
|
||||
painter->drawText( nameRect, nameStr );
|
||||
painter->restore();
|
||||
|
||||
// draw the online/offline status
|
||||
const int stateY = mid + quarter - ( smallFontFM.height() / 2 ) + top;
|
||||
|
||||
QPixmap p;
|
||||
QString statusText;
|
||||
Account::ConnectionState state = static_cast< Account::ConnectionState >( index.data( AccountModel::ConnectionStateRole ).toInt() );
|
||||
if ( state == Account::Connected )
|
||||
{
|
||||
p = m_cachedIcons[ "sipplugin-online" ];
|
||||
statusText = tr( "Online" );
|
||||
}
|
||||
else if ( state == Account::Connecting )
|
||||
{
|
||||
p = m_cachedIcons[ "sipplugin-offline" ];
|
||||
statusText = tr( "Connecting..." );
|
||||
}
|
||||
else
|
||||
{
|
||||
p = m_cachedIcons[ "sipplugin-offline" ];
|
||||
statusText = tr( "Offline" );
|
||||
}
|
||||
painter->drawPixmap( textLeftEdge, stateY, STATUS_ICON_SIZE, STATUS_ICON_SIZE, p );
|
||||
|
||||
int width = smallFontFM.width( statusText );
|
||||
int statusTextX = textLeftEdge + STATUS_ICON_SIZE + PADDING;
|
||||
painter->save();
|
||||
painter->setFont( smallFont );
|
||||
painter->drawText( QRect( statusTextX, stateY, width, smallFontFM.height() ), statusText );
|
||||
painter->restore();
|
||||
|
||||
// right-most edge of text on left (name, desc) is the cutoff point for the rest of the delegate
|
||||
width = qMax( statusTextX + width, textLeftEdge + titleWidth );
|
||||
|
||||
// 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( AccountModel::HasConfig ).toBool() ) {
|
||||
|
||||
QStyleOptionToolButton topt;
|
||||
topt.rect = confRect;
|
||||
topt.pos = confRect.topLeft();
|
||||
|
||||
drawConfigWrench( painter, opt, topt );
|
||||
}
|
||||
|
||||
const bool hasCapability = ( static_cast< Accounts::AccountTypes >( index.data( AccountModel::AccountTypeRole ).toInt() ) != Accounts::NoType );
|
||||
|
||||
// draw optional capability text if it exists
|
||||
if ( hasCapability )
|
||||
{
|
||||
QString capString;
|
||||
AccountTypes types = AccountTypes( index.data( AccountModel::AccountTypeRole ).toInt() );
|
||||
if ( ( types & Accounts::SipType ) && ( types & Accounts::ResolverType ) )
|
||||
capString = tr( "Connects to, plays from friends" );
|
||||
else if ( types & Accounts::SipType )
|
||||
capString = tr( "Connects to friends" );
|
||||
else if ( types & Accounts::ResolverType )
|
||||
capString = tr( "Finds Music");
|
||||
|
||||
// checkbox for capability
|
||||
// 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 capY = mid - ( smallFontFM.height() / 2 ) + top;
|
||||
const int configLeftEdge = confRect.left() - PADDING;
|
||||
const int capW = configLeftEdge - width;
|
||||
// Right-align text
|
||||
const int capTextX = qMax( width, configLeftEdge - smallFontFM.width( capString ) );
|
||||
painter->setFont( smallFont );
|
||||
painter->drawText( QRect( capTextX, capY, configLeftEdge - capTextX, smallFontFM.height() ), Qt::AlignRight, capString );
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
@ -294,7 +164,8 @@ AccountDelegate::paintTopLevel( QPainter* painter, const QStyleOptionViewItemV4&
|
||||
opt2.rect = checkRect;
|
||||
const AccountModel::ItemState state = static_cast< AccountModel::ItemState >( index.data( AccountModel::StateRole ).toInt() );
|
||||
const bool canCheck = ( state == AccountModel::Installed || state == AccountModel::ShippedWithTomahawk );
|
||||
opt2.state = canCheck ? QStyle::State_On : QStyle::State_Off;
|
||||
if ( !canCheck )
|
||||
opt2.state &= ~QStyle::State_Enabled;
|
||||
drawCheckBox( opt2, painter, opt.widget );
|
||||
}
|
||||
leftEdge += WRENCH_SIZE + PADDING / 2;
|
||||
@ -315,62 +186,69 @@ AccountDelegate::paintTopLevel( QPainter* painter, const QStyleOptionViewItemV4&
|
||||
|
||||
// install / status button
|
||||
const AccountModel::ItemState state = static_cast< AccountModel::ItemState >( index.data( AccountModel::StateRole ).toInt() );
|
||||
QString actionText;
|
||||
switch( state )
|
||||
int edgeOfRightExtras = opt.rect.right();
|
||||
if ( rowType == Tomahawk::Accounts::AccountModel::TopLevelFactory )
|
||||
{
|
||||
case AccountModel::Uninstalled:
|
||||
actionText = tr( "Install" );
|
||||
break;
|
||||
case AccountModel::Installing:
|
||||
actionText = tr( "Installing" );
|
||||
break;
|
||||
case AccountModel::Upgrading:
|
||||
actionText = tr( "Upgrading" );
|
||||
break;
|
||||
case AccountModel::Failed:
|
||||
actionText = tr( "Failed" );
|
||||
break;
|
||||
case AccountModel::Installed:
|
||||
actionText = tr( "Uninstall" );
|
||||
break;
|
||||
case AccountModel::NeedsUpgrade:
|
||||
actionText = tr( "Upgrade" );
|
||||
break;
|
||||
case AccountModel::ShippedWithTomahawk:
|
||||
actionText = tr( "Create" );
|
||||
break;
|
||||
case AccountModel::UniqueFactory:
|
||||
actionText = tr( "Installed" );
|
||||
break;
|
||||
QString actionText;
|
||||
switch( state )
|
||||
{
|
||||
case AccountModel::Uninstalled:
|
||||
actionText = tr( "Install" );
|
||||
break;
|
||||
case AccountModel::Installing:
|
||||
actionText = tr( "Installing" );
|
||||
break;
|
||||
case AccountModel::Upgrading:
|
||||
actionText = tr( "Upgrading" );
|
||||
break;
|
||||
case AccountModel::Failed:
|
||||
actionText = tr( "Failed" );
|
||||
break;
|
||||
case AccountModel::Installed:
|
||||
actionText = tr( "Uninstall" );
|
||||
break;
|
||||
case AccountModel::NeedsUpgrade:
|
||||
actionText = tr( "Upgrade" );
|
||||
break;
|
||||
case AccountModel::ShippedWithTomahawk:
|
||||
actionText = tr( "Create" );
|
||||
break;
|
||||
case AccountModel::UniqueFactory:
|
||||
actionText = tr( "Installed" );
|
||||
break;
|
||||
}
|
||||
// title and description
|
||||
const int btnWidth = m_widestTextWidth + 7;
|
||||
leftEdge = opt.rect.width() - PADDING - btnWidth - 3;
|
||||
const QRect btnRect( leftEdge, center - ( installMetrics.height() + 4 ) / 2, btnWidth, installMetrics.height() + 4 );
|
||||
m_cachedButtonRects[ index ] = btnRect;
|
||||
|
||||
|
||||
painter->save();
|
||||
painter->setPen( opt.palette.color( QPalette::Active, QPalette::AlternateBase ) );
|
||||
|
||||
drawRoundedButton( painter, btnRect );
|
||||
|
||||
painter->setFont( installFont );
|
||||
painter->drawText( btnRect, Qt::AlignCenter, actionText );
|
||||
painter->restore();
|
||||
|
||||
edgeOfRightExtras = btnRect.left();
|
||||
}
|
||||
|
||||
// title and description
|
||||
const int btnWidth = m_widestTextWidth + 7;
|
||||
leftEdge = opt.rect.width() - PADDING - btnWidth - 3;
|
||||
const QRect btnRect( leftEdge, center - ( installMetrics.height() + 4 ) / 2, btnWidth, installMetrics.height() + 4 );
|
||||
m_cachedButtonRects[ index ] = btnRect;
|
||||
|
||||
const QPen saved = painter->pen();
|
||||
painter->setPen( opt.palette.color( QPalette::Active, QPalette::AlternateBase ) );
|
||||
|
||||
drawRoundedButton( painter, btnRect );
|
||||
|
||||
painter->setFont( installFont );
|
||||
painter->drawText( btnRect, Qt::AlignCenter, actionText );
|
||||
|
||||
painter->setPen( saved );
|
||||
|
||||
|
||||
int edgeOfRightExtras = btnRect.x();
|
||||
if ( rowType == AccountModel::TopLevelAccount )
|
||||
{
|
||||
// rating stars
|
||||
const int rating = index.data( AccountModel::RatingRole ).toInt();
|
||||
const int ratingWidth = 5 * ( m_ratingStarPositive.width() + PADDING_BETWEEN_STARS );
|
||||
int runningEdge = ( btnRect.right() - btnRect.width() / 2 ) - ratingWidth / 2;
|
||||
|
||||
// int runningEdge = ( btnRect.right() - btnRect.width() / 2 ) - ratingWidth / 2;
|
||||
int runningEdge = opt.rect.right() - PADDING - ratingWidth;
|
||||
edgeOfRightExtras = runningEdge;
|
||||
for ( int i = 1; i < 6; i++ )
|
||||
{
|
||||
QRect r( runningEdge, btnRect.top() - m_ratingStarPositive.height() - PADDING, m_ratingStarPositive.width(), m_ratingStarPositive.height() );
|
||||
QRect r( runningEdge, opt.rect.top() + PADDING, m_ratingStarPositive.width(), m_ratingStarPositive.height() );
|
||||
if ( i == 1 )
|
||||
m_cachedStarRects[ index ] = r;
|
||||
|
||||
@ -401,19 +279,23 @@ AccountDelegate::paintTopLevel( QPainter* painter, const QStyleOptionViewItemV4&
|
||||
|
||||
// downloaded num times, underneath button
|
||||
QString count = tr( "%1 downloads" ).arg( index.data( AccountModel::DownloadCounterRole ).toInt() );
|
||||
const QRect countRect( btnRect.left(), btnRect.bottom() + PADDING, btnRect.width(), opt.rect.bottom() - PADDING - btnRect.bottom() );
|
||||
|
||||
QFont countFont = descFont;
|
||||
countFont.setPointSize( countFont.pointSize() - 2 );
|
||||
countFont.setBold( true );
|
||||
painter->setFont( countFont );
|
||||
const int countW = painter->fontMetrics().width( count );
|
||||
|
||||
const QRect countRect( opt.rect.right() - PADDING - countW, opt.rect.bottom() - PADDING - painter->fontMetrics().height(), countW, painter->fontMetrics().height() );
|
||||
painter->setFont( countFont );
|
||||
painter->drawText( countRect, Qt::AlignCenter | Qt::TextWordWrap, count );
|
||||
|
||||
// author and version
|
||||
QString author = index.data( AccountModel::AuthorRole ).toString();
|
||||
painter->setFont( authorFont );
|
||||
const int authorWidth = authorMetrics.width( author );
|
||||
const int topTextLine = opt.rect.top() + PADDING;
|
||||
const QRect authorRect( btnRect.x() - 3*PADDING - authorWidth, topTextLine, authorWidth + 6, authorMetrics.height() );
|
||||
painter->setFont( authorFont );
|
||||
const QRect authorRect( edgeOfRightExtras - 2*PADDING - authorWidth, topTextLine, authorWidth + 6, authorMetrics.height() );
|
||||
painter->drawText( authorRect, Qt::AlignCenter, author );
|
||||
|
||||
// Disable version for now, that space is used
|
||||
@ -425,10 +307,10 @@ AccountDelegate::paintTopLevel( QPainter* painter, const QStyleOptionViewItemV4&
|
||||
}
|
||||
|
||||
// if this is a real resolver, show config wrench, state/status, and string
|
||||
edgeOfRightExtras = btnRect.x();
|
||||
m_cachedConfigRects.remove( index );
|
||||
if ( rowType == AccountModel::TopLevelAccount )
|
||||
{
|
||||
const QRect confRect = QRect( btnRect.x() - 2*PADDING - WRENCH_SIZE, center - WRENCH_SIZE / 2, WRENCH_SIZE, WRENCH_SIZE );
|
||||
const QRect confRect = QRect( edgeOfRightExtras - 2*PADDING - WRENCH_SIZE, center - WRENCH_SIZE / 2, WRENCH_SIZE, WRENCH_SIZE );
|
||||
if( index.data( AccountModel::HasConfig ).toBool() ) {
|
||||
|
||||
QStyleOptionToolButton topt;
|
||||
@ -436,13 +318,17 @@ AccountDelegate::paintTopLevel( QPainter* painter, const QStyleOptionViewItemV4&
|
||||
topt.pos = confRect.topLeft();
|
||||
|
||||
drawConfigWrench( painter, opt, topt );
|
||||
m_cachedConfigRects[ index ] = confRect;
|
||||
edgeOfRightExtras = confRect.left();
|
||||
}
|
||||
|
||||
painter->save();
|
||||
painter->setFont( installFont );
|
||||
edgeOfRightExtras = drawStatus( painter, QPointF( edgeOfRightExtras - PADDING, center ), index );
|
||||
painter->restore();
|
||||
if ( state == AccountModel::Installed || state == AccountModel::ShippedWithTomahawk || state == AccountModel::NeedsUpgrade )
|
||||
{
|
||||
painter->save();
|
||||
painter->setFont( installFont );
|
||||
edgeOfRightExtras = drawStatus( painter, QPointF( edgeOfRightExtras - PADDING, center ), index );
|
||||
painter->restore();
|
||||
}
|
||||
}
|
||||
|
||||
// Title and description!
|
||||
@ -500,10 +386,12 @@ AccountDelegate::paintChild( QPainter* painter, const QStyleOptionViewItemV4& op
|
||||
|
||||
// draw remove icon, config wrench, and then status from right edge
|
||||
const QRect removeRect( option.rect.right() - rightPadding - PADDING - REMOVE_ICON_SIZE, center - REMOVE_ICON_SIZE/2, REMOVE_ICON_SIZE, REMOVE_ICON_SIZE );
|
||||
m_cachedButtonRects[ index ] = removeRect;
|
||||
painter->drawPixmap( removeRect, m_removeIcon );
|
||||
|
||||
int edgeOfRightExtras = removeRect.left();
|
||||
|
||||
m_cachedConfigRects.remove( index );
|
||||
if ( index.data( AccountModel::HasConfig ).toBool() )
|
||||
{
|
||||
const QRect confRect = QRect( removeRect.x() - PADDING - SMALL_WRENCH_SIZE, center - SMALL_WRENCH_SIZE / 2, SMALL_WRENCH_SIZE, SMALL_WRENCH_SIZE );
|
||||
@ -514,6 +402,7 @@ AccountDelegate::paintChild( QPainter* painter, const QStyleOptionViewItemV4& op
|
||||
|
||||
QStyleOptionViewItemV4 opt3 = option;
|
||||
drawConfigWrench( painter, opt3, topt );
|
||||
m_cachedConfigRects[ index ] = confRect;
|
||||
|
||||
edgeOfRightExtras = confRect.left();
|
||||
}
|
||||
@ -527,6 +416,103 @@ AccountDelegate::paintChild( QPainter* painter, const QStyleOptionViewItemV4& op
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
AccountDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, 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( AccountModel::AccountData ).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();
|
||||
|
||||
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
|
||||
|
||||
// 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, AccountModel::CheckboxClickedRole );
|
||||
}
|
||||
else if ( m_cachedButtonRects.contains( index ) && m_cachedButtonRects[ index ].contains( me->pos() ) )
|
||||
{
|
||||
// Install/create/etc button for this row
|
||||
model->setData( index, true, AccountModel::ButtonClickedRole );
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_cachedStarRects.contains( index ) )
|
||||
{
|
||||
QRect fullStars = m_cachedStarRects[ index ];
|
||||
const int starsWidth = 5 * ( m_ratingStarPositive.width() + PADDING_BETWEEN_STARS );
|
||||
fullStars.setWidth( starsWidth );
|
||||
|
||||
QMouseEvent* me = static_cast< QMouseEvent* >( event );
|
||||
|
||||
if ( fullStars.contains( me->pos() ) )
|
||||
{
|
||||
const int eachStar = starsWidth / 5;
|
||||
const int clickOffset = me->pos().x() - fullStars.x();
|
||||
const int whichStar = (clickOffset / eachStar) + 1;
|
||||
|
||||
if ( event->type() == QEvent::MouseButtonRelease )
|
||||
{
|
||||
model->setData( index, whichStar, AccountModel::RatingRole );
|
||||
}
|
||||
else if ( event->type() == QEvent::MouseMove )
|
||||
{
|
||||
// 0-indexed
|
||||
m_hoveringOver = whichStar;
|
||||
m_hoveringItem = index;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_hoveringOver > -1 )
|
||||
{
|
||||
emit update( m_hoveringItem );
|
||||
m_hoveringOver = -1;
|
||||
m_hoveringItem = QPersistentModelIndex();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AccountDelegate::drawRoundedButton( QPainter* painter, const QRect& btnRect ) const
|
||||
{
|
||||
@ -598,46 +584,62 @@ AccountDelegate::drawStatus( QPainter* painter, const QPointF& rightCenterEdge,
|
||||
}
|
||||
|
||||
|
||||
QRect
|
||||
AccountDelegate::checkRectForIndex( const QStyleOptionViewItem &option, const QModelIndex &idx, int role ) const
|
||||
void
|
||||
AccountDelegate::drawCheckBox( QStyleOptionViewItemV4& opt, QPainter* p, const QWidget* w ) 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::AccountTypeRole )
|
||||
// {
|
||||
// // 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;
|
||||
// }
|
||||
QStyle* style = w ? w->style() : QApplication::style();
|
||||
opt.checkState == Qt::Checked ? opt.state |= QStyle::State_On : opt.state |= QStyle::State_Off;
|
||||
style->drawPrimitive( QStyle::PE_IndicatorViewItemCheck, &opt, p, w );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AccountDelegate::drawConfigWrench ( QPainter* painter, QStyleOptionViewItemV4& opt, QStyleOptionToolButton& topt ) const
|
||||
{
|
||||
const QWidget* w = opt.widget;
|
||||
QStyle* style = w ? w->style() : QApplication::style();
|
||||
|
||||
// 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.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 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
QRect
|
||||
AccountDelegate::checkRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const
|
||||
{
|
||||
// the checkbox for this row was hit
|
||||
const AccountModel::RowType rowType = static_cast< AccountModel::RowType >( idx.data( AccountModel::RowTypeRole ).toInt() );
|
||||
|
||||
QStyleOptionViewItemV4 opt = option;
|
||||
initStyleOption( &opt, idx );
|
||||
|
||||
if ( rowType == AccountModel::TopLevelAccount || rowType == AccountModel::TopLevelFactory )
|
||||
{
|
||||
// Top level item, return the corresponding rect
|
||||
const int ypos = ( opt.rect.top() + opt.rect.height() / 2 ) - ( WRENCH_SIZE / 2 );
|
||||
QRect checkRect = QRect( PADDING, ypos, WRENCH_SIZE, WRENCH_SIZE );
|
||||
return checkRect;
|
||||
} else if ( rowType == AccountModel::ChildAccount )
|
||||
{
|
||||
// Return smaller rect of individual child account
|
||||
const int smallWrenchSize = opt.rect.height() - PADDING;
|
||||
int ypos = ( opt.rect.center().y() ) - ( smallWrenchSize / 2 );
|
||||
QRect checkRect = QRect( opt.rect.left() + PADDING, ypos, smallWrenchSize, smallWrenchSize );
|
||||
return checkRect;
|
||||
}
|
||||
|
||||
return QRect();
|
||||
}
|
||||
|
||||
QRect
|
||||
AccountDelegate::configRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
void
|
||||
AccountDelegate::askedForEdit( const QModelIndex& idx )
|
||||
{
|
||||
emit openConfig( qobject_cast< Account* >( idx.data( AccountModel::AccountData ).value< QObject* >() ) );
|
||||
}
|
||||
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
#ifndef ACCOUNTDELEGATE_H
|
||||
#define ACCOUNTDELEGATE_H
|
||||
|
||||
#include "configdelegatebase.h"
|
||||
#include <QStyledItemDelegate>
|
||||
#include "accounts/AccountModel.h"
|
||||
|
||||
namespace Tomahawk
|
||||
@ -29,21 +29,17 @@ namespace Accounts
|
||||
|
||||
class Account;
|
||||
|
||||
class AccountDelegate : public ConfigDelegateBase
|
||||
class AccountDelegate : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
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, int role ) const;
|
||||
virtual QRect configRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const;
|
||||
|
||||
private slots:
|
||||
void askedForEdit( const QModelIndex& idx );
|
||||
protected:
|
||||
virtual bool editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index );
|
||||
|
||||
signals:
|
||||
void update( const QModelIndex& idx );
|
||||
@ -52,17 +48,23 @@ signals:
|
||||
private:
|
||||
void paintTopLevel( QPainter* painter, const QStyleOptionViewItemV4& option, const QModelIndex& index ) const;
|
||||
void paintChild( QPainter* painter, const QStyleOptionViewItemV4& option, const QModelIndex& index ) const;
|
||||
|
||||
void drawRoundedButton( QPainter* painter, const QRect& buttonRect ) const;
|
||||
// Returns new left edge
|
||||
int drawStatus( QPainter* painter, const QPointF& rightCenterEdge, const QModelIndex& index ) const;
|
||||
void drawCheckBox( QStyleOptionViewItemV4& opt, QPainter* p, const QWidget* w ) const;
|
||||
void drawConfigWrench( QPainter* painter, QStyleOptionViewItemV4& option, QStyleOptionToolButton& topt ) const;
|
||||
|
||||
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_widestTextWidth;
|
||||
int m_hoveringOver;
|
||||
QPersistentModelIndex m_hoveringItem;
|
||||
QPersistentModelIndex m_hoveringItem, m_configPressed;
|
||||
mutable QHash< QPersistentModelIndex, QRect > m_cachedButtonRects;
|
||||
mutable QHash< QPersistentModelIndex, QRect > m_cachedStarRects;
|
||||
mutable QHash< QPersistentModelIndex, QRect > m_cachedConfigRects;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -74,7 +74,6 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui}
|
||||
audiocontrols.cpp
|
||||
settingsdialog.cpp
|
||||
diagnosticsdialog.cpp
|
||||
configdelegatebase.cpp
|
||||
AccountDelegate.cpp
|
||||
settingslistdelegate.cpp
|
||||
tomahawkwindow.cpp
|
||||
@ -98,13 +97,6 @@ IF(LIBLASTFM_FOUND)
|
||||
)
|
||||
ENDIF(LIBLASTFM_FOUND)
|
||||
|
||||
IF(LIBATTICA_FOUND)
|
||||
SET( tomahawkSourcesGui ${tomahawkSourcesGui} GetNewStuffDialog.cpp GetNewStuffDelegate.cpp GetNewStuffModel.cpp )
|
||||
SET( tomahawkHeadersGui ${tomahawkHeadersGui} GetNewStuffDialog.h GetNewStuffDelegate.h GetNewStuffModel.h )
|
||||
INCLUDE_DIRECTORIES( ${LIBATTICA_INCLUDE_DIR} )
|
||||
ENDIF(LIBATTICA_FOUND)
|
||||
|
||||
|
||||
SET( tomahawkHeadersGui ${tomahawkHeadersGui}
|
||||
sourcetree/sourcesmodel.h
|
||||
sourcetree/sourcesproxymodel.h
|
||||
@ -124,7 +116,6 @@ SET( tomahawkHeadersGui ${tomahawkHeadersGui}
|
||||
audiocontrols.h
|
||||
settingsdialog.h
|
||||
diagnosticsdialog.h
|
||||
configdelegatebase.h
|
||||
AccountDelegate.h
|
||||
settingslistdelegate.h
|
||||
delegateconfigwrapper.h
|
||||
@ -140,7 +131,6 @@ SET( tomahawkUI ${tomahawkUI}
|
||||
|
||||
audiocontrols.ui
|
||||
|
||||
GetNewStuffDialog.ui
|
||||
LoadXSPFDialog.ui
|
||||
)
|
||||
|
||||
@ -167,6 +157,7 @@ INCLUDE_DIRECTORIES(
|
||||
${TAGLIB_INCLUDES}
|
||||
${PHONON_INCLUDES}
|
||||
${QJSON_INCLUDE_DIR}
|
||||
${LIBATTICA_INCLUDE_DIR}
|
||||
${LIBECHONEST_INCLUDE_DIR}
|
||||
${LIBECHONEST_INCLUDE_DIR}/..
|
||||
)
|
||||
|
@ -1,326 +0,0 @@
|
||||
/* === 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 "GetNewStuffDelegate.h"
|
||||
|
||||
#include "GetNewStuffModel.h"
|
||||
#include "utils/tomahawkutils.h"
|
||||
#include "utils/logger.h"
|
||||
|
||||
#include <QtGui/QPainter>
|
||||
#include <QApplication>
|
||||
#include <QMouseEvent>
|
||||
#include "AtticaManager.h"
|
||||
|
||||
#define PADDING 4
|
||||
#define PADDING_BETWEEN_STARS 2
|
||||
#define STAR_SIZE 12
|
||||
|
||||
#ifdef Q_WS_MAC
|
||||
#define SIZEHINT_HEIGHT 70
|
||||
#else
|
||||
#define SIZEHINT_HEIGHT 60
|
||||
#endif
|
||||
|
||||
GetNewStuffDelegate::GetNewStuffDelegate( QObject* parent )
|
||||
: QStyledItemDelegate ( parent )
|
||||
, m_widestTextWidth( 0 )
|
||||
, m_hoveringOver( -1 )
|
||||
{
|
||||
m_defaultCover.load( RESPATH "images/sipplugin-online.png" );
|
||||
m_ratingStarPositive.load( RESPATH "images/starred.png" );
|
||||
m_ratingStarNegative.load( RESPATH "images/star-unstarred.png" );
|
||||
m_onHoverStar.load( RESPATH "images/star-hover.png" );
|
||||
|
||||
m_ratingStarPositive = m_ratingStarPositive.scaled( STAR_SIZE, STAR_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation );
|
||||
m_ratingStarNegative = m_ratingStarNegative.scaled( STAR_SIZE, STAR_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation );
|
||||
m_onHoverStar = m_onHoverStar.scaled( STAR_SIZE, STAR_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation );
|
||||
|
||||
const int w = SIZEHINT_HEIGHT - 2*PADDING;
|
||||
m_defaultCover = m_defaultCover.scaled( w, w, Qt::KeepAspectRatio, Qt::SmoothTransformation );
|
||||
|
||||
// save the widest wifth
|
||||
QFont f( QApplication::font() );
|
||||
f.setPointSize( f.pointSize() - 1 );
|
||||
QFontMetrics fm( f );
|
||||
QStringList l = QStringList() << tr( "Installed" ) << tr( "Installing" ) << tr( "Failed" ) << tr( "Uninstalling" );
|
||||
foreach ( const QString& str, l )
|
||||
{
|
||||
if ( fm.width( str ) > m_widestTextWidth )
|
||||
m_widestTextWidth = fm.width( str );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GetNewStuffDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const
|
||||
{
|
||||
QStyleOptionViewItemV4 opt = option;
|
||||
initStyleOption( &opt, index );
|
||||
|
||||
QApplication::style()->drawPrimitive( QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget );
|
||||
|
||||
painter->setRenderHint( QPainter::Antialiasing );
|
||||
|
||||
QFont titleFont = opt.font;
|
||||
titleFont.setBold( true );
|
||||
titleFont.setPointSize( titleFont.pointSize() + 2 );
|
||||
QFontMetrics titleMetrics( titleFont );
|
||||
|
||||
QFont authorFont = opt.font;
|
||||
authorFont.setItalic( true );
|
||||
authorFont.setPointSize( authorFont.pointSize() - 1 );
|
||||
QFontMetrics authorMetrics( authorFont );
|
||||
|
||||
QFont descFont = authorFont;
|
||||
descFont.setItalic( false );
|
||||
QFontMetrics descMetrics( descFont );
|
||||
|
||||
QFont installFont = opt.font;
|
||||
installFont.setPointSize( installFont.pointSize() - 1 );
|
||||
QFontMetrics installMetrics( descFont );
|
||||
|
||||
const int height = opt.rect.height();
|
||||
const int center = height / 2 + opt.rect.top();
|
||||
|
||||
// Pixmap
|
||||
QPixmap p = index.data( Qt::DecorationRole ).value< QPixmap >();
|
||||
const int pixmapWidth = height - 2*PADDING;
|
||||
QRect pixmapRect( PADDING, PADDING + opt.rect.top(), pixmapWidth, pixmapWidth );
|
||||
if ( p.isNull() ) // default image... TODO
|
||||
p = m_defaultCover;
|
||||
else
|
||||
p = p.scaled( pixmapRect.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation );
|
||||
|
||||
painter->drawPixmap( pixmapRect, p );
|
||||
|
||||
// Go from right edge now, stars, install button, and downloaded info
|
||||
|
||||
// install / status button
|
||||
GetNewStuffModel::ItemState state = static_cast< GetNewStuffModel::ItemState >( index.data( GetNewStuffModel::StateRole ).toInt() );
|
||||
QString actionText;
|
||||
switch( state )
|
||||
{
|
||||
case GetNewStuffModel::Uninstalled:
|
||||
actionText = tr( "Install" );
|
||||
break;
|
||||
case GetNewStuffModel::Installing:
|
||||
actionText = tr( "Installing" );
|
||||
break;
|
||||
case GetNewStuffModel::Upgrading:
|
||||
actionText = tr( "Upgrading" );
|
||||
break;
|
||||
case GetNewStuffModel::Failed:
|
||||
actionText = tr( "Failed" );
|
||||
break;
|
||||
case GetNewStuffModel::Installed:
|
||||
actionText = tr( "Uninstall" );
|
||||
break;
|
||||
case GetNewStuffModel::NeedsUpgrade:
|
||||
actionText = tr( "Upgrade" );
|
||||
break;
|
||||
case GetNewStuffModel::CanInstallMore:
|
||||
actionText = tr( "Install Another" );
|
||||
break;
|
||||
}
|
||||
|
||||
const int btnWidth = m_widestTextWidth + 7;
|
||||
const int leftEdge = opt.rect.width() - PADDING - btnWidth - 3;
|
||||
const QRect btnRect( leftEdge, center - ( installMetrics.height() + 4 ) / 2, btnWidth, installMetrics.height() + 4 );
|
||||
m_cachedButtonRects[ QPair<int, int>(index.row(), index.column()) ] = btnRect;
|
||||
|
||||
QPen saved = painter->pen();
|
||||
painter->setPen( opt.palette.color( QPalette::Active, QPalette::AlternateBase ) );
|
||||
|
||||
QPainterPath btnPath;
|
||||
const int radius = 3;
|
||||
//btnPath.addRoundedRect( btnRect, 3, 3 );
|
||||
// draw top half gradient
|
||||
const int btnCenter = btnRect.bottom() - ( btnRect.height() / 2 );
|
||||
btnPath.moveTo( btnRect.left(), btnCenter );
|
||||
btnPath.lineTo( btnRect.left(), btnRect.top() + radius );
|
||||
btnPath.quadTo( QPoint( btnRect.topLeft() ), QPoint( btnRect.left() + radius, btnRect.top() ) );
|
||||
btnPath.lineTo( btnRect.right() - radius, btnRect.top() );
|
||||
btnPath.quadTo( QPoint( btnRect.topRight() ), QPoint( btnRect.right(), btnRect.top() + radius ) );
|
||||
btnPath.lineTo( btnRect.right(),btnCenter );
|
||||
btnPath.lineTo( btnRect.left(), btnCenter );
|
||||
|
||||
QLinearGradient g;
|
||||
g.setColorAt( 0, QColor(54, 127, 211) );
|
||||
g.setColorAt( 0.5, QColor(43, 104, 182) );
|
||||
//painter->setPen( bg.darker() );
|
||||
painter->fillPath( btnPath, g );
|
||||
//painter->drawPath( btnPath );
|
||||
|
||||
btnPath = QPainterPath();
|
||||
btnPath.moveTo( btnRect.left(), btnCenter );
|
||||
btnPath.lineTo( btnRect.left(), btnRect.bottom() - radius );
|
||||
btnPath.quadTo( QPoint( btnRect.bottomLeft() ), QPoint( btnRect.left() + radius, btnRect.bottom() ) );
|
||||
btnPath.lineTo( btnRect.right() - radius, btnRect.bottom() );
|
||||
btnPath.quadTo( QPoint( btnRect.bottomRight() ), QPoint( btnRect.right(), btnRect.bottom() - radius ) );
|
||||
btnPath.lineTo( btnRect.right(), btnCenter );
|
||||
btnPath.lineTo( btnRect.left(), btnCenter );
|
||||
|
||||
g.setColorAt( 0, QColor(34, 85, 159) );
|
||||
g.setColorAt( 0.5, QColor(35, 79, 147) );
|
||||
painter->fillPath( btnPath, g );
|
||||
|
||||
painter->setFont( installFont );
|
||||
painter->drawText( btnRect, Qt::AlignCenter, actionText );
|
||||
|
||||
painter->setPen( saved );
|
||||
|
||||
// rating stars
|
||||
int rating = index.data( GetNewStuffModel::RatingRole ).toInt();
|
||||
const int ratingWidth = 5 * ( m_ratingStarPositive.width() + PADDING_BETWEEN_STARS );
|
||||
int runningEdge = ( btnRect.right() - btnRect.width() / 2 ) - ratingWidth / 2;
|
||||
for ( int i = 1; i < 6; i++ )
|
||||
{
|
||||
QRect r( runningEdge, btnRect.top() - m_ratingStarPositive.height() - PADDING, m_ratingStarPositive.width(), m_ratingStarPositive.height() );
|
||||
if ( i == 1 )
|
||||
m_cachedStarRects[ QPair<int, int>(index.row(), index.column()) ] = r;
|
||||
|
||||
const bool userHasRated = index.data( GetNewStuffModel::UserHasRatedRole ).toBool();
|
||||
if ( !userHasRated && // Show on-hover animation if the user hasn't rated it yet, and is hovering over it
|
||||
m_hoveringOver > -1 &&
|
||||
m_hoveringItem == index )
|
||||
{
|
||||
if ( i <= m_hoveringOver ) // positive star
|
||||
painter->drawPixmap( r, m_onHoverStar );
|
||||
else
|
||||
painter->drawPixmap( r, m_ratingStarNegative );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( i <= rating ) // positive or rated star
|
||||
{
|
||||
if ( userHasRated )
|
||||
painter->drawPixmap( r, m_onHoverStar );
|
||||
else
|
||||
painter->drawPixmap( r, m_ratingStarPositive );
|
||||
}
|
||||
else
|
||||
painter->drawPixmap( r, m_ratingStarNegative );
|
||||
}
|
||||
runningEdge += m_ratingStarPositive.width() + PADDING_BETWEEN_STARS;
|
||||
}
|
||||
|
||||
// downloaded num times, underneath button
|
||||
QString count = tr( "%1 downloads" ).arg( index.data( GetNewStuffModel::DownloadCounterRole ).toInt() );
|
||||
const QRect countRect( btnRect.left(), btnRect.bottom() + PADDING, btnRect.width(), opt.rect.bottom() - PADDING - btnRect.bottom() );
|
||||
QFont countFont = descFont;
|
||||
countFont.setPointSize( countFont.pointSize() - 2 );
|
||||
countFont.setBold( true );
|
||||
painter->setFont( countFont );
|
||||
painter->drawText( countRect, Qt::AlignCenter | Qt::TextWordWrap, count );
|
||||
|
||||
// author and version
|
||||
QString author = index.data( GetNewStuffModel::AuthorRole ).toString();
|
||||
const int authorWidth = authorMetrics.width( author );
|
||||
const int topTextLine = opt.rect.top() + PADDING;
|
||||
const QRect authorRect( btnRect.x() - 3*PADDING - authorWidth, topTextLine, authorWidth + 6, authorMetrics.height() );
|
||||
painter->setFont( authorFont );
|
||||
painter->drawText( authorRect, Qt::AlignCenter, author );
|
||||
|
||||
const QRect versionRect = authorRect.translated( 0, authorRect.height() );
|
||||
QString version = index.data( GetNewStuffModel::VersionRole ).toString();
|
||||
painter->drawText( versionRect, Qt::AlignCenter, version );
|
||||
|
||||
// title
|
||||
QString title = index.data( Qt::DisplayRole ).toString();
|
||||
const int rightTitleEdge = authorRect.left() - PADDING;
|
||||
const int leftTitleEdge = pixmapRect.right() + PADDING;
|
||||
const QRect textRect( leftTitleEdge, topTextLine, rightTitleEdge - leftTitleEdge, versionRect.bottom() - opt.rect.top() - PADDING );
|
||||
painter->setFont( titleFont );
|
||||
painter->drawText( textRect, Qt::AlignVCenter | Qt::AlignLeft, title );
|
||||
|
||||
// description
|
||||
QString desc = index.data( GetNewStuffModel::DescriptionRole ).toString();
|
||||
const int descWidth = btnRect.left() - leftTitleEdge - PADDING;
|
||||
const QRect descRect( leftTitleEdge, versionRect.bottom(), descWidth, opt.rect.bottom() - versionRect.bottom() + PADDING );
|
||||
painter->setFont( descFont );
|
||||
painter->drawText( descRect, Qt::AlignLeft | Qt::TextWordWrap, desc );
|
||||
}
|
||||
|
||||
|
||||
QSize
|
||||
GetNewStuffDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const
|
||||
{
|
||||
Q_UNUSED( option );
|
||||
Q_UNUSED( index );
|
||||
return QSize( 200, SIZEHINT_HEIGHT );
|
||||
}
|
||||
|
||||
bool
|
||||
GetNewStuffDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index )
|
||||
{
|
||||
Q_UNUSED( option );
|
||||
|
||||
if ( event->type() != QEvent::MouseButtonRelease &&
|
||||
event->type() != QEvent::MouseMove )
|
||||
return false;
|
||||
|
||||
if ( event->type() == QEvent::MouseButtonRelease && m_cachedButtonRects.contains( QPair<int, int>( index.row(), index.column() ) ) )
|
||||
{
|
||||
QRect rect = m_cachedButtonRects[ QPair<int, int>( index.row(), index.column() ) ];
|
||||
QMouseEvent* me = static_cast< QMouseEvent* >( event );
|
||||
|
||||
if ( rect.contains( me->pos() ) )
|
||||
{
|
||||
model->setData( index, true );
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_cachedStarRects.contains( QPair<int, int>( index.row(), index.column() ) ) )
|
||||
{
|
||||
QRect fullStars = m_cachedStarRects[ QPair<int, int>( index.row(), index.column() ) ];
|
||||
const int starsWidth = 5 * ( m_ratingStarPositive.width() + PADDING_BETWEEN_STARS );
|
||||
fullStars.setWidth( starsWidth );
|
||||
|
||||
QMouseEvent* me = static_cast< QMouseEvent* >( event );
|
||||
|
||||
if ( fullStars.contains( me->pos() ) )
|
||||
{
|
||||
const int eachStar = starsWidth / 5;
|
||||
const int clickOffset = me->pos().x() - fullStars.x();
|
||||
const int whichStar = (clickOffset / eachStar) + 1;
|
||||
|
||||
if ( event->type() == QEvent::MouseButtonRelease )
|
||||
{
|
||||
model->setData( index, whichStar, GetNewStuffModel::RatingRole );
|
||||
}
|
||||
else if ( event->type() == QEvent::MouseMove )
|
||||
{
|
||||
// 0-indexed
|
||||
m_hoveringOver = whichStar;
|
||||
m_hoveringItem = index;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_hoveringOver > -1 )
|
||||
{
|
||||
emit update( m_hoveringItem );
|
||||
m_hoveringOver = -1;
|
||||
m_hoveringItem = QPersistentModelIndex();
|
||||
}
|
||||
return false;
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
/* === 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 GETNEWSTUFFDELEGATE_H
|
||||
#define GETNEWSTUFFDELEGATE_H
|
||||
|
||||
#include <QStyledItemDelegate>
|
||||
|
||||
|
||||
class
|
||||
GetNewStuffDelegate : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit GetNewStuffDelegate( 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;
|
||||
|
||||
signals:
|
||||
void update( const QModelIndex& idx );
|
||||
|
||||
protected:
|
||||
virtual bool editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index );
|
||||
|
||||
private:
|
||||
QPixmap m_defaultCover, m_onHoverStar, m_ratingStarPositive, m_ratingStarNegative;
|
||||
|
||||
int m_widestTextWidth;
|
||||
int m_hoveringOver;
|
||||
QPersistentModelIndex m_hoveringItem;
|
||||
mutable QHash< QPair<int, int>, QRect > m_cachedButtonRects;
|
||||
mutable QHash< QPair<int, int>, QRect > m_cachedStarRects;
|
||||
};
|
||||
|
||||
#endif // GETNEWSTUFFDELEGATE_H
|
@ -1,75 +0,0 @@
|
||||
/* === This file is part of Tomahawk Player - <http://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
|
||||
* 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 "GetNewStuffDialog.h"
|
||||
|
||||
#include "ui_GetNewStuffDialog.h"
|
||||
#include "GetNewStuffDelegate.h"
|
||||
#include "GetNewStuffModel.h"
|
||||
#include "tomahawksettings.h"
|
||||
|
||||
#include <QtGui/QFileDialog>
|
||||
|
||||
GetNewStuffDialog::GetNewStuffDialog( QWidget* parent, Qt::WindowFlags f )
|
||||
: QDialog( parent, f )
|
||||
, ui( new Ui::GetNewStuffDialog )
|
||||
, m_model( new GetNewStuffModel( this ) )
|
||||
{
|
||||
ui->setupUi( this );
|
||||
|
||||
ui->accountsList->setModel( m_model );
|
||||
GetNewStuffDelegate* del = new GetNewStuffDelegate( ui->accountsList );
|
||||
connect( del, SIGNAL( update( QModelIndex ) ), ui->accountsList, SLOT( update( QModelIndex ) ) );
|
||||
ui->accountsList->setItemDelegate( del );
|
||||
ui->accountsList->setVerticalScrollMode( QAbstractItemView::ScrollPerPixel );
|
||||
|
||||
ui->accountsList->setMouseTracking( true );
|
||||
|
||||
setMinimumSize( 560, 350 );
|
||||
|
||||
#ifdef Q_WS_MAC
|
||||
setMaximumSize( 560, 350 );
|
||||
setSizeGripEnabled( false );
|
||||
|
||||
ui->accountsList->setAttribute( Qt::WA_MacShowFocusRect, false );
|
||||
#endif
|
||||
|
||||
connect( ui->installFromFileBtn, SIGNAL( clicked( bool ) ), this, SLOT( installFromFile() ) );
|
||||
}
|
||||
|
||||
|
||||
GetNewStuffDialog::~GetNewStuffDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GetNewStuffDialog::installFromFile()
|
||||
{
|
||||
QString resolver = QFileDialog::getOpenFileName( this, tr( "Load script resolver file" ), TomahawkSettings::instance()->scriptDefaultPath() );
|
||||
|
||||
// m_resolversModel->addResolver( resolver, true );
|
||||
// TODO
|
||||
if( !resolver.isEmpty() )
|
||||
{
|
||||
|
||||
QFileInfo resolverAbsoluteFilePath = resolver;
|
||||
TomahawkSettings::instance()->setScriptDefaultPath( resolverAbsoluteFilePath.absolutePath() );
|
||||
}
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
/* === This file is part of Tomahawk Player - <http://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
|
||||
* 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 GETNEWSTUFFDIALOG_H
|
||||
#define GETNEWSTUFFDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
class GetNewStuffModel;
|
||||
namespace Ui {
|
||||
class GetNewStuffDialog;
|
||||
}
|
||||
|
||||
class GetNewStuffDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit GetNewStuffDialog( QWidget *parent = 0, Qt::WindowFlags f = 0 );
|
||||
~GetNewStuffDialog();
|
||||
|
||||
private slots:
|
||||
void installFromFile();
|
||||
|
||||
private:
|
||||
Ui::GetNewStuffDialog *ui;
|
||||
GetNewStuffModel* m_model;
|
||||
};
|
||||
|
||||
#endif // GETNEWSTUFFDIALOG_H
|
@ -1,91 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>GetNewStuffDialog</class>
|
||||
<widget class="QDialog" name="GetNewStuffDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>449</width>
|
||||
<height>327</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Download New Resolvers</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QListView" name="accountsList"/>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="installFromFileBtn">
|
||||
<property name="text">
|
||||
<string>Install from file...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>GetNewStuffDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>GetNewStuffDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
@ -1,293 +0,0 @@
|
||||
/* === 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 "GetNewStuffModel.h"
|
||||
|
||||
#include "utils/tomahawkutils.h"
|
||||
#include "utils/logger.h"
|
||||
#include "AtticaManager.h"
|
||||
#include "accounts/AccountManager.h"
|
||||
|
||||
#include <QPixmap>
|
||||
#include <QUrl>
|
||||
|
||||
using namespace Tomahawk;
|
||||
using namespace Accounts;
|
||||
|
||||
GetNewStuffModel::GetNewStuffModel( QObject* parent )
|
||||
: QAbstractListModel ( parent )
|
||||
{
|
||||
connect( AtticaManager::instance(), SIGNAL( resolversReloaded( Attica::Content::List ) ), this, SLOT( resolversReloaded( Attica::Content::List ) ) );
|
||||
connect( AtticaManager::instance(), SIGNAL( resolverStateChanged( QString ) ), this, SLOT( resolverStateChanged( QString ) ) );
|
||||
|
||||
loadData();
|
||||
}
|
||||
|
||||
GetNewStuffModel::~GetNewStuffModel()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
GetNewStuffModel::loadData()
|
||||
{
|
||||
foreach ( const QVariant& content, m_contentList )
|
||||
{
|
||||
if ( !isAttica( content ) )
|
||||
{
|
||||
AccountItem* item = content.value< GetNewStuffModel::AccountItem* >();
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
m_contentList.clear();
|
||||
|
||||
Attica::Content::List fromAttica = AtticaManager::instance()->resolvers();
|
||||
foreach ( const Attica::Content& content, fromAttica )
|
||||
m_contentList.append( QVariant::fromValue< Attica::Content >( content ) );
|
||||
|
||||
QList< AccountFactory* > factories = AccountManager::instance()->factories();
|
||||
QList< Account* > allAccounts = AccountManager::instance()->accounts();
|
||||
foreach ( AccountFactory* fac, factories )
|
||||
{
|
||||
if ( !fac->allowUserCreation() )
|
||||
continue;
|
||||
|
||||
AccountItem* item = new AccountItem;
|
||||
item->factory = fac;
|
||||
|
||||
foreach ( Account* acct, allAccounts )
|
||||
{
|
||||
if ( AccountManager::instance()->factoryForAccount( acct ) == fac )
|
||||
{
|
||||
item->alreadyExists = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
item->alreadyExists = false;
|
||||
}
|
||||
|
||||
m_contentList.append( QVariant::fromValue< GetNewStuffModel::AccountItem* >( item ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GetNewStuffModel::resolversReloaded( const Attica::Content::List& resolvers )
|
||||
{
|
||||
beginResetModel();
|
||||
loadData();
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
void
|
||||
GetNewStuffModel::resolverStateChanged( const QString& resolverId )
|
||||
{
|
||||
for ( int i = 0; i < m_contentList.count(); i++ )
|
||||
{
|
||||
if ( !isAttica( m_contentList.at( i ) ) )
|
||||
continue;
|
||||
|
||||
const Attica::Content resolver = atticaFromItem( m_contentList.at( i ) );
|
||||
if ( resolver.id() == resolverId )
|
||||
{
|
||||
QModelIndex idx = index( i, 0, QModelIndex() );
|
||||
emit dataChanged( idx, idx );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QVariant
|
||||
GetNewStuffModel::data( const QModelIndex& index, int role ) const
|
||||
{
|
||||
if ( !index.isValid() || !hasIndex( index.row(), index.column(), index.parent() ) )
|
||||
return QVariant();
|
||||
|
||||
if ( isAttica( m_contentList.at( index.row() ) ) )
|
||||
{
|
||||
const Attica::Content resolver = atticaFromItem( m_contentList.at( index.row() ) );
|
||||
switch ( role )
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
return resolver.name();
|
||||
case Qt::DecorationRole:
|
||||
return QVariant::fromValue< QPixmap >( AtticaManager::instance()->iconForResolver( resolver ) );
|
||||
case DownloadUrlRole:
|
||||
// TODO
|
||||
return QUrl();
|
||||
case RatingRole:
|
||||
return resolver.rating() / 20; // rating is out of 100
|
||||
case DownloadCounterRole:
|
||||
return resolver.downloads();
|
||||
case VersionRole:
|
||||
return resolver.version();
|
||||
case DescriptionRole:
|
||||
return resolver.description();
|
||||
case TypeRole:
|
||||
return AtticaType;
|
||||
case AuthorRole:
|
||||
return resolver.author();
|
||||
case StateRole:
|
||||
return (int)AtticaManager::instance()->resolverState( resolver );
|
||||
case UserHasRatedRole:
|
||||
return AtticaManager::instance()->userHasRated( resolver );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Account, not from Attica
|
||||
AccountItem* item = accountFromItem( m_contentList.at( index.row() ) );
|
||||
Q_ASSERT( item );
|
||||
switch ( role )
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
return item->factory->prettyName();
|
||||
case Qt::DecorationRole:
|
||||
return QVariant::fromValue< QPixmap >( item->factory->icon() );
|
||||
case RatingRole:
|
||||
// TODO
|
||||
return 3;
|
||||
// return resolver.rating() / 20; // rating is out of 100
|
||||
case DownloadCounterRole:
|
||||
// TODO
|
||||
return 10;
|
||||
// return resolver.downloads();
|
||||
case VersionRole:
|
||||
return "1.0";
|
||||
// return resolver.version();
|
||||
case DescriptionRole:
|
||||
return item->factory->description();
|
||||
case TypeRole:
|
||||
return AccountType;
|
||||
case AuthorRole:
|
||||
return "Tomahawk Developers";
|
||||
case StateRole:
|
||||
{
|
||||
GetNewStuffModel::ItemState state = Uninstalled;
|
||||
if ( item->factory->isUnique() && item->alreadyExists )
|
||||
state = Installed;
|
||||
else if ( !item->factory->isUnique() && item->alreadyExists )
|
||||
state = CanInstallMore;
|
||||
else if ( !item->alreadyExists )
|
||||
state = Uninstalled;
|
||||
return (int)state;
|
||||
}
|
||||
case UserHasRatedRole:
|
||||
// TODO
|
||||
return true;
|
||||
// return AtticaManager::instance()->userHasRated( resolver );
|
||||
}
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
int
|
||||
GetNewStuffModel::rowCount( const QModelIndex& parent ) const
|
||||
{
|
||||
Q_UNUSED( parent );
|
||||
return m_contentList.count();
|
||||
}
|
||||
|
||||
bool
|
||||
GetNewStuffModel::setData( const QModelIndex &index, const QVariant &value, int role )
|
||||
{
|
||||
Q_UNUSED( value );
|
||||
if ( !hasIndex( index.row(), index.column(), index.parent() ) )
|
||||
return false;
|
||||
|
||||
if ( isAttica( m_contentList.at( index.row() ) ) )
|
||||
{
|
||||
Attica::Content resolver = atticaFromItem( m_contentList.at( index.row() ) );
|
||||
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;
|
||||
};
|
||||
} else if ( role == RatingRole )
|
||||
{
|
||||
// For now only allow rating if a resolver is installed!
|
||||
if ( state != AtticaManager::Installed && state != AtticaManager::NeedsUpgrade )
|
||||
return false;
|
||||
if ( AtticaManager::instance()->userHasRated( resolver ) )
|
||||
return false;
|
||||
resolver.setRating( value.toInt() * 20 );
|
||||
m_contentList[ index.row() ] = QVariant::fromValue< Attica::Content >( resolver );
|
||||
AtticaManager::instance()->uploadRating( resolver );
|
||||
}
|
||||
emit dataChanged( index, index );
|
||||
}
|
||||
else
|
||||
{
|
||||
AccountItem* item = accountFromItem( m_contentList.at( index.row() ) );
|
||||
if ( role == Qt::EditRole )
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
else if ( role == RatingRole )
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
GetNewStuffModel::isAttica( const QVariant& item ) const
|
||||
{
|
||||
return qstrcmp( item.typeName(),"Attica::Content" ) == 0;
|
||||
}
|
||||
|
||||
|
||||
GetNewStuffModel::AccountItem*
|
||||
GetNewStuffModel::accountFromItem( const QVariant& item ) const
|
||||
{
|
||||
Q_ASSERT( !isAttica( item ) );
|
||||
|
||||
return item.value< GetNewStuffModel::AccountItem* >();
|
||||
}
|
||||
|
||||
|
||||
Attica::Content
|
||||
GetNewStuffModel::atticaFromItem( const QVariant& item ) const
|
||||
{
|
||||
Q_ASSERT( isAttica( item ) );
|
||||
|
||||
return item.value< Attica::Content >();
|
||||
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
/* === 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 GETNEWSTUFFMODEL_H
|
||||
#define GETNEWSTUFFMODEL_H
|
||||
|
||||
#include "accounts/Account.h"
|
||||
|
||||
#include <attica/content.h>
|
||||
|
||||
#include <QModelIndex>
|
||||
#include <QPixmap>
|
||||
|
||||
class GetNewStuffModel: public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum NewStuffRoles {
|
||||
// DisplayRole is title
|
||||
// DecorationRole is qicon for item
|
||||
DownloadUrlRole = Qt::UserRole + 1,
|
||||
RatingRole = Qt::UserRole + 2,
|
||||
DownloadCounterRole = Qt::UserRole + 3,
|
||||
VersionRole = Qt::UserRole + 4,
|
||||
DescriptionRole = Qt::UserRole + 5,
|
||||
TypeRole = Qt::UserRole + 6, // Category in attica-speak. What sort of item this is (resolver, etc).
|
||||
AuthorRole = Qt::UserRole + 7,
|
||||
StateRole = Qt::UserRole + 8,
|
||||
UserHasRatedRole = Qt::UserRole + 9
|
||||
};
|
||||
|
||||
enum Types {
|
||||
AtticaType = 0,
|
||||
AccountType = 1
|
||||
};
|
||||
|
||||
enum ItemState {
|
||||
Uninstalled = 0,
|
||||
Installing,
|
||||
Installed,
|
||||
NeedsUpgrade,
|
||||
Upgrading,
|
||||
Failed,
|
||||
CanInstallMore, // accounts that are not unique
|
||||
};
|
||||
|
||||
// plz don't use me kthxbbq
|
||||
typedef struct {
|
||||
Tomahawk::Accounts::AccountFactory* factory;
|
||||
bool alreadyExists;
|
||||
} AccountItem;
|
||||
|
||||
explicit GetNewStuffModel( QObject* parent = 0 );
|
||||
virtual ~GetNewStuffModel();
|
||||
|
||||
virtual QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const;
|
||||
virtual int rowCount( const QModelIndex& parent = QModelIndex() ) const;
|
||||
virtual bool setData( const QModelIndex &index, const QVariant &value, int role );
|
||||
|
||||
private slots:
|
||||
void resolversReloaded( const Attica::Content::List& );
|
||||
void resolverStateChanged( const QString& resolverId );
|
||||
|
||||
private:
|
||||
void loadData();
|
||||
bool isAttica( const QVariant& item ) const;
|
||||
Attica::Content atticaFromItem( const QVariant& item ) const;
|
||||
AccountItem* accountFromItem( const QVariant& item ) const;
|
||||
|
||||
QVariantList m_contentList;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE( GetNewStuffModel::AccountItem* );
|
||||
|
||||
#endif // GETNEWSTUFFMODEL_H
|
@ -1,113 +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 "configdelegatebase.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QApplication>
|
||||
#include <QMouseEvent>
|
||||
|
||||
#include "utils/tomahawkutils.h"
|
||||
#include "utils/logger.h"
|
||||
|
||||
#define ROW_HEIGHT 40
|
||||
|
||||
ConfigDelegateBase::ConfigDelegateBase ( QObject* parent )
|
||||
: QStyledItemDelegate ( parent )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
QSize
|
||||
ConfigDelegateBase::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const
|
||||
{
|
||||
int width = QStyledItemDelegate::sizeHint( option, index ).width();
|
||||
return QSize( width, ROW_HEIGHT );
|
||||
}
|
||||
|
||||
void
|
||||
ConfigDelegateBase::drawCheckBox( QStyleOptionViewItemV4& opt, QPainter* p, const QWidget* w ) const
|
||||
{
|
||||
QStyle* style = w ? w->style() : QApplication::style();
|
||||
opt.checkState == Qt::Checked ? opt.state |= QStyle::State_On : opt.state |= QStyle::State_Off;
|
||||
style->drawPrimitive( QStyle::PE_IndicatorViewItemCheck, &opt, p, w );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ConfigDelegateBase::drawConfigWrench ( QPainter* painter, QStyleOptionViewItemV4& opt, QStyleOptionToolButton& topt ) const
|
||||
{
|
||||
const QWidget* w = opt.widget;
|
||||
QStyle* style = w ? w->style() : QApplication::style();
|
||||
|
||||
// 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.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 );
|
||||
}
|
||||
|
||||
bool
|
||||
ConfigDelegateBase::editorEvent ( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index )
|
||||
{
|
||||
QStyleOptionViewItemV4 viewOpt( option );
|
||||
initStyleOption( &viewOpt, index );
|
||||
|
||||
if( event->type() == QEvent::MouseButtonRelease || event->type() == QEvent::MouseButtonDblClick ) {
|
||||
m_configPressed = QModelIndex();
|
||||
|
||||
QMouseEvent* me = static_cast< QMouseEvent* >( event );
|
||||
QList<int> roles = QList<int>() << (int)Qt::CheckStateRole;
|
||||
roles.append( extraCheckRoles() );
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
|
||||
} else if( event->type() == QEvent::MouseButtonPress ) {
|
||||
QMouseEvent* me = static_cast< QMouseEvent* >( event );
|
||||
if( me->button() == Qt::LeftButton && configRectForIndex( option, index ).contains( me->pos() ) ) {
|
||||
m_configPressed = index;
|
||||
|
||||
emit configPressed( index );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return QStyledItemDelegate::editorEvent( event, model, option, index );
|
||||
}
|
@ -45,8 +45,6 @@ signals:
|
||||
void configPressed( const QModelIndex& idx );
|
||||
|
||||
protected:
|
||||
void drawCheckBox( QStyleOptionViewItemV4& opt, QPainter* p, const QWidget* w ) const;
|
||||
void drawConfigWrench( QPainter* painter, QStyleOptionViewItemV4& option, QStyleOptionToolButton& topt ) const;
|
||||
|
||||
private:
|
||||
QModelIndex m_configPressed;
|
||||
|
@ -210,6 +210,24 @@ AtticaManager::resolversList( BaseJob* j )
|
||||
m_resolvers = job->itemList();
|
||||
m_resolverStates = TomahawkSettingsGui::instanceGui()->atticaResolverStates();
|
||||
|
||||
// Sanity check. if any resolvers are installed that don't exist on the hd, remove them.
|
||||
foreach ( const QString& rId, m_resolverStates.keys() )
|
||||
{
|
||||
if ( m_resolverStates[ rId ].state == Installed ||
|
||||
m_resolverStates[ rId ].state == NeedsUpgrade )
|
||||
{
|
||||
// Guess location on disk
|
||||
QDir dir( QString( "%1/atticaresolvers/%2" ).arg( TomahawkUtils::appDataDir().absolutePath() ).arg( rId ) );
|
||||
if ( !dir.exists() )
|
||||
{
|
||||
// Uh oh
|
||||
qWarning() << "Found attica resolver marked as installed that didn't exist on disk! Setting to uninstalled: " << rId << dir.absolutePath();
|
||||
m_resolverStates[ rId ].state = Uninstalled;
|
||||
TomahawkSettingsGui::instanceGui()->setAtticaResolverState( rId, Uninstalled );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// load icon cache from disk, and fetch any we are missing
|
||||
loadPixmapsFromCache();
|
||||
|
||||
|
@ -70,6 +70,10 @@ AccountModel::loadData()
|
||||
}
|
||||
}
|
||||
|
||||
connect ( AccountManager::instance(), SIGNAL( added( Tomahawk::Accounts::Account* ) ), this, SLOT( accountAdded( Tomahawk::Accounts::Account* ) ) );
|
||||
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 ) ) );
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -82,7 +86,7 @@ AccountModel::data( const QModelIndex& index, int role ) const
|
||||
if ( !hasIndex( index.row(), index.column(), index.parent() ) )
|
||||
return QVariant();
|
||||
|
||||
AccountModelNode* node = nodeFromIndex( index );
|
||||
const AccountModelNode* node = nodeFromIndex( index );
|
||||
if ( node->parent == m_rootItem ) {
|
||||
// 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)
|
||||
@ -255,12 +259,267 @@ AccountModel::data( const QModelIndex& index, int role ) const
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
AccountModel::setData( const QModelIndex& index, const QVariant& value, int role )
|
||||
{
|
||||
if ( !index.isValid() || !hasIndex( index.row(), index.column(), index.parent() ) )
|
||||
return false;
|
||||
|
||||
AccountModelNode* node = nodeFromIndex( index );
|
||||
|
||||
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;
|
||||
switch ( node->type )
|
||||
{
|
||||
case AccountModelNode::AccountType:
|
||||
case AccountModelNode::UniqueFactoryType:
|
||||
acct = node->account;
|
||||
break;
|
||||
case AccountModelNode::AtticaType:
|
||||
acct = node->atticaAccount;
|
||||
break;
|
||||
case AccountModelNode::ManualResolverType:
|
||||
acct = node->resolverAccount;
|
||||
break;
|
||||
default:
|
||||
;
|
||||
};
|
||||
Q_ASSERT( acct );
|
||||
|
||||
Qt::CheckState state = static_cast< Qt::CheckState >( value.toInt() );
|
||||
|
||||
if ( state == Qt::Checked && !acct->enabled() )
|
||||
AccountManager::instance()->enableAccount( acct );
|
||||
else if( state == Qt::Unchecked )
|
||||
AccountManager::instance()->disableAccount( acct );
|
||||
|
||||
acct->sync();
|
||||
emit dataChanged( index, index );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// The install/create/remove/etc button was clicked. Handle it properly depending on this item
|
||||
if ( role == ButtonClickedRole )
|
||||
{
|
||||
switch ( node->type )
|
||||
{
|
||||
case AccountModelNode::FactoryType:
|
||||
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;
|
||||
}
|
||||
if ( role == RatingRole )
|
||||
{
|
||||
// We only support rating Attica resolvers for the moment.
|
||||
Q_ASSERT( node->type == AccountModelNode::AtticaType );
|
||||
|
||||
AtticaManager::ResolverState state = AtticaManager::instance()->resolverState( node->atticaContent );
|
||||
// For now only allow rating if a resolver is installed!
|
||||
if ( state != AtticaManager::Installed && state != AtticaManager::NeedsUpgrade )
|
||||
return false;
|
||||
if ( AtticaManager::instance()->userHasRated( node->atticaContent ) )
|
||||
return false;
|
||||
node->atticaContent.setRating( value.toInt() * 20 );
|
||||
AtticaManager::instance()->uploadRating( node->atticaContent );
|
||||
|
||||
emit dataChanged( index, index );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AccountModel::accountAdded( Account* account )
|
||||
{
|
||||
// Find the factory this belongs up, and update
|
||||
AccountFactory* factory = AccountManager::instance()->factoryForAccount( account );
|
||||
for ( int i = 0; i < m_rootItem->children.size(); i++ )
|
||||
{
|
||||
AccountModelNode* n = m_rootItem->children.at( i );
|
||||
if ( n->factory == factory )
|
||||
{
|
||||
if ( factory->isUnique() )
|
||||
{
|
||||
Q_ASSERT( n->type == AccountModelNode::UniqueFactoryType );
|
||||
n->account = account;
|
||||
const QModelIndex idx = index( i, 0, QModelIndex() );
|
||||
emit dataChanged( idx, idx );
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Not matched with a factory. Then just add it at the end
|
||||
if ( AtticaResolverAccount* attica = qobject_cast< AtticaResolverAccount* >( account ) )
|
||||
{
|
||||
Attica::Content::List allAtticaContent = AtticaManager::instance()->resolvers();
|
||||
foreach ( const Attica::Content& c, allAtticaContent )
|
||||
{
|
||||
if ( attica->atticaId() == c.id() )
|
||||
{
|
||||
// This is us. Create the row
|
||||
// const int count = m_rootItem->children.size()
|
||||
// beginInsertRows( QModelIndex(), );
|
||||
// new AccountModelNode( );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AccountModel::accountStateChanged( Account* account , Account::ConnectionState )
|
||||
{
|
||||
// Find the factory this belongs up, and update
|
||||
AccountFactory* factory = AccountManager::instance()->factoryForAccount( account );
|
||||
for ( int i = 0; i < m_rootItem->children.size(); i++ )
|
||||
{
|
||||
AccountModelNode* n = m_rootItem->children.at( i );
|
||||
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
|
||||
// For each type that this node could be, check the corresponding data
|
||||
if ( ( n->type == AccountModelNode::UniqueFactoryType && n->account && n->account == account ) ||
|
||||
( n->type == AccountModelNode::AccountType && n->account == account ) ||
|
||||
( n->type == AccountModelNode::AtticaType && n->atticaAccount && n->atticaAccount == account ) ||
|
||||
( n->type == AccountModelNode::ManualResolverType && n->resolverAccount && n->resolverAccount == account ) )
|
||||
{
|
||||
const QModelIndex idx = index( i, 0, QModelIndex() );
|
||||
emit dataChanged( idx, idx );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( int k = 0; k < n->children.size(); k++ )
|
||||
{
|
||||
AccountModelNode* childAccount = n->children.at( k );
|
||||
Q_ASSERT( childAccount->type == AccountModelNode::AccountType );
|
||||
if ( childAccount->account == account )
|
||||
{
|
||||
const QModelIndex parent = index( i, 0, QModelIndex() );
|
||||
const QModelIndex idx = index( k, 0, parent );
|
||||
emit dataChanged( idx, idx );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AccountModel::accountRemoved( Account* account )
|
||||
{
|
||||
// Find the factory this belongs up, and update
|
||||
AccountFactory* factory = AccountManager::instance()->factoryForAccount( account );
|
||||
for ( int i = 0; i < m_rootItem->children.size(); i++ )
|
||||
{
|
||||
AccountModelNode* n = m_rootItem->children.at( i );
|
||||
if ( n->factory == factory )
|
||||
{
|
||||
if ( factory->isUnique() )
|
||||
{
|
||||
Q_ASSERT( n->type == AccountModelNode::UniqueFactoryType );
|
||||
n->account = account;
|
||||
const QModelIndex idx = index( i, 0, QModelIndex() );
|
||||
emit dataChanged( idx, idx );
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
AccountModel::columnCount( const QModelIndex& parent ) const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
AccountModel::rowCount( const QModelIndex& parent ) const
|
||||
{
|
||||
@ -273,6 +532,7 @@ AccountModel::rowCount( const QModelIndex& parent ) const
|
||||
return nodeFromIndex( parent )->children.count();
|
||||
}
|
||||
|
||||
|
||||
QModelIndex
|
||||
AccountModel::parent( const QModelIndex& child ) const
|
||||
{
|
||||
@ -293,6 +553,7 @@ AccountModel::parent( const QModelIndex& child ) const
|
||||
return createIndex( m_rootItem->children.indexOf( parent ), 0, parent );
|
||||
}
|
||||
|
||||
|
||||
QModelIndex
|
||||
AccountModel::index( int row, int column, const QModelIndex& parent ) const
|
||||
{
|
||||
@ -309,6 +570,7 @@ AccountModel::index( int row, int column, const QModelIndex& parent ) const
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
|
||||
AccountModelNode*
|
||||
AccountModel::nodeFromIndex( const QModelIndex& idx ) const
|
||||
{
|
||||
|
@ -21,6 +21,8 @@
|
||||
|
||||
#include "dllmacro.h"
|
||||
|
||||
#include "Account.h"
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
|
||||
@ -53,7 +55,10 @@ public:
|
||||
ErrorString = Qt::UserRole + 27,
|
||||
|
||||
// used by individual accounts
|
||||
AccountData = Qt::UserRole + 28 // raw plugin
|
||||
AccountData = Qt::UserRole + 28, // raw plugin
|
||||
|
||||
CheckboxClickedRole = Qt::UserRole + 29, // the checkbox for this row was toggled
|
||||
ButtonClickedRole = Qt::UserRole + 30, // the generic install/create/remove/etc/ button was clicked
|
||||
};
|
||||
|
||||
enum RowType {
|
||||
@ -80,6 +85,15 @@ public:
|
||||
virtual int rowCount( const QModelIndex& parent = QModelIndex() ) const;
|
||||
virtual QModelIndex parent( const QModelIndex& child ) const;
|
||||
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:
|
||||
void createAccount( Tomahawk::Accounts::AccountFactory* factory );
|
||||
|
||||
private slots:
|
||||
void accountAdded( Tomahawk::Accounts::Account* );
|
||||
void accountRemoved( Tomahawk::Accounts::Account* );
|
||||
void accountStateChanged( Account*, Accounts::Account::ConnectionState );
|
||||
|
||||
private:
|
||||
AccountModelNode* nodeFromIndex( const QModelIndex& index ) const;
|
||||
|
@ -35,7 +35,7 @@ namespace Accounts {
|
||||
* Basically a union with possible types:
|
||||
* 1) AccountFactory* for accounts that are not unique (jabber, google, twitter)
|
||||
* 2) Account* for accounts that are associated with an AccountFactory (children of AccountFactory)
|
||||
* 3) Attica::Content for AtticaResolverAccounts (with associated AtticaResolverAccount*) (all synchroton resolvers)
|
||||
* 3) Attica::Content for AtticaResolverAccounts (with associated AtticaResolverAccount*) (all synchrotron resolvers)
|
||||
* 4) ResolverAccount* for manually added resolvers (from file).
|
||||
* 5) AccountFactory* + Account* for factories that are unique
|
||||
*
|
||||
|
@ -39,7 +39,6 @@
|
||||
#include "tomahawkapp.h"
|
||||
#include "tomahawksettings.h"
|
||||
#include "delegateconfigwrapper.h"
|
||||
#include "GetNewStuffDialog.h"
|
||||
#include "musicscanner.h"
|
||||
#include "pipeline.h"
|
||||
#include "resolver.h"
|
||||
@ -102,19 +101,21 @@ SettingsDialog::SettingsDialog( QWidget *parent )
|
||||
#endif
|
||||
|
||||
// SIP PLUGINS
|
||||
AccountDelegate* sipdel = new AccountDelegate( this );
|
||||
ui->accountsView->setItemDelegate( sipdel );
|
||||
AccountDelegate* accountDelegate = new AccountDelegate( this );
|
||||
ui->accountsView->setItemDelegate( accountDelegate );
|
||||
ui->accountsView->setContextMenuPolicy( Qt::CustomContextMenu );
|
||||
ui->accountsView->setVerticalScrollMode( QAbstractItemView::ScrollPerPixel );
|
||||
|
||||
// connect( sipdel, SIGNAL( openConfig( Tomahawk::Accounts::Account* ) ), this, SLOT( openAccountConfig( Tomahawk::Accounts::Account* ) ) );
|
||||
connect( accountDelegate, SIGNAL( openConfig( Tomahawk::Accounts::Account* ) ), this, SLOT( openAccountConfig( Tomahawk::Accounts::Account* ) ) );
|
||||
connect( accountDelegate, SIGNAL( update( QModelIndex ) ), ui->accountsView, SLOT( update( QModelIndex ) ) );
|
||||
|
||||
connect( ui->accountsView, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( accountContextMenuRequest( QPoint ) ) );
|
||||
m_accountModel = new AccountModel( this );
|
||||
|
||||
ui->accountsView->setModel( m_accountModel );
|
||||
ui->accountsView->expandAll();
|
||||
|
||||
connect( ui->addNewServiceBtn, SIGNAL( clicked( bool ) ), this, SLOT( getMoreResolvers() ) );
|
||||
connect( ui->removeServiceBtn, SIGNAL( clicked( bool ) ), this, SLOT( accountDeleted( bool ) ) );
|
||||
connect( m_accountModel, SIGNAL( createAccount( Tomahawk::Accounts::AccountFactory* ) ), this, SLOT( createAccountFromFactory( Tomahawk::Accounts::AccountFactory* ) ) );
|
||||
|
||||
connect( AtticaManager::instance(), SIGNAL( resolverInstalled( QString ) ), this, SLOT( accountAdded( Tomahawk::Accounts::Account* ) ) );
|
||||
connect( AtticaManager::instance(), SIGNAL( resolverUninstalled( QString ) ), this, SLOT( accountUninstalled( QString ) ) );
|
||||
@ -425,22 +426,6 @@ SettingsDialog::onLastFmFinished()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SettingsDialog::getMoreResolvers()
|
||||
{
|
||||
#if defined(Q_WS_MAC)
|
||||
GetNewStuffDialog* diag = new GetNewStuffDialog( this, Qt::Sheet );
|
||||
connect( diag, SIGNAL( finished( int ) ), this, SLOT( getMoreResolversFinished( int ) ) );
|
||||
diag->show();
|
||||
#else
|
||||
GetNewStuffDialog diag( this );
|
||||
int ret = diag.exec();
|
||||
Q_UNUSED( ret );
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SettingsDialog::accountInstalled(Account* account)
|
||||
{
|
||||
@ -469,14 +454,6 @@ SettingsDialog::accountsSelectionChanged()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SettingsDialog::getMoreResolversFinished( int ret )
|
||||
{
|
||||
Q_UNUSED( ret );
|
||||
sender()->deleteLater();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SettingsDialog::openAccountConfig( Account* account )
|
||||
{
|
||||
|
@ -95,8 +95,6 @@ private slots:
|
||||
void onAccountRowDeleted( bool );
|
||||
|
||||
void accountsSelectionChanged();
|
||||
void getMoreResolvers();
|
||||
void getMoreResolversFinished( int );
|
||||
|
||||
void accountInstalled( Tomahawk::Accounts::Account* account );
|
||||
void accountUninstalled( const QString& acct );
|
||||
@ -125,4 +123,3 @@ private:
|
||||
|
||||
#endif // SETTINGSDIALOG_H
|
||||
|
||||
struct A;
|
||||
|
Loading…
x
Reference in New Issue
Block a user