mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-01-18 23:17:59 +01:00
* Added TransferView to monitor current streaming activity.
This commit is contained in:
parent
0718be3848
commit
527f0a43fb
@ -10,6 +10,7 @@
|
||||
#include "typedefs.h"
|
||||
|
||||
class ControlConnection;
|
||||
class FileTransferConnection;
|
||||
|
||||
namespace Tomahawk
|
||||
{
|
||||
@ -71,8 +72,10 @@ private:
|
||||
QString m_username, m_friendlyname;
|
||||
unsigned int m_id;
|
||||
QList< QSharedPointer<Collection> > m_collections;
|
||||
ControlConnection* m_cc;
|
||||
QVariantMap m_stats;
|
||||
|
||||
ControlConnection* m_cc;
|
||||
FileTransferConnection* m_ftc;
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -140,6 +140,7 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui}
|
||||
|
||||
infowidgets/sourceinfowidget.cpp
|
||||
|
||||
transferview.cpp
|
||||
tomahawkwindow.cpp
|
||||
tomahawktrayicon.cpp
|
||||
audiocontrols.cpp
|
||||
@ -270,6 +271,7 @@ SET( tomahawkHeadersGui ${tomahawkHeadersGui}
|
||||
|
||||
infowidgets/sourceinfowidget.h
|
||||
|
||||
transferview.h
|
||||
tomahawkwindow.h
|
||||
tomahawktrayicon.h
|
||||
audiocontrols.h
|
||||
@ -321,12 +323,6 @@ ENDIF( WIN32 )
|
||||
IF( UNIX )
|
||||
INCLUDE( "CMakeLists.unix.txt" )
|
||||
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" )
|
||||
qt4_add_resources( RC_SRCS "../resources.qrc" )
|
||||
|
@ -19,3 +19,10 @@ SET( OS_SPECIFIC_LINK_LIBRARIES
|
||||
ogg
|
||||
FLAC++
|
||||
)
|
||||
|
||||
IF( APPLE )
|
||||
INCLUDE( "CMakeLists.osx.txt" )
|
||||
ENDIF( APPLE )
|
||||
IF( UNIX AND NOT APPLE )
|
||||
INCLUDE( "CMakeLists.linux.txt" )
|
||||
ENDIF( UNIX AND NOT APPLE )
|
||||
|
@ -90,7 +90,7 @@ void
|
||||
ControlConnection::registerSource()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
Source * source = (Source*) sender();
|
||||
Source* source = (Source*) sender();
|
||||
Q_ASSERT( source == m_source.data() );
|
||||
// .. but we'll use the shared pointer we've already made:
|
||||
|
||||
@ -100,7 +100,7 @@ ControlConnection::registerSource()
|
||||
|
||||
m_registered = true;
|
||||
setupDbSyncConnection();
|
||||
m_servent->registerControlConnection(this);
|
||||
m_servent->registerControlConnection( this );
|
||||
}
|
||||
|
||||
|
||||
@ -176,7 +176,7 @@ ControlConnection::handleMsg( msg_ptr msg )
|
||||
{
|
||||
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();
|
||||
return;
|
||||
}
|
||||
|
@ -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 )
|
||||
, m_cc( cc )
|
||||
, m_fid( fid )
|
||||
, m_type( SENDING )
|
||||
, m_badded( 0 )
|
||||
@ -74,7 +75,7 @@ FileTransferConnection::~FileTransferConnection()
|
||||
((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( "Up: %L1 bytes/sec" ).arg( tx );
|
||||
}
|
||||
|
||||
m_transferRate = tx + rx;
|
||||
emit updated();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
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 ) ) );
|
||||
if( m_type == RECEIVING )
|
||||
{
|
||||
@ -118,17 +136,19 @@ FileTransferConnection::setup()
|
||||
|
||||
|
||||
void
|
||||
FileTransferConnection::startSending( QVariantMap f )
|
||||
FileTransferConnection::startSending( const QVariantMap& f )
|
||||
{
|
||||
Tomahawk::result_ptr result( new Tomahawk::Result( f, collection_ptr() ) );
|
||||
qDebug() << "Starting to transmit" << result->url();
|
||||
QSharedPointer<QIODevice> io = TomahawkApp::instance()->getIODeviceForUrl( result );
|
||||
m_result = Tomahawk::result_ptr( new Tomahawk::Result( f, collection_ptr() ) );
|
||||
qDebug() << "Starting to transmit" << m_result->url();
|
||||
|
||||
QSharedPointer<QIODevice> io = TomahawkApp::instance()->getIODeviceForUrl( m_result );
|
||||
if( !io )
|
||||
{
|
||||
qDebug() << "Couldn't read from source:" << result->url();
|
||||
qDebug() << "Couldn't read from source:" << m_result->url();
|
||||
shutdown();
|
||||
return;
|
||||
}
|
||||
|
||||
m_readdev = QSharedPointer<QIODevice>( io );
|
||||
sendSome();
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <QIODevice>
|
||||
|
||||
#include "connection.h"
|
||||
#include "tomahawk/result.h"
|
||||
|
||||
class ControlConnection;
|
||||
class BufferIODevice;
|
||||
@ -22,9 +23,9 @@ public:
|
||||
};
|
||||
|
||||
// RX:
|
||||
explicit FileTransferConnection( Servent* s, ControlConnection* parent, QString fid, unsigned int size );
|
||||
explicit FileTransferConnection( Servent* s, ControlConnection* cc, QString fid, unsigned int size );
|
||||
// TX:
|
||||
explicit FileTransferConnection( Servent* s, QString fid );
|
||||
explicit FileTransferConnection( Servent* s, ControlConnection* cc, QString fid );
|
||||
|
||||
virtual ~FileTransferConnection();
|
||||
|
||||
@ -33,15 +34,23 @@ public:
|
||||
Connection* clone();
|
||||
|
||||
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; }
|
||||
QString fid() const { return m_fid; }
|
||||
|
||||
signals:
|
||||
void updated();
|
||||
|
||||
protected slots:
|
||||
virtual void handleMsg( msg_ptr msg );
|
||||
|
||||
private slots:
|
||||
void startSending( QVariantMap );
|
||||
void startSending( const QVariantMap& );
|
||||
void sendSome();
|
||||
void showStats(qint64 tx, qint64 rx);
|
||||
|
||||
@ -54,6 +63,10 @@ private:
|
||||
|
||||
int m_badded, m_bsent;
|
||||
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
|
||||
|
@ -121,9 +121,10 @@ QString
|
||||
Servent::createConnectionKey( const QString& name )
|
||||
{
|
||||
Q_ASSERT( this->thread() == QThread::currentThread() );
|
||||
|
||||
QString key = uuid();
|
||||
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 );
|
||||
return key;
|
||||
}
|
||||
@ -227,37 +228,51 @@ Servent::readyRead()
|
||||
sock->_msg->fill( ba );
|
||||
Q_ASSERT( sock->_msg->is( Msg::JSON ) );
|
||||
|
||||
ControlConnection* cc = 0;
|
||||
bool ok;
|
||||
int pport = 0;
|
||||
QString key, conntype, nodeid;
|
||||
QString key, conntype, nodeid, controlid;
|
||||
QVariantMap m = parser.parse( sock->_msg->payload(), &ok ).toMap();
|
||||
if( !ok )
|
||||
{
|
||||
qDebug() << "Invalid JSON on new conection, aborting";
|
||||
goto closeconnection;
|
||||
}
|
||||
conntype = m.value( "conntype" ).toString();
|
||||
key = m.value( "key" ).toString();
|
||||
pport = m.value( "port" ).toInt();
|
||||
nodeid = m.value( "nodeid" ).toString();
|
||||
conntype = m.value( "conntype" ).toString();
|
||||
key = m.value( "key" ).toString();
|
||||
pport = m.value( "port" ).toInt();
|
||||
nodeid = m.value( "nodeid" ).toString();
|
||||
controlid = m.value( "controlid" ).toString();
|
||||
|
||||
qDebug() << m;
|
||||
|
||||
if( !nodeid.isEmpty() ) // only control connections send nodeid
|
||||
foreach( ControlConnection* cc, m_controlconnections )
|
||||
if( !nodeid.isEmpty() && cc != 0 ) // only control connections send nodeid
|
||||
{
|
||||
if( cc->id() == nodeid )
|
||||
foreach( ControlConnection* con, m_controlconnections )
|
||||
{
|
||||
qDebug() << "Duplicate control connection detected, dropping:" << nodeid << conntype;
|
||||
goto closeconnection;
|
||||
qDebug() << con->socket() << sock;
|
||||
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
|
||||
if( conntype == "accept-offer" || "push-offer" )
|
||||
{
|
||||
sock->_msg.clear();
|
||||
Connection * conn = claimOffer( key, sock->peerAddress() );
|
||||
Connection* conn = claimOffer( cc, key, sock->peerAddress() );
|
||||
if( !conn )
|
||||
{
|
||||
qDebug() << "claimOffer FAILED, key:" << key;
|
||||
@ -265,10 +280,10 @@ Servent::readyRead()
|
||||
}
|
||||
qDebug() << "claimOffer OK:" << key;
|
||||
|
||||
if( !nodeid.isEmpty() ) conn->setId( nodeid );
|
||||
if( !nodeid.isEmpty() )
|
||||
conn->setId( nodeid );
|
||||
|
||||
handoverSocket( conn, sock );
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
@ -310,6 +325,7 @@ Servent::createParallelConnection( Connection* orig_conn, Connection* new_conn,
|
||||
m.insert( "key", tmpkey );
|
||||
m.insert( "offer", key );
|
||||
m.insert( "port", externalPort() );
|
||||
m.insert( "controlid", orig_conn->id() );
|
||||
|
||||
QJson::Serializer ser;
|
||||
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 );
|
||||
QVariantMap m;
|
||||
m["conntype"] = "accept-offer";
|
||||
m["key"] = key;
|
||||
m["port"] = externalPort();
|
||||
m["nodeid"] = APP->nodeID();
|
||||
m["conntype"] = "accept-offer";
|
||||
m["key"] = key;
|
||||
m["port"] = externalPort();
|
||||
m["nodeid"] = APP->nodeID();
|
||||
|
||||
conn->setFirstMessage( m );
|
||||
if( name.length() )
|
||||
@ -411,9 +427,10 @@ Servent::connectToPeer( const QString& ha, int port, const QString &key, Connect
|
||||
if( key.length() && conn->firstMessage().isNull() )
|
||||
{
|
||||
QVariantMap m;
|
||||
m["conntype"] = "accept-offer";
|
||||
m["key"] = key;
|
||||
m["port"] = externalPort();
|
||||
m["conntype"] = "accept-offer";
|
||||
m["key"] = key;
|
||||
m["port"] = externalPort();
|
||||
m["controlid"] = APP->nodeID();
|
||||
conn->setFirstMessage( m );
|
||||
}
|
||||
|
||||
@ -435,13 +452,13 @@ Servent::connectToPeer( const QString& ha, int port, const QString &key, Connect
|
||||
|
||||
|
||||
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() );
|
||||
|
||||
qDebug() << "Servent::reverseOfferRequest received for" << key;
|
||||
Connection * new_conn = claimOffer( key );
|
||||
if( !new_conn )
|
||||
Connection* new_conn = claimOffer( orig_conn, key );
|
||||
if ( !new_conn )
|
||||
{
|
||||
qDebug() << "claimOffer failed, killing requesting connection out of spite";
|
||||
orig_conn->shutdown();
|
||||
@ -449,9 +466,10 @@ Servent::reverseOfferRequest( Connection* orig_conn, const QString& key, const Q
|
||||
}
|
||||
|
||||
QVariantMap m;
|
||||
m["conntype"] = "push-offer";
|
||||
m["key"] = theirkey;
|
||||
m["port"] = externalPort();
|
||||
m["conntype"] = "push-offer";
|
||||
m["key"] = theirkey;
|
||||
m["port"] = externalPort();
|
||||
m["controlid"] = orig_conn->id();
|
||||
new_conn->setFirstMessage( m );
|
||||
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
|
||||
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" );
|
||||
|
||||
// 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
|
||||
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 );
|
||||
FileTransferConnection* ftc = new FileTransferConnection( this, fid );
|
||||
FileTransferConnection* ftc = new FileTransferConnection( this, cc, fid );
|
||||
return ftc;
|
||||
}
|
||||
|
||||
if( key == "whitelist" ) // LAN IP address, check source IP
|
||||
{
|
||||
if( isIPWhitelisted(peer) )
|
||||
if( isIPWhitelisted( peer ) )
|
||||
{
|
||||
qDebug() << "Connection is from whitelisted IP range (LAN)";
|
||||
Connection* conn = new ControlConnection( this );
|
||||
@ -567,23 +585,28 @@ void
|
||||
Servent::registerFileTransferConnection( FileTransferConnection* ftc )
|
||||
{
|
||||
Q_ASSERT( !m_ftsessions.contains( ftc ) );
|
||||
QMutexLocker lock( &m_ftsession_mut );
|
||||
qDebug() << "Registering FileTransfer" << m_ftsessions.length() + 1;
|
||||
|
||||
QMutexLocker lock( &m_ftsession_mut );
|
||||
m_ftsessions.append( ftc );
|
||||
|
||||
printCurrentTransfers();
|
||||
emit fileTransferStarted( ftc );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Servent::fileTransferFinished( FileTransferConnection* ftc )
|
||||
Servent::onFileTransferFinished( FileTransferConnection* ftc )
|
||||
{
|
||||
Q_ASSERT( ftc );
|
||||
|
||||
qDebug() << "FileTransfer Finished, unregistering" << ftc->id();
|
||||
|
||||
QMutexLocker lock( &m_ftsession_mut );
|
||||
int rem = m_ftsessions.removeAll( ftc );
|
||||
Q_ASSERT( rem == 1 );
|
||||
|
||||
printCurrentTransfers();
|
||||
emit fileTransferFinished( ftc );
|
||||
}
|
||||
|
||||
|
||||
@ -608,11 +631,11 @@ Servent::isIPWhitelisted( QHostAddress ip )
|
||||
static QList<range> whitelist;
|
||||
if( whitelist.isEmpty() )
|
||||
{
|
||||
whitelist << range( QHostAddress("10.0.0.0"), 8 )
|
||||
<< range( QHostAddress("172.16.0.0"), 12 )
|
||||
<< range( QHostAddress("192.168.0.0"), 16 )
|
||||
<< range( QHostAddress("169.254.0.0"), 16 )
|
||||
<< range( QHostAddress("127.0.0.0"), 24 );
|
||||
whitelist << range( QHostAddress( "10.0.0.0" ), 8 )
|
||||
<< range( QHostAddress( "172.16.0.0" ), 12 )
|
||||
<< range( QHostAddress( "192.168.0.0" ), 16 )
|
||||
<< range( QHostAddress( "169.254.0.0" ), 16 )
|
||||
<< range( QHostAddress( "127.0.0.0" ), 24 );
|
||||
|
||||
// qDebug() << "Loaded whitelist IP range:" << whitelist;
|
||||
}
|
||||
|
@ -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, 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 );
|
||||
bool visibleExternally() const { return m_externalPort > 0; }
|
||||
@ -93,9 +93,14 @@ public:
|
||||
static bool isIPWhitelisted( QHostAddress ip );
|
||||
|
||||
bool connectedToSession( const QString& session );
|
||||
|
||||
unsigned int numConnectedPeers() const { return m_controlconnections.length(); }
|
||||
|
||||
QList< FileTransferConnection* > fileTransfers() const { return m_ftsessions; }
|
||||
|
||||
signals:
|
||||
void fileTransferStarted( FileTransferConnection* );
|
||||
void fileTransferFinished( FileTransferConnection* );
|
||||
|
||||
protected:
|
||||
void incomingConnection( int sd );
|
||||
|
||||
@ -104,7 +109,7 @@ public slots:
|
||||
void createParallelConnection( Connection* orig_conn, Connection* new_conn, const QString& key );
|
||||
|
||||
void registerFileTransferConnection( FileTransferConnection* );
|
||||
void fileTransferFinished( FileTransferConnection* ftc );
|
||||
void onFileTransferFinished( FileTransferConnection* ftc );
|
||||
|
||||
void socketConnected();
|
||||
void triggerDBSync();
|
||||
@ -112,7 +117,7 @@ public slots:
|
||||
private slots:
|
||||
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:
|
||||
void handoverSocket( Connection* conn, QTcpSocketExtra* sock );
|
||||
|
@ -18,6 +18,7 @@ Source::Source( const QString &username, ControlConnection* cc )
|
||||
, m_username( username )
|
||||
, m_id( 0 )
|
||||
, m_cc( cc )
|
||||
, m_ftc( 0 )
|
||||
{
|
||||
// source for local machine doesn't have a controlconnection. this is normal.
|
||||
if ( cc )
|
||||
|
@ -65,6 +65,9 @@ TomahawkWindow::TomahawkWindow( QWidget* parent )
|
||||
ui->splitter->setStretchFactor( 0, 1 );
|
||||
ui->splitter->setStretchFactor( 1, 3 );
|
||||
|
||||
ui->splitter_2->setStretchFactor( 0, 3 );
|
||||
ui->splitter_2->setStretchFactor( 1, 1 );
|
||||
|
||||
QToolBar* toolbar = addToolBar( "TomahawkToolbar" );
|
||||
toolbar->setObjectName( "TomahawkToolbar" );
|
||||
toolbar->addWidget( m_topbar );
|
||||
|
@ -20,13 +20,19 @@
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<widget class="SourceTreeView" name="sourceTreeView">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>250</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
<widget class="AnimatedSplitter" name="splitter_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</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 class="QWidget" name="playlistWidget" native="true"/>
|
||||
</widget>
|
||||
@ -144,6 +150,17 @@
|
||||
<extends>QTreeView</extends>
|
||||
<header>sourcetreeview.h</header>
|
||||
</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>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
74
src/transferview.cpp
Normal file
74
src/transferview.cpp
Normal 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
36
src/transferview.h
Normal 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
|
Loading…
x
Reference in New Issue
Block a user