diff --git a/src/AccountDelegate.cpp b/src/AccountDelegate.cpp index ddff13f7a..1b9295447 100644 --- a/src/AccountDelegate.cpp +++ b/src/AccountDelegate.cpp @@ -26,6 +26,7 @@ #include "accounts/Account.h" #include "utils/TomahawkUtils.h" +#include "utils/TomahawkUtilsGui.h" #include "utils/Logger.h" #define CHILD_ACCOUNT_HEIGHT 24 @@ -523,53 +524,10 @@ AccountDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const QS void AccountDelegate::drawRoundedButton( QPainter* painter, const QRect& btnRect, bool red ) const { - QPainterPath btnPath; - const int radius = 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; if ( !red ) - { - g.setColorAt( 0, QColor(54, 127, 211) ); - g.setColorAt( 0.5, QColor(43, 104, 182) ); - } + TomahawkUtils::drawRoundedButton( painter, btnRect, QColor(54, 127, 211), QColor(43, 104, 182), QColor(34, 85, 159), QColor(35, 79, 147) ); else - { - g.setColorAt( 0, QColor(206, 63, 63) ); - g.setColorAt( 0.5, QColor(170, 52, 52) ); - } - //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 ); - - if ( !red ) - { - g.setColorAt( 0, QColor(34, 85, 159) ); - g.setColorAt( 0.5, QColor(35, 79, 147) ); - } - else - { - g.setColorAt( 0, QColor(150, 50, 50) ); - g.setColorAt( 0.5, QColor(130, 40, 40) ); - } - painter->fillPath( btnPath, g ); + TomahawkUtils::drawRoundedButton( painter, btnRect, QColor(206, 63, 63), QColor(170, 52, 52), QColor(150, 50, 50), QColor(130, 40, 40) ); } diff --git a/src/libtomahawk/AclRegistry.cpp b/src/libtomahawk/AclRegistry.cpp index 78f370ee5..3f9b40303 100644 --- a/src/libtomahawk/AclRegistry.cpp +++ b/src/libtomahawk/AclRegistry.cpp @@ -70,8 +70,8 @@ ACLRegistry::isAuthorizedUser( const QString& dbid, const QString &username, ACL } //FIXME: Remove when things are working - emit aclResult( dbid, username, ACLRegistry::Stream ); - return ACLRegistry::NotFound; +// emit aclResult( dbid, username, ACLRegistry::Stream ); +// return ACLRegistry::NotFound; bool found = false; QMutableListIterator< ACLRegistry::User > i( m_cache ); @@ -156,9 +156,11 @@ ACLRegistry::userDecision( ACLRegistry::User user ) void ACLRegistry::queueNextJob() { + tDebug() << Q_FUNC_INFO << "jobCount = " << m_jobCount; if ( m_jobCount != 0 ) return; - + + tDebug() << Q_FUNC_INFO << "jobQueue size = " << m_jobQueue.length(); if ( !m_jobQueue.isEmpty() ) { AclJobItem* job = m_jobQueue.dequeue(); @@ -169,18 +171,21 @@ ACLRegistry::queueNextJob() ACLRegistry::ACL acl = isAuthorizedUser( dbid, job->username(), ACLRegistry::NotFound, true ); if ( acl != ACLRegistry::NotFound ) { + tDebug() << Q_FUNC_INFO << "Found existing acl entry for = " << user.knownAccountIds.first(); found = true; break; } } if ( found ) { + tDebug() << Q_FUNC_INFO << "deleting job, already have ACL for " << user.knownAccountIds.first(); delete job; QTimer::singleShot( 0, this, SLOT( queueNextJob() ) ); return; } else { + tDebug() << Q_FUNC_INFO << "activating job for user" << user.knownAccountIds.first(); m_jobCount++; JobStatusView::instance()->model()->addJob( job ); connect( job, SIGNAL( userDecision( ACLRegistry::User ) ), this, SLOT( userDecision( ACLRegistry::User ) ) ); diff --git a/src/libtomahawk/jobview/AclJobItem.cpp b/src/libtomahawk/jobview/AclJobItem.cpp index 45793cbf1..ea8d93f96 100644 --- a/src/libtomahawk/jobview/AclJobItem.cpp +++ b/src/libtomahawk/jobview/AclJobItem.cpp @@ -21,30 +21,31 @@ #include "JobStatusModel.h" #include "utils/TomahawkUtils.h" +#include "utils/TomahawkUtilsGui.h" +#include "libtomahawk/infosystem/InfoSystem.h" #include #include #include #include +#include -#define ROW_HEIGHT 40 +#define ROW_HEIGHT 20 #define ICON_PADDING 1 #define PADDING 2 AclJobDelegate::AclJobDelegate( QObject* parent ) : QStyledItemDelegate ( parent ) - , m_parentView( qobject_cast< QListView* >( parent ) ) { - Q_ASSERT( m_parentView ); } void AclJobDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const { - tDebug( LOGVERBOSE ) << Q_FUNC_INFO; + //tDebug( LOGVERBOSE ) << Q_FUNC_INFO; QStyleOptionViewItemV4 opt = option; initStyleOption( &opt, index ); QFontMetrics fm( opt.font ); @@ -54,95 +55,90 @@ AclJobDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, co painter->setRenderHint( QPainter::Antialiasing ); + painter->fillRect( opt.rect, Qt::lightGray ); + QString mainText; AclJobItem* item = dynamic_cast< AclJobItem* >( index.data( JobStatusModel::JobDataRole ).value< JobStatusItem* >() ); if ( !item ) mainText = tr( "Error displaying ACL info" ); else mainText = QString( tr( "Allow %1 to\nconnect and stream from you?" ) ).arg( item->username() ); - tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Displaying text:" << mainText; + //tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Displaying text:" << mainText; 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, ROW_HEIGHT + PADDING, opt.rect.width() - 2*PADDING, opt.rect.height() - 2*PADDING ); - painter->drawText( rRect, Qt::AlignCenter, text ); + const QRect rRect( opt.rect.left() + PADDING, opt.rect.top() + 4*PADDING, opt.rect.width() - 2*PADDING, opt.rect.height() - 2*PADDING ); + painter->drawText( rRect, Qt::AlignHCenter, text ); - -/* - QStyleOptionViewItemV4 opt = option; - initStyleOption( &opt, index ); - QFontMetrics fm( opt.font ); - const bool allowMultiLine = index.data( JobStatusModel::AllowMultiLineRole ).toBool(); + //tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Using rect " << rRect << ", opt rect is " << opt.rect; - opt.state &= ~QStyle::State_MouseOver; - QApplication::style()->drawPrimitive( QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget ); + int totalwidth = opt.rect.width(); + int thirds = totalwidth/3; + QRect btnRect; + painter->setPen( Qt::white ); + + QString btnText = tr( "Allow Streaming" ); + int btnWidth = fm.width( btnText ) + 2*PADDING; + btnRect = QRect( opt.rect.left() + thirds - btnWidth/2, opt.rect.bottom() - fm.height() - 4*PADDING, btnWidth + 2*PADDING, fm.height() + 2*PADDING ); + drawRoundedButton( painter, btnRect, btnRect.contains( m_savedHoverPos ) ); + painter->drawText( btnRect, Qt::AlignCenter, btnText ); + m_savedAcceptRect = btnRect; -// 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 ); - - // 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 ); - - rightEdge = rRect.left(); - } - - QString mainText; - AclJobItem* item = dynamic_cast< AclJobItem* >( index.data( JobStatusModel::JobDataRole ).value< JobStatusItem* >() ); - //QString mainText = index.data( Qt::DisplayRole ).toString(); - if ( !item ) - mainText = tr( "Error displaying ACL info" ); - else - mainText = QString( tr( "Allow %1 to\nconnect and stream from you?" ) ).arg( item->username() ); - tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Displaying text:" << mainText; - const int mainW = rightEdge - 3*PADDING - iconRect.right(); - QTextOption to( Qt::AlignLeft | Qt::AlignVCenter ); - if ( !allowMultiLine ) - mainText = fm.elidedText( mainText, Qt::ElideRight, mainW ); - else - to.setWrapMode( QTextOption::WrapAtWordBoundaryOrAnywhere ); - painter->drawText( QRect( iconRect.right() + 2*PADDING, PADDING + opt.rect.y(), mainW, opt.rect.height() - 2*PADDING ), mainText, to ); - */ + btnText = tr( "Deny Access" ); + btnWidth = fm.width( btnText ) + 2*PADDING; + btnRect = QRect( opt.rect.right() - thirds - btnWidth/2, opt.rect.bottom() - fm.height() - 4*PADDING, btnWidth + 2*PADDING, fm.height() + 2*PADDING ); + drawRoundedButton( painter, btnRect, btnRect.contains( m_savedHoverPos ) ); + painter->drawText( btnRect, Qt::AlignCenter, btnText ); + m_savedDenyRect = btnRect; } QSize AclJobDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const +{ + QSize size( QStyledItemDelegate::sizeHint ( option, index ).width(), ROW_HEIGHT * 3 ); + return size; +} + + +void +AclJobDelegate::drawRoundedButton( QPainter* painter, const QRect& btnRect, bool red ) const +{ + if ( !red ) + TomahawkUtils::drawRoundedButton( painter, btnRect, QColor(54, 127, 211), QColor(43, 104, 182), QColor(34, 85, 159), QColor(35, 79, 147) ); + else + TomahawkUtils::drawRoundedButton( painter, btnRect, QColor(206, 63, 63), QColor(170, 52, 52), QColor(150, 50, 50), QColor(130, 40, 40) ); +} + + +bool +AclJobDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index ) { tDebug( LOGVERBOSE ) << Q_FUNC_INFO; - return QSize( QStyledItemDelegate::sizeHint ( option, index ).width(), ROW_HEIGHT ); + if ( event->type() != QEvent::MouseButtonPress && + event->type() != QEvent::MouseButtonRelease && + event->type() != QEvent::MouseButtonDblClick && + event->type() != QEvent::MouseMove ) + return false; - /* - const bool allowMultiLine = index.data( JobStatusModel::AllowMultiLineRole ).toBool(); + if ( event->type() == QEvent::MouseMove ) + { + QMouseEvent* me = static_cast< QMouseEvent* >( event ); + m_savedHoverPos = me->pos(); + tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Setting position to " << m_savedHoverPos; + emit update( index ); + return true; + } - if ( !allowMultiLine ) - return QSize( QStyledItemDelegate::sizeHint ( option, index ).width(), ROW_HEIGHT ); - else if ( m_cachedMultiLineHeights.contains( index ) ) - return QSize( QStyledItemDelegate::sizeHint ( option, index ).width(), m_cachedMultiLineHeights[ index ] ); + if ( event->type() == QEvent::MouseButtonRelease || event->type() == QEvent::MouseButtonDblClick ) + { + QMouseEvent* me = static_cast< QMouseEvent* >( event ); + if ( m_savedAcceptRect.contains( me->pos() ) ) + emit aclResult( ACLRegistry::Stream ); + else if ( m_savedDenyRect.contains( me->pos() ) ) + emit aclResult( ACLRegistry::Deny ); + return true; + } - // Don't elide, but stretch across as many rows as required - QStyleOptionViewItemV4 opt = option; - initStyleOption( &opt, index ); - - const QString text = index.data( Qt::DisplayRole ).toString(); - const int leftEdge = ICON_PADDING + ROW_HEIGHT + 2*PADDING; - const QRect rect = opt.fontMetrics.boundingRect( leftEdge, opt.rect.top(), m_parentView->width() - leftEdge, 200, Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, text ); - - m_cachedMultiLineHeights.insert( index, rect.height() + 4*PADDING ); - - return QSize( QStyledItemDelegate::sizeHint ( option, index ).width(), rect.height() + 4*PADDING ); - */ + return false; } @@ -167,6 +163,25 @@ AclJobItem::createDelegate( QObject* parent ) return; m_delegate = new AclJobDelegate( parent ); + + Tomahawk::InfoSystem::InfoPushData pushData( "AclJobItem", Tomahawk::InfoSystem::InfoNotifyUser, tr( "Tomahawk needs you to decide whether %1 is allowed to connect." ).arg( m_username ), Tomahawk::InfoSystem::PushNoFlag ); + Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( pushData ); +} + + +void +AclJobDelegate::emitSizeHintChanged( const QModelIndex& index ) +{ + emit sizeHintChanged( index ); +} + + +void +AclJobItem::aclResult( ACLRegistry::ACL result ) +{ + m_user.acl = result; + emit userDecision( m_user ); + done(); } diff --git a/src/libtomahawk/jobview/AclJobItem.h b/src/libtomahawk/jobview/AclJobItem.h index fd5377ca1..df6bd425a 100644 --- a/src/libtomahawk/jobview/AclJobItem.h +++ b/src/libtomahawk/jobview/AclJobItem.h @@ -38,9 +38,21 @@ public: virtual void paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const; virtual QSize sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const; + virtual void emitSizeHintChanged( const QModelIndex &index ); + +signals: + void update( const QModelIndex& idx ); + void aclResult( ACLRegistry::ACL result ); + +protected: + virtual bool editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index ); + private: - mutable QHash< QPersistentModelIndex, int > m_cachedMultiLineHeights; - QListView* m_parentView; + void drawRoundedButton( QPainter* painter, const QRect& btnRect, bool red = false ) const; + + QPoint m_savedHoverPos; + mutable QRect m_savedAcceptRect; + mutable QRect m_savedDenyRect; }; @@ -69,6 +81,9 @@ public: signals: void userDecision( ACLRegistry::User user ); + +public slots: + void aclResult( ACLRegistry::ACL result ); private: QStyledItemDelegate* m_delegate; diff --git a/src/libtomahawk/jobview/JobStatusView.cpp b/src/libtomahawk/jobview/JobStatusView.cpp index 204ae9182..a758ed28b 100644 --- a/src/libtomahawk/jobview/JobStatusView.cpp +++ b/src/libtomahawk/jobview/JobStatusView.cpp @@ -20,6 +20,7 @@ #include "JobStatusView.h" #include "Pipeline.h" +#include "AclJobItem.h" #include "JobStatusModel.h" #include "JobStatusItem.h" #include "JobStatusDelegate.h" @@ -74,6 +75,9 @@ JobStatusView::JobStatusView( AnimatedSplitter* parent ) new PipelineStatusManager( this ); new TransferStatusManager( this ); new LatchedStatusManager( this ); + + setMouseTracking( true ); + m_view->setMouseTracking( true ); } @@ -103,6 +107,13 @@ JobStatusView::customDelegateJobInserted( int row, JobStatusItem* item ) item->createDelegate( m_view ); tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "item delegate is " << item->customDelegate(); m_view->setItemDelegateForRow( row, item->customDelegate() ); + AclJobDelegate* delegate = qobject_cast< AclJobDelegate* >( item->customDelegate() ); + if ( delegate ) + { + connect( delegate, SIGNAL( update( const QModelIndex& ) ), m_view, SLOT( update( const QModelIndex & ) ) ); + connect( delegate, SIGNAL( aclResult( ACLRegistry::ACL ) ), item, SLOT( aclResult( ACLRegistry::ACL ) ) ); + delegate->emitSizeHintChanged( m_model->index( row ) ); + } } diff --git a/src/libtomahawk/network/Servent.cpp b/src/libtomahawk/network/Servent.cpp index f1f29b018..323a99016 100644 --- a/src/libtomahawk/network/Servent.cpp +++ b/src/libtomahawk/network/Servent.cpp @@ -536,6 +536,8 @@ Servent::connectToPeer( const QString& ha, int port, const QString &key, const Q if( id.length() ) conn->setId( id ); + conn->setProperty( "nodeid", id ); + connectToPeer( ha, port, key, conn ); } diff --git a/src/libtomahawk/utils/TomahawkUtilsGui.cpp b/src/libtomahawk/utils/TomahawkUtilsGui.cpp index 5e9f5478d..9c9ede8f4 100644 --- a/src/libtomahawk/utils/TomahawkUtilsGui.cpp +++ b/src/libtomahawk/utils/TomahawkUtilsGui.cpp @@ -414,4 +414,54 @@ prepareStyleOption( QStyleOptionViewItemV4* option, const QModelIndex& index, Tr } } + +void +drawRoundedButton( QPainter* painter, const QRect& btnRect, const QColor& color, const QColor &gradient1bottom, const QColor& gradient2top, const QColor& gradient2bottom ) +{ + QPainterPath btnPath; + const int radius = 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; + if ( gradient1bottom.isValid() ) + { + g.setColorAt( 0, color ); + g.setColorAt( 0.5, gradient1bottom ); + painter->fillPath( btnPath, g ); + } + else + painter->fillPath( btnPath, color ); + //painter->setPen( bg.darker() ); + + //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 ); + + if ( gradient2top.isValid() && gradient2bottom.isValid() ) + { + g.setColorAt( 0, gradient2top ); + g.setColorAt( 0.5, gradient2bottom ); + painter->fillPath( btnPath, g ); + } + else + painter->fillPath( btnPath, color ); + +} + + } // ns diff --git a/src/libtomahawk/utils/TomahawkUtilsGui.h b/src/libtomahawk/utils/TomahawkUtilsGui.h index 48f03cb2f..475f64ba1 100644 --- a/src/libtomahawk/utils/TomahawkUtilsGui.h +++ b/src/libtomahawk/utils/TomahawkUtilsGui.h @@ -22,6 +22,8 @@ #include #include +#include +#include #include "TomahawkUtils.h" #include "DllMacro.h" @@ -29,11 +31,9 @@ class TrackModelItem; class QStyleOptionViewItemV4; class QPainter; -class QColor; class QPixmap; class QLayout; class QPalette; -class QRect; namespace TomahawkUtils { @@ -57,6 +57,7 @@ namespace TomahawkUtils DLLEXPORT void prepareStyleOption( QStyleOptionViewItemV4* option, const QModelIndex& index, TrackModelItem* item ); + DLLEXPORT void drawRoundedButton( QPainter* painter, const QRect& btnRect, const QColor& color, const QColor &gradient1bottom = QColor(), const QColor& gradient2top = QColor(), const QColor& gradient2bottom = QColor() ); } #endif // TOMAHAWKUTILSGUI_H