1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-01 20:00:13 +02:00

* Added TransferView to monitor current streaming activity.

This commit is contained in:
Christian Muehlhaeuser
2010-11-28 12:26:01 +01:00
parent 0718be3848
commit 527f0a43fb
13 changed files with 267 additions and 69 deletions

View File

@@ -10,6 +10,7 @@
#include "typedefs.h" #include "typedefs.h"
class ControlConnection; class ControlConnection;
class FileTransferConnection;
namespace Tomahawk namespace Tomahawk
{ {
@@ -71,8 +72,10 @@ private:
QString m_username, m_friendlyname; QString m_username, m_friendlyname;
unsigned int m_id; unsigned int m_id;
QList< QSharedPointer<Collection> > m_collections; QList< QSharedPointer<Collection> > m_collections;
ControlConnection* m_cc;
QVariantMap m_stats; QVariantMap m_stats;
ControlConnection* m_cc;
FileTransferConnection* m_ftc;
}; };
}; };

View File

@@ -140,6 +140,7 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui}
infowidgets/sourceinfowidget.cpp infowidgets/sourceinfowidget.cpp
transferview.cpp
tomahawkwindow.cpp tomahawkwindow.cpp
tomahawktrayicon.cpp tomahawktrayicon.cpp
audiocontrols.cpp audiocontrols.cpp
@@ -270,6 +271,7 @@ SET( tomahawkHeadersGui ${tomahawkHeadersGui}
infowidgets/sourceinfowidget.h infowidgets/sourceinfowidget.h
transferview.h
tomahawkwindow.h tomahawkwindow.h
tomahawktrayicon.h tomahawktrayicon.h
audiocontrols.h audiocontrols.h
@@ -321,12 +323,6 @@ ENDIF( WIN32 )
IF( UNIX ) IF( UNIX )
INCLUDE( "CMakeLists.unix.txt" ) INCLUDE( "CMakeLists.unix.txt" )
ENDIF( UNIX ) ENDIF( UNIX )
IF( APPLE )
INCLUDE( "CMakeLists.osx.txt" )
ENDIF( APPLE )
IF( UNIX AND NOT APPLE )
INCLUDE( "CMakeLists.linux.txt" )
ENDIF( UNIX AND NOT APPLE )
kde4_add_app_icon( tomahawkSources "${CMAKE_CURRENT_SOURCE_DIR}/../data/icons/tomahawk-icon-*.png" ) kde4_add_app_icon( tomahawkSources "${CMAKE_CURRENT_SOURCE_DIR}/../data/icons/tomahawk-icon-*.png" )
qt4_add_resources( RC_SRCS "../resources.qrc" ) qt4_add_resources( RC_SRCS "../resources.qrc" )

View File

@@ -19,3 +19,10 @@ SET( OS_SPECIFIC_LINK_LIBRARIES
ogg ogg
FLAC++ FLAC++
) )
IF( APPLE )
INCLUDE( "CMakeLists.osx.txt" )
ENDIF( APPLE )
IF( UNIX AND NOT APPLE )
INCLUDE( "CMakeLists.linux.txt" )
ENDIF( UNIX AND NOT APPLE )

View File

