1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-11 16:44:05 +02:00

Merge remote-tracking branch 'origin/master' into sourcelistrefactor

Conflicts:
	src/sourcetree/sourcetreeitem.cpp
	src/sourcetree/sourcetreeview.cpp
	thirdparty/jreen
This commit is contained in:
Leo Franchi
2011-04-21 11:32:14 -04:00
38 changed files with 1127 additions and 289 deletions

View File

@@ -8,10 +8,10 @@ ENDIF( ${CMAKE_VERSION} VERSION_GREATER 2.8.3 )
###
### Tomahawk application info
###
SET( ORGANIZATION_NAME "Tomahawk" )
SET( ORGANIZATION_DOMAIN "tomahawk-player.org" )
SET( APPLICATION_NAME "Tomahawk" )
SET( VERSION "0.0.3" )
SET( TOMAHAWK_ORGANIZATION_NAME "Tomahawk" )
SET( TOMAHAWK_ORGANIZATION_DOMAIN "tomahawk-player.org" )
SET( TOMAHAWK_APPLICATION_NAME "Tomahawk" )
SET( TOMAHAWK_VERSION "0.0.3" )
# set paths
@@ -50,6 +50,28 @@ macro_log_feature(QJSON_FOUND "QJson" "Qt library that maps JSON data to QVarian
macro_optional_find_package(Taglib 1.6.0)
macro_log_feature(TAGLIB_FOUND "TagLib" "Audio Meta-Data Library" "http://developer.kde.org/~wheeler/taglib.html" TRUE "" "taglib is needed for reading meta data from audio files")
# this installs headers and such and should really be handled in a separate package by packagers
IF( INTERNAL_JREEN )
ADD_SUBDIRECTORY( thirdparty/jreen )
SET( LIBJREEN_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/thirdparty/jreen/include )
IF( UNIX AND NOT APPLE )
SET( LIBJREEN_LIBRARY ${CMAKE_CURRENT_BINARY_DIR}/thirdparty/jreen/libjreen.so )
ENDIF( UNIX AND NOT APPLE )
IF( APPLE )
SET( LIBJREEN_LIBRARY ${CMAKE_CURRENT_BINARY_DIR}/thirdparty/jreen/libjreen.dylib )
ENDIF( APPLE )
IF( WIN32 )
SET( LIBJREEN_LIBRARY ${CMAKE_CURRENT_BINARY_DIR}/thirdparty/jreen/libjreen.dll )
ENDIF( WIN32 )
SET( LIBJREEN_FOUND true )
MESSAGE(STATUS "INTERNAL libjreen: ${LIBJREEN_INCLUDE_DIR}, ${LIBJREEN_LIBRARY}")
ELSE( INTERNAL_JREEN )
macro_optional_find_package(Jreen)
ENDIF( INTERNAL_JREEN )
macro_log_feature(LIBJREEN_FOUND "Jreen" "Qt XMPP Library" "http://gitorious.org/jreen/jreen" FALSE "" "Jreen is needed for the Jabber SIP plugin. \n\n Use -DINTERNAL_JREEN=ON to build the git submodule inside Tomahawk \n Be aware this installs a full jreen with headers and everything!")
# we need pthreads too
find_package(Threads)
@@ -65,32 +87,6 @@ ENDIF()
include( CheckTagLibFileName )
check_taglib_filename( COMPLEX_TAGLIB_FILENAME )
# optional
IF( ENABLE_JREEN )
macro_optional_find_package(Jreen)
IF( LIBJREEN_FOUND )
macro_log_feature(JREEN_FOUND "Jreen" "Qt XMPP library" "http://gitorious.org/jreen" FALSE "" "Jreen is needed for the alternative/new Jabber SIP plugin. Built automatically inside Tomahawk, if not installed systemwide and ENABLE_JREEN is true")
ELSE( LIBJREEN_FOUND )
SET( OLD_C_FLAGS ${CMAKE_C_FLAGS} )
SET( CMAKE_C_FLAGS ${CLEAN_C_FLAGS} )
ADD_SUBDIRECTORY( thirdparty/jreen )
SET( LIBJREEN_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/thirdparty/jreen/include )
IF( UNIX AND NOT APPLE )
SET( LIBJREEN_LIBRARY ${CMAKE_CURRENT_BINARY_DIR}/thirdparty/jreen/libjreen.so )
ENDIF( UNIX AND NOT APPLE )
IF( WIN32 )
SET( LIBJREEN_LIBRARY ${CMAKE_CURRENT_BINARY_DIR}/thirdparty/jreen/libjreen.dll )
ENDIF( WIN32 )
SET( LIBJREEN_FOUND true )
MESSAGE(STATUS "Internal libjreen: ${LIBJREEN_INCLUDE_DIR}, ${LIBJREEN_LIBRARY}")
SET( CMAKE_C_FLAGS ${OLD_C_FLAGS} )
ENDIF( LIBJREEN_FOUND )
ELSE( LIBJREEN_FOUND )
macro_optional_find_package(Gloox 1.0)
macro_log_feature(GLOOX_FOUND "Gloox" "A portable high-level Jabber/XMPP library for C++" "http://camaya.net/gloox" FALSE "" "Gloox is needed for the Jabber SIP plugin and the XMPP-Bot")
ENDIF( ENABLE_JREEN )
IF( WIN32 )
find_library(QTSPARKLE_LIBRARIES qtsparkle)
ENDIF( WIN32 )

View File

@@ -6,15 +6,15 @@
# LIBJREEN_FOUND, whether libjreen was found
find_path(LIBJREEN_INCLUDE_DIR NAMES jreen.h
find_path(LIBJREEN_INCLUDE_DIR NAMES jreen/jreen.h
HINTS
~/usr/include
/opt/local/include
/usr/include
/usr/local/include
/opt/kde4/include
${CMAKE_INSTALL_PREFIX}/include
${KDE4_INCLUDE_DIR}
PATH_SUFFIXES jreen
)
find_library( LIBJREEN_LIBRARY NAMES jreen
@@ -25,6 +25,8 @@ find_library( LIBJREEN_LIBRARY NAMES jreen
/usr/lib64
/usr/local/lib
/opt/kde4/lib
${CMAKE_INSTALL_PREFIX}/lib
${CMAKE_INSTALL_PREFIX}/lib64
${KDE4_LIB_DIR}
)

View File

@@ -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 );

View File

@@ -37,7 +37,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
)

View File

@@ -32,8 +32,6 @@ ENDIF()
#ENDFOREACH( moddir )
SET( tomahawkSources ${tomahawkSources}
sip/SipHandler.cpp
web/api_v1.cpp
resolvers/scriptresolver.cpp
@@ -70,7 +68,6 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui}
SET( tomahawkHeaders ${tomahawkHeaders}
"${TOMAHAWK_INC_DIR}/tomahawk/tomahawkapp.h"
sip/SipHandler.h
web/api_v1.h

View File

@@ -213,13 +213,13 @@ AudioControls::onPlaybackStarted( const Tomahawk::result_ptr& result )
onPlaybackLoading( result );
Tomahawk::InfoSystem::InfoCustomData trackInfo;
trackInfo["artist"] = QVariant::fromValue< QString >( result->artist()->name() );
trackInfo["album"] = QVariant::fromValue< QString >( result->album()->name() );
Tomahawk::InfoSystem::InfoCriteriaHash trackInfo;
trackInfo["artist"] = result->artist()->name();
trackInfo["album"] = result->album()->name();
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo(
s_acInfoIdentifier, Tomahawk::InfoSystem::InfoAlbumCoverArt,
QVariant::fromValue< Tomahawk::InfoSystem::InfoCustomData >( trackInfo ), Tomahawk::InfoSystem::InfoCustomData() );
QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ), Tomahawk::InfoSystem::InfoCustomData() );
}

