diff --git a/src/GetNewStuffDelegate.cpp b/src/GetNewStuffDelegate.cpp index 58d1d6239..7ae0466f1 100644 --- a/src/GetNewStuffDelegate.cpp +++ b/src/GetNewStuffDelegate.cpp @@ -20,6 +20,7 @@ #include "GetNewStuffModel.h" #include "utils/tomahawkutils.h" +#include "utils/logger.h" #include #include @@ -27,6 +28,7 @@ #include "AtticaManager.h" #define PADDING 4 +#define PADDING_BETWEEN_STARS 2 #ifdef Q_WS_MAC #define SIZEHINT_HEIGHT 70 @@ -175,17 +177,19 @@ GetNewStuffDelegate::paint( QPainter* painter, const QStyleOptionViewItem& optio painter->setPen( saved ); // rating stars int rating = index.data( GetNewStuffModel::RatingRole ).toInt(); - const int paddingBetweenStars = 2; - const int ratingWidth = 5 * ( m_ratingStarPositive.width() + paddingBetweenStars ); + 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; + if ( i <= rating ) // positive star painter->drawPixmap( r, m_ratingStarPositive ); else painter->drawPixmap( r, m_ratingStarNegative ); - runningEdge += m_ratingStarPositive.width() + paddingBetweenStars; + runningEdge += m_ratingStarPositive.width() + PADDING_BETWEEN_STARS; } // downloaded num times, underneath button @@ -238,7 +242,10 @@ bool GetNewStuffDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index ) { Q_UNUSED( option ); - if ( event->type() == QEvent::MouseButtonRelease && m_cachedButtonRects.contains( QPair( index.row(), index.column() ) ) ) + if ( event->type() != QEvent::MouseButtonRelease ) + return false; + + if ( m_cachedButtonRects.contains( QPair( index.row(), index.column() ) ) ) { QRect rect = m_cachedButtonRects[ QPair( index.row(), index.column() ) ]; QMouseEvent* me = static_cast< QMouseEvent* >( event ); @@ -250,5 +257,27 @@ GetNewStuffDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, cons 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() ) ) + { + tDebug() << "A star was pressed...which one?"; + + const int eachStar = starsWidth / 5; + const int clickOffset = me->pos().x() - fullStars.x(); + const int whichStar = (clickOffset / eachStar) + 1; + tDebug() << "Clicked on:" << whichStar; + model->setData( index, whichStar, GetNewStuffModel::RatingRole ); + + return true; + } + } return false; } diff --git a/src/GetNewStuffDelegate.h b/src/GetNewStuffDelegate.h index 2677d2856..a1976a8b5 100644 --- a/src/GetNewStuffDelegate.h +++ b/src/GetNewStuffDelegate.h @@ -41,6 +41,7 @@ private: int m_widestTextWidth; mutable QHash< QPair, QRect > m_cachedButtonRects; + mutable QHash< QPair, QRect > m_cachedStarRects; }; #endif // GETNEWSTUFFDELEGATE_H diff --git a/src/GetNewStuffModel.cpp b/src/GetNewStuffModel.cpp index 55366e8d5..04a30e77f 100644 --- a/src/GetNewStuffModel.cpp +++ b/src/GetNewStuffModel.cpp @@ -109,36 +109,41 @@ bool GetNewStuffModel::setData( const QModelIndex &index, const QVariant &value, int role ) { Q_UNUSED( value ); - Q_UNUSED( role ); if ( !hasIndex( index.row(), index.column(), index.parent() ) ) return false; - // the install/uninstall button was clicked - const Attica::Content resolver = m_contentList[ index.row() ]; - AtticaManager::ResolverState state = AtticaManager::instance()->resolverState( resolver ); - - switch( state ) + if ( role == Qt::EditRole ) { - 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; - }; + Attica::Content resolver = m_contentList[ index.row() ]; + AtticaManager::ResolverState state = AtticaManager::instance()->resolverState( resolver ); + + 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 ) + { + m_contentList[ index.row() ].setRating( value.toInt() * 20 ); + AtticaManager::instance()->uploadRating( m_contentList[ index.row() ] ); + } emit dataChanged( index, index ); return true; diff --git a/src/libtomahawk/AtticaManager.cpp b/src/libtomahawk/AtticaManager.cpp index 95caf398a..5f004ce8b 100644 --- a/src/libtomahawk/AtticaManager.cpp +++ b/src/libtomahawk/AtticaManager.cpp @@ -148,6 +148,19 @@ AtticaManager::pathFromId( const QString& resolverId ) const return m_resolverStates.value( resolverId ).scriptPath; } +void +AtticaManager::uploadRating( const Content& c ) +{ + m_resolverStates[ c.id() ].rating = c.rating(); + + PostJob* job = m_resolverProvider.voteForContent( c.id(), (uint)c.rating() ); + connect( job, SIGNAL( finished( Attica::BaseJob* ) ), job, SLOT( deleteLater() ) ); + + job->start(); + + emit resolverStateChanged( c.id() ); +} + void AtticaManager::providerAdded( const Provider& provider ) @@ -186,7 +199,7 @@ AtticaManager::resolversList( BaseJob* j ) } } - checkForUpdates(); + syncServerData(); } @@ -211,23 +224,28 @@ AtticaManager::resolverIconFetched() } void -AtticaManager::checkForUpdates() +AtticaManager::syncServerData() { // look for any newer. m_resolvers has list from server, and m_resolverStates will contain any locally installed ones + // also update ratings foreach ( const QString& id, m_resolverStates.keys() ) { Resolver r = m_resolverStates[ id ]; - if ( r.state == Installed || r.state == NeedsUpgrade ) + foreach ( const Content& upstream, m_resolvers ) { - foreach ( const Content& upstream, m_resolvers ) + // same resolver + if ( id != upstream.id() ) + continue; + + // Update our rating with the server's idea of rating + m_resolverStates[ id ].rating = upstream.rating(); + // DO we need to upgrade? + if ( ( r.state == Installed || r.state == NeedsUpgrade ) && + !upstream.version().isEmpty() ) { - if ( id == upstream.id() && // the right one - !upstream.version().isEmpty() ) // valid version + if ( newerVersion( r.version, upstream.version() ) ) { - if ( newerVersion( r.version, upstream.version() ) ) - { - m_resolverStates[ id ].state = NeedsUpgrade; - } + m_resolverStates[ id ].state = NeedsUpgrade; } } } @@ -513,7 +531,7 @@ AtticaManager::doResolverRemove( const QString& id ) const // taken from util/fileutils.cpp in kdevplatform bool -AtticaManager::removeDirectory( const QString& dir ) const +AtticaManager::removeDirectory( const QString& dir ) { const QDir aDir(dir); diff --git a/src/libtomahawk/AtticaManager.h b/src/libtomahawk/AtticaManager.h index 5b0ffcd3e..ce2f6af27 100644 --- a/src/libtomahawk/AtticaManager.h +++ b/src/libtomahawk/AtticaManager.h @@ -48,11 +48,12 @@ public: struct Resolver { QString version, scriptPath; + int rating; // 0-100 ResolverState state; QPixmap* pixmap; - Resolver( const QString& v, const QString& path, ResolverState s ) - : version( v ), scriptPath( path ), state( s ), pixmap( 0 ) {} + Resolver( const QString& v, const QString& path, int r, ResolverState s ) + : version( v ), scriptPath( path ), rating( r ), state( s ), pixmap( 0 ) {} Resolver() : state( Uninstalled ), pixmap( 0 ) {} }; @@ -88,6 +89,10 @@ public: void uninstallResolver( const QString& pathToResolver ); QString pathFromId( const QString& resolverId ) const; + void uploadRating( const Attica::Content& c ); + + static bool removeDirectory( const QString& dir ); + signals: void resolversReloaded( const Attica::Content::List& resolvers ); @@ -105,13 +110,12 @@ private slots: void savePixmapsToCache(); void resolverIconFetched(); - void checkForUpdates(); + void syncServerData(); bool newerVersion( const QString& older, const QString& newer ) const; private: QString extractPayload( const QString& filename, const QString& resolverId ) const; void doResolverRemove( const QString& id ) const; - bool removeDirectory( const QString& dir ) const; Attica::ProviderManager m_manager; diff --git a/src/libtomahawk/tomahawksettings.cpp b/src/libtomahawk/tomahawksettings.cpp index db13c9497..bca889326 100644 --- a/src/libtomahawk/tomahawksettings.cpp +++ b/src/libtomahawk/tomahawksettings.cpp @@ -29,8 +29,9 @@ #include "playlistinterface.h" #include "utils/logger.h" +#include "utils/tomahawkutils.h" -#define VERSION 3 +#define VERSION 4 using namespace Tomahawk; @@ -39,11 +40,12 @@ TomahawkSettings* TomahawkSettings::s_instance = 0; inline QDataStream& operator<<(QDataStream& out, const AtticaManager::StateHash& states) { + out << VERSION; out << (quint32)states.count(); foreach( const QString& key, states.keys() ) { AtticaManager::Resolver resolver = states[ key ]; - out << key << resolver.version << resolver.scriptPath << (qint32)resolver.state; + out << key << resolver.version << resolver.scriptPath << (qint32)resolver.state << (quint32)resolver.rating; } return out; } @@ -51,22 +53,23 @@ inline QDataStream& operator<<(QDataStream& out, const AtticaManager::StateHash& inline QDataStream& operator>>(QDataStream& in, AtticaManager::StateHash& states) { - quint32 count = 0; + quint32 count = 0, version = 0; + in >> version; in >> count; for ( uint i = 0; i < count; i++ ) { QString key, version, scriptPath; - qint32 state; + qint32 state, rating; in >> key; in >> version; in >> scriptPath; in >> state; - states[ key ] = AtticaManager::Resolver( version, scriptPath, (AtticaManager::ResolverState)state ); + in >> rating; + states[ key ] = AtticaManager::Resolver( version, scriptPath, rating, (AtticaManager::ResolverState)state ); } return in; } - TomahawkSettings* TomahawkSettings::instance() { @@ -178,6 +181,45 @@ TomahawkSettings::doUpgrade( int oldVersion, int newVersion ) } // create a zeroconf plugin too addSipPlugin( "sipzeroconf_legacy" ); + } else if ( oldVersion == 3 ) + { + if ( contains( "script/atticaResolverStates" ) ) + { + // Do messy binary upgrade. remove attica resolvers :( + setValue( "script/atticaresolverstates", QVariant() ); + + QDir resolverDir = TomahawkUtils::appDataDir(); + if ( !resolverDir.cd( QString( "atticaresolvers" ) ) ) + return; + + QStringList toremove; + QStringList resolvers = resolverDir.entryList( QDir::Dirs | QDir::NoDotAndDotDot ); + QStringList listedResolvers = allScriptResolvers(); + QStringList enabledResolvers = enabledScriptResolvers(); + foreach ( const QString& resolver, resolvers ) + { + foreach ( const QString& r, listedResolvers ) + { + if ( r.contains( resolver ) ) + { + tDebug() << "Deleting listed resolver:" << r; + listedResolvers.removeAll( r ); + } + } + foreach ( const QString& r, enabledResolvers ) + { + if ( r.contains( resolver ) ) + { + tDebug() << "Deleting enabled resolver:" << r; + enabledResolvers.removeAll( r ); + } + } + } + setAllScriptResolvers( listedResolvers ); + setEnabledScriptResolvers( enabledResolvers ); + tDebug() << "UPGRADING AND DELETING:" << resolverDir.absolutePath(); + AtticaManager::removeDirectory( resolverDir.absolutePath() ); + } } }