From 34dbc50b3a6777f25f886ebb5cea1c00409688c6 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 3 Feb 2012 17:19:04 -0500 Subject: [PATCH] Work to add setData to the model, and hook up model to some signals --- src/AccountDelegate.cpp | 452 ++++++++++---------- src/AccountDelegate.h | 20 +- src/CMakeLists.txt | 11 +- src/GetNewStuffDelegate.cpp | 326 -------------- src/GetNewStuffDelegate.h | 50 --- src/GetNewStuffDialog.cpp | 75 ---- src/GetNewStuffDialog.h | 44 -- src/GetNewStuffDialog.ui | 91 ---- src/GetNewStuffModel.cpp | 293 ------------- src/GetNewStuffModel.h | 91 ---- src/configdelegatebase.cpp | 113 ----- src/configdelegatebase.h | 2 - src/libtomahawk/AtticaManager.cpp | 18 + src/libtomahawk/accounts/AccountModel.cpp | 264 +++++++++++- src/libtomahawk/accounts/AccountModel.h | 16 +- src/libtomahawk/accounts/AccountModelNode.h | 2 +- src/settingsdialog.cpp | 37 +- src/settingsdialog.h | 3 - 18 files changed, 543 insertions(+), 1365 deletions(-) delete mode 100644 src/GetNewStuffDelegate.cpp delete mode 100644 src/GetNewStuffDelegate.h delete mode 100644 src/GetNewStuffDialog.cpp delete mode 100644 src/GetNewStuffDialog.h delete mode 100644 src/GetNewStuffDialog.ui delete mode 100644 src/GetNewStuffModel.cpp delete mode 100644 src/GetNewStuffModel.h delete mode 100644 src/configdelegatebase.cpp diff --git a/src/AccountDelegate.cpp b/src/AccountDelegate.cpp index 6f4efb1ce..020a0e89a 100644 --- a/src/AccountDelegate.cpp +++ b/src/AccountDelegate.cpp @@ -20,6 +20,7 @@ #include #include +#include #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* >() ) ); -} - diff --git a/src/AccountDelegate.h b/src/AccountDelegate.h index a12c21e73..f9b565d79 100644 --- a/src/AccountDelegate.h +++ b/src/AccountDelegate.h @@ -19,7 +19,7 @@ #ifndef ACCOUNTDELEGATE_H #define ACCOUNTDELEGATE_H -#include "configdelegatebase.h" +#include #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; }; } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 31591e961..72de137ed 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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}/.. ) diff --git a/src/GetNewStuffDelegate.cpp b/src/GetNewStuffDelegate.cpp deleted file mode 100644 index a1a3409bd..000000000 --- a/src/GetNewStuffDelegate.cpp +++ /dev/null @@ -1,326 +0,0 @@ -/* === This file is part of Tomahawk Player - === - * - * Copyright 2010-2011, Leo Franchi - * - * 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 . - */ - -#include "GetNewStuffDelegate.h" - -#include "GetNewStuffModel.h" -#include "utils/tomahawkutils.h" -#include "utils/logger.h" - -#include -#include -#include -#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(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(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( index.row(), index.column() ) ) ) - { - QRect rect = m_cachedButtonRects[ QPair( 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( index.row(), index.column() ) ) ) - { - QRect fullStars = m_cachedStarRects[ QPair( 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; -} diff --git a/src/GetNewStuffDelegate.h b/src/GetNewStuffDelegate.h deleted file mode 100644 index 570210226..000000000 --- a/src/GetNewStuffDelegate.h +++ /dev/null @@ -1,50 +0,0 @@ -/* === This file is part of Tomahawk Player - === - * - * Copyright 2010-2011, Leo Franchi - * - * 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 . - */ - -#ifndef GETNEWSTUFFDELEGATE_H -#define GETNEWSTUFFDELEGATE_H - -#include - - -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, QRect > m_cachedButtonRects; - mutable QHash< QPair, QRect > m_cachedStarRects; -}; - -#endif // GETNEWSTUFFDELEGATE_H diff --git a/src/GetNewStuffDialog.cpp b/src/GetNewStuffDialog.cpp deleted file mode 100644 index b188a2f38..000000000 --- a/src/GetNewStuffDialog.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* === This file is part of Tomahawk Player - === - * - * Copyright 2011, Leo Franchi - * - * 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 . - */ - -#include "GetNewStuffDialog.h" - -#include "ui_GetNewStuffDialog.h" -#include "GetNewStuffDelegate.h" -#include "GetNewStuffModel.h" -#include "tomahawksettings.h" - -#include - -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() ); - } -} diff --git a/src/GetNewStuffDialog.h b/src/GetNewStuffDialog.h deleted file mode 100644 index 3e63a66c1..000000000 --- a/src/GetNewStuffDialog.h +++ /dev/null @@ -1,44 +0,0 @@ -/* === This file is part of Tomahawk Player - === - * - * Copyright 2011, Leo Franchi - * - * 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 . - */ - -#ifndef GETNEWSTUFFDIALOG_H -#define GETNEWSTUFFDIALOG_H - -#include - -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 diff --git a/src/GetNewStuffDialog.ui b/src/GetNewStuffDialog.ui deleted file mode 100644 index f844f82f4..000000000 --- a/src/GetNewStuffDialog.ui +++ /dev/null @@ -1,91 +0,0 @@ - - - GetNewStuffDialog - - - - 0 - 0 - 449 - 327 - - - - Download New Resolvers - - - - - - - - - - - Install from file... - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - - - buttonBox - accepted() - GetNewStuffDialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - GetNewStuffDialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff --git a/src/GetNewStuffModel.cpp b/src/GetNewStuffModel.cpp deleted file mode 100644 index 412e6d7da..000000000 --- a/src/GetNewStuffModel.cpp +++ /dev/null @@ -1,293 +0,0 @@ -/* === This file is part of Tomahawk Player - === - * - * Copyright 2010-2011, Leo Franchi - * - * 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 . - */ - -#include "GetNewStuffModel.h" - -#include "utils/tomahawkutils.h" -#include "utils/logger.h" -#include "AtticaManager.h" -#include "accounts/AccountManager.h" - -#include -#include - -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 >(); - -} diff --git a/src/GetNewStuffModel.h b/src/GetNewStuffModel.h deleted file mode 100644 index c2e21afba..000000000 --- a/src/GetNewStuffModel.h +++ /dev/null @@ -1,91 +0,0 @@ -/* === This file is part of Tomahawk Player - === - * - * Copyright 2010-2011, Leo Franchi - * - * 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 . - */ - -#ifndef GETNEWSTUFFMODEL_H -#define GETNEWSTUFFMODEL_H - -#include "accounts/Account.h" - -#include - -#include -#include - -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 diff --git a/src/configdelegatebase.cpp b/src/configdelegatebase.cpp deleted file mode 100644 index 6503ca223..000000000 --- a/src/configdelegatebase.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/* - Copyright (C) 2011 Leo Franchi - - 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 . -*/ - - -#include "configdelegatebase.h" - -#include -#include -#include - -#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 roles = QList() << (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 ); -} diff --git a/src/configdelegatebase.h b/src/configdelegatebase.h index 929467a00..bce0581c9 100644 --- a/src/configdelegatebase.h +++ b/src/configdelegatebase.h @@ -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; diff --git a/src/libtomahawk/AtticaManager.cpp b/src/libtomahawk/AtticaManager.cpp index 54f8fcd87..160fc5cd0 100644 --- a/src/libtomahawk/AtticaManager.cpp +++ b/src/libtomahawk/AtticaManager.cpp @@ -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(); diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index 8522a1cf7..4ddc4df80 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -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 { diff --git a/src/libtomahawk/accounts/AccountModel.h b/src/libtomahawk/accounts/AccountModel.h index a5aca2fed..ad16c4add 100644 --- a/src/libtomahawk/accounts/AccountModel.h +++ b/src/libtomahawk/accounts/AccountModel.h @@ -21,6 +21,8 @@ #include "dllmacro.h" +#include "Account.h" + #include @@ -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; diff --git a/src/libtomahawk/accounts/AccountModelNode.h b/src/libtomahawk/accounts/AccountModelNode.h index 7f0708d0a..5c8396ba2 100644 --- a/src/libtomahawk/accounts/AccountModelNode.h +++ b/src/libtomahawk/accounts/AccountModelNode.h @@ -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 * diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index 41d94a131..cbd83833a 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -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 ) { diff --git a/src/settingsdialog.h b/src/settingsdialog.h index de2e948e1..5f8300171 100644 --- a/src/settingsdialog.h +++ b/src/settingsdialog.h @@ -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;