View File

@@ -1,14 +1,15 @@
#ifndef CONFIG_H_IN
#define CONFIG_H_IN
#cmakedefine ORGANIZATION_NAME "${ORGANIZATION_NAME}"
#cmakedefine ORGANIZATION_DOMAIN "${ORGANIZATION_DOMAIN}"
#cmakedefine APPLICATION_NAME "${APPLICATION_NAME}"
#cmakedefine VERSION "${VERSION}"
#cmakedefine TOMAHAWK_ORGANIZATION_NAME "${TOMAHAWK_ORGANIZATION_NAME}"
#cmakedefine TOMAHAWK_ORGANIZATION_DOMAIN "${TOMAHAWK_ORGANIZATION_DOMAIN}"
#cmakedefine TOMAHAWK_APPLICATION_NAME "${TOMAHAWK_APPLICATION_NAME}"
#cmakedefine TOMAHAWK_VERSION "${TOMAHAWK_VERSION}"
#cmakedefine DEBUG_BUILD
#define CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}"
#define CMAKE_SYSTEM "${CMAKE_SYSTEM}"
#cmakedefine SNOW_LEOPARD
#cmakedefine LEOPARD

View File

@@ -30,6 +30,7 @@ set( libSources
viewmanager.cpp
sip/SipPlugin.cpp
sip/SipHandler.cpp
audio/madtranscode.cpp
audio/dummytranscode.cpp
@@ -188,6 +189,7 @@ set( libHeaders
playlist.h
sip/SipPlugin.h
sip/SipHandler.h
audio/transcodeinterface.h
audio/madtranscode.h

View File

@@ -70,7 +70,7 @@ FLACTranscode::processData( const QByteArray& data, bool finish )
m_buffer.append( data );
m_mutex.unlock();
while ( m_buffer.size() >= FLAC_BUFFER )
while ( m_buffer.size() >= FLAC_BUFFER || ( finish && !m_buffer.isEmpty() ) )
{
process_single();
}

View File

@@ -64,11 +64,11 @@ Collection::addPlaylist( const Tomahawk::playlist_ptr& p )
qDebug() << Q_FUNC_INFO;
QList<playlist_ptr> toadd;
toadd << p;
m_playlists.append( toadd );
m_playlists.insert( p->guid(), p );
qDebug() << Q_FUNC_INFO << "Collection name" << name()
<< "from source id" << source()->id()
<< "numplaylists:" << m_playlists.length();
<< "numplaylists:" << m_playlists.count();
emit playlistsAdded( toadd );
}
@@ -79,11 +79,11 @@ Collection::addDynamicPlaylist( const Tomahawk::dynplaylist_ptr& p )
qDebug() << Q_FUNC_INFO;
QList<dynplaylist_ptr> toadd;
toadd << p;
m_dynplaylists.append( toadd );
m_dynplaylists.insert( p->guid(), p );
qDebug() << Q_FUNC_INFO << "Collection name" << name()
<< "from source id" << source()->id()
<< "numplaylists:" << m_playlists.length();
<< "numplaylists:" << m_playlists.count();
emit dynamicPlaylistsAdded( toadd );
}
@@ -94,11 +94,11 @@ Collection::deletePlaylist( const Tomahawk::playlist_ptr& p )
qDebug() << Q_FUNC_INFO;
QList<playlist_ptr> todelete;
todelete << p;
m_playlists.removeAll( p );
m_playlists.remove( p->guid() );
qDebug() << Q_FUNC_INFO << "Collection name" << name()
<< "from source id" << source()->id()
<< "numplaylists:" << m_playlists.length();
<< "numplaylists:" << m_playlists.count();
emit playlistsDeleted( todelete );
}
@@ -109,11 +109,11 @@ Collection::deleteDynamicPlaylist( const Tomahawk::dynplaylist_ptr& p )
qDebug() << Q_FUNC_INFO;
QList<dynplaylist_ptr> todelete;
todelete << p;
m_dynplaylists.removeAll( p );
m_dynplaylists.remove( p->guid() );
qDebug() << Q_FUNC_INFO << "Collection name" << name()
<< "from source id" << source()->id()
<< "numplaylists:" << m_playlists.length();
<< "numplaylists:" << m_playlists.count();
emit dynamicPlaylistsDeleted( todelete );
}
@@ -121,33 +121,15 @@ Collection::deleteDynamicPlaylist( const Tomahawk::dynplaylist_ptr& p )
playlist_ptr
Collection::playlist( const QString& guid )
{
foreach( const playlist_ptr& pp, m_playlists )
{
if( pp->guid() == guid )
return pp;
}
// TODO do we really want to do this?
foreach( const dynplaylist_ptr& pp, m_dynplaylists )
{
if( pp->guid() == guid )
return pp.staticCast<Playlist>();
}
return playlist_ptr();
return m_playlists.value( guid, playlist_ptr() );
}
dynplaylist_ptr
Collection::dynamicPlaylist( const QString& guid )
{
foreach( const dynplaylist_ptr& pp, m_dynplaylists )
{
if( pp->guid() == guid )
return pp;
}
return dynplaylist_ptr();
return m_dynplaylists.value( guid, dynplaylist_ptr() );
}
@@ -155,8 +137,9 @@ void
Collection::setPlaylists( const QList<Tomahawk::playlist_ptr>& plists )
{
qDebug() << Q_FUNC_INFO << plists.count();
foreach ( const playlist_ptr& p, plists )
m_playlists.insert( p->guid(), p );
m_playlists.append( plists );
emit playlistsAdded( plists );
}
@@ -166,7 +149,8 @@ Collection::setDynamicPlaylists( const QList< Tomahawk::dynplaylist_ptr >& plist
{
qDebug() << Q_FUNC_INFO << plists.count();
m_dynplaylists.append( plists );
foreach ( const dynplaylist_ptr& p, plists )
m_dynplaylists.insert( p->guid(), p );
// emit dynamicPlaylistsAdded( plists );
}

View File

@@ -68,8 +68,8 @@ public:
virtual void addDynamicPlaylist( const Tomahawk::dynplaylist_ptr& p );
virtual void deleteDynamicPlaylist( const Tomahawk::dynplaylist_ptr& p );
virtual QList< Tomahawk::playlist_ptr > playlists() { return m_playlists; }
virtual QList< Tomahawk::dynplaylist_ptr > dynamicPlaylists() { return m_dynplaylists; }
virtual QList< Tomahawk::playlist_ptr > playlists() { return m_playlists.values(); }
virtual QList< Tomahawk::dynplaylist_ptr > dynamicPlaylists() { return m_dynplaylists.values(); }
virtual QList< Tomahawk::query_ptr > tracks() { return m_tracks; }
const source_ptr& source() const;
@@ -107,8 +107,8 @@ private:
source_ptr m_source;
QList< Tomahawk::query_ptr > m_tracks;
QList< Tomahawk::playlist_ptr > m_playlists;
QList< Tomahawk::dynplaylist_ptr > m_dynplaylists;
QHash< QString, Tomahawk::playlist_ptr > m_playlists;
QHash< QString, Tomahawk::dynplaylist_ptr > m_dynplaylists;
};
}; // ns