@@ -90,7 +90,7 @@ void
ControlConnection::registerSource() ControlConnection::registerSource()
{ {
qDebug() << Q_FUNC_INFO; qDebug() << Q_FUNC_INFO;
Source * source = (Source*) sender(); Source* source = (Source*) sender();
Q_ASSERT( source == m_source.data() ); Q_ASSERT( source == m_source.data() );
// .. but we'll use the shared pointer we've already made: // .. but we'll use the shared pointer we've already made:
@@ -100,7 +100,7 @@ ControlConnection::registerSource()
m_registered = true; m_registered = true;
setupDbSyncConnection(); setupDbSyncConnection();
m_servent->registerControlConnection(this); m_servent->registerControlConnection( this );
} }
@@ -176,7 +176,7 @@ ControlConnection::handleMsg( msg_ptr msg )
{ {
if ( msg->is( Msg::PING ) ) if ( msg->is( Msg::PING ) )
{ {
qDebug() << "Received Connection PING, nice." << m_pingtimer_mark.elapsed(); // qDebug() << "Received Connection PING, nice." << m_pingtimer_mark.elapsed();
m_pingtimer_mark.restart(); m_pingtimer_mark.restart();
return; return;
} }

View File

@@ -46,8 +46,9 @@ FileTransferConnection::FileTransferConnection( Servent* s, ControlConnection* c
} }
FileTransferConnection::FileTransferConnection( Servent* s, QString fid ) FileTransferConnection::FileTransferConnection( Servent* s, ControlConnection* cc, QString fid )
: Connection( s ) : Connection( s )
, m_cc( cc )
, m_fid( fid ) , m_fid( fid )
, m_type( SENDING ) , m_type( SENDING )
, m_badded( 0 ) , m_badded( 0 )
@@ -74,7 +75,7 @@ FileTransferConnection::~FileTransferConnection()
((BufferIODevice*)m_iodev.data())->inputComplete(); ((BufferIODevice*)m_iodev.data())->inputComplete();
} }
APP->servent().fileTransferFinished( this ); APP->servent().onFileTransferFinished( this );
} }
@@ -96,12 +97,29 @@ FileTransferConnection::showStats( qint64 tx, qint64 rx )
<< QString( "Down: %L1 bytes/sec," ).arg( rx ) << QString( "Down: %L1 bytes/sec," ).arg( rx )
<< QString( "Up: %L1 bytes/sec" ).arg( tx ); << QString( "Up: %L1 bytes/sec" ).arg( tx );
} }
m_transferRate = tx + rx;
emit updated();
} }
void void
FileTransferConnection::setup() FileTransferConnection::setup()
{ {
QList<source_ptr> sources = APP->sourcelist().sources();
foreach( const source_ptr& src, sources )
{
// local src doesnt have a control connection, skip it:
if( src.isNull() || src->isLocal() )
continue;
if ( src->controlConnection() == m_cc )
{
m_source = src;
break;
}
}
connect( this, SIGNAL( statsTick( qint64, qint64 ) ), SLOT( showStats( qint64, qint64 ) ) ); connect( this, SIGNAL( statsTick( qint64, qint64 ) ), SLOT( showStats( qint64, qint64 ) ) );
if( m_type == RECEIVING ) if( m_type == RECEIVING )
{ {
@@ -118,17 +136,19 @@ FileTransferConnection::setup()
void void
FileTransferConnection::startSending( QVariantMap f ) FileTransferConnection::startSending( const QVariantMap& f )
{ {
Tomahawk::result_ptr result( new Tomahawk::Result( f, collection_ptr() ) ); m_result = Tomahawk::result_ptr( new Tomahawk::Result( f, collection_ptr() ) );
qDebug() << "Starting to transmit" << result->url(); qDebug() << "Starting to transmit" << m_result->url();
QSharedPointer<QIODevice> io = TomahawkApp::instance()->getIODeviceForUrl( result );
QSharedPointer<QIODevice> io = TomahawkApp::instance()->getIODeviceForUrl( m_result );
if( !io ) if( !io )
{ {
qDebug() << "Couldn't read from source:" << result->url(); qDebug() << "Couldn't read from source:" << m_result->url();
shutdown(); shutdown();
return; return;
} }
m_readdev = QSharedPointer<QIODevice>( io ); m_readdev = QSharedPointer<QIODevice>( io );
sendSome(); sendSome();
} }

View File

@@ -6,6 +6,7 @@
#include <QIODevice> #include <QIODevice>
#include "connection.h" #include "connection.h"
#include "tomahawk/result.h"
class ControlConnection; class ControlConnection;
class BufferIODevice; class BufferIODevice;
@@ -22,9 +23,9 @@ public:
}; };
// RX: // RX:
explicit FileTransferConnection( Servent* s, ControlConnection* parent, QString fid, unsigned int size ); explicit FileTransferConnection( Servent* s, ControlConnection* cc, QString fid, unsigned int size );
// TX: // TX:
explicit FileTransferConnection( Servent* s, QString fid ); explicit FileTransferConnection( Servent* s, ControlConnection* cc, QString fid );
virtual ~FileTransferConnection(); virtual ~FileTransferConnection();
@@ -33,15 +34,23 @@ public:
Connection* clone(); Connection* clone();
const QSharedPointer<QIODevice>& iodevice() { return m_iodev; } const QSharedPointer<QIODevice>& iodevice() { return m_iodev; }
ControlConnection* controlConnection() const { return m_cc; }
Tomahawk::source_ptr source() const { return m_source; }
Tomahawk::result_ptr track() const { return m_result; }
qint64 transferRate() const { return m_transferRate; }
Type type() const { return m_type; } Type type() const { return m_type; }
QString fid() const { return m_fid; } QString fid() const { return m_fid; }
signals:
void updated();
protected slots: protected slots:
virtual void handleMsg( msg_ptr msg ); virtual void handleMsg( msg_ptr msg );
private slots: private slots:
void startSending( QVariantMap ); void startSending( const QVariantMap& );
void sendSome(); void sendSome();
void showStats(qint64 tx, qint64 rx); void showStats(qint64 tx, qint64 rx);
@@ -54,6 +63,10 @@ private:
int m_badded, m_bsent; int m_badded, m_bsent;
bool m_allok; // got last msg ok, transfer complete? bool m_allok; // got last msg ok, transfer complete?
Tomahawk::source_ptr m_source;
Tomahawk::result_ptr m_result;
qint64 m_transferRate;
}; };
#endif // FILETRANSFERCONNECTION_H #endif // FILETRANSFERCONNECTION_H

