mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-06 14:16:32 +02:00
Merge branch 'aclwidget'. NOTE: If you have previous [acl] entries in
your Tomahawk.conf from previous testing, be sure to remove them, or clear them from the button in Settings->Advanced. Conflicts: ChangeLog
This commit is contained in:
@@ -1,4 +1,6 @@
|
|||||||
Version 0.5.0:
|
Version 0.5.0:
|
||||||
|
* Initial Access Control support. Entries can be cleared en masse in the Advanced area of Settings.
|
||||||
|
* Priortize resolution of a track on double-click.
|
||||||
* Spotify Resolver can now be easily installed on-demand from the settings.
|
* Spotify Resolver can now be easily installed on-demand from the settings.
|
||||||
* You can now sync selected playlists (and updates) with Spotify.
|
* You can now sync selected playlists (and updates) with Spotify.
|
||||||
* Support .aiff (AIFF mimetype) files.
|
* Support .aiff (AIFF mimetype) files.
|
||||||
|
@@ -30,6 +30,7 @@
|
|||||||
#include <QtGui/QSizeGrip>
|
#include <QtGui/QSizeGrip>
|
||||||
|
|
||||||
#include "AtticaManager.h"
|
#include "AtticaManager.h"
|
||||||
|
#include "AclRegistry.h"
|
||||||
#include "TomahawkApp.h"
|
#include "TomahawkApp.h"
|
||||||
#include "TomahawkSettings.h"
|
#include "TomahawkSettings.h"
|
||||||
#include "accounts/DelegateConfigWrapper.h"
|
#include "accounts/DelegateConfigWrapper.h"
|
||||||
@@ -98,6 +99,8 @@ SettingsDialog::SettingsDialog( QWidget *parent )
|
|||||||
ui->enableProxyCheckBox->setChecked( useProxy );
|
ui->enableProxyCheckBox->setChecked( useProxy );
|
||||||
ui->proxyButton->setEnabled( useProxy );
|
ui->proxyButton->setEnabled( useProxy );
|
||||||
|
|
||||||
|
ui->aclEntryClearButton->setEnabled( TomahawkSettings::instance()->aclEntries().size() > 0 );
|
||||||
|
connect( ui->aclEntryClearButton, SIGNAL( clicked( bool ) ), this, SLOT( aclEntryClearButtonClicked() ) );
|
||||||
|
|
||||||
createIcons();
|
createIcons();
|
||||||
#ifdef Q_WS_X11
|
#ifdef Q_WS_X11
|
||||||
@@ -497,6 +500,24 @@ SettingsDialog::installFromFile()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SettingsDialog::aclEntryClearButtonClicked()
|
||||||
|
{
|
||||||
|
QMessageBox::StandardButton button = QMessageBox::question(
|
||||||
|
ui->stackedWidget,
|
||||||
|
tr( "Delete all Access Control entries?" ),
|
||||||
|
tr( "Do you really want to delete all Access Control entries? You will be be asked for a decision again for each peer that you connect to." ),
|
||||||
|
QMessageBox::Ok | QMessageBox::Cancel,
|
||||||
|
QMessageBox::Ok
|
||||||
|
);
|
||||||
|
if ( button == QMessageBox::Ok )
|
||||||
|
{
|
||||||
|
ACLRegistry::instance()->wipeEntries();
|
||||||
|
ui->aclEntryClearButton->setEnabled( false );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SettingsDialog::scrollTo( const QModelIndex& idx )
|
SettingsDialog::scrollTo( const QModelIndex& idx )
|
||||||
{
|
{
|
||||||
|
@@ -97,6 +97,8 @@ private slots:
|
|||||||
void changePage( QListWidgetItem*, QListWidgetItem* );
|
void changePage( QListWidgetItem*, QListWidgetItem* );
|
||||||
void serventReady();
|
void serventReady();
|
||||||
|
|
||||||
|
void aclEntryClearButtonClicked();
|
||||||
|
|
||||||
void requiresRestart();
|
void requiresRestart();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@@ -418,6 +418,30 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="aclEntryClearLayout">
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="aclEntryClearButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Clear All Access Control Entries</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@@ -799,7 +799,7 @@ XmppSipPlugin::onSubscriptionReceived( const Jreen::RosterItem::Ptr& item, const
|
|||||||
QMessageBox *confirmBox = new QMessageBox(
|
QMessageBox *confirmBox = new QMessageBox(
|
||||||
QMessageBox::Question,
|
QMessageBox::Question,
|
||||||
tr( "Authorize User" ),
|
tr( "Authorize User" ),
|
||||||
QString( tr( "Do you want to grant <b>%1</b> access to your Collection?" ) ).arg( presence.from().bare() ),
|
QString( tr( "Do you want to add <b>%1</b> to your friend list?" ) ).arg( presence.from().bare() ),
|
||||||
QMessageBox::Yes | QMessageBox::No,
|
QMessageBox::Yes | QMessageBox::No,
|
||||||
TomahawkUtils::tomahawkWindow()
|
TomahawkUtils::tomahawkWindow()
|
||||||
);
|
);
|
||||||
|
@@ -35,6 +35,51 @@
|
|||||||
#include "utils/Logger.h"
|
#include "utils/Logger.h"
|
||||||
|
|
||||||
|
|
||||||
|
QDataStream& operator<<( QDataStream &out, const ACLRegistry::User &user )
|
||||||
|
{
|
||||||
|
out << ACLUSERVERSION;
|
||||||
|
out << user.uuid;
|
||||||
|
out << user.knownDbids.length();
|
||||||
|
foreach( QString knownDbid, user.knownDbids )
|
||||||
|
out << knownDbid;
|
||||||
|
out << user.knownAccountIds.length();
|
||||||
|
foreach( QString knownAccount, user.knownAccountIds )
|
||||||
|
out << knownAccount;
|
||||||
|
out << (int)( user.acl );
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDataStream& operator>>( QDataStream &in, ACLRegistry::User &user )
|
||||||
|
{
|
||||||
|
int ver;
|
||||||
|
in >> ver;
|
||||||
|
if ( ver == ACLUSERVERSION )
|
||||||
|
{
|
||||||
|
in >> user.uuid;
|
||||||
|
int dbidsLength;
|
||||||
|
in >> dbidsLength;
|
||||||
|
QString knownDbid;
|
||||||
|
for ( int i = 0; i < dbidsLength; i++ )
|
||||||
|
{
|
||||||
|
in >> knownDbid;
|
||||||
|
user.knownDbids << knownDbid;
|
||||||
|
}
|
||||||
|
int accountsLength;
|
||||||
|
in >> accountsLength;
|
||||||
|
QString knownAccountId;
|
||||||
|
for ( int i = 0; i < accountsLength; i++ )
|
||||||
|
{
|
||||||
|
in >> knownAccountId;
|
||||||
|
user.knownAccountIds << knownAccountId;
|
||||||
|
}
|
||||||
|
int aclIn;
|
||||||
|
in >> aclIn;
|
||||||
|
user.acl = (ACLRegistry::ACL)( aclIn );
|
||||||
|
}
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ACLRegistry* ACLRegistry::s_instance = 0;
|
ACLRegistry* ACLRegistry::s_instance = 0;
|
||||||
|
|
||||||
ACLRegistry*
|
ACLRegistry*
|
||||||
@@ -53,7 +98,7 @@ ACLRegistry::ACLRegistry( QObject* parent )
|
|||||||
s_instance = this;
|
s_instance = this;
|
||||||
qRegisterMetaType< ACLRegistry::ACL >( "ACLRegistry::ACL" );
|
qRegisterMetaType< ACLRegistry::ACL >( "ACLRegistry::ACL" );
|
||||||
qRegisterMetaType< ACLRegistry::User >( "ACLRegistry::User" );
|
qRegisterMetaType< ACLRegistry::User >( "ACLRegistry::User" );
|
||||||
|
qRegisterMetaTypeStreamOperators< ACLRegistry::User >( "ACLRegistry::User" );
|
||||||
load();
|
load();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,17 +111,17 @@ ACLRegistry::~ACLRegistry()
|
|||||||
ACLRegistry::ACL
|
ACLRegistry::ACL
|
||||||
ACLRegistry::isAuthorizedUser( const QString& dbid, const QString &username, ACLRegistry::ACL globalType, bool skipEmission )
|
ACLRegistry::isAuthorizedUser( const QString& dbid, const QString &username, ACLRegistry::ACL globalType, bool skipEmission )
|
||||||
{
|
{
|
||||||
|
tLog() << Q_FUNC_INFO;
|
||||||
if ( QThread::currentThread() != TOMAHAWK_APPLICATION::instance()->thread() )
|
if ( QThread::currentThread() != TOMAHAWK_APPLICATION::instance()->thread() )
|
||||||
{
|
{
|
||||||
if ( !skipEmission )
|
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 ) );
|
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;
|
return ACLRegistry::NotFound;
|
||||||
}
|
}
|
||||||
|
tLog() << Q_FUNC_INFO << "in right thread";
|
||||||
//FIXME: Remove when things are working
|
//FIXME: Remove when things are working
|
||||||
emit aclResult( dbid, username, ACLRegistry::Stream );
|
// emit aclResult( dbid, username, ACLRegistry::Stream );
|
||||||
return ACLRegistry::NotFound;
|
// return ACLRegistry::NotFound;
|
||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
QMutableListIterator< ACLRegistry::User > i( m_cache );
|
QMutableListIterator< ACLRegistry::User > i( m_cache );
|
||||||
while ( i.hasNext() )
|
while ( i.hasNext() )
|
||||||
@@ -139,28 +184,37 @@ ACLRegistry::isAuthorizedUser( const QString& dbid, const QString &username, ACL
|
|||||||
void
|
void
|
||||||
ACLRegistry::getUserDecision( ACLRegistry::User user, const QString &username )
|
ACLRegistry::getUserDecision( ACLRegistry::User user, const QString &username )
|
||||||
{
|
{
|
||||||
|
tLog() << Q_FUNC_INFO;
|
||||||
AclJobItem* job = new AclJobItem( user, username );
|
AclJobItem* job = new AclJobItem( user, username );
|
||||||
m_jobQueue.enqueue( job );
|
m_jobQueue.enqueue( job );
|
||||||
queueNextJob();
|
QTimer::singleShot( 0, this, SLOT( queueNextJob() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ACLRegistry::userDecision( ACLRegistry::User user )
|
ACLRegistry::userDecision( ACLRegistry::User user )
|
||||||
{
|
{
|
||||||
|
tLog() << Q_FUNC_INFO;
|
||||||
m_cache.append( user );
|
m_cache.append( user );
|
||||||
save();
|
save();
|
||||||
emit aclResult( user.knownDbids.first(), user.knownAccountIds.first(), user.acl );
|
emit aclResult( user.knownDbids.first(), user.knownAccountIds.first(), user.acl );
|
||||||
|
|
||||||
m_jobCount--;
|
m_jobCount--;
|
||||||
if ( !m_jobQueue.isEmpty() )
|
if ( !m_jobQueue.isEmpty() )
|
||||||
queueNextJob();
|
QTimer::singleShot( 0, this, SLOT( queueNextJob() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ACLRegistry::queueNextJob()
|
ACLRegistry::queueNextJob()
|
||||||
{
|
{
|
||||||
|
if ( QThread::currentThread() != TOMAHAWK_APPLICATION::instance()->thread() )
|
||||||
|
{
|
||||||
|
QMetaObject::invokeMethod( this, "queueNextJob", Qt::QueuedConnection );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tLog() << Q_FUNC_INFO << "jobCount = " << m_jobCount;
|
||||||
|
tLog() << Q_FUNC_INFO << "jobQueue size = " << m_jobQueue.length();
|
||||||
if ( m_jobCount != 0 )
|
if ( m_jobCount != 0 )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -174,18 +228,21 @@ ACLRegistry::queueNextJob()
|
|||||||
ACLRegistry::ACL acl = isAuthorizedUser( dbid, job->username(), ACLRegistry::NotFound, true );
|
ACLRegistry::ACL acl = isAuthorizedUser( dbid, job->username(), ACLRegistry::NotFound, true );
|
||||||
if ( acl != ACLRegistry::NotFound )
|
if ( acl != ACLRegistry::NotFound )
|
||||||
{
|
{
|
||||||
|
tLog() << Q_FUNC_INFO << "Found existing acl entry for = " << user.knownAccountIds.first();
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( found )
|
if ( found )
|
||||||
{
|
{
|
||||||
|
tLog() << Q_FUNC_INFO << "deleting job, already have ACL for " << user.knownAccountIds.first();
|
||||||
delete job;
|
delete job;
|
||||||
QTimer::singleShot( 0, this, SLOT( queueNextJob() ) );
|
QTimer::singleShot( 0, this, SLOT( queueNextJob() ) );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
tLog() << Q_FUNC_INFO << "activating job for user" << user.knownAccountIds.first();
|
||||||
m_jobCount++;
|
m_jobCount++;
|
||||||
JobStatusView::instance()->model()->addJob( job );
|
JobStatusView::instance()->model()->addJob( job );
|
||||||
connect( job, SIGNAL( userDecision( ACLRegistry::User ) ), this, SLOT( userDecision( ACLRegistry::User ) ) );
|
connect( job, SIGNAL( userDecision( ACLRegistry::User ) ), this, SLOT( userDecision( ACLRegistry::User ) ) );
|
||||||
@@ -199,12 +256,22 @@ ACLRegistry::queueNextJob()
|
|||||||
void
|
void
|
||||||
ACLRegistry::load()
|
ACLRegistry::load()
|
||||||
{
|
{
|
||||||
|
tLog() << Q_FUNC_INFO;
|
||||||
QVariantList entryList = TomahawkSettings::instance()->aclEntries();
|
QVariantList entryList = TomahawkSettings::instance()->aclEntries();
|
||||||
foreach ( QVariant entry, entryList )
|
foreach ( QVariant entry, entryList )
|
||||||
{
|
{
|
||||||
if ( !entry.isValid() || !entry.canConvert< ACLRegistry::User >() )
|
if ( !entry.isValid() || !entry.canConvert< ACLRegistry::User >() )
|
||||||
|
{
|
||||||
|
tLog() << Q_FUNC_INFO << "entry is invalid";
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
tLog() << Q_FUNC_INFO << "loading entry";
|
||||||
ACLRegistry::User entryUser = entry.value< ACLRegistry::User >();
|
ACLRegistry::User entryUser = entry.value< ACLRegistry::User >();
|
||||||
|
if ( entryUser.knownAccountIds.empty() || entryUser.knownDbids.empty() )
|
||||||
|
{
|
||||||
|
tLog() << Q_FUNC_INFO << "user known account/dbids is empty";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
m_cache.append( entryUser );
|
m_cache.append( entryUser );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -213,8 +280,23 @@ ACLRegistry::load()
|
|||||||
void
|
void
|
||||||
ACLRegistry::save()
|
ACLRegistry::save()
|
||||||
{
|
{
|
||||||
|
tLog() << Q_FUNC_INFO;
|
||||||
QVariantList entryList;
|
QVariantList entryList;
|
||||||
foreach ( ACLRegistry::User user, m_cache )
|
foreach ( ACLRegistry::User user, m_cache )
|
||||||
entryList.append( QVariant::fromValue< ACLRegistry::User >( user ) );
|
{
|
||||||
|
tLog() << Q_FUNC_INFO << "user is " << user.uuid << " with known name " << user.knownAccountIds.first();
|
||||||
|
QVariant val = QVariant::fromValue< ACLRegistry::User >( user );
|
||||||
|
if ( val.isValid() )
|
||||||
|
entryList.append( val );
|
||||||
|
}
|
||||||
TomahawkSettings::instance()->setAclEntries( entryList );
|
TomahawkSettings::instance()->setAclEntries( entryList );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ACLRegistry::wipeEntries()
|
||||||
|
{
|
||||||
|
tLog() << Q_FUNC_INFO;
|
||||||
|
m_cache.clear();
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
@@ -33,6 +33,8 @@
|
|||||||
#include "HeadlessCheck.h"
|
#include "HeadlessCheck.h"
|
||||||
#include "DllMacro.h"
|
#include "DllMacro.h"
|
||||||
|
|
||||||
|
#define ACLUSERVERSION 1
|
||||||
|
|
||||||
class AclJobItem;
|
class AclJobItem;
|
||||||
|
|
||||||
class DLLEXPORT ACLRegistry : public QObject
|
class DLLEXPORT ACLRegistry : public QObject
|
||||||
@@ -54,19 +56,31 @@ public:
|
|||||||
QString uuid;
|
QString uuid;
|
||||||
QStringList knownDbids;
|
QStringList knownDbids;
|
||||||
QStringList knownAccountIds;
|
QStringList knownAccountIds;
|
||||||
ACL acl;
|
ACLRegistry::ACL acl;
|
||||||
|
|
||||||
User()
|
User()
|
||||||
: uuid( QUuid::createUuid().toString() )
|
: uuid( QUuid::createUuid().toString() )
|
||||||
|
, knownDbids()
|
||||||
|
, knownAccountIds()
|
||||||
, acl( ACLRegistry::NotFound )
|
, acl( ACLRegistry::NotFound )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
User( QString p_uuid, QStringList p_knownDbids, QStringList p_knownAccountIds, ACL p_acl )
|
~User()
|
||||||
|
{}
|
||||||
|
|
||||||
|
User( QString p_uuid, QStringList p_knownDbids, QStringList p_knownAccountIds, ACLRegistry::ACL p_acl )
|
||||||
: uuid( p_uuid )
|
: uuid( p_uuid )
|
||||||
, knownDbids( p_knownDbids )
|
, knownDbids( p_knownDbids )
|
||||||
, knownAccountIds( p_knownAccountIds )
|
, knownAccountIds( p_knownAccountIds )
|
||||||
, acl( p_acl )
|
, acl( p_acl )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
User( const User &other )
|
||||||
|
: uuid( other.uuid )
|
||||||
|
, knownDbids( other.knownDbids )
|
||||||
|
, knownAccountIds( other.knownAccountIds )
|
||||||
|
, acl( other.acl )
|
||||||
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
ACLRegistry( QObject *parent = 0 );
|
ACLRegistry( QObject *parent = 0 );
|
||||||
@@ -85,6 +99,7 @@ public slots:
|
|||||||
* @return ACLRegistry::ACL
|
* @return ACLRegistry::ACL
|
||||||
**/
|
**/
|
||||||
ACLRegistry::ACL isAuthorizedUser( const QString &dbid, const QString &username, ACLRegistry::ACL globalType = ACLRegistry::NotFound, bool skipEmission = false );
|
ACLRegistry::ACL isAuthorizedUser( const QString &dbid, const QString &username, ACLRegistry::ACL globalType = ACLRegistry::NotFound, bool skipEmission = false );
|
||||||
|
void wipeEntries();
|
||||||
|
|
||||||
#ifndef ENABLE_HEADLESS
|
#ifndef ENABLE_HEADLESS
|
||||||
void getUserDecision( ACLRegistry::User user, const QString &username );
|
void getUserDecision( ACLRegistry::User user, const QString &username );
|
||||||
|
@@ -839,7 +839,10 @@ TomahawkSettings::aclEntries() const
|
|||||||
void
|
void
|
||||||
TomahawkSettings::setAclEntries( const QVariantList &entries )
|
TomahawkSettings::setAclEntries( const QVariantList &entries )
|
||||||
{
|
{
|
||||||
|
tDebug() << "Setting entries";
|
||||||
setValue( "acl/entries", entries );
|
setValue( "acl/entries", entries );
|
||||||
|
sync();
|
||||||
|
tDebug() << "Done setting entries";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -27,6 +27,7 @@
|
|||||||
#include "accounts/AccountManager.h"
|
#include "accounts/AccountManager.h"
|
||||||
|
|
||||||
#include "utils/TomahawkUtils.h"
|
#include "utils/TomahawkUtils.h"
|
||||||
|
#include "utils/TomahawkUtilsGui.h"
|
||||||
#include "utils/Logger.h"
|
#include "utils/Logger.h"
|
||||||
#include "utils/AnimatedSpinner.h"
|
#include "utils/AnimatedSpinner.h"
|
||||||
#include "utils/Closure.h"
|
#include "utils/Closure.h"
|
||||||
@@ -549,53 +550,10 @@ AccountDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const QS
|
|||||||
void
|
void
|
||||||
AccountDelegate::drawRoundedButton( QPainter* painter, const QRect& btnRect, bool red ) const
|
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 )
|
if ( !red )
|
||||||
{
|
TomahawkUtils::drawRoundedButton( painter, btnRect, QColor(54, 127, 211), QColor(43, 104, 182), QColor(34, 85, 159), QColor(35, 79, 147) );
|
||||||
g.setColorAt( 0, QColor(54, 127, 211) );
|
|
||||||
g.setColorAt( 0.5, QColor(43, 104, 182) );
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
TomahawkUtils::drawRoundedButton( painter, btnRect, QColor(206, 63, 63), QColor(170, 52, 52), QColor(150, 50, 50), QColor(130, 40, 40) );
|
||||||
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 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -21,31 +21,39 @@
|
|||||||
|
|
||||||
#include "JobStatusModel.h"
|
#include "JobStatusModel.h"
|
||||||
#include "utils/TomahawkUtils.h"
|
#include "utils/TomahawkUtils.h"
|
||||||
|
#include "utils/TomahawkUtilsGui.h"
|
||||||
|
#include "libtomahawk/infosystem/InfoSystem.h"
|
||||||
#include "utils/Logger.h"
|
#include "utils/Logger.h"
|
||||||
|
|
||||||
#include <QPixmap>
|
#include <QPixmap>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QListView>
|
#include <QListView>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#include <QMouseEvent>
|
||||||
|
|
||||||
|
|
||||||
#define ROW_HEIGHT 40
|
#define ROW_HEIGHT 20
|
||||||
#define ICON_PADDING 1
|
#define ICON_PADDING 1
|
||||||
#define PADDING 2
|
#define PADDING 2
|
||||||
|
|
||||||
|
|
||||||
AclJobDelegate::AclJobDelegate( QObject* parent )
|
AclJobDelegate::AclJobDelegate( QObject* parent )
|
||||||
: QStyledItemDelegate ( parent )
|
: QStyledItemDelegate ( parent )
|
||||||
, m_parentView( qobject_cast< QListView* >( parent ) )
|
|
||||||
{
|
{
|
||||||
Q_ASSERT( m_parentView );
|
tLog() << Q_FUNC_INFO;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AclJobDelegate::~AclJobDelegate()
|
||||||
|
{
|
||||||
|
tLog() << Q_FUNC_INFO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AclJobDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const
|
AclJobDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const
|
||||||
{
|
{
|
||||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO;
|
//tDebug( LOGVERBOSE ) << Q_FUNC_INFO;
|
||||||
QStyleOptionViewItemV4 opt = option;
|
QStyleOptionViewItemV4 opt = option;
|
||||||
initStyleOption( &opt, index );
|
initStyleOption( &opt, index );
|
||||||
QFontMetrics fm( opt.font );
|
QFontMetrics fm( opt.font );
|
||||||
@@ -55,96 +63,91 @@ AclJobDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, co
|
|||||||
|
|
||||||
painter->setRenderHint( QPainter::Antialiasing );
|
painter->setRenderHint( QPainter::Antialiasing );
|
||||||
|
|
||||||
|
painter->fillRect( opt.rect, Qt::lightGray );
|
||||||
|
|
||||||
QString mainText;
|
QString mainText;
|
||||||
AclJobItem* item = dynamic_cast< AclJobItem* >( index.data( JobStatusModel::JobDataRole ).value< JobStatusItem* >() );
|
AclJobItem* item = dynamic_cast< AclJobItem* >( index.data( JobStatusModel::JobDataRole ).value< JobStatusItem* >() );
|
||||||
if ( !item )
|
if ( !item )
|
||||||
mainText = tr( "Error displaying ACL info" );
|
mainText = tr( "Error displaying ACL info" );
|
||||||
else
|
else
|
||||||
mainText = QString( tr( "Allow %1 to\nconnect and stream from you?" ) ).arg( item->username() );
|
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 QRect rRect( opt.rect.left() + PADDING, opt.rect.top() + 4*PADDING, opt.rect.width() - 2*PADDING, opt.rect.height() - 2*PADDING );
|
||||||
const int w = fm.width( text );
|
painter->drawText( rRect, Qt::AlignHCenter, mainText );
|
||||||
Q_UNUSED( w ); // looks obsolete
|
|
||||||
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 );
|
|
||||||
|
|
||||||
|
//tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Using rect " << rRect << ", opt rect is " << opt.rect;
|
||||||
|
|
||||||
/*
|
int totalwidth = opt.rect.width();
|
||||||
QStyleOptionViewItemV4 opt = option;
|
int thirds = totalwidth/3;
|
||||||
initStyleOption( &opt, index );
|
QRect btnRect;
|
||||||
QFontMetrics fm( opt.font );
|
painter->setPen( Qt::white );
|
||||||
const bool allowMultiLine = index.data( JobStatusModel::AllowMultiLineRole ).toBool();
|
|
||||||
|
|
||||||
opt.state &= ~QStyle::State_MouseOver;
|
QString btnText = tr( "Allow Streaming" );
|
||||||
QApplication::style()->drawPrimitive( QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget );
|
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() );
|
btnText = tr( "Deny Access" );
|
||||||
|
btnWidth = fm.width( btnText ) + 2*PADDING;
|
||||||
painter->setRenderHint( QPainter::Antialiasing );
|
btnRect = QRect( opt.rect.right() - thirds - btnWidth/2, opt.rect.bottom() - fm.height() - 4*PADDING, btnWidth + 2*PADDING, fm.height() + 2*PADDING );
|
||||||
QRect iconRect( ICON_PADDING, ICON_PADDING + opt.rect.y(), ROW_HEIGHT - 2*ICON_PADDING, ROW_HEIGHT - 2*ICON_PADDING );
|
drawRoundedButton( painter, btnRect, btnRect.contains( m_savedHoverPos ) );
|
||||||
if ( allowMultiLine )
|
painter->drawText( btnRect, Qt::AlignCenter, btnText );
|
||||||
iconRect.moveTop( opt.rect.top() + opt.rect.height() / 2 - iconRect.height() / 2);
|
m_savedDenyRect = btnRect;
|
||||||
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 );
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QSize
|
QSize
|
||||||
AclJobDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const
|
AclJobDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const
|
||||||
{
|
{
|
||||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO;
|
QSize size( QStyledItemDelegate::sizeHint ( option, index ).width(), ROW_HEIGHT * 3 );
|
||||||
return QSize( QStyledItemDelegate::sizeHint ( option, index ).width(), ROW_HEIGHT );
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
const bool allowMultiLine = index.data( JobStatusModel::AllowMultiLineRole ).toBool();
|
|
||||||
|
|
||||||
if ( !allowMultiLine )
|
void
|
||||||
return QSize( QStyledItemDelegate::sizeHint ( option, index ).width(), ROW_HEIGHT );
|
AclJobDelegate::drawRoundedButton( QPainter* painter, const QRect& btnRect, bool red ) const
|
||||||
else if ( m_cachedMultiLineHeights.contains( index ) )
|
{
|
||||||
return QSize( QStyledItemDelegate::sizeHint ( option, index ).width(), m_cachedMultiLineHeights[ index ] );
|
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) );
|
||||||
|
}
|
||||||
|
|
||||||
// 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();
|
bool
|
||||||
const int leftEdge = ICON_PADDING + ROW_HEIGHT + 2*PADDING;
|
AclJobDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index )
|
||||||
const QRect rect = opt.fontMetrics.boundingRect( leftEdge, opt.rect.top(), m_parentView->width() - leftEdge, 200, Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, text );
|
{
|
||||||
|
Q_UNUSED( option )
|
||||||
|
Q_UNUSED( model )
|
||||||
|
//tDebug( LOGVERBOSE ) << Q_FUNC_INFO;
|
||||||
|
if ( event->type() != QEvent::MouseButtonPress &&
|
||||||
|
event->type() != QEvent::MouseButtonRelease &&
|
||||||
|
event->type() != QEvent::MouseButtonDblClick &&
|
||||||
|
event->type() != QEvent::MouseMove )
|
||||||
|
return false;
|
||||||
|
|
||||||
m_cachedMultiLineHeights.insert( index, rect.height() + 4*PADDING );
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
return QSize( QStyledItemDelegate::sizeHint ( option, index ).width(), rect.height() + 4*PADDING );
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -154,27 +157,44 @@ AclJobItem::AclJobItem( ACLRegistry::User user, const QString &username )
|
|||||||
, m_user( user )
|
, m_user( user )
|
||||||
, m_username( username )
|
, m_username( username )
|
||||||
{
|
{
|
||||||
|
tLog() << Q_FUNC_INFO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
AclJobItem::~AclJobItem()
|
AclJobItem::~AclJobItem()
|
||||||
{
|
{
|
||||||
|
tLog() << Q_FUNC_INFO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AclJobItem::createDelegate( QObject* parent )
|
AclJobItem::createDelegate( QObject* parent )
|
||||||
{
|
{
|
||||||
|
tLog() << Q_FUNC_INFO;
|
||||||
|
|
||||||
if ( m_delegate )
|
if ( m_delegate )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_delegate = new AclJobDelegate( parent );
|
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
|
void
|
||||||
AclJobItem::done()
|
AclJobDelegate::emitSizeHintChanged( const QModelIndex& index )
|
||||||
{
|
{
|
||||||
|
emit sizeHintChanged( index );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AclJobItem::aclResult( ACLRegistry::ACL result )
|
||||||
|
{
|
||||||
|
tLog() << Q_FUNC_INFO;
|
||||||
|
m_user.acl = result;
|
||||||
|
emit userDecision( m_user );
|
||||||
emit finished();
|
emit finished();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -33,14 +33,26 @@ class AclJobDelegate : public QStyledItemDelegate
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
explicit AclJobDelegate ( QObject* parent = 0 );
|
explicit AclJobDelegate ( QObject* parent = 0 );
|
||||||
virtual ~AclJobDelegate() {}
|
virtual ~AclJobDelegate();
|
||||||
|
|
||||||
virtual void paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const;
|
virtual void paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const;
|
||||||
virtual QSize sizeHint( 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:
|
private:
|
||||||
mutable QHash< QPersistentModelIndex, int > m_cachedMultiLineHeights;
|
void drawRoundedButton( QPainter* painter, const QRect& btnRect, bool red = false ) const;
|
||||||
QListView* m_parentView;
|
|
||||||
|
QPoint m_savedHoverPos;
|
||||||
|
mutable QRect m_savedAcceptRect;
|
||||||
|
mutable QRect m_savedDenyRect;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -51,8 +63,6 @@ public:
|
|||||||
explicit AclJobItem( ACLRegistry::User user, const QString &username );
|
explicit AclJobItem( ACLRegistry::User user, const QString &username );
|
||||||
virtual ~AclJobItem();
|
virtual ~AclJobItem();
|
||||||
|
|
||||||
void done();
|
|
||||||
|
|
||||||
virtual QString rightColumnText() const { return QString(); }
|
virtual QString rightColumnText() const { return QString(); }
|
||||||
virtual QString mainText() const { return QString(); }
|
virtual QString mainText() const { return QString(); }
|
||||||
virtual QPixmap icon() const { return QPixmap(); }
|
virtual QPixmap icon() const { return QPixmap(); }
|
||||||
@@ -61,7 +71,7 @@ public:
|
|||||||
virtual int concurrentJobLimit() const { return 3; }
|
virtual int concurrentJobLimit() const { return 3; }
|
||||||
|
|
||||||
virtual bool hasCustomDelegate() const { return true; }
|
virtual bool hasCustomDelegate() const { return true; }
|
||||||
virtual void createDelegate( QObject* parent );
|
virtual void createDelegate( QObject* parent = 0 );
|
||||||
virtual QStyledItemDelegate* customDelegate() const { return m_delegate; }
|
virtual QStyledItemDelegate* customDelegate() const { return m_delegate; }
|
||||||
|
|
||||||
virtual ACLRegistry::User user() const { return m_user; }
|
virtual ACLRegistry::User user() const { return m_user; }
|
||||||
@@ -70,6 +80,9 @@ public:
|
|||||||
signals:
|
signals:
|
||||||
void userDecision( ACLRegistry::User user );
|
void userDecision( ACLRegistry::User user );
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void aclResult( ACLRegistry::ACL result );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QStyledItemDelegate* m_delegate;
|
QStyledItemDelegate* m_delegate;
|
||||||
ACLRegistry::User m_user;
|
ACLRegistry::User m_user;
|
||||||
|
@@ -59,8 +59,11 @@ JobStatusDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option,
|
|||||||
if ( allowMultiLine )
|
if ( allowMultiLine )
|
||||||
iconRect.moveTop( opt.rect.top() + opt.rect.height() / 2 - iconRect.height() / 2);
|
iconRect.moveTop( opt.rect.top() + opt.rect.height() / 2 - iconRect.height() / 2);
|
||||||
QPixmap p = index.data( Qt::DecorationRole ).value< QPixmap >();
|
QPixmap p = index.data( Qt::DecorationRole ).value< QPixmap >();
|
||||||
p = p.scaledToHeight( iconRect.height(), Qt::SmoothTransformation );
|
if ( !p.isNull() )
|
||||||
painter->drawPixmap( iconRect, p );
|
{
|
||||||
|
p = p.scaledToHeight( iconRect.height(), Qt::SmoothTransformation );
|
||||||
|
painter->drawPixmap( iconRect, p );
|
||||||
|
}
|
||||||
|
|
||||||
// draw right column if there is one
|
// draw right column if there is one
|
||||||
const QString rCol = index.data( JobStatusModel::RightColumnRole ).toString();
|
const QString rCol = index.data( JobStatusModel::RightColumnRole ).toString();
|
||||||
|
@@ -41,6 +41,7 @@ JobStatusModel::~JobStatusModel()
|
|||||||
void
|
void
|
||||||
JobStatusModel::addJob( JobStatusItem* item )
|
JobStatusModel::addJob( JobStatusItem* item )
|
||||||
{
|
{
|
||||||
|
tLog() << Q_FUNC_INFO << "current jobs of item type: " << m_jobTypeCount[ item->type() ] << ", current queue size of item type: " << m_jobQueue[ item->type() ].size();
|
||||||
if ( item->concurrentJobLimit() > 0 )
|
if ( item->concurrentJobLimit() > 0 )
|
||||||
{
|
{
|
||||||
if ( m_jobTypeCount[ item->type() ] >= item->concurrentJobLimit() )
|
if ( m_jobTypeCount[ item->type() ] >= item->concurrentJobLimit() )
|
||||||
@@ -53,6 +54,8 @@ JobStatusModel::addJob( JobStatusItem* item )
|
|||||||
m_jobTypeCount[ item->type() ] = currentJobCount;
|
m_jobTypeCount[ item->type() ] = currentJobCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tLog() << Q_FUNC_INFO << "new current jobs of item type: " << m_jobTypeCount[ item->type() ];
|
||||||
|
|
||||||
connect( item, SIGNAL( statusChanged() ), SLOT( itemUpdated() ) );
|
connect( item, SIGNAL( statusChanged() ), SLOT( itemUpdated() ) );
|
||||||
connect( item, SIGNAL( finished() ), SLOT( itemFinished() ) );
|
connect( item, SIGNAL( finished() ), SLOT( itemFinished() ) );
|
||||||
|
|
||||||
@@ -70,7 +73,7 @@ JobStatusModel::addJob( JobStatusItem* item )
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
qDebug() << "Adding item:" << item;
|
tLog() << Q_FUNC_INFO << "Adding item:" << item;
|
||||||
|
|
||||||
int currentEndRow = m_items.count();
|
int currentEndRow = m_items.count();
|
||||||
beginInsertRows( QModelIndex(), currentEndRow, currentEndRow );
|
beginInsertRows( QModelIndex(), currentEndRow, currentEndRow );
|
||||||
@@ -79,7 +82,7 @@ JobStatusModel::addJob( JobStatusItem* item )
|
|||||||
|
|
||||||
if ( item->hasCustomDelegate() )
|
if ( item->hasCustomDelegate() )
|
||||||
{
|
{
|
||||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "job has custom delegate";
|
tLog() << Q_FUNC_INFO << "job has custom delegate";
|
||||||
emit customDelegateJobInserted( currentEndRow, item );
|
emit customDelegateJobInserted( currentEndRow, item );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -184,6 +187,7 @@ JobStatusModel::itemFinished()
|
|||||||
// One less to count, but item is still there
|
// One less to count, but item is still there
|
||||||
const QModelIndex idx = index( indexOf, 0, QModelIndex() );
|
const QModelIndex idx = index( indexOf, 0, QModelIndex() );
|
||||||
emit dataChanged( idx, idx );
|
emit dataChanged( idx, idx );
|
||||||
|
emit refreshDelegates();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -200,6 +204,9 @@ JobStatusModel::itemFinished()
|
|||||||
if ( item->customDelegate() )
|
if ( item->customDelegate() )
|
||||||
emit customDelegateJobRemoved( idx );
|
emit customDelegateJobRemoved( idx );
|
||||||
|
|
||||||
|
emit refreshDelegates();
|
||||||
|
|
||||||
|
tLog() << Q_FUNC_INFO << "current jobs of item type: " << m_jobTypeCount[ item->type() ] << ", current queue size of item type: " << m_jobQueue[ item->type() ].size();
|
||||||
if ( item->concurrentJobLimit() > 0 )
|
if ( item->concurrentJobLimit() > 0 )
|
||||||
{
|
{
|
||||||
int currentJobs = m_jobTypeCount[ item->type() ];
|
int currentJobs = m_jobTypeCount[ item->type() ];
|
||||||
|
@@ -49,6 +49,7 @@ public:
|
|||||||
signals:
|
signals:
|
||||||
void customDelegateJobInserted( int row, JobStatusItem* item );
|
void customDelegateJobInserted( int row, JobStatusItem* item );
|
||||||
void customDelegateJobRemoved( int row );
|
void customDelegateJobRemoved( int row );
|
||||||
|
void refreshDelegates();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
/// Takes ownership of job
|
/// Takes ownership of job
|
||||||
|
@@ -20,6 +20,7 @@
|
|||||||
#include "JobStatusView.h"
|
#include "JobStatusView.h"
|
||||||
|
|
||||||
#include "Pipeline.h"
|
#include "Pipeline.h"
|
||||||
|
#include "AclJobItem.h"
|
||||||
#include "JobStatusModel.h"
|
#include "JobStatusModel.h"
|
||||||
#include "JobStatusItem.h"
|
#include "JobStatusItem.h"
|
||||||
#include "JobStatusDelegate.h"
|
#include "JobStatusDelegate.h"
|
||||||
@@ -75,6 +76,9 @@ JobStatusView::JobStatusView( AnimatedSplitter* parent )
|
|||||||
new PipelineStatusManager( this );
|
new PipelineStatusManager( this );
|
||||||
new TransferStatusManager( this );
|
new TransferStatusManager( this );
|
||||||
new LatchedStatusManager( this );
|
new LatchedStatusManager( this );
|
||||||
|
|
||||||
|
setMouseTracking( true );
|
||||||
|
m_view->setMouseTracking( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -90,27 +94,66 @@ JobStatusView::setModel( JobStatusModel* m )
|
|||||||
connect( m_view->model(), SIGNAL( modelReset() ), this, SLOT( checkCount() ) );
|
connect( m_view->model(), SIGNAL( modelReset() ), this, SLOT( checkCount() ) );
|
||||||
connect( m_view->model(), SIGNAL( customDelegateJobInserted( int, JobStatusItem* ) ), this, SLOT( customDelegateJobInserted( int, JobStatusItem* ) ) );
|
connect( m_view->model(), SIGNAL( customDelegateJobInserted( int, JobStatusItem* ) ), this, SLOT( customDelegateJobInserted( int, JobStatusItem* ) ) );
|
||||||
connect( m_view->model(), SIGNAL( customDelegateJobRemoved( int ) ), this, SLOT( customDelegateJobRemoved( int ) ) );
|
connect( m_view->model(), SIGNAL( customDelegateJobRemoved( int ) ), this, SLOT( customDelegateJobRemoved( int ) ) );
|
||||||
|
connect( m_view->model(), SIGNAL( refreshDelegates() ), this, SLOT( refreshDelegates() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
JobStatusView::customDelegateJobInserted( int row, JobStatusItem* item )
|
JobStatusView::customDelegateJobInserted( int row, JobStatusItem* item )
|
||||||
{
|
{
|
||||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO;
|
tLog() << Q_FUNC_INFO << "item is " << item << ", row is " << row;
|
||||||
if ( !item )
|
if ( !item )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "telling item to create delegate";
|
tLog() << Q_FUNC_INFO << "telling item to create delegate";
|
||||||
item->createDelegate( m_view );
|
item->createDelegate( m_view );
|
||||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "item delegate is " << item->customDelegate();
|
tLog() << Q_FUNC_INFO << "item delegate is " << item->customDelegate();
|
||||||
m_view->setItemDelegateForRow( row, item->customDelegate() );
|
m_view->setItemDelegateForRow( row, item->customDelegate() );
|
||||||
|
AclJobDelegate* delegate = qobject_cast< AclJobDelegate* >( item->customDelegate() );
|
||||||
|
if ( delegate )
|
||||||
|
{
|
||||||
|
tLog() << Q_FUNC_INFO << "delegate found";
|
||||||
|
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 ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
tLog() << Q_FUNC_INFO << "delegate was not properly found!";
|
||||||
|
|
||||||
|
checkCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
JobStatusView::customDelegateJobRemoved( int row )
|
JobStatusView::customDelegateJobRemoved( int row )
|
||||||
{
|
{
|
||||||
m_view->setItemDelegateForRow( row, m_view->itemDelegate() );
|
tLog() << Q_FUNC_INFO << "row is " << row;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
JobStatusView::refreshDelegates()
|
||||||
|
{
|
||||||
|
tLog() << Q_FUNC_INFO;
|
||||||
|
int count = m_model->rowCount();
|
||||||
|
for ( int i = 0; i < count; i++ )
|
||||||
|
{
|
||||||
|
tLog() << Q_FUNC_INFO << "checking row " << i;
|
||||||
|
QModelIndex index = m_model->index( i );
|
||||||
|
QVariant itemVar = index.data( JobStatusModel::JobDataRole );
|
||||||
|
if ( !itemVar.canConvert< JobStatusItem* >() || !itemVar.value< JobStatusItem* >() )
|
||||||
|
{
|
||||||
|
tLog() << Q_FUNC_INFO << "unable to fetch JobStatusItem* at row " << i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
JobStatusItem* item = itemVar.value< JobStatusItem* >();
|
||||||
|
if ( item->hasCustomDelegate() )
|
||||||
|
m_view->setItemDelegateForRow( i, item->customDelegate() );
|
||||||
|
else
|
||||||
|
m_view->setItemDelegateForRow( i, m_view->itemDelegate() );
|
||||||
|
}
|
||||||
|
|
||||||
|
checkCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -55,6 +55,7 @@ private slots:
|
|||||||
void checkCount();
|
void checkCount();
|
||||||
void customDelegateJobInserted( int row, JobStatusItem* item );
|
void customDelegateJobInserted( int row, JobStatusItem* item );
|
||||||
void customDelegateJobRemoved( int row );
|
void customDelegateJobRemoved( int row );
|
||||||
|
void refreshDelegates();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QListView* m_view;
|
QListView* m_view;
|
||||||
|
@@ -200,9 +200,10 @@ Connection::checkACL()
|
|||||||
}
|
}
|
||||||
|
|
||||||
QString nodeid = property( "nodeid" ).toString();
|
QString nodeid = property( "nodeid" ).toString();
|
||||||
|
QString bareName = name().left( name().indexOf( "/" ) );
|
||||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "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 );
|
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 ) );
|
QMetaObject::invokeMethod( ACLRegistry::instance(), "isAuthorizedUser", Qt::QueuedConnection, Q_ARG( QString, nodeid ), Q_ARG( QString, bareName ), Q_ARG( ACLRegistry::ACL, ACLRegistry::NotFound ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -535,6 +535,8 @@ Servent::connectToPeer( const QString& ha, int port, const QString &key, const Q
|
|||||||
if( id.length() )
|
if( id.length() )
|
||||||
conn->setId( id );
|
conn->setId( id );
|
||||||
|
|
||||||
|
conn->setProperty( "nodeid", id );
|
||||||
|
|
||||||
connectToPeer( ha, port, key, conn );
|
connectToPeer( ha, port, key, conn );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -169,6 +169,11 @@ SipHandler::onSipInfo( const QString& peerId, const SipInfo& info )
|
|||||||
{
|
{
|
||||||
tDebug() << Q_FUNC_INFO << "SIP Message:" << peerId << info;
|
tDebug() << Q_FUNC_INFO << "SIP Message:" << peerId << info;
|
||||||
|
|
||||||
|
QString barePeerId = peerId.left( peerId.indexOf( "/" ) );
|
||||||
|
|
||||||
|
//FIXME: We should probably be using barePeerId in the connectToPeer call below.
|
||||||
|
//But, verify this doesn't cause any problems (there is still a uniquename after all)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If only one party is externally visible, connection is obvious
|
If only one party is externally visible, connection is obvious
|
||||||
If both are, peer with lowest IP address initiates the connection.
|
If both are, peer with lowest IP address initiates the connection.
|
||||||
@@ -199,7 +204,7 @@ SipHandler::onSipInfo( const QString& peerId, const SipInfo& info )
|
|||||||
m_peersSipInfos.insert( peerId, info );
|
m_peersSipInfos.insert( peerId, info );
|
||||||
}
|
}
|
||||||
|
|
||||||
void SipHandler::onSoftwareVersion(const QString& peerId, const QString& versionString)
|
void SipHandler::onSoftwareVersion( const QString& peerId, const QString& versionString )
|
||||||
{
|
{
|
||||||
m_peersSoftwareVersions.insert( peerId, versionString );
|
m_peersSoftwareVersions.insert( peerId, versionString );
|
||||||
}
|
}
|
||||||
|
@@ -443,6 +443,55 @@ prepareStyleOption( QStyleOptionViewItemV4* option, const QModelIndex& index, Pl
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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 );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
styleScrollBar( QScrollBar* scrollBar )
|
styleScrollBar( QScrollBar* scrollBar )
|
||||||
{
|
{
|
||||||
|
@@ -22,6 +22,8 @@
|
|||||||
|
|
||||||
#include <QSize>
|
#include <QSize>
|
||||||
#include <QModelIndex>
|
#include <QModelIndex>
|
||||||
|
#include <QColor>
|
||||||
|
#include <QRect>
|
||||||
#include <QTextOption>
|
#include <QTextOption>
|
||||||
|
|
||||||
#include "TomahawkUtils.h"
|
#include "TomahawkUtils.h"
|
||||||
@@ -30,7 +32,6 @@
|
|||||||
class PlayableItem;
|
class PlayableItem;
|
||||||
class QStyleOptionViewItemV4;
|
class QStyleOptionViewItemV4;
|
||||||
class QPainter;
|
class QPainter;
|
||||||
class QColor;
|
|
||||||
class QPixmap;
|
class QPixmap;
|
||||||
class QLayout;
|
class QLayout;
|
||||||
class QPalette;
|
class QPalette;
|
||||||
@@ -61,6 +62,8 @@ namespace TomahawkUtils
|
|||||||
|
|
||||||
DLLEXPORT void prepareStyleOption( QStyleOptionViewItemV4* option, const QModelIndex& index, PlayableItem* item );
|
DLLEXPORT void prepareStyleOption( QStyleOptionViewItemV4* option, const QModelIndex& index, PlayableItem* item );
|
||||||
|
|
||||||
|
DLLEXPORT void drawRoundedButton( QPainter* painter, const QRect& btnRect, const QColor& color, const QColor &gradient1bottom = QColor(), const QColor& gradient2top = QColor(), const QColor& gradient2bottom = QColor() );
|
||||||
|
|
||||||
DLLEXPORT void styleScrollBar( QScrollBar* scrollBar );
|
DLLEXPORT void styleScrollBar( QScrollBar* scrollBar );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user