diff --git a/src/TomahawkApp.cpp b/src/TomahawkApp.cpp index ecdfbf9e3..08de78118 100644 --- a/src/TomahawkApp.cpp +++ b/src/TomahawkApp.cpp @@ -410,6 +410,7 @@ TomahawkApp::registerMetaTypes() qRegisterMetaType< QMap< QString, QMap< unsigned int, unsigned int > > >("QMap< QString, QMap< unsigned int, unsigned int > >"); qRegisterMetaType< PairList >("PairList"); qRegisterMetaType< JobStatusItem* >("JobStatusItem*"); + qRegisterMetaType< AclJobItem* >("AclJobItem*"); qRegisterMetaType< GeneratorMode>("GeneratorMode"); qRegisterMetaType("Tomahawk::GeneratorMode"); diff --git a/src/libtomahawk/AclRegistry.cpp b/src/libtomahawk/AclRegistry.cpp index e47fddc1d..ef462ded2 100644 --- a/src/libtomahawk/AclRegistry.cpp +++ b/src/libtomahawk/AclRegistry.cpp @@ -44,6 +44,7 @@ ACLRegistry::instance() ACLRegistry::ACLRegistry( QObject* parent ) : QObject( parent ) + , m_jobCount( 0 ) { s_instance = this; qRegisterMetaType< ACLRegistry::ACL >( "ACLRegistry::ACL" ); @@ -58,18 +59,19 @@ ACLRegistry::~ACLRegistry() } -void -ACLRegistry::isAuthorizedUser( const QString& dbid, const QString &username, ACLRegistry::ACL globalType ) +ACLRegistry::ACL +ACLRegistry::isAuthorizedUser( const QString& dbid, const QString &username, ACLRegistry::ACL globalType, bool skipEmission ) { if ( QThread::currentThread() != TOMAHAWK_APPLICATION::instance()->thread() ) { - emit aclResult( dbid, username, globalType ); - return; + if ( !skipEmission ) + QMetaObject::invokeMethod( this, "isAuthorizedUser", Qt::QueuedConnection, Q_ARG( const QString&, dbid ), Q_ARG( const QString &, username ), Q_ARG( ACLRegistry::ACL, globalType ), Q_ARG( bool, skipEmission ) ); + return ACLRegistry::NotFound; } //FIXME: Remove when things are working - emit aclResult( dbid, username, ACLRegistry::Stream ); - return; + emit aclResult( dbid, username, ACLRegistry::Stream ); + return ACLRegistry::NotFound; bool found = false; QMutableListIterator< ACLRegistry::User > i( m_cache ); @@ -98,12 +100,16 @@ ACLRegistry::isAuthorizedUser( const QString& dbid, const QString &username, ACL if ( found ) { - emit aclResult( dbid, username, user.acl ); + if ( !skipEmission ) + emit aclResult( dbid, username, user.acl ); i.setValue( user ); - return; + return user.acl; } } + if ( skipEmission ) + return ACLRegistry::NotFound; + // User was not found, create a new user entry ACLRegistry::User user; user.knownDbids.append( dbid ); @@ -113,23 +119,23 @@ ACLRegistry::isAuthorizedUser( const QString& dbid, const QString &username, ACL #ifndef ENABLE_HEADLESS else { - getUserDecision( user ); - return; + getUserDecision( user, username ); + return ACLRegistry::NotFound; } #endif m_cache.append( user ); emit aclResult( dbid, username, user.acl ); - return; + return user.acl; } #ifndef ENABLE_HEADLESS void -ACLRegistry::getUserDecision( User user ) +ACLRegistry::getUserDecision( ACLRegistry::User user, const QString &username ) { - AclJobItem* job = new AclJobItem( user ); - connect( job, SIGNAL( userDecision( ACLRegistry::User ) ), this, SLOT( userDecision( ACLRegistry::User ) ) ); - JobStatusView::instance()->model()->addJob( job ); + AclJobItem* job = new AclJobItem( user, username ); + m_jobQueue.enqueue( job ); + queueNextJob(); } #endif @@ -138,7 +144,48 @@ void ACLRegistry::userDecision( ACLRegistry::User user ) { m_cache.append( user ); + save(); emit aclResult( user.knownDbids.first(), user.knownAccountIds.first(), user.acl ); + + m_jobCount--; + if ( !m_jobQueue.isEmpty() ) + queueNextJob(); +} + + +void +ACLRegistry::queueNextJob() +{ + if ( m_jobCount != 0 ) + return; + + if ( !m_jobQueue.isEmpty() ) + { + AclJobItem* job = m_jobQueue.dequeue(); + ACLRegistry::User user = job->user(); + bool found = false; + foreach( QString dbid, user.knownDbids ) + { + ACLRegistry::ACL acl = isAuthorizedUser( dbid, job->username(), ACLRegistry::NotFound, true ); + if ( acl != ACLRegistry::NotFound ) + { + found = true; + break; + } + } + if ( found ) + { + delete job; + QTimer::singleShot( 0, this, SLOT( queueNextJob() ) ); + return; + } + else + { + m_jobCount++; + JobStatusView::instance()->model()->addJob( job ); + connect( job, SIGNAL( userDecision( ACLRegistry::User ) ), this, SLOT( userDecision( ACLRegistry::User ) ) ); + } + } } diff --git a/src/libtomahawk/AclRegistry.h b/src/libtomahawk/AclRegistry.h index a8326e2b5..1530a843f 100644 --- a/src/libtomahawk/AclRegistry.h +++ b/src/libtomahawk/AclRegistry.h @@ -30,6 +30,8 @@ #include "HeadlessCheck.h" #include "DllMacro.h" +class AclJobItem; + class DLLEXPORT ACLRegistry : public QObject { Q_OBJECT @@ -79,14 +81,15 @@ public slots: * @param username If not empty, will store the given username along with the new ACL value. Defaults to QString(). * @return ACLRegistry::ACL **/ - void isAuthorizedUser( const QString &dbid, const QString &username, ACLRegistry::ACL globalType = ACLRegistry::NotFound ); + ACLRegistry::ACL isAuthorizedUser( const QString &dbid, const QString &username, ACLRegistry::ACL globalType = ACLRegistry::NotFound, bool skipEmission = false ); #ifndef ENABLE_HEADLESS - void getUserDecision( User user ); + void getUserDecision( ACLRegistry::User user, const QString &username ); #endif private slots: void userDecision( ACLRegistry::User user ); + void queueNextJob(); private: /** @@ -101,6 +104,9 @@ private: QList< ACLRegistry::User > m_cache; static ACLRegistry* s_instance; + + QQueue< AclJobItem* > m_jobQueue; + int m_jobCount; }; Q_DECLARE_METATYPE( ACLRegistry::ACL ); diff --git a/src/libtomahawk/jobview/AclJobItem.cpp b/src/libtomahawk/jobview/AclJobItem.cpp index be0146313..6dbcc415e 100644 --- a/src/libtomahawk/jobview/AclJobItem.cpp +++ b/src/libtomahawk/jobview/AclJobItem.cpp @@ -19,9 +19,11 @@ #include "AclJobItem.h" +#include "JobStatusModel.h" #include "utils/TomahawkUtils.h" #include +#include #include #include @@ -40,11 +42,9 @@ AclJobDelegate::AclJobDelegate( QObject* parent ) void AclJobDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const { - /* QStyleOptionViewItemV4 opt = option; initStyleOption( &opt, index ); QFontMetrics fm( opt.font ); - const bool allowMultiLine = index.data( JobStatusModel::AllowMultiLineRole ).toBool(); opt.state &= ~QStyle::State_MouseOver; QApplication::style()->drawPrimitive( QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget ); @@ -52,24 +52,20 @@ AclJobDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, co // painter->drawLine( opt.rect.topLeft(), opt.rect.topRight() ); painter->setRenderHint( QPainter::Antialiasing ); - QRect iconRect( ICON_PADDING, ICON_PADDING + opt.rect.y(), ROW_HEIGHT - 2*ICON_PADDING, ROW_HEIGHT - 2*ICON_PADDING ); - if ( allowMultiLine ) - iconRect.moveTop( opt.rect.top() + opt.rect.height() / 2 - iconRect.height() / 2); - QPixmap p = index.data( Qt::DecorationRole ).value< QPixmap >(); - p = p.scaledToHeight( iconRect.height(), Qt::SmoothTransformation ); - painter->drawPixmap( iconRect, p ); + //QRect iconRect( ICON_PADDING, ICON_PADDING + opt.rect.y(), ROW_HEIGHT - 2*ICON_PADDING, ROW_HEIGHT - 2*ICON_PADDING ); + //QPixmap p = index.data( Qt::DecorationRole ).value< QPixmap >(); + //p = p.scaledToHeight( iconRect.height(), Qt::SmoothTransformation ); + //painter->drawPixmap( iconRect, p ); // draw right column if there is one - const QString rCol = index.data( JobStatusModel::RightColumnRole ).toString(); - int rightEdge = opt.rect.right(); - if ( !rCol.isEmpty() ) - { - const int w = fm.width( rCol ); - const QRect rRect( opt.rect.right() - PADDING - w, PADDING + opt.rect.y(), w, opt.rect.height() - 2*PADDING ); - painter->drawText( rRect, Qt::AlignCenter, rCol ); + AclJobItem* item = index.data( JobStatusModel::JobDataRole ).value< AclJobItem* >(); + const QString text = QString( tr( "Allow %1 to\nconnect and stream from you?" ) ).arg( item->username() ); + const int w = fm.width( text ); + const QRect rRect( opt.rect.left() + PADDING, opt.rect.y() - PADDING, opt.rect.width() - 2*PADDING, opt.rect.height() - 2*PADDING ); + painter->drawText( rRect, Qt::AlignCenter, text ); - rightEdge = rRect.left(); - } + /* + rightEdge = rRect.left(); const int mainW = rightEdge - 3*PADDING - iconRect.right(); QString mainText = index.data( Qt::DisplayRole ).toString(); @@ -90,9 +86,10 @@ AclJobDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& -AclJobItem::AclJobItem( ACLRegistry::User user ) +AclJobItem::AclJobItem( ACLRegistry::User user, const QString &username ) : m_delegate( 0 ) , m_user( user ) + , m_username( username ) { } diff --git a/src/libtomahawk/jobview/AclJobItem.h b/src/libtomahawk/jobview/AclJobItem.h index 37e4bf529..b79302691 100644 --- a/src/libtomahawk/jobview/AclJobItem.h +++ b/src/libtomahawk/jobview/AclJobItem.h @@ -48,7 +48,7 @@ class AclJobItem : public JobStatusItem { Q_OBJECT public: - explicit AclJobItem( ACLRegistry::User user ); + explicit AclJobItem( ACLRegistry::User user, const QString &username ); virtual ~AclJobItem(); void done(); @@ -65,13 +65,17 @@ public: virtual QStyledItemDelegate* customDelegate() const { return m_delegate; } virtual ACLRegistry::User user() const { return m_user; } - + virtual const QString& username() const { return m_username; } + signals: void userDecision( ACLRegistry::User user ); private: QStyledItemDelegate* m_delegate; ACLRegistry::User m_user; + const QString m_username; }; +Q_DECLARE_METATYPE( AclJobItem* ); + #endif // ACLJOBITEM_H diff --git a/src/libtomahawk/network/Connection.cpp b/src/libtomahawk/network/Connection.cpp index 9a34c28cf..78ec3fef2 100644 --- a/src/libtomahawk/network/Connection.cpp +++ b/src/libtomahawk/network/Connection.cpp @@ -193,12 +193,13 @@ Connection::checkACL() { if ( !property( "nodeid" ).isValid() ) { + tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Not checking ACL, nodeid is empty"; QTimer::singleShot( 0, this, SLOT( doSetup() ) ); return; } QString nodeid = property( "nodeid" ).toString(); - tDebug( LOGVERBOSE ) << "Checking ACL for" << name(); + tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Checking ACL for" << name(); connect( ACLRegistry::instance(), SIGNAL( aclResult( QString, QString, ACLRegistry::ACL ) ), this, SLOT( checkACLResult( QString, QString, ACLRegistry::ACL ) ), Qt::QueuedConnection ); QMetaObject::invokeMethod( ACLRegistry::instance(), "isAuthorizedUser", Qt::QueuedConnection, Q_ARG( QString, nodeid ), Q_ARG( QString, name() ), Q_ARG( ACLRegistry::ACL, ACLRegistry::NotFound ) ); } @@ -211,7 +212,7 @@ Connection::checkACLResult( const QString &nodeid, const QString &username, ACLR return; disconnect( ACLRegistry::instance(), SIGNAL( aclResult( QString, QString, ACLRegistry::ACL ) ) ); - tDebug( LOGVERBOSE ) << "ACL status is" << peerStatus; + tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "ACL status is" << peerStatus; if ( peerStatus == ACLRegistry::Stream ) { QTimer::singleShot( 0, this, SLOT( doSetup() ) ); diff --git a/src/libtomahawk/network/Servent.cpp b/src/libtomahawk/network/Servent.cpp index ab0d5d137..f1f29b018 100644 --- a/src/libtomahawk/network/Servent.cpp +++ b/src/libtomahawk/network/Servent.cpp @@ -668,6 +668,7 @@ Servent::claimOffer( ControlConnection* cc, const QString &nodeid, const QString return NULL; } + tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "nodeid is: " << nodeid; if( !nodeid.isEmpty() ) { // Used by the connection for the ACL check