View File

@@ -134,12 +134,12 @@ LastFmPlugin::getInfo( const QString &caller, const InfoType type, const QVarian
void
LastFmPlugin::nowPlaying( const QString &caller, const InfoType type, const QVariant& data, Tomahawk::InfoSystem::InfoCustomData &customData )
{
if ( !data.canConvert< Tomahawk::InfoSystem::InfoCustomData >() || !m_scrobbler )
if ( !data.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() || !m_scrobbler )
{
dataError( caller, type, data, customData );
return;
}
InfoCustomData hash = data.value< Tomahawk::InfoSystem::InfoCustomData >();
InfoCriteriaHash hash = data.value< Tomahawk::InfoSystem::InfoCriteriaHash >();
if ( !hash.contains( "title" ) || !hash.contains( "artist" ) || !hash.contains( "album" ) || !hash.contains( "duration" ) )
{
dataError( caller, type, data, customData );
@@ -149,10 +149,11 @@ LastFmPlugin::nowPlaying( const QString &caller, const InfoType type, const QVar
m_track = lastfm::MutableTrack();
m_track.stamp();
m_track.setTitle( hash["title"].toString() );
m_track.setArtist( hash["artist"].toString() );
m_track.setAlbum( hash["album"].toString() );
m_track.setDuration( hash["duration"].toUInt() );
m_track.setTitle( hash["title"] );
m_track.setArtist( hash["artist"] );
m_track.setAlbum( hash["album"] );
bool ok;
m_track.setDuration( hash["duration"].toUInt( &ok ) );
m_track.setSource( lastfm::Track::Player );
m_scrobbler->nowPlaying( m_track );
@@ -183,12 +184,12 @@ void
LastFmPlugin::fetchCoverArt( const QString &caller, const InfoType type, const QVariant& data, Tomahawk::InfoSystem::InfoCustomData &customData )
{
qDebug() << Q_FUNC_INFO;
if ( !data.canConvert< Tomahawk::InfoSystem::InfoCustomData >() )
if ( !data.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() )
{
dataError( caller, type, data, customData );
return;
}
InfoCustomData hash = data.value< Tomahawk::InfoSystem::InfoCustomData >();
InfoCriteriaHash hash = data.value< Tomahawk::InfoSystem::InfoCriteriaHash >();
if ( !hash.contains( "artist" ) || !hash.contains( "album" ) )
{
dataError( caller, type, data, customData );
@@ -196,8 +197,8 @@ LastFmPlugin::fetchCoverArt( const QString &caller, const InfoType type, const Q
}
Tomahawk::InfoSystem::InfoCriteriaHash criteria;
criteria["artist"] = hash["artist"].toString();
criteria["album"] = hash["album"].toString();
criteria["artist"] = hash["artist"];
criteria["album"] = hash["album"];
emit getCachedInfo( criteria, 2419200000, caller, type, data, customData );
}
@@ -207,12 +208,12 @@ void
LastFmPlugin::fetchArtistImages( const QString &caller, const InfoType type, const QVariant& data, Tomahawk::InfoSystem::InfoCustomData &customData )
{
qDebug() << Q_FUNC_INFO;
if ( !data.canConvert< Tomahawk::InfoSystem::InfoCustomData >() )
if ( !data.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() )
{
dataError( caller, type, data, customData );
return;
}
InfoCustomData hash = data.value< Tomahawk::InfoSystem::InfoCustomData >();
InfoCriteriaHash hash = data.value< Tomahawk::InfoSystem::InfoCriteriaHash >();
if ( !hash.contains( "artist" ) )
{
dataError( caller, type, data, customData );
@@ -220,7 +221,7 @@ LastFmPlugin::fetchArtistImages( const QString &caller, const InfoType type, con
}
Tomahawk::InfoSystem::InfoCriteriaHash criteria;
criteria["artist"] = hash["artist"].toString();
criteria["artist"] = hash["artist"];
emit getCachedInfo( criteria, 2419200000, caller, type, data, customData );
}
@@ -301,10 +302,10 @@ LastFmPlugin::coverArtReturned()
customData
);
InfoCustomData origData = reply->property( "origData" ).value< Tomahawk::InfoSystem::InfoCustomData >();
InfoCriteriaHash origData = reply->property( "origData" ).value< Tomahawk::InfoSystem::InfoCriteriaHash >();
Tomahawk::InfoSystem::InfoCriteriaHash criteria;
criteria["artist"] = origData["artist"].toString();
criteria["album"] = origData["album"].toString();
criteria["artist"] = origData["artist"];
criteria["album"] = origData["album"];
emit updateCache( criteria, 2419200000, type, returnedData );
}
else
@@ -352,9 +353,9 @@ LastFmPlugin::artistImagesReturned()
customData
);
InfoCustomData origData = reply->property( "origData" ).value< Tomahawk::InfoSystem::InfoCustomData >();
InfoCriteriaHash origData = reply->property( "origData" ).value< Tomahawk::InfoSystem::InfoCriteriaHash >();
Tomahawk::InfoSystem::InfoCriteriaHash criteria;
criteria["artist"] = origData["artist"].toString();
criteria["artist"] = origData["artist"];
emit updateCache( criteria, 2419200000, type, returnedData );
}
else

View File

@@ -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;

View File

@@ -44,6 +44,8 @@ public:
DBSyncConnection* dbSyncConnection();
Tomahawk::source_ptr source() const { return m_source; }
protected:
virtual void setup();

View File

@@ -41,7 +41,7 @@ PortFwdThread::~PortFwdThread()
{
qDebug() << Q_FUNC_INFO << "waiting for event loop to finish...";
quit();
wait( 10000 );
wait( 1000 );
delete m_portfwd;
}

View File

@@ -223,12 +223,12 @@ ArtistView::onScrollTimeout()
{
TreeModelItem* item = m_model->itemFromIndex( m_proxyModel->mapToSource( m_proxyModel->index( i, 0 ) ) );
Tomahawk::InfoSystem::InfoCustomData trackInfo;
trackInfo["artist"] = QVariant::fromValue< QString >( item->artist()->name() );
trackInfo["pptr"] = QVariant::fromValue< qlonglong >( (qlonglong)item );
Tomahawk::InfoSystem::InfoCriteriaHash trackInfo;
trackInfo["artist"] = item->artist()->name();
trackInfo["pptr"] = QString::number( (qlonglong)item );
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo(
s_tmInfoIdentifier, Tomahawk::InfoSystem::InfoArtistImages,
QVariant::fromValue< Tomahawk::InfoSystem::InfoCustomData >( trackInfo ), Tomahawk::InfoSystem::InfoCustomData() );
QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ), Tomahawk::InfoSystem::InfoCustomData() );
}
}

View File

