mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-03-21 16:29:43 +01:00
* Merged master into phonon branch.
This commit is contained in:
parent
af0b7f9a74
commit
34ac2b6b86
@ -98,9 +98,6 @@ public:
|
||||
virtual void activate();
|
||||
virtual bool loadUrl( const QString& url );
|
||||
|
||||
// because QApplication::arguments() is expensive
|
||||
bool scrubFriendlyName() const { return m_scrubFriendlyName; }
|
||||
|
||||
public slots:
|
||||
void instanceStarted( KDSingleApplicationGuard::Instance );
|
||||
|
||||
|
@ -35,7 +35,7 @@ if (APPLE)
|
||||
# We have to change the URL in the Info.plist file :-/
|
||||
FILE(READ ${CMAKE_SOURCE_DIR}/admin/mac/Info.plist plist)
|
||||
STRING( REPLACE "TOMAHAWK_VERSION"
|
||||
${VERSION}
|
||||
${TOMAHAWK_VERSION}
|
||||
edited_plist # save in this variable
|
||||
"${plist}" # from the contents of this var
|
||||
)
|
||||
|
@ -33,8 +33,6 @@ ENDIF()
|
||||
#ENDFOREACH( moddir )
|
||||
|
||||
SET( tomahawkSources ${tomahawkSources}
|
||||
sip/SipHandler.cpp
|
||||
|
||||
web/api_v1.cpp
|
||||
|
||||
resolvers/scriptresolver.cpp
|
||||
@ -72,7 +70,6 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui}
|
||||
SET( tomahawkHeaders ${tomahawkHeaders}
|
||||
"${TOMAHAWK_INC_DIR}/tomahawk/tomahawkapp.h"
|
||||
|
||||
sip/SipHandler.h
|
||||
|
||||
web/api_v1.h
|
||||
|
||||
|
@ -30,6 +30,7 @@ set( libSources
|
||||
viewpage.cpp
|
||||
|
||||
sip/SipPlugin.cpp
|
||||
sip/SipHandler.cpp
|
||||
|
||||
audio/audioengine.cpp
|
||||
|
||||
@ -184,6 +185,7 @@ set( libHeaders
|
||||
playlist.h
|
||||
|
||||
sip/SipPlugin.h
|
||||
sip/SipHandler.h
|
||||
|
||||
audio/audioengine.h
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "database/databasecommand_collectionstats.h"
|
||||
#include "dbsyncconnection.h"
|
||||
#include "sourcelist.h"
|
||||
#include <sip/SipHandler.h>
|
||||
|
||||
#define TCP_TIMEOUT 600
|
||||
|
||||
@ -120,6 +121,10 @@ ControlConnection::registerSource()
|
||||
Source* source = (Source*) sender();
|
||||
Q_UNUSED( source )
|
||||
Q_ASSERT( source == m_source.data() );
|
||||
|
||||
qDebug() << Q_FUNC_INFO << "Setting avatar ... " << name() << !SipHandler::instance()->avatar( name() ).isNull();
|
||||
source->setAvatar( SipHandler::instance()->avatar( name() ) );
|
||||
|
||||
// .. but we'll use the shared pointer we've already made:
|
||||
|
||||
m_registered = true;
|
||||
|
@ -44,6 +44,8 @@ public:
|
||||
|
||||
DBSyncConnection* dbSyncConnection();
|
||||
|
||||
Tomahawk::source_ptr source() const { return m_source; }
|
||||
|
||||
protected:
|
||||
virtual void setup();
|
||||
|
||||
|
@ -41,7 +41,7 @@ PortFwdThread::~PortFwdThread()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << "waiting for event loop to finish...";
|
||||
quit();
|
||||
wait( 10000 );
|
||||
wait( 1000 );
|
||||
|
||||
delete m_portfwd;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
*
|
||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
@ -24,19 +24,33 @@
|
||||
#include <QPluginLoader>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "functimeout.h"
|
||||
|
||||
#include "database/database.h"
|
||||
#include "network/controlconnection.h"
|
||||
#include "sourcelist.h"
|
||||
#include "tomahawksettings.h"
|
||||
#include "tomahawk/tomahawkapp.h"
|
||||
//#include "tomahawk/tomahawkapp.h"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
//remove
|
||||
#include <QLabel>
|
||||
|
||||
SipHandler* SipHandler::s_instance = 0;
|
||||
|
||||
SipHandler* SipHandler::instance()
|
||||
{
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
SipHandler::SipHandler( QObject* parent )
|
||||
: QObject( parent )
|
||||
, m_connected( false )
|
||||
{
|
||||
s_instance = this;
|
||||
|
||||
loadPlugins( findPlugins() );
|
||||
|
||||
connect( TomahawkSettings::instance(), SIGNAL( changed() ), SLOT( onSettingsChanged() ) );
|
||||
@ -55,6 +69,23 @@ SipHandler::plugins() const
|
||||
return m_plugins;
|
||||
}
|
||||
|
||||
const QPixmap SipHandler::avatar( const QString& name ) const
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << "Getting avatar" << name << m_usernameAvatars.keys();
|
||||
if( m_usernameAvatars.keys().contains( name ) )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << "Getting avatar and avatar != null ";
|
||||
Q_ASSERT(!m_usernameAvatars.value( name ).isNull());
|
||||
return m_usernameAvatars.value( name );
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << "Getting avatar and avatar == null, GAAAAAH ";
|
||||
return QPixmap();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
SipHandler::onSettingsChanged()
|
||||
@ -147,6 +178,8 @@ SipHandler::loadPlugin( const QString& path )
|
||||
QObject::connect( sip, SIGNAL( disconnected() ), SIGNAL( disconnected() ) );
|
||||
QObject::connect( sip, SIGNAL( error( int, QString ) ), SLOT( onError( int, QString ) ) );
|
||||
|
||||
QObject::connect( sip, SIGNAL( avatarReceived( QString, QPixmap ) ), SLOT( onAvatarReceived( QString, QPixmap ) ) );
|
||||
QObject::connect( sip, SIGNAL( avatarReceived( QPixmap ) ), SLOT( onAvatarReceived( QPixmap ) ) );
|
||||
m_plugins << sip;
|
||||
}
|
||||
}
|
||||
@ -182,7 +215,8 @@ SipHandler::connectPlugins( bool startup, const QString &pluginName )
|
||||
if ( !TomahawkSettings::instance()->acceptedLegalWarning() )
|
||||
{
|
||||
int result = QMessageBox::question(
|
||||
TomahawkApp::instance()->mainWindow(), tr( "Legal Warning" ),
|
||||
//TomahawkApp::instance()->mainWindow(),
|
||||
0, tr( "Legal Warning" ),
|
||||
tr( "By pressing OK below, you agree that your use of Tomahawk will be in accordance with any applicable laws, including copyright and intellectual property laws, in effect in your country of residence, and indemnify the Tomahawk developers and project from liability should you choose to break those laws.\n\nFor more information, please see http://gettomahawk.com/legal" ),
|
||||
tr( "I Do Not Agree" ), tr( "I Agree" )
|
||||
);
|
||||
@ -346,3 +380,41 @@ SipHandler::onError( int code, const QString& msg )
|
||||
QTimer::singleShot( 10000, sip, SLOT( connectPlugin() ) );
|
||||
}
|
||||
}
|
||||
|
||||
void SipHandler::onAvatarReceived( const QString& from, const QPixmap& avatar )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << "Set avatar on source for " << from;
|
||||
Q_ASSERT(!avatar.isNull());
|
||||
|
||||
m_usernameAvatars.insert( from, avatar );
|
||||
|
||||
//
|
||||
|
||||
//Tomahawk::source_ptr source = ->source();
|
||||
ControlConnection *conn = Servent::instance()->lookupControlConnection( from );
|
||||
if( conn )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << from << "got control connection";
|
||||
Tomahawk::source_ptr source = conn->source();
|
||||
if( source )
|
||||
{
|
||||
|
||||
qDebug() << Q_FUNC_INFO << from << "got source, setting avatar";
|
||||
source->setAvatar( avatar );
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << from << "no source found, not setting avatar";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << from << "no control connection setup yet";
|
||||
}
|
||||
}
|
||||
|
||||
void SipHandler::onAvatarReceived( const QPixmap& avatar )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << "Set own avatar on MyCollection";
|
||||
SourceList::instance()->getLocal()->setAvatar( avatar );
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
*
|
||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
@ -20,22 +20,28 @@
|
||||
#define SIPHANDLER_H
|
||||
|
||||
#include "sip/SipPlugin.h"
|
||||
#include "dllmacro.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QObject>
|
||||
#include <QHash>
|
||||
#include <QPixmap>
|
||||
#include <QString>
|
||||
|
||||
class SipHandler : public QObject
|
||||
class DLLEXPORT SipHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
// static SipHandler* instance() { return s_instance ? s_instance : new SipHandler(); }
|
||||
static SipHandler* instance();
|
||||
|
||||
SipHandler( QObject* parent );
|
||||
~SipHandler();
|
||||
|
||||
QList< SipPlugin* > plugins() const;
|
||||
|
||||
const QPixmap avatar( const QString& name ) const;
|
||||
|
||||
public slots:
|
||||
void addContact( const QString& id ) { qDebug() << Q_FUNC_INFO << id; }
|
||||
|
||||
@ -57,7 +63,16 @@ private slots:
|
||||
|
||||
void onSettingsChanged();
|
||||
|
||||
// set data for local source
|
||||
void onAvatarReceived( const QPixmap& avatar );
|
||||
|
||||
// set data for other sources
|
||||
void onAvatarReceived( const QString& from, const QPixmap& avatar );
|
||||
|
||||
|
||||
private:
|
||||
static SipHandler *s_instance;
|
||||
|
||||
QStringList findPlugins();
|
||||
bool pluginLoaded( const QString& name ) const;
|
||||
|
||||
@ -66,6 +81,9 @@ private:
|
||||
|
||||
QList< SipPlugin* > m_plugins;
|
||||
bool m_connected;
|
||||
|
||||
|
||||
QHash<QString, QPixmap> m_usernameAvatars;
|
||||
};
|
||||
|
||||
#endif
|
@ -57,7 +57,14 @@ signals:
|
||||
void peerOnline( const QString& );
|
||||
void peerOffline( const QString& );
|
||||
void msgReceived( const QString& from, const QString& msg );
|
||||
|
||||
|
||||
// new data for own source
|
||||
void avatarReceived ( const QPixmap& avatar );
|
||||
|
||||
// new data for other sources;
|
||||
void avatarReceived ( const QString& from, const QPixmap& avatar);
|
||||
|
||||
|
||||
void addMenu( QMenu* menu );
|
||||
void removeMenu( QMenu* menu );
|
||||
};
|
||||
|
@ -27,6 +27,8 @@
|
||||
#include "database/databasecommand_logplayback.h"
|
||||
#include "database/database.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
|
||||
@ -40,6 +42,8 @@ Source::Source( int id, const QString& username )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << id << username;
|
||||
|
||||
m_scrubFriendlyName = qApp->arguments().contains( "--demo" );
|
||||
|
||||
if ( id == 0 )
|
||||
{
|
||||
m_isLocal = true;
|
||||
@ -98,8 +102,8 @@ Source::friendlyName() const
|
||||
return m_username;
|
||||
|
||||
//TODO: this is a terrible assumption, help me clean this up, mighty muesli!
|
||||
if ( m_friendlyname.contains( "@conference.") )
|
||||
return QString(m_friendlyname).remove( 0, m_friendlyname.lastIndexOf( "/" )+1 ).append(" via MUC");
|
||||
if ( m_friendlyname.contains( "@conference." ) )
|
||||
return QString( m_friendlyname ).remove( 0, m_friendlyname.lastIndexOf( "/" ) + 1 ).append( " via MUC" );
|
||||
|
||||
if ( m_friendlyname.contains( "/tomahawk" ) )
|
||||
return m_friendlyname.left( m_friendlyname.indexOf( "/tomahawk" ) );
|
||||
@ -107,6 +111,25 @@ Source::friendlyName() const
|
||||
return m_friendlyname;
|
||||
}
|
||||
|
||||
void Source::setAvatar(const QPixmap& avatar)
|
||||
{
|
||||
m_avatar = avatar;
|
||||
}
|
||||
|
||||
const QPixmap Source::avatar() const
|
||||
{
|
||||
return m_avatar;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Source::setFriendlyName( const QString& fname )
|
||||
{
|
||||
m_friendlyname = fname;
|
||||
if ( m_scrubFriendlyName )
|
||||
m_friendlyname = m_friendlyname.split( "@" ).first();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Source::addCollection( const collection_ptr& c )
|
||||
@ -164,7 +187,7 @@ Source::dbLoaded( unsigned int id, const QString& fname )
|
||||
qDebug() << Q_FUNC_INFO << id << fname;
|
||||
|
||||
m_id = id;
|
||||
m_friendlyname = fname;
|
||||
setFriendlyName( fname );
|
||||
|
||||
emit syncedWithDatabase();
|
||||
}
|
||||
@ -225,10 +248,7 @@ Source::onStateChanged( DBSyncConnection::State newstate, DBSyncConnection::Stat
|
||||
unsigned int
|
||||
Source::trackCount() const
|
||||
{
|
||||
if ( m_stats.contains( "numfiles" ) )
|
||||
return m_stats.value( "numfiles" ).toUInt();
|
||||
else
|
||||
return 0;
|
||||
return m_stats.value( "numfiles" ).toUInt();
|
||||
}
|
||||
|
||||
|
||||
|
@ -53,7 +53,9 @@ public:
|
||||
|
||||
QString userName() const { return m_username; }
|
||||
QString friendlyName() const;
|
||||
void setFriendlyName( const QString& fname ) { m_friendlyname = fname; }
|
||||
void setFriendlyName( const QString& fname );
|
||||
void setAvatar(const QPixmap &avatar);
|
||||
const QPixmap avatar() const;
|
||||
|
||||
collection_ptr collection() const;
|
||||
void addCollection( const Tomahawk::collection_ptr& c );
|
||||
@ -111,11 +113,14 @@ private:
|
||||
QList< QSharedPointer<Collection> > m_collections;
|
||||
QVariantMap m_stats;
|
||||
QString m_lastOpGuid;
|
||||
bool m_scrubFriendlyName;
|
||||
|
||||
Tomahawk::query_ptr m_currentTrack;
|
||||
QString m_textStatus;
|
||||
|
||||
ControlConnection* m_cc;
|
||||
|
||||
QPixmap m_avatar;
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -11,6 +11,7 @@ set( jabberSources
|
||||
jabber_p.cpp
|
||||
tomahawksipmessage.cpp
|
||||
tomahawksipmessagefactory.cpp
|
||||
avatarmanager.cpp
|
||||
)
|
||||
|
||||
set( jabberHeaders
|
||||
@ -18,6 +19,7 @@ set( jabberHeaders
|
||||
jabber_p.h
|
||||
tomahawksipmessage.h
|
||||
tomahawksipmessagefactory.h
|
||||
avatarmanager.h
|
||||
)
|
||||
|
||||
include_directories( . ${CMAKE_CURRENT_BINARY_DIR} ..
|
||||
|
171
src/sip/jreen/avatarmanager.cpp
Normal file
171
src/sip/jreen/avatarmanager.cpp
Normal file
@ -0,0 +1,171 @@
|
||||
#include "avatarmanager.h"
|
||||
|
||||
|
||||
#include "utils/tomahawkutils.h"
|
||||
|
||||
#include <jreen/vcard.h>
|
||||
#include <jreen/vcardupdate.h>
|
||||
#include <jreen/presence.h>
|
||||
|
||||
#include <QDir>
|
||||
#include <QDebug>
|
||||
#include <QCryptographicHash>
|
||||
#include <QPixmap>
|
||||
|
||||
AvatarManager::AvatarManager(Jreen::Client *client) :
|
||||
m_cacheDir(TomahawkUtils::appDataDir().absolutePath().append("/jreen/"))
|
||||
{
|
||||
m_client = client;
|
||||
|
||||
m_cachedAvatars = m_cacheDir.entryList();
|
||||
|
||||
connect(m_client, SIGNAL(serverFeaturesReceived(QSet<QString>)), SLOT(onNewConnection()));
|
||||
connect(m_client, SIGNAL(newPresence(Jreen::Presence)), SLOT(onNewPresence(Jreen::Presence)));
|
||||
connect(m_client, SIGNAL(newIQ(Jreen::IQ)), SLOT(onNewIq(Jreen::IQ)));
|
||||
|
||||
connect(this, SIGNAL(newAvatar(QString)), SLOT(onNewAvatar(QString)));
|
||||
}
|
||||
|
||||
AvatarManager::~AvatarManager()
|
||||
{
|
||||
}
|
||||
|
||||
void AvatarManager::onNewConnection()
|
||||
{
|
||||
fetchVCard( m_client->jid().bare() );
|
||||
}
|
||||
|
||||
|
||||
void AvatarManager::fetchVCard(const QString &jid)
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
Jreen::IQ iq(Jreen::IQ::Get, jid );
|
||||
iq.addExtension(new Jreen::VCard());
|
||||
m_client->send( iq, this, SLOT( onNewIq( Jreen::IQ, int ) ), 0 );
|
||||
}
|
||||
|
||||
void AvatarManager::onNewPresence(const Jreen::Presence& presence)
|
||||
{
|
||||
Jreen::VCardUpdate::Ptr update = presence.findExtension<Jreen::VCardUpdate>();
|
||||
if(update)
|
||||
{
|
||||
qDebug() << "vcard: found update for " << presence.from().full();
|
||||
if(!isCached(update->photoHash()))
|
||||
{
|
||||
qDebug() << presence.from().full() << "vcard: photo not cached, starting request..." << update->photoHash();
|
||||
fetchVCard( presence.from().bare() );
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << presence.from().full() << "vcard: photo already cached no request necessary " << update->photoHash();
|
||||
m_JidsAvatarHashes.insert( update->photoHash(), presence.from().bare() );
|
||||
|
||||
Q_ASSERT(!this->avatar(presence.from().bare()).isNull());
|
||||
emit newAvatar(presence.from().bare());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << presence.from().full() << "got no statusupdateextension";
|
||||
|
||||
//TODO: do we want this? might fetch avatars for broken clients
|
||||
fetchVCard( presence.from().bare() );
|
||||
}
|
||||
}
|
||||
|
||||
void AvatarManager::onNewIq(const Jreen::IQ& iq, int context)
|
||||
{
|
||||
Jreen::VCard *vcard = iq.findExtension<Jreen::VCard>().data();
|
||||
if(vcard)
|
||||
{
|
||||
iq.accept();
|
||||
|
||||
qDebug() << Q_FUNC_INFO << "Got vcard from " << iq.from().full();
|
||||
|
||||
QString id = iq.from().full();
|
||||
QString avatarHash;
|
||||
|
||||
const Jreen::VCard::Photo &photo = vcard->photo();
|
||||
if (!photo.data().isEmpty()) {
|
||||
qDebug() << "vcard: got photo data" << id;
|
||||
|
||||
avatarHash = QCryptographicHash::hash(photo.data(), QCryptographicHash::Sha1).toHex();
|
||||
|
||||
if (!m_cacheDir.exists())
|
||||
m_cacheDir.mkpath( avatarDir( avatarHash ).absolutePath() );
|
||||
|
||||
|
||||
QFile file(avatarPath(avatarHash));
|
||||
if (file.open(QIODevice::WriteOnly)) {
|
||||
file.write(photo.data());
|
||||
file.close();
|
||||
}
|
||||
|
||||
m_cachedAvatars.append(avatarHash);
|
||||
m_JidsAvatarHashes.insert( avatarHash, iq.from().bare() );
|
||||
|
||||
Q_ASSERT(!this->avatar(iq.from().bare()).isNull());
|
||||
emit newAvatar(iq.from().bare());
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "vcard: got no photo data" << id;
|
||||
}
|
||||
|
||||
// got own presence
|
||||
if ( m_client->jid().bare() == id )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << "got own vcard";
|
||||
|
||||
Jreen::Presence presence = m_client->presence();
|
||||
Jreen::VCardUpdate::Ptr update = presence.findExtension<Jreen::VCardUpdate>();
|
||||
if (update->photoHash() != avatarHash)
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << "Updating own presence...";
|
||||
|
||||
update->setPhotoHash(avatarHash);
|
||||
m_client->send(presence);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QPixmap AvatarManager::avatar(const QString &jid) const
|
||||
{
|
||||
if( isCached( avatarHash( jid ) ) )
|
||||
{
|
||||
return QPixmap( avatarPath( avatarHash( jid ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return QPixmap();
|
||||
}
|
||||
}
|
||||
|
||||
QString AvatarManager::avatarHash(const QString &jid) const
|
||||
{
|
||||
//qDebug() << Q_FUNC_INFO << jid << m_JidsAvatarHashes.key(jid);
|
||||
return m_JidsAvatarHashes.key(jid);
|
||||
}
|
||||
|
||||
QDir AvatarManager::avatarDir(const QString &avatarHash) const
|
||||
{
|
||||
return m_cacheDir;
|
||||
}
|
||||
|
||||
QString AvatarManager::avatarPath(const QString &avatarHash) const
|
||||
{
|
||||
Q_ASSERT(!avatarHash.contains("@"));
|
||||
return avatarDir(avatarHash).absoluteFilePath(avatarHash);
|
||||
}
|
||||
|
||||
bool AvatarManager::isCached(const QString &avatarHash) const
|
||||
{
|
||||
return m_cachedAvatars.contains( avatarHash );
|
||||
}
|
||||
|
||||
void AvatarManager::onNewAvatar(const QString& jid)
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << "Found new Avatar..." << jid;
|
||||
}
|
43
src/sip/jreen/avatarmanager.h
Normal file
43
src/sip/jreen/avatarmanager.h
Normal file
@ -0,0 +1,43 @@
|
||||
#ifndef AVATARMANAGER_H
|
||||
#define AVATARMANAGER_H
|
||||
|
||||
#include <jreen/client.h>
|
||||
|
||||
#include <QObject>
|
||||
#include <QDir>
|
||||
|
||||
|
||||
class AvatarManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AvatarManager(Jreen::Client *client);
|
||||
virtual ~AvatarManager();
|
||||
|
||||
QPixmap avatar(const QString &jid) const;
|
||||
|
||||
signals:
|
||||
void newAvatar( const QString &jid );
|
||||
|
||||
private slots:
|
||||
void onNewPresence( const Jreen::Presence& presence );
|
||||
void onNewIq(const Jreen::IQ &iq, int context = 0 );
|
||||
void onNewConnection();
|
||||
void onNewAvatar( const QString &jid );
|
||||
|
||||
private:
|
||||
void fetchVCard( const QString &jid);
|
||||
QString avatarHash(const QString &jid) const;
|
||||
QString avatarPath(const QString &avatarHash) const;
|
||||
|
||||
QDir avatarDir(const QString &avatarHash) const;
|
||||
bool isCached(const QString &avatarHash) const;
|
||||
|
||||
Jreen::Client *m_client;
|
||||
QStringList m_cachedAvatars;
|
||||
QDir m_cacheDir;
|
||||
QMap<QString, QString> m_JidsAvatarHashes;
|
||||
};
|
||||
|
||||
#endif // AVATARMANAGER_H
|
@ -110,6 +110,8 @@ JabberPlugin::connectPlugin( bool startup )
|
||||
QObject::connect( p, SIGNAL( disconnected() ), SLOT( onDisconnected() ) );
|
||||
|
||||
QObject::connect( p, SIGNAL( authError( int, QString ) ), SLOT( onAuthError( int, QString ) ) );
|
||||
QObject::connect( p, SIGNAL( avatarReceived( QString, QPixmap ) ), SIGNAL( avatarReceived( QString, QPixmap ) ) );
|
||||
QObject::connect( p, SIGNAL( avatarReceived( QPixmap ) ), SIGNAL( avatarReceived( QPixmap) ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -25,6 +25,8 @@
|
||||
#include "utils/tomahawkutils.h"
|
||||
|
||||
#include <jreen/capabilities.h>
|
||||
#include <jreen/vcardupdate.h>
|
||||
#include <jreen/vcard.h>
|
||||
|
||||
#include <qjson/parser.h>
|
||||
#include <qjson/serializer.h>
|
||||
@ -37,6 +39,14 @@
|
||||
#include <QThread>
|
||||
#include <QVariant>
|
||||
#include <QMap>
|
||||
#include <QCryptographicHash>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QPixmap>
|
||||
|
||||
//remove
|
||||
#include <QLabel>
|
||||
#include <QtGui/QLabel>
|
||||
|
||||
#define TOMAHAWK_FEATURE QLatin1String( "tomahawk:sip:v1" )
|
||||
|
||||
@ -57,6 +67,12 @@ Jabber_p::Jabber_p( const QString& jid, const QString& password, const QString&
|
||||
m_client->registerStanzaExtension(new TomahawkSipMessageFactory);
|
||||
m_client->setResource( QString( "tomahawk%1" ).arg( QString::number( qrand() % 10000 ) ) );
|
||||
|
||||
// add VCardUpdate extension to own presence
|
||||
m_client->presence().addExtension( new Jreen::VCardUpdate() );
|
||||
|
||||
// initialize the AvatarManager
|
||||
m_avatarManager = new AvatarManager(m_client);
|
||||
|
||||
// setup disco
|
||||
m_client->disco()->setSoftwareVersion( "Tomahawk Player", TOMAHAWK_VERSION, CMAKE_SYSTEM );
|
||||
m_client->disco()->addIdentity( Jreen::Disco::Identity( "client", "type", "tomahawk", "en" ) );
|
||||
@ -80,6 +96,8 @@ Jabber_p::Jabber_p( const QString& jid, const QString& password, const QString&
|
||||
connect(m_client, SIGNAL(newPresence(Jreen::Presence)), SLOT(onNewPresence(Jreen::Presence)));
|
||||
connect(m_client, SIGNAL(newIQ(Jreen::IQ)), SLOT(onNewIq(Jreen::IQ)));
|
||||
|
||||
connect(m_avatarManager, SIGNAL(newAvatar(QString)), SLOT(onNewAvatar(QString)));
|
||||
|
||||
|
||||
// connect
|
||||
qDebug() << "Connecting to the XMPP server...";
|
||||
@ -329,6 +347,7 @@ void Jabber_p::onNewPresence( const Jreen::Presence& presence)
|
||||
Jreen::JID jid = presence.from();
|
||||
QString fulljid( jid.full() );
|
||||
|
||||
|
||||
qDebug() << Q_FUNC_INFO << "* New presence: " << fulljid << presence.subtype();
|
||||
|
||||
if( jid == m_jid )
|
||||
@ -411,11 +430,18 @@ Jabber_p::onNewIq( const Jreen::IQ &iq, int context )
|
||||
{
|
||||
qDebug() << "Sent SipMessage... what now?!";
|
||||
}
|
||||
/*else if(context == RequestedVCard )
|
||||
{
|
||||
qDebug() << "Requested VCard... what now?!";
|
||||
}*/
|
||||
else
|
||||
{
|
||||
|
||||
TomahawkSipMessage *sipMessage = iq.findExtension<TomahawkSipMessage>().data();
|
||||
if(sipMessage)
|
||||
{
|
||||
iq.accept();
|
||||
|
||||
qDebug() << Q_FUNC_INFO << "Got SipMessage ...";
|
||||
qDebug() << "ip" << sipMessage->ip();
|
||||
qDebug() << "port" << sipMessage->port();
|
||||
@ -466,8 +492,10 @@ Jabber_p::presenceMeansOnline( Jreen::Presence::Type p )
|
||||
}
|
||||
|
||||
void
|
||||
Jabber_p::handlePeerStatus( const QString& fulljid, Jreen::Presence::Type presenceType )
|
||||
Jabber_p::handlePeerStatus( const Jreen::JID& jid, Jreen::Presence::Type presenceType )
|
||||
{
|
||||
QString fulljid = jid.full();
|
||||
|
||||
// "going offline" event
|
||||
if ( !presenceMeansOnline( presenceType ) &&
|
||||
( !m_peers.contains( fulljid ) ||
|
||||
@ -497,7 +525,12 @@ Jabber_p::handlePeerStatus( const QString& fulljid, Jreen::Presence::Type presen
|
||||
{
|
||||
m_peers[ fulljid ] = presenceType;
|
||||
qDebug() << Q_FUNC_INFO << "* Peer goes online:" << fulljid;
|
||||
|
||||
emit peerOnline( fulljid );
|
||||
|
||||
if(!m_avatarManager->avatar(jid.bare()).isNull())
|
||||
onNewAvatar( jid.bare() );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -505,3 +538,25 @@ Jabber_p::handlePeerStatus( const QString& fulljid, Jreen::Presence::Type presen
|
||||
m_peers[ fulljid ] = presenceType;
|
||||
}
|
||||
|
||||
void Jabber_p::onNewAvatar(const QString& jid)
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << jid;
|
||||
Q_ASSERT(!m_avatarManager->avatar( jid ).isNull());
|
||||
|
||||
// find peers for the jid
|
||||
QStringList peers = m_peers.keys();
|
||||
foreach(const QString &peer, peers)
|
||||
{
|
||||
if( peer.startsWith(jid) )
|
||||
{
|
||||
emit avatarReceived ( peer, m_avatarManager->avatar( jid ) );
|
||||
}
|
||||
}
|
||||
|
||||
if( jid == m_client->jid().bare() )
|
||||
// own avatar
|
||||
emit avatarReceived ( m_avatarManager->avatar( jid ) );
|
||||
else
|
||||
// someone else's avatar
|
||||
emit avatarReceived ( jid, m_avatarManager->avatar( jid ) );
|
||||
}
|
||||
|
@ -22,6 +22,8 @@
|
||||
|
||||
#include "../sipdllmacro.h"
|
||||
|
||||
#include "avatarmanager.h"
|
||||
|
||||
#include <jreen/client.h>
|
||||
#include <jreen/disco.h>
|
||||
#include <jreen/message.h>
|
||||
@ -63,6 +65,8 @@ signals:
|
||||
void connected();
|
||||
void disconnected();
|
||||
void jidChanged( const QString& );
|
||||
void avatarReceived( const QPixmap& avatar );
|
||||
void avatarReceived( const QString&, const QPixmap& avatar );
|
||||
void authError( int, const QString& );
|
||||
|
||||
public slots:
|
||||
@ -82,10 +86,11 @@ private slots:
|
||||
qDebug() << e;
|
||||
}
|
||||
virtual void onNewIq( const Jreen::IQ &iq, int context = NoContext );
|
||||
virtual void onNewAvatar( const QString &jid );
|
||||
|
||||
private:
|
||||
bool presenceMeansOnline( Jreen::Presence::Type p );
|
||||
void handlePeerStatus( const QString &fulljid, Jreen::Presence::Type presenceType );
|
||||
void handlePeerStatus( const Jreen::JID &jid, Jreen::Presence::Type presenceType );
|
||||
|
||||
Jreen::Client *m_client;
|
||||
Jreen::MUCRoom *m_room;
|
||||
@ -95,9 +100,11 @@ private:
|
||||
QMap<QString, Jreen::Presence::Type> m_peers;
|
||||
QString m_server;
|
||||
|
||||
enum IqContext { NoContext, RequestDisco, RequestedDisco, SipMessageSent };
|
||||
enum IqContext { NoContext, RequestDisco, RequestedDisco, SipMessageSent, RequestedVCard };
|
||||
|
||||
QStringList m_legacy_peers;
|
||||
|
||||
AvatarManager *m_avatarManager;
|
||||
};
|
||||
|
||||
#endif // JABBER_H
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
*
|
||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
@ -46,14 +46,9 @@ SourceTreeItem::SourceTreeItem( const source_ptr& source, QObject* parent )
|
||||
QString name;
|
||||
if( source.isNull() )
|
||||
name = tr( "Super Collection" );
|
||||
else
|
||||
{
|
||||
if( TomahawkApp::instance()->scrubFriendlyName() && source->friendlyName().contains( '@' ) )
|
||||
name = source->friendlyName().left( source->friendlyName().indexOf( '@' ) );
|
||||
else
|
||||
name = source->friendlyName();
|
||||
}
|
||||
|
||||
else
|
||||
name = source->friendlyName();
|
||||
|
||||
QStandardItem* item = new QStandardItem( name );
|
||||
item->setIcon( QIcon( RESPATH "images/user-avatar.png" ) );
|
||||
item->setEditable( false );
|
||||
@ -114,7 +109,7 @@ SourceTreeItem::onPlaylistsAdded( const QList<playlist_ptr>& playlists )
|
||||
{
|
||||
// const-ness is important for getting the right pointer!
|
||||
foreach( const playlist_ptr& p, playlists )
|
||||
{
|
||||
{
|
||||
m_playlists.append( p );
|
||||
qlonglong ptr = reinterpret_cast<qlonglong>( &m_playlists.last() );
|
||||
|
||||
|
@ -537,17 +537,23 @@ SourceDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, co
|
||||
|
||||
SourceTreeItem* sti = SourcesModel::indexToTreeItem( index );
|
||||
bool status = !( !sti || sti->source().isNull() || !sti->source()->isOnline() );
|
||||
QPixmap avatar( RESPATH "images/user-avatar.png" );
|
||||
QString tracks;
|
||||
QString name = index.data().toString();
|
||||
int figWidth = 0;
|
||||
|
||||
if ( status )
|
||||
if ( status && sti && !sti->source().isNull() )
|
||||
{
|
||||
tracks = QString::number( sti->source()->trackCount() );
|
||||
figWidth = painter->fontMetrics().width( tracks );
|
||||
|
||||
name = sti->source()->friendlyName();
|
||||
if ( !sti->source()->avatar().isNull() )
|
||||
avatar = sti->source()->avatar();
|
||||
}
|
||||
|
||||
QRect iconRect = option.rect.adjusted( 4, 6, -option.rect.width() + option.rect.height() - 12 + 4, -6 );
|
||||
painter->drawPixmap( iconRect, QPixmap( RESPATH "images/user-avatar.png" ).scaledToHeight( iconRect.height(), Qt::SmoothTransformation ) );
|
||||
painter->drawPixmap( iconRect, avatar.scaledToHeight( iconRect.height(), Qt::SmoothTransformation ) );
|
||||
|
||||
if ( ( option.state & QStyle::State_Selected ) == QStyle::State_Selected )
|
||||
{
|
||||
@ -557,7 +563,7 @@ SourceDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, co
|
||||
QRect textRect = option.rect.adjusted( iconRect.width() + 8, 6, -figWidth - 24, 0 );
|
||||
if ( status || sti->source().isNull() )
|
||||
painter->setFont( bold );
|
||||
QString text = painter->fontMetrics().elidedText( index.data().toString(), Qt::ElideRight, textRect.width() );
|
||||
QString text = painter->fontMetrics().elidedText( name, Qt::ElideRight, textRect.width() );
|
||||
painter->drawText( textRect, text );
|
||||
|
||||
QString desc = status ? sti->source()->textStatus() : tr( "Offline" );
|
||||
|
@ -150,7 +150,6 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] )
|
||||
, m_sipHandler( 0 )
|
||||
, m_servent( 0 )
|
||||
, m_shortcutHandler( 0 )
|
||||
, m_scrubFriendlyName( false )
|
||||
, m_mainwindow( 0 )
|
||||
{
|
||||
qDebug() << "TomahawkApp thread:" << this->thread();
|
||||
@ -193,7 +192,6 @@ TomahawkApp::init()
|
||||
qDebug() << "Init Echonest Factory.";
|
||||
GeneratorFactory::registerFactory( "echonest", new EchonestFactory );
|
||||
|
||||
m_scrubFriendlyName = arguments().contains( "--demo" );
|
||||
// Register shortcut handler for this platform
|
||||
#ifdef Q_WS_MAC
|
||||
m_shortcutHandler = new MacShortcutHandler( this );
|
||||
|
Loading…
x
Reference in New Issue
Block a user