View File

@@ -121,9 +121,10 @@ QString
Servent::createConnectionKey( const QString& name ) Servent::createConnectionKey( const QString& name )
{ {
Q_ASSERT( this->thread() == QThread::currentThread() ); Q_ASSERT( this->thread() == QThread::currentThread() );
QString key = uuid(); QString key = uuid();
ControlConnection * cc = new ControlConnection( this ); ControlConnection * cc = new ControlConnection( this );
cc->setName( name=="" ? QString( "KEY(%1)" ).arg(key) : name ); cc->setName( name.isEmpty() ? QString( "KEY(%1)" ).arg( key ) : name );
registerOffer( key, cc ); registerOffer( key, cc );
return key; return key;
} }
@@ -227,37 +228,51 @@ Servent::readyRead()
sock->_msg->fill( ba ); sock->_msg->fill( ba );
Q_ASSERT( sock->_msg->is( Msg::JSON ) ); Q_ASSERT( sock->_msg->is( Msg::JSON ) );
ControlConnection* cc = 0;
bool ok; bool ok;
int pport = 0; int pport = 0;
QString key, conntype, nodeid; QString key, conntype, nodeid, controlid;
QVariantMap m = parser.parse( sock->_msg->payload(), &ok ).toMap(); QVariantMap m = parser.parse( sock->_msg->payload(), &ok ).toMap();
if( !ok ) if( !ok )
{ {
qDebug() << "Invalid JSON on new conection, aborting"; qDebug() << "Invalid JSON on new conection, aborting";
goto closeconnection; goto closeconnection;
} }
conntype = m.value( "conntype" ).toString(); conntype = m.value( "conntype" ).toString();
key = m.value( "key" ).toString(); key = m.value( "key" ).toString();
pport = m.value( "port" ).toInt(); pport = m.value( "port" ).toInt();
nodeid = m.value( "nodeid" ).toString(); nodeid = m.value( "nodeid" ).toString();
controlid = m.value( "controlid" ).toString();
qDebug() << m; qDebug() << m;
if( !nodeid.isEmpty() ) // only control connections send nodeid if( !nodeid.isEmpty() && cc != 0 ) // only control connections send nodeid
foreach( ControlConnection* cc, m_controlconnections )
{ {
if( cc->id() == nodeid ) foreach( ControlConnection* con, m_controlconnections )
{ {
qDebug() << "Duplicate control connection detected, dropping:" << nodeid << conntype; qDebug() << con->socket() << sock;
goto closeconnection; if( con->id() == nodeid )
{
qDebug() << "Duplicate control connection detected, dropping:" << nodeid << conntype;
goto closeconnection;
}
} }
} }
foreach( ControlConnection* con, m_controlconnections )
{
qDebug() << "cons:" << con;
qDebug() << "conid:" << con->id();
if ( con->id() == controlid )
cc = con;
}
// they connected to us and want something we are offering // they connected to us and want something we are offering
if( conntype == "accept-offer" || "push-offer" ) if( conntype == "accept-offer" || "push-offer" )
{ {
sock->_msg.clear(); sock->_msg.clear();
Connection * conn = claimOffer( key, sock->peerAddress() ); Connection* conn = claimOffer( cc, key, sock->peerAddress() );
if( !conn ) if( !conn )
{ {
qDebug() << "claimOffer FAILED, key:" << key; qDebug() << "claimOffer FAILED, key:" << key;
@@ -265,10 +280,10 @@ Servent::readyRead()
} }
qDebug() << "claimOffer OK:" << key; qDebug() << "claimOffer OK:" << key;
if( !nodeid.isEmpty() ) conn->setId( nodeid ); if( !nodeid.isEmpty() )
conn->setId( nodeid );
handoverSocket( conn, sock ); handoverSocket( conn, sock );
return; return;
} }
else else
@@ -310,6 +325,7 @@ Servent::createParallelConnection( Connection* orig_conn, Connection* new_conn,
m.insert( "key", tmpkey ); m.insert( "key", tmpkey );
m.insert( "offer", key ); m.insert( "offer", key );
m.insert( "port", externalPort() ); m.insert( "port", externalPort() );
m.insert( "controlid", orig_conn->id() );
QJson::Serializer ser; QJson::Serializer ser;
orig_conn->sendMsg( Msg::factory( ser.serialize(m), Msg::JSON ) ); orig_conn->sendMsg( Msg::factory( ser.serialize(m), Msg::JSON ) );
@@ -383,10 +399,10 @@ Servent::connectToPeer( const QString& ha, int port, const QString &key, const Q
ControlConnection* conn = new ControlConnection( this ); ControlConnection* conn = new ControlConnection( this );
QVariantMap m; QVariantMap m;
m["conntype"] = "accept-offer"; m["conntype"] = "accept-offer";
m["key"] = key; m["key"] = key;
m["port"] = externalPort(); m["port"] = externalPort();
m["nodeid"] = APP->nodeID(); m["nodeid"] = APP->nodeID();
conn->setFirstMessage( m ); conn->setFirstMessage( m );
if( name.length() ) if( name.length() )
@@ -411,9 +427,10 @@ Servent::connectToPeer( const QString& ha, int port, const QString &key, Connect
if( key.length() && conn->firstMessage().isNull() ) if( key.length() && conn->firstMessage().isNull() )
{ {
QVariantMap m; QVariantMap m;
m["conntype"] = "accept-offer"; m["conntype"] = "accept-offer";
m["key"] = key; m["key"] = key;
m["port"] = externalPort(); m["port"] = externalPort();
m["controlid"] = APP->nodeID();
conn->setFirstMessage( m ); conn->setFirstMessage( m );
} }
@@ -435,13 +452,13 @@ Servent::connectToPeer( const QString& ha, int port, const QString &key, Connect
void void
Servent::reverseOfferRequest( Connection* orig_conn, const QString& key, const QString& theirkey ) Servent::reverseOfferRequest( ControlConnection* orig_conn, const QString& key, const QString& theirkey )
{ {
Q_ASSERT( this->thread() == QThread::currentThread() ); Q_ASSERT( this->thread() == QThread::currentThread() );
qDebug() << "Servent::reverseOfferRequest received for" << key; qDebug() << "Servent::reverseOfferRequest received for" << key;
Connection * new_conn = claimOffer( key ); Connection* new_conn = claimOffer( orig_conn, key );
if( !new_conn ) if ( !new_conn )
{ {
qDebug() << "claimOffer failed, killing requesting connection out of spite"; qDebug() << "claimOffer failed, killing requesting connection out of spite";
orig_conn->shutdown(); orig_conn->shutdown();
@@ -449,9 +466,10 @@ Servent::reverseOfferRequest( Connection* orig_conn, const QString& key, const Q
} }
QVariantMap m; QVariantMap m;
m["conntype"] = "push-offer"; m["conntype"] = "push-offer";
m["key"] = theirkey; m["key"] = theirkey;
m["port"] = externalPort(); m["port"] = externalPort();
m["controlid"] = orig_conn->id();
new_conn->setFirstMessage( m ); new_conn->setFirstMessage( m );
createParallelConnection( orig_conn, new_conn, QString() ); createParallelConnection( orig_conn, new_conn, QString() );
} }
@@ -459,12 +477,12 @@ Servent::reverseOfferRequest( Connection* orig_conn, const QString& key, const Q
// return the appropriate connection for a given offer key, or NULL if invalid // return the appropriate connection for a given offer key, or NULL if invalid
Connection* Connection*
Servent::claimOffer( const QString &key, const QHostAddress peer ) Servent::claimOffer( ControlConnection* cc, const QString &key, const QHostAddress peer )
{ {
bool noauth = qApp->arguments().contains( "--noauth" ); bool noauth = qApp->arguments().contains( "--noauth" );
// magic key for file transfers: // magic key for file transfers:
if( key.startsWith("FILE_REQUEST_KEY:") ) if( key.startsWith( "FILE_REQUEST_KEY:" ) )
{ {
// check if the source IP matches an existing, authenticated connection // check if the source IP matches an existing, authenticated connection
if ( !noauth && peer != QHostAddress::Any && !isIPWhitelisted( peer ) ) if ( !noauth && peer != QHostAddress::Any && !isIPWhitelisted( peer ) )
@@ -486,13 +504,13 @@ Servent::claimOffer( const QString &key, const QHostAddress peer )
} }
QString fid = key.right( key.length() - 17 ); QString fid = key.right( key.length() - 17 );
FileTransferConnection* ftc = new FileTransferConnection( this, fid ); FileTransferConnection* ftc = new FileTransferConnection( this, cc, fid );
return ftc; return ftc;
} }
if( key == "whitelist" ) // LAN IP address, check source IP if( key == "whitelist" ) // LAN IP address, check source IP
{ {
if( isIPWhitelisted(peer) ) if( isIPWhitelisted( peer ) )
{ {
qDebug() << "Connection is from whitelisted IP range (LAN)"; qDebug() << "Connection is from whitelisted IP range (LAN)";
Connection* conn = new ControlConnection( this ); Connection* conn = new ControlConnection( this );
@@ -567,23 +585,28 @@ void
Servent::registerFileTransferConnection( FileTransferConnection* ftc ) Servent::registerFileTransferConnection( FileTransferConnection* ftc )
{ {
Q_ASSERT( !m_ftsessions.contains( ftc ) ); Q_ASSERT( !m_ftsessions.contains( ftc ) );
QMutexLocker lock( &m_ftsession_mut );
qDebug() << "Registering FileTransfer" << m_ftsessions.length() + 1; qDebug() << "Registering FileTransfer" << m_ftsessions.length() + 1;
QMutexLocker lock( &m_ftsession_mut );
m_ftsessions.append( ftc ); m_ftsessions.append( ftc );
printCurrentTransfers(); printCurrentTransfers();
emit fileTransferStarted( ftc );
} }
void void
Servent::fileTransferFinished( FileTransferConnection* ftc ) Servent::onFileTransferFinished( FileTransferConnection* ftc )
{ {
Q_ASSERT( ftc ); Q_ASSERT( ftc );
qDebug() << "FileTransfer Finished, unregistering" << ftc->id(); qDebug() << "FileTransfer Finished, unregistering" << ftc->id();
QMutexLocker lock( &m_ftsession_mut ); QMutexLocker lock( &m_ftsession_mut );
int rem = m_ftsessions.removeAll( ftc ); int rem = m_ftsessions.removeAll( ftc );
Q_ASSERT( rem == 1 ); Q_ASSERT( rem == 1 );
printCurrentTransfers(); printCurrentTransfers();
emit fileTransferFinished( ftc );
} }
@@ -608,11 +631,11 @@ Servent::isIPWhitelisted( QHostAddress ip )
static QList<range> whitelist; static QList<range> whitelist;
if( whitelist.isEmpty() ) if( whitelist.isEmpty() )
{ {
whitelist << range( QHostAddress("10.0.0.0"), 8 ) whitelist << range( QHostAddress( "10.0.0.0" ), 8 )
<< range( QHostAddress("172.16.0.0"), 12 ) << range( QHostAddress( "172.16.0.0" ), 12 )
<< range( QHostAddress("192.168.0.0"), 16 ) << range( QHostAddress( "192.168.0.0" ), 16 )
<< range( QHostAddress("169.254.0.0"), 16 ) << range( QHostAddress( "169.254.0.0" ), 16 )
<< range( QHostAddress("127.0.0.0"), 24 ); << range( QHostAddress( "127.0.0.0" ), 24 );
// qDebug() << "Loaded whitelist IP range:" << whitelist; // qDebug() << "Loaded whitelist IP range:" << whitelist;
} }

View File

@@ -82,7 +82,7 @@ public:
void connectToPeer( const QString& ha, int port, const QString &key, const QString& name = "", const QString& id = "" ); void connectToPeer( const QString& ha, int port, const QString &key, const QString& name = "", const QString& id = "" );
void connectToPeer( const QString& ha, int port, const QString &key, Connection* conn ); void connectToPeer( const QString& ha, int port, const QString &key, Connection* conn );
void reverseOfferRequest( Connection* orig_conn, const QString& key, const QString& theirkey ); void reverseOfferRequest( ControlConnection* orig_conn, const QString& key, const QString& theirkey );
void setExternalAddress( QHostAddress ha, int port ); void setExternalAddress( QHostAddress ha, int port );
bool visibleExternally() const { return m_externalPort > 0; } bool visibleExternally() const { return m_externalPort > 0; }
@@ -93,9 +93,14 @@ public:
static bool isIPWhitelisted( QHostAddress ip ); static bool isIPWhitelisted( QHostAddress ip );
bool connectedToSession( const QString& session ); bool connectedToSession( const QString& session );
unsigned int numConnectedPeers() const { return m_controlconnections.length(); } unsigned int numConnectedPeers() const { return m_controlconnections.length(); }
QList< FileTransferConnection* > fileTransfers() const { return m_ftsessions; }
signals:
void fileTransferStarted( FileTransferConnection* );
void fileTransferFinished( FileTransferConnection* );
protected: protected:
void incomingConnection( int sd ); void incomingConnection( int sd );
@@ -104,7 +109,7 @@ public slots:
void createParallelConnection( Connection* orig_conn, Connection* new_conn, const QString& key ); void createParallelConnection( Connection* orig_conn, Connection* new_conn, const QString& key );
void registerFileTransferConnection( FileTransferConnection* ); void registerFileTransferConnection( FileTransferConnection* );
void fileTransferFinished( FileTransferConnection* ftc ); void onFileTransferFinished( FileTransferConnection* ftc );
void socketConnected(); void socketConnected();
void triggerDBSync(); void triggerDBSync();
@@ -112,7 +117,7 @@ public slots:
private slots: private slots:
void readyRead(); void readyRead();
Connection* claimOffer( const QString &key, const QHostAddress peer = QHostAddress::Any ); Connection* claimOffer( ControlConnection* cc, const QString &key, const QHostAddress peer = QHostAddress::Any );
private: private:
void handoverSocket( Connection* conn, QTcpSocketExtra* sock ); void handoverSocket( Connection* conn, QTcpSocketExtra* sock );

View File

@@ -18,6 +18,7 @@ Source::Source( const QString &username, ControlConnection* cc )
, m_username( username ) , m_username( username )
, m_id( 0 ) , m_id( 0 )
, m_cc( cc ) , m_cc( cc )
, m_ftc( 0 )
{ {
// source for local machine doesn't have a controlconnection. this is normal. // source for local machine doesn't have a controlconnection. this is normal.
if ( cc ) if ( cc )

View File

@@ -65,6 +65,9 @@ TomahawkWindow::TomahawkWindow( QWidget* parent )
ui->splitter->setStretchFactor( 0, 1 ); ui->splitter->setStretchFactor( 0, 1 );
ui->splitter->setStretchFactor( 1, 3 ); ui->splitter->setStretchFactor( 1, 3 );
ui->splitter_2->setStretchFactor( 0, 3 );
ui->splitter_2->setStretchFactor( 1, 1 );
QToolBar* toolbar = addToolBar( "TomahawkToolbar" ); QToolBar* toolbar = addToolBar( "TomahawkToolbar" );
toolbar->setObjectName( "TomahawkToolbar" ); toolbar->setObjectName( "TomahawkToolbar" );
toolbar->addWidget( m_topbar ); toolbar->addWidget( m_topbar );

View File

@@ -20,13 +20,19 @@
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
<widget class="SourceTreeView" name="sourceTreeView"> <widget class="AnimatedSplitter" name="splitter_2">
<property name="minimumSize"> <property name="orientation">
<size> <enum>Qt::Vertical</enum>
<width>250</width>
<height>0</height>
</size>
</property> </property>
<widget class="SourceTreeView" name="sourceTreeView">
<property name="minimumSize">
<size>
<width>250</width>
<height>0</height>
</size>
</property>
</widget>
<widget class="TransferView" name="treeWidget"/>
</widget> </widget>
<widget class="QWidget" name="playlistWidget" native="true"/> <widget class="QWidget" name="playlistWidget" native="true"/>
</widget> </widget>
@@ -144,6 +150,17 @@
<extends>QTreeView</extends> <extends>QTreeView</extends>
<header>sourcetreeview.h</header> <header>sourcetreeview.h</header>
</customwidget> </customwidget>
<customwidget>
<class>AnimatedSplitter</class>
<extends>QSplitter</extends>
<header location="global">animatedsplitter.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>TransferView</class>
<extends>QTreeWidget</extends>
<header>transferview.h</header>
</customwidget>
</customwidgets> </customwidgets>
<resources/> <resources/>
<connections/> <connections/>

74
src/transferview.cpp Normal file
View File

@@ -0,0 +1,74 @@
#include "transferview.h"
#include <QHeaderView>
#include "tomahawk/tomahawkapp.h"
#include "network/filetransferconnection.h"
#include "network/servent.h"
TransferView::TransferView( QWidget* parent )
: QTreeWidget( parent )
{
connect( &APP->servent(), SIGNAL( fileTransferStarted( FileTransferConnection* ) ), SLOT( fileTransferRegistered( FileTransferConnection* ) ) );
connect( &APP->servent(), SIGNAL( fileTransferFinished( FileTransferConnection* ) ), SLOT( fileTransferFinished( FileTransferConnection* ) ) );
QStringList headers;
headers << tr( "Peer" ) << tr( "Rate" ) << tr( "Track" );
setHeaderLabels( headers );
setColumnCount( 3 );
setColumnWidth( 0, 80 );
setColumnWidth( 1, 65 );
setColumnWidth( 2, 10 );
header()->setStretchLastSection( true );
setRootIsDecorated( false );
}
void
TransferView::fileTransferRegistered( FileTransferConnection* ftc )
{
connect( ftc, SIGNAL( updated() ), SLOT( onTransferUpdate() ) );
}
void
TransferView::fileTransferFinished( FileTransferConnection* ftc )
{
if ( !m_index.contains( ftc ) )
return;
/* int i = m_index.take( ftc );
delete invisibleRootItem()->takeChild( i ); */
if ( m_index.contains( ftc ) )
{
int i = m_index.value( ftc );
invisibleRootItem()->child( i )->setText( 1, tr( "Finished" ) );
}
}
void
TransferView::onTransferUpdate()
{
FileTransferConnection* ftc = (FileTransferConnection*)sender();
QTreeWidgetItem* ti = 0;
if ( m_index.contains( ftc ) )
{
int i = m_index.value( ftc );
ti = invisibleRootItem()->child( i );
}
else
{
ti = new QTreeWidgetItem( this );
m_index.insert( ftc, invisibleRootItem()->childCount() - 1 );
}
ti->setText( 0, ftc->source()->friendlyName() );
ti->setText( 1, QString( "%1 kb/s" ).arg( ftc->transferRate() / 1024 ) );
ti->setText( 2, QString( "%1 - %2" ).arg( ftc->track()->artist()->name() ).arg( ftc->track()->track() ) );
}

36
src/transferview.h Normal file
View File

@@ -0,0 +1,36 @@
#ifndef TRANSFERVIEW_H
#define TRANSFERVIEW_H
#include <QDebug>
#include <QTreeWidget>
#include "tomahawk/typedefs.h"
class FileTransferConnection;
class TransferView : public QTreeWidget
{
Q_OBJECT
public:
explicit TransferView( QWidget* parent = 0 );
virtual ~TransferView()
{
qDebug() << Q_FUNC_INFO;
}
signals:
public slots:
private slots:
void fileTransferRegistered( FileTransferConnection* ftc );
void fileTransferFinished( FileTransferConnection* ftc );
void onTransferUpdate();
private:
QHash< FileTransferConnection*, int > m_index;
};
#endif // TRANSFERVIEW_H