@@ -476,14 +476,14 @@ TreeModel::onAlbumsAdded( const QList<Tomahawk::album_ptr>& albums, const QVaria
albumitem->index = createIndex( parentItem->children.count() - 1, 0, albumitem );
connect( albumitem, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) );
Tomahawk::InfoSystem::InfoCustomData trackInfo;
trackInfo["artist"] = QVariant::fromValue< QString >( album->artist()->name() );
trackInfo["album"] = QVariant::fromValue< QString >( album->name() );
trackInfo["pptr"] = QVariant::fromValue< qlonglong >( (qlonglong)albumitem );
Tomahawk::InfoSystem::InfoCriteriaHash trackInfo;
trackInfo["artist"] = album->artist()->name();
trackInfo["album"] = album->name();
trackInfo["pptr"] = QString::number( (qlonglong)albumitem );
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo(
s_tmInfoIdentifier, Tomahawk::InfoSystem::InfoAlbumCoverArt,
QVariant::fromValue< Tomahawk::InfoSystem::InfoCustomData >( trackInfo ), Tomahawk::InfoSystem::InfoCustomData() );
QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ), Tomahawk::InfoSystem::InfoCustomData() );
}
if ( crows.second > 0 )
@@ -555,7 +555,7 @@ TreeModel::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type,
return;
}
Tomahawk::InfoSystem::InfoCustomData pptr = input.value< Tomahawk::InfoSystem::InfoCustomData >();
Tomahawk::InfoSystem::InfoCriteriaHash pptr = input.value< Tomahawk::InfoSystem::InfoCriteriaHash >();
Tomahawk::InfoSystem::InfoCustomData returnedData = output.value< Tomahawk::InfoSystem::InfoCustomData >();
const QByteArray ba = returnedData["imgbytes"].toByteArray();
if ( ba.length() )
@@ -563,7 +563,8 @@ TreeModel::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type,
QPixmap pm;
pm.loadFromData( ba );
qlonglong p = pptr["pptr"].toLongLong();
bool ok;
qlonglong p = pptr["pptr"].toLongLong( &ok );
TreeModelItem* ai = reinterpret_cast<TreeModelItem*>(p);
if ( pm.isNull() )

View File

@@ -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 );
}

View File

@@ -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

View File

@@ -58,6 +58,13 @@ signals:
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 );
};

View File

@@ -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;
@@ -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;
}

View File

@@ -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;
};
};

View File

@@ -74,15 +74,15 @@ Scrobbler::trackStarted( const Tomahawk::result_ptr& track )
scrobble();
}
Tomahawk::InfoSystem::InfoCustomData trackInfo;
Tomahawk::InfoSystem::InfoCriteriaHash trackInfo;
trackInfo["title"] = QVariant::fromValue< QString >( track->track() );
trackInfo["artist"] = QVariant::fromValue< QString >( track->artist()->name() );
trackInfo["album"] = QVariant::fromValue< QString >( track->album()->name() );
trackInfo["duration"] = QVariant::fromValue< uint >( track->duration() );
trackInfo["title"] = track->track();
trackInfo["artist"] = track->artist()->name();
trackInfo["album"] = track->album()->name();
trackInfo["duration"] = QString::number( track->duration() );
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo(
s_scInfoIdentifier, Tomahawk::InfoSystem::InfoMiscSubmitNowPlaying,
QVariant::fromValue< Tomahawk::InfoSystem::InfoCustomData >( trackInfo ), Tomahawk::InfoSystem::InfoCustomData() );
QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ), Tomahawk::InfoSystem::InfoCustomData() );
m_scrobblePoint = ScrobblePoint( track->duration() / 2 );
}

View File

@@ -1,10 +1,11 @@
# only build one of them, if ENABLE_JREEN is true, GLOOX_FOUND is automatically set to "false"
IF( GLOOX_FOUND )
IF( GLOOX_FOUND AND NOT LIBJREEN_FOUND )
ADD_SUBDIRECTORY( jabber )
ENDIF( GLOOX_FOUND )
IF( ENABLE_JREEN )
ENDIF( GLOOX_FOUND AND NOT LIBJREEN_FOUND )
IF( LIBJREEN_FOUND )
ADD_SUBDIRECTORY( jreen )
ENDIF( ENABLE_JREEN)
ENDIF( LIBJREEN_FOUND )
ADD_SUBDIRECTORY( twitter )
ADD_SUBDIRECTORY( zeroconf )

View File

@@ -9,11 +9,17 @@ add_definitions( -DSIPDLLEXPORT_PRO )
set( jabberSources
jabber.cpp
jabber_p.cpp
tomahawksipmessage.cpp
tomahawksipmessagefactory.cpp
avatarmanager.cpp
)
set( jabberHeaders
jabber.h
jabber_p.h
tomahawksipmessage.h
tomahawksipmessagefactory.h
avatarmanager.h
)
include_directories( . ${CMAKE_CURRENT_BINARY_DIR} ..
@@ -22,7 +28,7 @@ include_directories( . ${CMAKE_CURRENT_BINARY_DIR} ..
)
qt4_wrap_cpp( jabberMoc ${jabberHeaders} )
add_library( tomahawk_sipjreen SHARED ${jabberSources} ${jabberMoc} )
add_library( tomahawk_sipjabber SHARED ${jabberSources} ${jabberMoc} )
IF( WIN32 )
SET( OS_SPECIFIC_LINK_LIBRARIES
@@ -33,7 +39,7 @@ SET( OS_SPECIFIC_LINK_LIBRARIES
)
ENDIF( WIN32 )
target_link_libraries( tomahawk_sipjreen
target_link_libraries( tomahawk_sipjabber
${QT_LIBRARIES}
${LIBJREEN_LIBRARY}
${OS_SPECIFIC_LINK_LIBRARIES}
@@ -44,4 +50,4 @@ IF( APPLE )
# SET( CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} "-undefined dynamic_lookup" )
ENDIF( APPLE )
install( TARGETS tomahawk_sipjreen DESTINATION lib${LIB_SUFFIX} )
install( TARGETS tomahawk_sipjabber DESTINATION lib${LIB_SUFFIX} )

View 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;
}

View 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

View File

@@ -1,5 +1,6 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2010-2011, Dominik Schmidt <dev@dominik-schmidt.de>
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
@@ -105,8 +106,12 @@ JabberPlugin::connectPlugin( bool startup )
QObject::connect( p, SIGNAL( peerOffline( QString ) ), SIGNAL( peerOffline( QString ) ) );
QObject::connect( p, SIGNAL( msgReceived( QString, QString ) ), SIGNAL( msgReceived( QString, QString ) ) );
QObject::connect( p, SIGNAL( connected() ), SIGNAL( onConnected() ) );
QObject::connect( p, SIGNAL( disconnected() ), SIGNAL( onDisconnected() ) );
QObject::connect( p, SIGNAL( connected() ), SLOT( onConnected() ) );
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;
}
@@ -155,6 +160,33 @@ JabberPlugin::onDisconnected()
emit disconnected();
}
void
JabberPlugin::onAuthError( int code, const QString& msg )
{
switch( code )
{
case Jreen::Client::AuthorizationError:
emit error( SipPlugin::AuthError, msg );
break;
case Jreen::Client::HostUnknown:
case Jreen::Client::ItemNotFound:
case Jreen::Client::RemoteStreamError:
case Jreen::Client::RemoteConnectionFailed:
case Jreen::Client::InternalServerError:
case Jreen::Client::SystemShutdown:
case Jreen::Client::Conflict:
case Jreen::Client::Unknown:
emit error( SipPlugin::ConnectionError, msg );
break;
default:
qDebug() << "Not all Client::DisconnectReasons checked";
Q_ASSERT(false);
break;
}
}
void
JabberPlugin::sendMsg(const QString& to, const QString& msg)
{

View File

@@ -1,5 +1,6 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2010-2011, Dominik Schmidt <dev@dominik-schmidt.de>
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
@@ -24,7 +25,7 @@
#include "../sipdllmacro.h"
#define MYNAME "SIPJABBER"
#define MYNAME "SIPJREEN"
class SIPDLLEXPORT JabberPlugin : public SipPlugin
{
@@ -56,6 +57,7 @@ private slots:
void showAddFriendDialog();
void onConnected();
void onDisconnected();
void onAuthError(int code, const QString &msg);
private:
Jabber_p* p;

View File

@@ -1,5 +1,6 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2010-2011, Dominik Schmidt <dev@dominik-schmidt.de>
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
@@ -17,6 +18,18 @@
*/
#include "jabber_p.h"
#include "tomahawksipmessage.h"
#include "tomahawksipmessagefactory.h"
#include "config.h"
#include "utils/tomahawkutils.h"
#include <jreen/capabilities.h>
#include <jreen/vcardupdate.h>
#include <jreen/vcard.h>
#include <qjson/parser.h>
#include <qjson/serializer.h>
#include <QDebug>
#include <QTime>
@@ -24,18 +37,18 @@
#include <QString>
#include <QRegExp>
#include <QThread>
#include <utils/tomahawkutils.h>
#include <jreen/abstractroster.h>
#include <jreen/capabilities.h>
#include <QVariant>
#include <QMap>
#include <QCryptographicHash>
#include <QDir>
#include <QFile>
#include <QPixmap>
//remove
#include <QMessageBox>
#include <jreen/connection.h>
using namespace std;
#include <QLabel>
#include <QtGui/QLabel>
#define TOMAHAWK_FEATURE QLatin1String( "tomahawk:sip:v1" )
#define TOMAHAWK_CAP_NODE_NAME QLatin1String( "http://tomahawk-player.org/" )
@@ -44,38 +57,49 @@ Jabber_p::Jabber_p( const QString& jid, const QString& password, const QString&
, m_server()
{
qDebug() << Q_FUNC_INFO;
//qsrand( QTime( 0, 0, 0 ).secsTo( QTime::currentTime() ) );
qsrand(QDateTime::currentDateTime().toTime_t());
m_presences[Jreen::Presence::Available] = "available";
m_presences[Jreen::Presence::Chat] = "chat";
m_presences[Jreen::Presence::Away] = "away";
m_presences[Jreen::Presence::DND] = "dnd";
m_presences[Jreen::Presence::XA] = "xa";
m_presences[Jreen::Presence::Unavailable] = "unavailable";
m_presences[Jreen::Presence::Probe] = "probe";
m_presences[Jreen::Presence::Error] = "error";
m_presences[Jreen::Presence::Invalid] = "invalid";
// setup JID object
m_jid = Jreen::JID( jid );
// general client setup
m_client = new Jreen::Client( jid, password );
m_client->setResource( QString( "tomahawk-jreen%1" ).arg( QString::number( qrand() % 10000 ) ) );
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" ) );
m_client->disco()->addFeature( TOMAHAWK_FEATURE );
// setup caps node, legacy peer detection - used before 0.1
Jreen::Capabilities::Ptr caps = m_client->presence().findExtension<Jreen::Capabilities>();
caps->setNode( TOMAHAWK_CAP_NODE_NAME );
// print connection parameters
qDebug() << "Our JID set to:" << m_client->jid().full();
qDebug() << "Our Server set to:" << m_client->server();
qDebug() << "Our Port set to" << m_client->port();
// setup slots
connect(m_client->connection(), SIGNAL(error(SocketError)), SLOT(onError(SocketError)));
connect(m_client, SIGNAL(serverFeaturesReceived(QSet<QString>)), SLOT(onConnect()));
connect(m_client, SIGNAL(disconnected(Jreen::Client::DisconnectReason)), SLOT(onDisconnect(Jreen::Client::DisconnectReason)));
connect(m_client, SIGNAL(destroyed(QObject*)), this, SLOT(onDestroy()));
connect(m_client, SIGNAL(newMessage(Jreen::Message)), SLOT(onNewMessage(Jreen::Message)));
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...";
m_client->connectToServer();
}
@@ -105,28 +129,57 @@ Jabber_p::disconnect()
void
Jabber_p::sendMsg( const QString& to, const QString& msg )
{
qDebug() << Q_FUNC_INFO;
if ( QThread::currentThread() != thread() )
{
qDebug() << Q_FUNC_INFO << "invoking in correct thread, not"
<< QThread::currentThread();
QMetaObject::invokeMethod( this, "sendMsg",
Qt::QueuedConnection,
Q_ARG( const QString, to ),
Q_ARG( const QString, msg )
);
return;
}
qDebug() << Q_FUNC_INFO << to << msg;
if ( !m_client ) {
return;
}
qDebug() << Q_FUNC_INFO << to << msg;
if( m_legacy_peers.contains( to ) )
{
qDebug() << Q_FUNC_INFO << to << "Send legacy message" << msg;
Jreen::Message m( Jreen::Message::Chat, Jreen::JID(to), msg);
m_client->send( m );
m_client->send( m ); // assuming this is threadsafe
return;
}
/*******************************************************
* Obsolete this by a SipMessage class
*/
QJson::Parser parser;
bool ok;
QVariant v = parser.parse( msg.toAscii(), &ok );
if ( !ok || v.type() != QVariant::Map )
{
qDebug() << "Invalid JSON in XMPP msg";
return;
}
QVariantMap m = v.toMap();
/*******************************************************/
TomahawkSipMessage *sipMessage;
if(m["visible"].toBool())
{
sipMessage = new TomahawkSipMessage(m["ip"].toString(),
m["port"].toInt(),
m["uniqname"].toString(),
m["key"].toString(),
m["visible"].toBool()
);
}
else
{
sipMessage = new TomahawkSipMessage();
}
qDebug() << "Send sip messsage to " << to;
Jreen::IQ iq( Jreen::IQ::Set, to );
iq.addExtension( sipMessage );
m_client->send( iq, this, SLOT( onNewIq( Jreen::IQ, int ) ), SipMessageSent );
}
@@ -134,23 +187,13 @@ void
Jabber_p::broadcastMsg( const QString &msg )
{
qDebug() << Q_FUNC_INFO;
if ( QThread::currentThread() != thread() )
{
QMetaObject::invokeMethod( this, "broadcastMsg",
Qt::QueuedConnection,
Q_ARG(const QString, msg)
);
return;
}
if ( !m_client )
return;
foreach( const QString& jidstr, m_peers.keys() )
{
qDebug() << "Broadcasting to" << jidstr <<"...";
Jreen::Message m(Jreen::Message::Chat, Jreen::JID(jidstr), msg, "");
m_client->send( m );
sendMsg( jidstr, msg );
}
}
@@ -158,16 +201,6 @@ Jabber_p::broadcastMsg( const QString &msg )
void
Jabber_p::addContact( const QString& jid, const QString& msg )
{
if ( QThread::currentThread() != thread() )
{
QMetaObject::invokeMethod( this, "addContact",
Qt::QueuedConnection,
Q_ARG(const QString, jid),
Q_ARG(const QString, msg)
);
return;
}
// Add contact to the Tomahawk group on the roster
m_roster->add( jid, jid, QStringList() << "Tomahawk" );
@@ -183,6 +216,7 @@ Jabber_p::onConnect()
// have changed our requested /resource
if ( m_client->jid().resource() != m_jid.resource() )
{
// TODO: check if this is still neccessary with jreen
m_jid.setResource( m_client->jid().resource() );
QString jidstr( m_jid.full() );
emit jidChanged( jidstr );
@@ -191,16 +225,21 @@ Jabber_p::onConnect()
emit connected();
qDebug() << "Connected as:" << m_jid.full();
m_client->setPresence(Jreen::Presence::Available, "Tomahawk-JREEN available", 1);
m_client->disco()->setSoftwareVersion( "Tomahawk JREEN", "0.0.0.0", "Foobar" );
m_client->setPingInterval(60000);
// set presence to least valid value
m_client->setPresence(Jreen::Presence::XA, "Got Tomahawk? http://gettomahawk.com", -127);
// set ping timeout to 15 secs (TODO: verify if this works)
m_client->setPingInterval(15000);
// load roster
m_roster = new Jreen::SimpleRoster( m_client );
m_roster->load();
//FIXME: this implementation is totally broken atm, so it's disabled to avoid harm :P
// join MUC with bare jid as nickname
//TODO: make the room a list of rooms and make that configurable
QString bare(m_jid.bare());
m_room = new Jreen::MUCRoom(m_client, Jreen::JID(QString("tomahawk@conference.qutim.org/").append(bare.replace("@", "-"))));
QString mucNickname = QString( "tomahawk@conference.qutim.org/" ).append( QString( m_jid.bare() ).replace( "@", "-" ) );
m_room = new Jreen::MUCRoom(m_client, Jreen::JID( mucNickname ) );
//m_room->setHistorySeconds(0);
//m_room->join();
@@ -262,6 +301,10 @@ Jabber_p::onDisconnect( Jreen::Client::DisconnectReason reason )
}
qDebug() << "Disconnected from server:" << error;
if( reason != Jreen::Client::User )
{
emit authError( reason, error );
}
if(reconnect)
QTimer::singleShot(reconnectInSeconds*1000, m_client, SLOT(connectToServer()));
@@ -278,81 +321,159 @@ Jabber_p::onNewMessage( const Jreen::Message& m )
if ( msg.isEmpty() )
return;
qDebug() << Q_FUNC_INFO << m.from().full() << ":" << m.body();
QJson::Parser parser;
bool ok;
QVariant v = parser.parse( msg.toAscii(), &ok );
if ( !ok || v.type() != QVariant::Map )
{
QString to = from;
QString response = QString( tr("I'm sorry -- I'm just an automatic presence used by Tomahawk Player"
" (http://gettomahawk.com). If you are getting this message, the person you"
" are trying to reach is probably not signed on, so please try again later!") );
// this is not a sip message, so we send it directly through the client
m_client->send( Jreen::Message ( Jreen::Message::Chat, Jreen::JID(to), response) );
return;
}
qDebug() << Q_FUNC_INFO << "From:" << m.from().full() << ":" << m.body();
emit msgReceived( from, msg );
}
void Jabber_p::onNewPresence( const Jreen::Presence& presence)
{
Jreen::JID jid = presence.from();
QString fulljid( jid.full() );
qDebug() << Q_FUNC_INFO << "handle presence" << fulljid << presence.subtype();
qDebug() << Q_FUNC_INFO << "* New presence: " << fulljid << presence.subtype();
if( jid == m_jid )
return;
if ( presence.error() ) {
qDebug() << Q_FUNC_INFO << "presence error: no tomahawk";
//qDebug() << Q_FUNC_INFO << fulljid << "Running tomahawk: no" << "presence error";
return;
}
// ignore anyone not running tomahawk:
// ignore anyone not Running tomahawk:
Jreen::Capabilities::Ptr caps = presence.findExtension<Jreen::Capabilities>();
if ( caps && ( caps->node() == TOMAHAWK_CAP_NODE_NAME ) )
{
qDebug() << Q_FUNC_INFO << presence.from().full() << "tomahawk detected by caps";
// must be a jreen resource, implementation in gloox was broken
qDebug() << Q_FUNC_INFO << fulljid << "Running tomahawk: yes" << "caps " << caps->node();
handlePeerStatus( fulljid, presence.subtype() );
}
// this is a hack actually as long as gloox based libsip_jabber is around
// remove this as soon as everyone is using jreen
else if( presence.from().resource().startsWith( QLatin1String("tomahawk") ) )
else if( caps )
{
qDebug() << Q_FUNC_INFO << presence.from().full() << "tomahawk detected by resource";
}
else if( caps && caps->node() != TOMAHAWK_CAP_NODE_NAME )
{
qDebug() << Q_FUNC_INFO << presence.from().full() << "*no tomahawk* detected by caps!" << caps->node() << presence.from().resource();
return;
qDebug() << Q_FUNC_INFO << fulljid << "Running tomahawk: maybe" << "caps " << caps->node()
<< "requesting disco..";
// request disco features
QString node = caps->node() + '#' + caps->ver();
Jreen::IQ iq( Jreen::IQ::Get, jid );
iq.addExtension( new Jreen::Disco::Info( node ) );
m_client->send( iq, this, SLOT( onNewIq( Jreen::IQ, int ) ), RequestDisco );
}
else if( !caps )
{
qDebug() << Q_FUNC_INFO << "no tomahawk detected by resource and !caps";
return;
qDebug() << Q_FUNC_INFO << "Running tomahawk: no" << "no caps";
}
}
qDebug() << Q_FUNC_INFO << fulljid << " is a tomahawk resource.";
// "going offline" event
if ( !presenceMeansOnline( presence.subtype() ) &&
( !m_peers.contains( fulljid ) ||
presenceMeansOnline( m_peers.value( fulljid ) )
)
)
void
Jabber_p::onNewIq( const Jreen::IQ &iq, int context )
{
m_peers[ fulljid ] = presence.subtype();
qDebug() << Q_FUNC_INFO << "* Peer goes offline:" << fulljid;
emit peerOffline( fulljid );
return;
}
// "coming online" event
if( presenceMeansOnline( presence.subtype() ) &&
( !m_peers.contains( fulljid ) ||
!presenceMeansOnline( m_peers.value( fulljid ) )
)
)
if( context == RequestDisco )
{
m_peers[ fulljid ] = presence.subtype();
qDebug() << Q_FUNC_INFO << "* Peer goes online:" << fulljid;
emit peerOnline( fulljid );
qDebug() << Q_FUNC_INFO << "Received disco IQ...";
Jreen::Disco::Info *discoInfo = iq.findExtension<Jreen::Disco::Info>().data();
if(!discoInfo)
return;
iq.accept();
QString fulljid = iq.from().full();
Jreen::DataForm::Ptr form = discoInfo->form();
if(discoInfo->features().contains( TOMAHAWK_FEATURE ))
{
qDebug() << Q_FUNC_INFO << fulljid << "Running tomahawk/feature enabled: yes";
// the actual presence doesn't matter, it just needs to be "online"
handlePeerStatus( fulljid, Jreen::Presence::Available );
}
else
{
qDebug() << Q_FUNC_INFO << fulljid << "Running tomahawk/feature enabled: no";
//LEGACY: accept resources starting with tomahawk too
if( iq.from().resource().startsWith("tomahawk") )
{
qDebug() << Q_FUNC_INFO << fulljid << "Detected legacy tomahawk..";
// add to legacy peers, so we can send text messages instead of iqs
m_legacy_peers.append( fulljid );
handlePeerStatus( fulljid, Jreen::Presence::Available );
}
}
}
else if(context == RequestedDisco)
{
qDebug() << "Sent IQ(Set), what should be happening here?";
}
else if(context == SipMessageSent )
{
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();
qDebug() << "uniqname" << sipMessage->uniqname();
qDebug() << "key" << sipMessage->key();
qDebug() << "visible" << sipMessage->visible();
QVariantMap m;
if( sipMessage->visible() )
{
m["visible"] = true;
m["ip"] = sipMessage->ip();
m["port"] = sipMessage->port();
m["key"] = sipMessage->key();
m["uniqname"] = sipMessage->uniqname();
}
else
{
m["visible"] = false;
}
//qDebug() << "Updating presence data for" << fulljid;
m_peers[ fulljid ] = presence.subtype();
QJson::Serializer ser;
QByteArray ba = ser.serialize( m );
QString msg = QString::fromAscii( ba );
QString from = iq.from().full();
qDebug() << Q_FUNC_INFO << "From:" << from << ":" << msg;
emit msgReceived( from, msg );
}
}
}
bool
@@ -369,3 +490,73 @@ Jabber_p::presenceMeansOnline( Jreen::Presence::Type p )
return true;
}
}
void
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 ) ||
presenceMeansOnline( m_peers.value( fulljid ) )
)
)
{
m_peers[ fulljid ] = presenceType;
qDebug() << Q_FUNC_INFO << "* Peer goes offline:" << fulljid;
// remove peer from legacy peers
if( m_legacy_peers.contains( fulljid ) )
{
m_legacy_peers.removeAll( fulljid );
}
emit peerOffline( fulljid );
return;
}
// "coming online" event
if( presenceMeansOnline( presenceType ) &&
( !m_peers.contains( fulljid ) ||
!presenceMeansOnline( m_peers.value( fulljid ) )
)
)
{
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;
}
//qDebug() << "Updating presence data for" << fulljid;
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 ) );
}

View File

@@ -1,5 +1,6 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2010-2011, Dominik Schmidt <dev@dominik-schmidt.de>
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
@@ -16,20 +17,12 @@
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
/*
This is the Jabber client that the rest of the app sees
Gloox stuff should NOT leak outside this class.
We may replace jreen later, this interface should remain the same.
*/
#ifndef JABBER_P_H
#define JABBER_P_H
#include <QObject>
#include <QSharedPointer>
#include <QMap>
#include <QNetworkProxy>
#include "../sipdllmacro.h"
#include <string>
#include "avatarmanager.h"
#include <jreen/client.h>
#include <jreen/disco.h>
@@ -41,16 +34,19 @@
#include <jreen/presence.h>
#include <jreen/vcard.h>
#include <jreen/abstractroster.h>
#include <jreen/connection.h>
#include <jreen/mucroom.h>
#include <QObject>
#include <QSharedPointer>
#include <QMap>
#include <QNetworkProxy>
#if defined( WIN32 ) || defined( _WIN32 )
#include <windows.h>
#endif
#include "../sipdllmacro.h"
#include <jreen/connection.h>
#include <jreen/mucroom.h>
class SIPDLLEXPORT Jabber_p :
public QObject
{
@@ -69,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:
@@ -87,9 +85,13 @@ 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 Jreen::JID &jid, Jreen::Presence::Type presenceType );
Jreen::Client *m_client;
Jreen::MUCRoom *m_room;
Jreen::SimpleRoster *m_roster;
@@ -97,6 +99,12 @@ private:
QMap<Jreen::Presence::Type, QString> m_presences;
QMap<QString, Jreen::Presence::Type> m_peers;
QString m_server;
enum IqContext { NoContext, RequestDisco, RequestedDisco, SipMessageSent, RequestedVCard };
QStringList m_legacy_peers;
AvatarManager *m_avatarManager;
};
#endif // JABBER_H

View File

@@ -0,0 +1,74 @@
/****************************************************************************
*
* This file is part of qutIM
*
* Copyright (c) 2011 by Nigmatullin Ruslan <euroelessar@gmail.com>
*
***************************************************************************
* *
* This file is part of free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation; either version 2 of the *
* License, or (at your option) any later version. *
* *
***************************************************************************
****************************************************************************/
#include "tomahawksipmessage.h"
class TomahawkSipMessagePrivate
{
public:
QString ip;
int port;
QString uniqname;
QString key;
bool visible;
};
TomahawkSipMessage::TomahawkSipMessage(QString ip, unsigned int port, QString uniqname, QString key, bool visible) : d_ptr(new TomahawkSipMessagePrivate)
{
Q_D(TomahawkSipMessage);
d->ip = ip;
d->port = port;
d->uniqname = uniqname;
d->key = key;
d->visible = visible;
}
TomahawkSipMessage::TomahawkSipMessage() : d_ptr(new TomahawkSipMessagePrivate)
{
Q_D(TomahawkSipMessage);
d->visible = false;
d->port = -1;
}
TomahawkSipMessage::~TomahawkSipMessage()
{
}
const QString TomahawkSipMessage::ip() const
{
return d_func()->ip;
}
unsigned int TomahawkSipMessage::port() const
{
return d_func()->port;
}
QString TomahawkSipMessage::uniqname() const
{
return d_func()->uniqname;
}
QString TomahawkSipMessage::key() const
{
return d_func()->key;
}
bool TomahawkSipMessage::visible() const
{
return d_func()->visible;
}

View File

@@ -0,0 +1,28 @@
#ifndef ENTITYTIME_H
#define ENTITYTIME_H
#include <jreen/stanzaextension.h>
#define TOMAHAWK_SIP_MESSAGE_NS QLatin1String("http://www.tomhawk-player.org/sip/transports")
class TomahawkSipMessagePrivate;
class TomahawkSipMessage : public Jreen::StanzaExtension
{
J_EXTENSION(TomahawkSipMessage, "")
Q_DECLARE_PRIVATE(TomahawkSipMessage)
public:
TomahawkSipMessage(QString ip, unsigned int port, QString uniqname, QString key, bool visible);
// sets visible to false as we dont have any extra information
TomahawkSipMessage();
~TomahawkSipMessage();
const QString ip() const;
unsigned int port() const;
QString uniqname() const;
QString key() const;
bool visible() const;
private:
QScopedPointer<TomahawkSipMessagePrivate> d_ptr;
};
#endif // ENTITYTIME_H

View File

@@ -0,0 +1,124 @@
#include "tomahawksipmessagefactory.h"
//#include "util.h"
#include <QStringList>
#include <QXmlStreamWriter>
#include <QDebug>
#include <QVariant>
using namespace Jreen;
TomahawkSipMessageFactory::TomahawkSipMessageFactory()
{
m_depth = 0;
m_state = AtNowhere;
}
TomahawkSipMessageFactory::~TomahawkSipMessageFactory()
{
}
QStringList TomahawkSipMessageFactory::features() const
{
return QStringList(TOMAHAWK_SIP_MESSAGE_NS);
}
bool TomahawkSipMessageFactory::canParse(const QStringRef &name, const QStringRef &uri, const QXmlStreamAttributes &attributes)
{
Q_UNUSED(uri);
Q_UNUSED(attributes);
return name == QLatin1String("tomahawk") && uri == TOMAHAWK_SIP_MESSAGE_NS;
}
void TomahawkSipMessageFactory::handleStartElement(const QStringRef &name, const QStringRef &uri,
const QXmlStreamAttributes &attributes)
{
m_depth++;
if (m_depth == 1) {
m_state = AtNowhere;
m_ip = QString();
m_port = -1;
m_uniqname = QString();
m_key = QString();
m_visible = false;
} else if (m_depth == 2) {
if (name == QLatin1String("transport"))
{
qDebug() << "Found Transport";
m_state = AtTransport;
m_uniqname = attributes.value(QLatin1String("uniqname")).toString();
m_key = attributes.value(QLatin1String("pwd")).toString();
m_visible = true;
}
} else if(m_depth == 3) {
if (name == QLatin1String("candidate"))
{
m_state = AtCandidate;
qDebug() << "Found candidate";
m_ip = attributes.value(QLatin1String("ip")).toString();
m_port = attributes.value(QLatin1String("port")).toString().toInt();
}
}
Q_UNUSED(uri);
Q_UNUSED(attributes);
}
void TomahawkSipMessageFactory::handleEndElement(const QStringRef &name, const QStringRef &uri)
{
if (m_depth == 3)
m_state = AtNowhere;
Q_UNUSED(name);
Q_UNUSED(uri);
m_depth--;
}
void TomahawkSipMessageFactory::handleCharacterData(const QStringRef &text)
{
/*if (m_state == AtUtc) {
//m_utc = Util::fromStamp(text.toString());
} else if (m_state == AtTzo) {
QString str = text.toString();
int multiple = str.startsWith('-') ? -1 : 1;
//QTime delta = QTime::fromString(str.mid(1), QLatin1String("hh:mm"));
//m_tzo = multiple * (delta.hour() * 60 + delta.minute());
}*/
Q_UNUSED(text);
}
void TomahawkSipMessageFactory::serialize(StanzaExtension *extension, QXmlStreamWriter *writer)
{
TomahawkSipMessage *sipMessage = se_cast<TomahawkSipMessage*>(extension);
writer->writeStartElement(QLatin1String("tomahawk"));
writer->writeDefaultNamespace(TOMAHAWK_SIP_MESSAGE_NS);
if(sipMessage->visible())
{
// add transport tag
writer->writeStartElement(QLatin1String("transport"));
writer->writeAttribute(QLatin1String("pwd"), sipMessage->key());
writer->writeAttribute(QLatin1String("uniqname"), sipMessage->uniqname());
writer->writeEmptyElement(QLatin1String("candidate"));
writer->writeAttribute(QLatin1String("component"), "1");
writer->writeAttribute(QLatin1String("id"), "el0747fg11"); // FIXME
writer->writeAttribute(QLatin1String("ip"), sipMessage->ip());
writer->writeAttribute(QLatin1String("network"), "1");
writer->writeAttribute(QLatin1String("port"), QVariant(sipMessage->port()).toString());
writer->writeAttribute(QLatin1String("priority"), "1"); //TODO
writer->writeAttribute(QLatin1String("protocol"), "tcp");
writer->writeAttribute(QLatin1String("type"), "host"); //FIXME: correct?!
writer->writeEndElement();
}
else
{
writer->writeEmptyElement(QLatin1String("transport"));
}
writer->writeEndElement();
}
StanzaExtension::Ptr TomahawkSipMessageFactory::createExtension()
{
return StanzaExtension::Ptr(new TomahawkSipMessage(m_ip, m_port, m_uniqname, m_key, m_visible));
}

View File

@@ -0,0 +1,46 @@
/****************************************************************************
*
* This file is part of qutIM
*
* Copyright (c) 2011 by Nigmatullin Ruslan <euroelessar@gmail.com>
*
***************************************************************************
* *
* This file is part of free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation; either version 2 of the *
* License, or (at your option) any later version. *
* *
***************************************************************************
****************************************************************************/
#ifndef ENTITYTIMEFACTORY_P_H
#define ENTITYTIMEFACTORY_P_H
#include "tomahawksipmessage.h"
#include <jreen/stanzaextension.h>
class TomahawkSipMessageFactory : public Jreen::StanzaExtensionFactory<TomahawkSipMessage>
{
public:
TomahawkSipMessageFactory();
virtual ~TomahawkSipMessageFactory();
QStringList features() const;
bool canParse(const QStringRef &name, const QStringRef &uri, const QXmlStreamAttributes &attributes);
void handleStartElement(const QStringRef &name, const QStringRef &uri, const QXmlStreamAttributes &attributes);
void handleEndElement(const QStringRef &name, const QStringRef &uri);
void handleCharacterData(const QStringRef &text);
void serialize(Jreen::StanzaExtension *extension, QXmlStreamWriter *writer);
Jreen::StanzaExtension::Ptr createExtension();
private:
enum State { AtNowhere, AtTransport, AtCandidate } m_state;
int m_depth;
QString m_ip;
int m_port;
QString m_uniqname;
QString m_key;
bool m_visible;
};
#endif // ENTITYTIMEFACTORY_P_H

View File

@@ -465,20 +465,23 @@ SourceDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, co
CollectionItem* colItem = qobject_cast< CollectionItem* >( item );
Q_ASSERT( colItem );
bool status = !( !colItem || colItem->source().isNull() || !colItem->source()->isOnline() );
QPixmap avatar( RESPATH "images/user-avatar.png" );
QString tracks;
int figWidth = 0;
if ( status )
if ( status && colItem && !colItem->source().isNull() )
{
tracks = QString::number( colItem->source()->trackCount() );
figWidth = painter->fontMetrics().width( tracks );
if ( !colItem->source()->avatar().isNull() )
avatar = colItem->source()->avatar();
}
QRect iconRect = option.rect.adjusted( 4, 6, -option.rect.width() + option.rect.height() - 12 + 4, -6 );
painter->drawPixmap( iconRect, item->icon().pixmap( iconRect.size() ) );
painter->drawPixmap( iconRect, avatar.scaledToHeight( iconRect.height(), Qt::SmoothTransformation ) );
if ( ( option.state & QStyle::State_Selected ) == QStyle::State_Selected )
{

View File

@@ -150,14 +150,14 @@ 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();
setOrganizationName( QLatin1String( ORGANIZATION_NAME ) );
setOrganizationDomain( QLatin1String( ORGANIZATION_DOMAIN ) );
setApplicationName( QLatin1String( APPLICATION_NAME ) );
setApplicationVersion( QLatin1String( VERSION ) );
setOrganizationName( QLatin1String( TOMAHAWK_ORGANIZATION_NAME ) );
setOrganizationDomain( QLatin1String( TOMAHAWK_ORGANIZATION_DOMAIN ) );
setApplicationName( QLatin1String( TOMAHAWK_APPLICATION_NAME ) );
setApplicationVersion( QLatin1String( TOMAHAWK_VERSION ) );
registerMetaTypes();
setupLogfile();
}
@@ -192,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 );

View File

@@ -1,5 +1,5 @@
add_subdirectory( jdns )
add_subdirectory( qtweetlib )
ADD_SUBDIRECTORY( jdns )
ADD_SUBDIRECTORY( qtweetlib )
ADD_SUBDIRECTORY( libportfwd )
ADD_SUBDIRECTORY( qxt )
ADD_SUBDIRECTORY( liblastfm2 )