1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-21 21:25:52 +02:00

Merge remote-tracking branch 'origin/master'

Conflicts:
	src/libtomahawk/sip/SipPlugin.cpp
	src/resolverconfigdelegate.cpp
	src/sip/jreen/jabber.cpp
	src/sip/jreen/jabber.h
This commit is contained in:
Leo Franchi
2011-05-03 16:16:16 -04:00
39 changed files with 752 additions and 212 deletions

View File

@@ -39,7 +39,6 @@ SET( tomahawkSources ${tomahawkSources}
musicscanner.cpp
shortcuthandler.cpp
globalactionmanager.cpp
scanmanager.cpp
tomahawkapp.cpp
main.cpp
@@ -84,7 +83,6 @@ SET( tomahawkHeaders ${tomahawkHeaders}
musicscanner.h
scanmanager.h
shortcuthandler.h
globalactionmanager.h
)
IF(LIBLASTFM_FOUND)

View File

@@ -29,6 +29,7 @@ set( libSources
source.cpp
viewpage.cpp
viewmanager.cpp
globalactionmanager.cpp
sip/SipPlugin.cpp
sip/SipHandler.cpp
@@ -159,6 +160,7 @@ set( libSources
widgets/newplaylistwidget.cpp
widgets/welcomewidget.cpp
widgets/welcomeplaylistmodel.cpp
widgets/overlaywidget.cpp
widgets/infowidgets/sourceinfowidget.cpp
@@ -183,6 +185,7 @@ set( libHeaders
source.h
viewpage.h
viewmanager.h
globalactionmanager.h
artist.h
album.h
@@ -318,6 +321,7 @@ set( libHeaders
widgets/newplaylistwidget.h
widgets/welcomewidget.h
widgets/welcomeplaylistmodel.h
widgets/overlaywidget.h
widgets/infowidgets/sourceinfowidget.h

View File

@@ -153,7 +153,6 @@ Collection::deleteStation( const dynplaylist_ptr& s )
playlist_ptr
Collection::playlist( const QString& guid )
{
qDebug() << "Returning playlist for guid:" << guid << "found?" << m_playlists.contains( guid );
return m_playlists.value( guid, playlist_ptr() );
}
@@ -161,7 +160,6 @@ Collection::playlist( const QString& guid )
dynplaylist_ptr
Collection::autoPlaylist( const QString& guid )
{
qDebug() << "Returning auto playlist for guid:" << guid << "found?" << m_autoplaylists.contains( guid );
return m_autoplaylists.value( guid, dynplaylist_ptr() );
}
@@ -169,7 +167,6 @@ dynplaylist_ptr
Collection::station( const QString& guid )
{
qDebug() << "Returning station for guid:" << guid << "found?" << m_stations.contains( guid );
return m_stations.value( guid, dynplaylist_ptr() );
}

View File

@@ -31,6 +31,8 @@
#include <QUrl>
#include <Playlist.h>
#include <qclipboard.h>
#include <qapplication.h>
GlobalActionManager* GlobalActionManager::s_instance = 0;
@@ -53,6 +55,28 @@ GlobalActionManager::GlobalActionManager( QObject* parent )
GlobalActionManager::~GlobalActionManager()
{}
QUrl
GlobalActionManager::openLinkFromQuery( const Tomahawk::query_ptr& query ) const
{
QUrl link( "tomahawk://open/track/" );
if( !query->track().isEmpty() )
link.addQueryItem( "title", query->track() );
if( !query->artist().isEmpty() )
link.addQueryItem( "artist", query->artist() );
if( !query->album().isEmpty() )
link.addQueryItem( "album", query->album() );
return link;
}
void
GlobalActionManager::copyToClipboard( const Tomahawk::query_ptr& query ) const
{
QClipboard* cb = QApplication::clipboard();
cb->setText( openLinkFromQuery( query ).toEncoded() );
}
bool
GlobalActionManager::parseTomahawkLink( const QString& url )
{
@@ -88,6 +112,10 @@ GlobalActionManager::parseTomahawkLink( const QString& url )
return handleSearchCommand( u );
} else if( cmdType == "play" ) {
return handlePlayCommand( u );
} else if( cmdType == "bookmark" ) {
return handlePlayCommand( u );
} else if( cmdType == "open" ) {
return handleOpenCommand( u );
} else {
qDebug() << "Tomahawk link not supported, command not known!" << cmdType << u.path();
return false;
@@ -128,7 +156,7 @@ GlobalActionManager::handlePlaylistCommand( const QUrl& url )
pl->createNewRevision( uuid(), pl->currentrevision(), QList< Tomahawk::plentry_ptr >() );
ViewManager::instance()->show( pl );
} else if( parts[ 0 ] == "add" ) {
if( !url.hasQueryItem( "playlistid" ) || !url.hasQueryItem( "track" ) || !url.hasQueryItem( "artist" ) ) {
if( !url.hasQueryItem( "playlistid" ) || !url.hasQueryItem( "title" ) || !url.hasQueryItem( "artist" ) ) {
qDebug() << "Add to playlist command needs playlistid, track, and artist..." << url.toString();
return false;
}
@@ -155,6 +183,19 @@ GlobalActionManager::handleCollectionCommand( const QUrl& url )
return false;
}
bool
GlobalActionManager::handleOpenCommand(const QUrl& url)
{
QStringList parts = url.path().split( "/" ).mid( 1 );
if( parts.isEmpty() ) {
qDebug() << "No specific type to open:" << url.toString();
return false;
}
// TODO user configurable in the UI
return doQueueAdd( parts, url.queryItems() );
}
bool
GlobalActionManager::handleQueueCommand( const QUrl& url )
{
@@ -165,9 +206,50 @@ GlobalActionManager::handleQueueCommand( const QUrl& url )
}
if( parts[ 0 ] == "add" ) {
if( parts.size() > 1 && parts[ 1 ] == "track" ) {
QPair< QString, QString > pair;
foreach( pair, url.queryItems() ) {
doQueueAdd( parts.mid( 1 ), url.queryItems() );
} else {
qDebug() << "Only queue/add/track is support at the moment, got:" << parts;
return false;
}
return false;
}
bool
GlobalActionManager::doQueueAdd( const QStringList& parts, const QList< QPair< QString, QString > >& queryItems )
{
if( parts.size() && parts[ 0 ] == "track" ) {
QPair< QString, QString > pair;
QString title, artist, album, urlStr;
foreach( pair, queryItems ) {
if( pair.first == "title" )
title = pair.second;
else if( pair.first == "artist" )
artist = pair.second;
else if( pair.first == "album" )
album = pair.second;
else if( pair.first == "url" )
urlStr = pair.second;
}
if( !title.isEmpty() || !artist.isEmpty() || !album.isEmpty() ) { // an individual; query to add to queue
Tomahawk::query_ptr q = Tomahawk::Query::get( artist, title, album );
if( !urlStr.isEmpty() )
q->setResultHint( urlStr );
Tomahawk::Pipeline::instance()->resolve( q, true );
ViewManager::instance()->queue()->model()->append( q );
ViewManager::instance()->showQueue();
if( !AudioEngine::instance()->isPlaying() ) {
connect( q.data(), SIGNAL( resolvingFinished( bool ) ), this, SLOT( waitingForResolved( bool ) ) );
m_waitingToPlay = q;
}
return true;
} else { // a list of urls to add to the queue
foreach( pair, queryItems ) {
if( pair.first != "url" )
continue;
QUrl track = QUrl::fromUserInput( pair.second );
@@ -175,7 +257,6 @@ GlobalActionManager::handleQueueCommand( const QUrl& url )
if( track.toString().startsWith( "file://" ) ) { // it's local, so we see if it's in the DB and load it if so
// TODO
} else { // give it a web result hint
// TODO actually read the tags
QFileInfo info( track.path() );
Tomahawk::query_ptr q = Tomahawk::Query::get( QString(), info.baseName(), QString() );
q->setResultHint( track.toString() );
@@ -186,12 +267,8 @@ GlobalActionManager::handleQueueCommand( const QUrl& url )
}
return true;
}
} else {
qDebug() << "Only queue/add/track is support at the moment, got:" << parts;
return false;
}
}
return false;
}
@@ -204,8 +281,8 @@ GlobalActionManager::handleSearchCommand( const QUrl& url )
query << url.queryItemValue( "artist" );
if( url.hasQueryItem( "album" ) )
query << url.queryItemValue( "album" );
if( url.hasQueryItem( "track" ) )
query << url.queryItemValue( "track" );
if( url.hasQueryItem( "title" ) )
query << url.queryItemValue( "title" );
QString queryStr = query.join( " " );
if( queryStr.isEmpty() )
@@ -268,7 +345,42 @@ GlobalActionManager::handlePlayCommand( const QUrl& url )
QPair< QString, QString > pair;
QString title, artist, album, urlStr;
foreach( pair, url.queryItems() ) {
if( pair.first == "track" )
if( pair.first == "title" )
title = pair.second;
else if( pair.first == "artist" )
artist = pair.second;
else if( pair.first == "album" )
album = pair.second;
else if( pair.first == "url" )
urlStr = pair.second;
}
Tomahawk::query_ptr q = Tomahawk::Query::get( artist, title, album );
if( !urlStr.isEmpty() )
q->setResultHint( urlStr );
Tomahawk::Pipeline::instance()->resolve( q, true );
m_waitingToPlay = q;
connect( q.data(), SIGNAL( resolvingFinished( bool ) ), this, SLOT( waitingForResolved( bool ) ) );
return true;
}
return false;
}
bool GlobalActionManager::handleBookmarkCommand(const QUrl& url)
{
QStringList parts = url.path().split( "/" ).mid( 1 ); // get the rest of the command
if( parts.isEmpty() ) {
qDebug() << "No specific bookmark command:" << url.toString();
return false;
}
if( parts[ 0 ] == "track" ) {
QPair< QString, QString > pair;
QString title, artist, album, urlStr;
foreach( pair, url.queryItems() ) {
if( pair.first == "title" )
title = pair.second;
else if( pair.first == "artist" )
artist = pair.second;
@@ -299,6 +411,8 @@ GlobalActionManager::handlePlayCommand( const QUrl& url )
return false;
}
void
GlobalActionManager::bookmarkPlaylistCreated( const Tomahawk::playlist_ptr& pl )
{
@@ -326,13 +440,6 @@ GlobalActionManager::doBookmark( const Tomahawk::playlist_ptr& pl, const Tomahaw
m_toShow = pl;
// if nothing is playing, lets start this
// TODO
if( !AudioEngine::instance()->isPlaying() ) {
connect( q.data(), SIGNAL( resolvingFinished( bool ) ), this, SLOT( waitingForResolved( bool ) ) );
m_waitingToPlay = q;
}
m_waitingToBookmark.clear();
}
@@ -351,7 +458,8 @@ void
GlobalActionManager::waitingForResolved( bool success )
{
if( success && !m_waitingToPlay.isNull() && !m_waitingToPlay->results().isEmpty() ) { // play it!
AudioEngine::instance()->playItem( AudioEngine::instance()->playlist(), m_waitingToPlay->results().first() );
// AudioEngine::instance()->playItem( AudioEngine::instance()->playlist(), m_waitingToPlay->results().first() );
AudioEngine::instance()->play();
}
m_waitingToPlay.clear();

View File

@@ -21,17 +21,21 @@
#define GLOBALACTIONMANAGER_H
#include "playlist.h"
#include "dllmacro.h"
#include <QObject>
#include <QUrl>
class GlobalActionManager : public QObject
class DLLEXPORT GlobalActionManager : public QObject
{
Q_OBJECT
public:
static GlobalActionManager* instance();
virtual ~GlobalActionManager();
QUrl openLinkFromQuery( const Tomahawk::query_ptr& query ) const;
void copyToClipboard( const Tomahawk::query_ptr& query ) const;
public slots:
bool parseTomahawkLink( const QString& link );
void waitingForResolved( bool );
@@ -50,6 +54,10 @@ private:
bool handleStationCommand(const QUrl& url );
bool handleSearchCommand(const QUrl& url );
bool handlePlayCommand(const QUrl& url );
bool handleBookmarkCommand(const QUrl& url );
bool handleOpenCommand(const QUrl& url );
bool doQueueAdd( const QStringList& parts, const QList< QPair< QString, QString > >& queryItems );
Tomahawk::playlist_ptr m_toShow;
Tomahawk::query_ptr m_waitingToBookmark;

View File

@@ -68,11 +68,6 @@ LastFmPlugin::LastFmPlugin( InfoSystemWorker* parent )
m_pw = TomahawkSettings::instance()->lastFmPassword();
if( TomahawkSettings::instance()->scrobblingEnabled() && !lastfm::ws::Username.isEmpty() )
{
createScrobbler();
}
//HACK work around a bug in liblastfm---it doesn't create its config dir, so when it
// tries to write the track cache, it fails silently. until we have a fixed version, do this
// code taken from Amarok (src/services/lastfm/ScrobblerAdapter.cpp)
@@ -94,7 +89,9 @@ LastFmPlugin::LastFmPlugin( InfoSystemWorker* parent )
LastFmPlugin::~LastFmPlugin()
{
qDebug() << Q_FUNC_INFO << " beginning";
delete m_scrobbler;
qDebug() << Q_FUNC_INFO << " exiting";
}
@@ -103,6 +100,7 @@ LastFmPlugin::namChangedSlot()
{
qDebug() << Q_FUNC_INFO;
lastfm::setNetworkAccessManager( m_infoSystemWorker->nam() );
settingsChanged(); // to get the scrobbler set up
}
@@ -158,13 +156,20 @@ LastFmPlugin::pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoTy
void
LastFmPlugin::nowPlaying( const QString &caller, const InfoType type, const QVariant &input )
{
qDebug() << Q_FUNC_INFO;
if ( !input.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() || !m_scrobbler )
{
qDebug() << "LastFmPlugin::nowPlaying no m_scrobbler, or cannot convert input!";
if ( ! m_scrobbler )
qDebug() << "no scrobbler!";
return;
}
InfoCriteriaHash hash = input.value< Tomahawk::InfoSystem::InfoCriteriaHash >();
if ( !hash.contains( "title" ) || !hash.contains( "artist" ) || !hash.contains( "album" ) || !hash.contains( "duration" ) )
return;
qDebug() << "LastFmPlugin::nowPlaying valid criteria hash";
m_track = lastfm::MutableTrack();
m_track.stamp();
@@ -182,7 +187,8 @@ LastFmPlugin::nowPlaying( const QString &caller, const InfoType type, const QVar
void
LastFmPlugin::scrobble( const QString &caller, const InfoType type, const QVariant &input )
{
Q_ASSERT( QThread::currentThread() == thread() );
qDebug() << Q_FUNC_INFO;
//Q_ASSERT( QThread::currentThread() == thread() );
if ( !m_scrobbler || m_track.isNull() )
return;
@@ -418,6 +424,7 @@ LastFmPlugin::settingsChanged()
void
LastFmPlugin::onAuthenticated()
{
qDebug() << Q_FUNC_INFO;
if( !m_authJob )
{
qDebug() << Q_FUNC_INFO << "Help! No longer got a last.fm auth job!";
@@ -440,6 +447,7 @@ LastFmPlugin::onAuthenticated()
TomahawkSettings::instance()->setLastFmSessionKey( lastfm::ws::SessionKey.toLatin1() );
qDebug() << "Got session key from last.fm";
if( TomahawkSettings::instance()->scrobblingEnabled() )
m_scrobbler = new lastfm::Audioscrobbler( "thk" );
}
@@ -456,8 +464,10 @@ LastFmPlugin::onAuthenticated()
void
LastFmPlugin::createScrobbler()
{
qDebug() << Q_FUNC_INFO;
if( TomahawkSettings::instance()->lastFmSessionKey().isEmpty() ) // no session key, so get one
{
qDebug() << "LastFmPlugin::createScrobbler Session key is empty";
QString authToken = md5( ( lastfm::ws::Username.toLower() + md5( m_pw.toUtf8() ) ).toUtf8() );
QMap<QString, QString> query;
@@ -470,9 +480,9 @@ LastFmPlugin::createScrobbler()
}
else
{
qDebug() << "LastFmPlugin::createScrobbler Already have session key";
lastfm::ws::SessionKey = TomahawkSettings::instance()->lastFmSessionKey();
m_scrobbler = new lastfm::Audioscrobbler( "thk" );
m_scrobbler->moveToThread( thread() );
}
}

View File

@@ -78,17 +78,44 @@ InfoSystem::InfoSystem(QObject *parent)
InfoSystem::~InfoSystem()
{
qDebug() << Q_FUNC_INFO;
qDebug() << Q_FUNC_INFO << " beginning";
if ( m_infoSystemWorkerThreadController )
m_infoSystemWorkerThreadController->quit();
qDebug() << Q_FUNC_INFO << " sent quit signals";
if( m_infoSystemWorkerThreadController )
{
while( !m_infoSystemWorkerThreadController->isFinished() )
{
qDebug() << Q_FUNC_INFO << " worker thread controller not finished, processing events";
QCoreApplication::processEvents( QEventLoop::AllEvents, 200 );
TomahawkUtils::Sleep::msleep( 100 );
}
qDebug() << Q_FUNC_INFO << " worker is finished, deleting worker";
if( m_worker )
{
delete m_worker;
m_worker = 0;
}
qDebug() << Q_FUNC_INFO << " worker finished being deleted";
delete m_infoSystemWorkerThreadController;
m_infoSystemWorkerThreadController = 0;
}
qDebug() << Q_FUNC_INFO << " done deleting worker";
if ( m_infoSystemCacheThreadController )
m_infoSystemCacheThreadController->quit();
if ( m_infoSystemWorkerThreadController )
m_infoSystemWorkerThreadController->quit();
if( m_infoSystemCacheThreadController )
{
while( !m_infoSystemCacheThreadController->isFinished() )
{
qDebug() << Q_FUNC_INFO << " cache thread controller not finished, processing events";
QCoreApplication::processEvents( QEventLoop::AllEvents, 200 );
TomahawkUtils::Sleep::msleep( 100 );
}
@@ -102,24 +129,7 @@ InfoSystem::~InfoSystem()
delete m_infoSystemCacheThreadController;
m_infoSystemCacheThreadController = 0;
}
if( m_infoSystemWorkerThreadController )
{
while( !m_infoSystemWorkerThreadController->isFinished() )
{
QCoreApplication::processEvents( QEventLoop::AllEvents, 200 );
TomahawkUtils::Sleep::msleep( 100 );
}
if( m_worker )
{
delete m_worker;
m_worker = 0;
}
delete m_infoSystemWorkerThreadController;
m_infoSystemWorkerThreadController = 0;
}
qDebug() << Q_FUNC_INFO << " done deleting cache";
}

View File

@@ -107,7 +107,10 @@ class DLLEXPORT InfoPlugin : public QObject
public:
InfoPlugin( InfoSystemWorker *parent );
virtual ~InfoPlugin() {}
virtual ~InfoPlugin()
{
qDebug() << Q_FUNC_INFO;
}
signals:
void getCachedInfo( Tomahawk::InfoSystem::InfoCriteriaHash criteria, qint64 newMaxAge, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, Tomahawk::InfoSystem::InfoCustomData customData );

View File

@@ -27,6 +27,8 @@
#include "infoplugins/musixmatchplugin.h"
#include "infoplugins/lastfmplugin.h"
#include "lastfm/NetworkAccessManager"
namespace Tomahawk
{
@@ -42,12 +44,13 @@ InfoSystemWorker::InfoSystemWorker()
InfoSystemWorker::~InfoSystemWorker()
{
qDebug() << Q_FUNC_INFO;
qDebug() << Q_FUNC_INFO << " beginning";
Q_FOREACH( InfoPluginPtr plugin, m_plugins )
{
if( plugin )
delete plugin.data();
}
qDebug() << Q_FUNC_INFO << " is done deleting plugins";
}
@@ -165,7 +168,13 @@ void
InfoSystemWorker::newNam()
{
qDebug() << Q_FUNC_INFO;
QNetworkAccessManager *newNam = new QNetworkAccessManager();
QNetworkAccessManager* newNam;
#ifdef LIBLASTFM_FOUND
newNam = new lastfm::NetworkAccessManager( this );
#else
newNam = new QNetworkAccessManager( this );
#endif
if ( m_nam )
{
delete m_nam;

View File

@@ -184,7 +184,6 @@ playlist_ptr
Playlist::load( const QString& guid )
{
playlist_ptr p;
qDebug() << "asked to load playlist:" << guid;
foreach( const Tomahawk::source_ptr& source, SourceList::instance()->sources() )
{

View File

@@ -262,4 +262,6 @@ private:
};
Q_DECLARE_METATYPE( QSharedPointer< Tomahawk::Playlist > )
#endif // PLAYLIST_H

View File

@@ -83,7 +83,10 @@ CollectionView::setupMenus()
m_playItemAction = m_itemMenu.addAction( tr( "&Play" ) );
m_addItemsToQueueAction = m_itemMenu.addAction( tr( "Add to &Queue" ) );
// m_itemMenu.addSeparator();
m_itemMenu.addSeparator();
foreach( QAction* a, actions() )
m_itemMenu.addAction( a );
// m_addItemsToPlaylistAction = m_itemMenu.addAction( tr( "&Add to Playlist" ) );
connect( m_playItemAction, SIGNAL( triggered() ), SLOT( playItem() ) );

View File

@@ -30,6 +30,12 @@ using namespace Tomahawk;
PlaylistView::PlaylistView( QWidget* parent )
: TrackView( parent )
, m_model( 0 )
, m_itemMenu( 0 )
, m_playItemAction( 0 )
, m_addItemsToQueueAction( 0 )
, m_addItemsToPlaylistAction( 0 )
, m_deleteItemsAction( 0 )
{
setProxyModel( new PlaylistProxyModel( this ) );
@@ -84,6 +90,9 @@ PlaylistView::setupMenus()
m_playItemAction = m_itemMenu.addAction( tr( "&Play" ) );
m_addItemsToQueueAction = m_itemMenu.addAction( tr( "Add to &Queue" ) );
m_itemMenu.addSeparator();
foreach( QAction* a, actions() )
m_itemMenu.addAction( a );
// m_addItemsToPlaylistAction = m_itemMenu.addAction( tr( "&Add to Playlist" ) );
// m_itemMenu.addSeparator();
m_deleteItemsAction = m_itemMenu.addAction( i > 1 ? tr( "&Delete Items" ) : tr( "&Delete Item" ) );
@@ -144,7 +153,6 @@ PlaylistView::deleteItems()
proxyModel()->removeIndexes( selectedIndexes() );
}
void
PlaylistView::onTrackCountChanged( unsigned int tracks )
{

View File

@@ -65,7 +65,6 @@ private slots:
void deleteItems();
void onDeleted();
private:
void setupMenus();

View File

@@ -33,7 +33,8 @@
#include "queueview.h"
#include "trackmodel.h"
#include "trackproxymodel.h"
#include <track.h>
#include "track.h"
#include "globalactionmanager.h"
using namespace Tomahawk;
@@ -77,6 +78,10 @@ TrackView::TrackView( QWidget* parent )
setFont( f );
#endif
QAction* createLinkAction = new QAction( tr( "Copy track link" ), this );
connect( createLinkAction, SIGNAL( triggered( bool ) ), this, SLOT( copyLink() ) );
addAction( createLinkAction );
connect( this, SIGNAL( doubleClicked( QModelIndex ) ), SLOT( onItemActivated( QModelIndex ) ) );
}
@@ -173,7 +178,6 @@ TrackView::onItemResized( const QModelIndex& index )
m_delegate->updateRowSize( index );
}
void
TrackView::playItem()
{
@@ -341,6 +345,16 @@ TrackView::onFilterChanged( const QString& )
m_overlay->hide();
}
void
TrackView::copyLink()
{
TrackModelItem* item = model()->itemFromIndex( proxyModel()->mapToSource( contextMenuIndex() ) );
if ( item && !item->query().isNull() )
{
GlobalActionManager::instance()->copyToClipboard( item->query() );
}
}
void
TrackView::startDrag( Qt::DropActions supportedActions )

View File

@@ -26,6 +26,7 @@
#include "dllmacro.h"
class QAction;
class LoadingSpinner;
class PlaylistInterface;
class TrackHeader;
@@ -80,6 +81,7 @@ private slots:
void onFilterChanged( const QString& filter );
void copyLink();
private:
QString m_guid;
TrackModel* m_model;

View File

@@ -1,6 +1,7 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* 2011, Dominik Schmidt <dev@dominik-schmidt.de>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -64,3 +65,9 @@ SipPlugin::icon() const
{
return QIcon();
}
void
SipPlugin::setProxy( const QNetworkProxy& proxy )
{
qDebug() << Q_FUNC_INFO << "Not implemented";
}

View File

@@ -1,6 +1,7 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* 2011, Dominik Schmidt <dev@dominik-schmidt.de>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,6 +23,8 @@
#include <QObject>
#include <QString>
#include <QMenu>
#include <QNetworkProxy>
#include "dllmacro.h"
@@ -80,6 +83,8 @@ public slots:
virtual void addContact( const QString &jid, const QString& msg = QString() ) = 0;
virtual void sendMsg( const QString& to, const QString& msg ) = 0;
void setProxy( const QNetworkProxy &proxy );
signals:
void error( int, const QString& );
void stateChanged( SipPlugin::ConnectionState state );

View File

@@ -365,6 +365,12 @@ TomahawkSettings::recentlyPlayedPlaylists() const
return playlists;
}
QStringList
TomahawkSettings::recentlyPlayedPlaylistGuids() const
{
return value( "playlists/recentlyPlayed" ).toStringList();
}
void
TomahawkSettings::appendRecentlyPlayedPlaylist( const Tomahawk::playlist_ptr& playlist )
@@ -375,6 +381,8 @@ TomahawkSettings::appendRecentlyPlayedPlaylist( const Tomahawk::playlist_ptr& pl
playlist_guids.append( playlist->guid() );
setValue( "playlists/recentlyPlayed", playlist_guids );
emit recentlyPlayedPlaylistAdded( playlist );
}
QString

View File

@@ -66,6 +66,7 @@ public:
void setPlaylistColumnSizes( const QString& playlistid, const QByteArray& state );
QList<Tomahawk::playlist_ptr> recentlyPlayedPlaylists() const;
QStringList recentlyPlayedPlaylistGuids() const;
void appendRecentlyPlayedPlaylist( const Tomahawk::playlist_ptr& playlist );
/// SIP plugins
@@ -158,6 +159,7 @@ public:
signals:
void changed();
void recentlyPlayedPlaylistAdded( const Tomahawk::playlist_ptr& playlist );
private:
void doUpgrade( int oldVersion, int newVersion );

View File

@@ -121,6 +121,8 @@ ViewManager::ViewManager( QObject* parent )
m_widget->layout()->setMargin( 0 );
m_widget->layout()->setSpacing( 0 );
connect( AudioEngine::instance(), SIGNAL( playlistChanged( PlaylistInterface* ) ), this, SLOT( playlistInterfaceChanged( PlaylistInterface* ) ) );
connect( &m_filterTimer, SIGNAL( timeout() ), SLOT( applyFilter() ) );
connect( m_topbar, SIGNAL( filterTextChanged( QString ) ),
@@ -180,7 +182,7 @@ ViewManager::show( const Tomahawk::playlist_ptr& playlist )
}
setPage( view );
TomahawkSettings::instance()->appendRecentlyPlayedPlaylist( playlist );
emit numSourcesChanged( SourceList::instance()->count() );
return view;
@@ -206,7 +208,6 @@ ViewManager::show( const Tomahawk::dynplaylist_ptr& playlist )
else
m_queueView->show();
TomahawkSettings::instance()->appendRecentlyPlayedPlaylist( playlist );
emit numSourcesChanged( SourceList::instance()->count() );
return m_dynamicWidgets.value( playlist );
@@ -421,6 +422,22 @@ ViewManager::showSuperCollection()
return shown;
}
void
ViewManager::playlistInterfaceChanged( PlaylistInterface* interface )
{
playlist_ptr pl = playlistForInterface( interface );
if ( !pl.isNull() )
{
TomahawkSettings::instance()->appendRecentlyPlayedPlaylist( pl );
} else
{
pl = dynamicPlaylistForInterface( interface );
if ( !pl.isNull() )
TomahawkSettings::instance()->appendRecentlyPlayedPlaylist( pl );
}
}
Tomahawk::ViewPage*
ViewManager::showWelcomePage()
{
@@ -599,7 +616,7 @@ ViewManager::setPage( ViewPage* page, bool trackHistory )
qDebug() << "View page shown:" << page->title();
emit viewPageActivated( page );
if ( !AudioEngine::instance()->isPlaying() )
if ( !AudioEngine::instance()->playlist() )
AudioEngine::instance()->setPlaylist( currentPlaylistInterface() );
// UGH!

View File

@@ -145,6 +145,8 @@ public slots:
void setRepeatMode( PlaylistInterface::RepeatMode mode );
void setShuffled( bool enabled );
void playlistInterfaceChanged( PlaylistInterface* );
// called by the playlist creation dbcmds
void createPlaylist( const Tomahawk::source_ptr& src, const QVariant& contents );
void createDynamicPlaylist( const Tomahawk::source_ptr& src, const QVariant& contents );

View File

@@ -0,0 +1,177 @@
/*
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 2011 Leo Franchi <leo.franchi@kdab.com>
This program is 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.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "welcomeplaylistmodel.h"
#include <tomahawksettings.h>
#include <audio/audioengine.h>
#include <sourcelist.h>
using namespace Tomahawk;
WelcomePlaylistModel::WelcomePlaylistModel( QObject* parent )
: QAbstractListModel( parent )
, m_waitingForSome( true )
{
loadFromSettings();
connect( SourceList::instance(), SIGNAL( sourceAdded( Tomahawk::source_ptr ) ), this, SLOT( onSourceAdded( Tomahawk::source_ptr ) ), Qt::QueuedConnection );
connect( TomahawkSettings::instance(), SIGNAL( recentlyPlayedPlaylistAdded( Tomahawk::playlist_ptr ) ), this, SLOT( plAdded( Tomahawk::playlist_ptr ) ) );
connect( AudioEngine::instance(),SIGNAL( playlistChanged( PlaylistInterface* ) ), this, SLOT( playlistChanged( PlaylistInterface* ) ), Qt::QueuedConnection );
emit emptinessChanged( m_recplaylists.isEmpty() );
}
void
WelcomePlaylistModel::loadFromSettings()
{
if( !m_waitingForSome )
return;
beginResetModel();
m_recplaylists.clear();
m_waitingForSome = false;
QStringList playlist_guids = TomahawkSettings::instance()->recentlyPlayedPlaylistGuids();
for( int i = playlist_guids.size() - 1; i >= 0; i-- )
{
qDebug() << "loading playlist" << playlist_guids[i];
playlist_ptr pl = m_cached.value( playlist_guids[i], playlist_ptr() );
if( pl.isNull() )
pl = Tomahawk::Playlist::load( playlist_guids[i] );
if ( !pl.isNull() ) {
m_recplaylists << pl;
if( !m_cached.contains( playlist_guids[i] ) )
m_cached[playlist_guids[i]] = pl;
} else
m_waitingForSome = true;
}
endResetModel();
emit emptinessChanged( m_recplaylists.isEmpty() );
}
QVariant
WelcomePlaylistModel::data( const QModelIndex& index, int role ) const
{
if( !index.isValid() || !hasIndex( index.row(), index.column(), index.parent() ) )
return QVariant();
playlist_ptr pl = m_recplaylists[index.row()];
switch( role )
{
case Qt::DisplayRole:
return pl->title();
case PlaylistRole:
return QVariant::fromValue< Tomahawk::playlist_ptr >( pl );
case ArtistRole:
{
if( m_artists.value( pl ).isEmpty() )
{
QStringList artists;
foreach( const Tomahawk::plentry_ptr& entry, pl->entries() )
{
if ( !artists.contains( entry->query()->artist() ) )
artists << entry->query()->artist();
}
m_artists[pl] = artists.join( ", " );
}
return m_artists[pl];
}
case TrackCountRole:
return pl->entries().count();
default:
return QVariant();
}
}
void
WelcomePlaylistModel::onSourceAdded( const Tomahawk::source_ptr& source )
{
connect( source->collection().data(), SIGNAL( playlistsAdded( QList<Tomahawk::playlist_ptr> ) ), SLOT( loadFromSettings() ) );
connect( source->collection().data(), SIGNAL( playlistsDeleted( QList<Tomahawk::playlist_ptr> ) ), SLOT( onPlaylistsRemoved( QList<Tomahawk::playlist_ptr> ) ) );
}
void
WelcomePlaylistModel::onPlaylistsRemoved( QList< playlist_ptr > playlists )
{
foreach( const playlist_ptr& pl, playlists ) {
if( m_recplaylists.contains( pl ) ) {
m_artists.remove( pl );
m_cached.remove( pl->guid() );
int idx = m_recplaylists.indexOf( pl );
beginRemoveRows( QModelIndex(), idx, idx );
m_recplaylists.removeAt( idx );
endRemoveRows();
}
}
emit emptinessChanged( m_recplaylists.isEmpty() );
}
int
WelcomePlaylistModel::rowCount( const QModelIndex& ) const
{
return m_recplaylists.count();
}
void
WelcomePlaylistModel::plAdded( const playlist_ptr& pl )
{
onPlaylistsRemoved( QList< playlist_ptr >() << pl );
beginInsertRows( QModelIndex(), 0, 0 );
m_recplaylists.prepend( pl );;
endInsertRows();
emit emptinessChanged( m_recplaylists.isEmpty() );
}
void
WelcomePlaylistModel::playlistChanged( PlaylistInterface* pli )
{
// ARG
if( Playlist* pl = dynamic_cast< Playlist* >( pli ) ) {
// look for it, qsharedpointer fail
playlist_ptr ptr;
foreach( const playlist_ptr& test, m_recplaylists ) {
if( test.data() == pl )
ptr = test;
}
if( !ptr.isNull() && m_artists.contains( ptr ) ) {
m_artists[ ptr ] = QString();
}
QModelIndex idx = index( m_recplaylists.indexOf( ptr ), 0, QModelIndex() );
emit dataChanged( idx, idx );
}
}

View File

@@ -0,0 +1,59 @@
/*
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 2011 Leo Franchi <leo.franchi@kdab.com>
This program is 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.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef WELCOMEPLAYLISTMODEL_H
#define WELCOMEPLAYLISTMODEL_H
#include <QModelIndex>
#include "playlist.h"
class WelcomePlaylistModel : public QAbstractListModel
{
Q_OBJECT
public:
enum ItemRoles
{ ArtistRole = Qt::UserRole, TrackCountRole, PlaylistRole };
explicit WelcomePlaylistModel( QObject* parent = 0 );
virtual QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const;
virtual int rowCount( const QModelIndex& parent = QModelIndex() ) const;
signals:
void emptinessChanged( bool isEmpty );
private slots:
void playlistChanged( PlaylistInterface* );
void onSourceAdded( const Tomahawk::source_ptr& source );
void onPlaylistsRemoved( QList<Tomahawk::playlist_ptr> );
void loadFromSettings();
void plAdded( const Tomahawk::playlist_ptr& );
private:
QList< Tomahawk::playlist_ptr > m_recplaylists;
QHash< QString, Tomahawk::playlist_ptr > m_cached;
mutable QHash< Tomahawk::playlist_ptr, QString > m_artists;
bool m_waitingForSome;
};
#endif // WELCOMEPLAYLISTMODEL_H

View File

@@ -31,6 +31,7 @@
#include "tomahawksettings.h"
#include <QPainter>
#include "welcomeplaylistmodel.h"
#define HISTORY_TRACK_ITEMS 50
#define HISTORY_PLAYLIST_ITEMS 10
@@ -44,9 +45,14 @@ WelcomeWidget::WelcomeWidget( QWidget* parent )
ui->setupUi( this );
ui->playlistWidget->setItemDelegate( new PlaylistDelegate() );
WelcomePlaylistModel* model = new WelcomePlaylistModel( this );
ui->playlistWidget->setModel( model );
ui->playlistWidget->overlay()->resize( 380, 86 );
ui->tracksView->overlay()->setEnabled( false );
connect( model,SIGNAL( emptinessChanged( bool) ), this, SLOT( updatePlaylists() ) );
m_tracksModel = new PlaylistModel( ui->tracksView );
ui->tracksView->setPlaylistModel( m_tracksModel );
m_tracksModel->loadHistory( Tomahawk::source_ptr(), HISTORY_TRACK_ITEMS );
@@ -56,7 +62,7 @@ WelcomeWidget::WelcomeWidget( QWidget* parent )
connect( SourceList::instance(), SIGNAL( sourceAdded( Tomahawk::source_ptr ) ), SLOT( onSourceAdded( Tomahawk::source_ptr ) ) );
connect( ui->playlistWidget, SIGNAL( itemActivated( QListWidgetItem* ) ), SLOT( onPlaylistActivated( QListWidgetItem* ) ) );
connect( ui->playlistWidget, SIGNAL( activated( QModelIndex ) ), SLOT( onPlaylistActivated( QModelIndex ) ) );
connect( AudioEngine::instance() ,SIGNAL( playlistChanged( PlaylistInterface* ) ), this, SLOT( updatePlaylists() ), Qt::QueuedConnection );
}
@@ -70,10 +76,10 @@ WelcomeWidget::~WelcomeWidget()
void
WelcomeWidget::updatePlaylists()
{
ui->playlistWidget->clear();
QList<Tomahawk::playlist_ptr> playlists = TomahawkSettings::instance()->recentlyPlayedPlaylists();
// ui->playlistWidget->clear();
// QList<Tomahawk::playlist_ptr> playlists = TomahawkSettings::instance()->recentlyPlayedPlaylists();
/*
foreach( const Tomahawk::playlist_ptr& playlist, playlists )
{
connect( playlist.data(), SIGNAL( revisionLoaded( Tomahawk::PlaylistRevision ) ), SLOT( refresh() ) );
@@ -81,9 +87,10 @@ WelcomeWidget::updatePlaylists()
PlaylistWidgetItem* item = new PlaylistWidgetItem( playlist );
ui->playlistWidget->addItem( item );
item->setData( Qt::DisplayRole, playlist->title() );
}
}*/
if ( !playlists.count() )
int num = ui->playlistWidget->model()->rowCount( QModelIndex() );
if ( num == 0 )
{
ui->playlistWidget->overlay()->setText( tr( "You have not played any playlists yet." ) );
ui->playlistWidget->overlay()->show();
@@ -92,19 +99,9 @@ WelcomeWidget::updatePlaylists()
ui->playlistWidget->overlay()->hide();
}
void
WelcomeWidget::refresh()
{
ui->playlistWidget->update();
}
void
WelcomeWidget::onSourceAdded( const Tomahawk::source_ptr& source )
{
connect( source->collection().data(), SIGNAL( playlistsAdded( QList<Tomahawk::playlist_ptr> ) ), SLOT( updatePlaylists() ) );
connect( source->collection().data(), SIGNAL( playlistsDeleted( QList<Tomahawk::playlist_ptr> ) ), SLOT( updatePlaylists() ) );
connect( source.data(), SIGNAL( playbackFinished( Tomahawk::query_ptr ) ), SLOT( onPlaybackFinished( Tomahawk::query_ptr ) ) );
}
@@ -132,15 +129,15 @@ WelcomeWidget::onPlaybackFinished( const Tomahawk::query_ptr& query )
void
WelcomeWidget::onPlaylistActivated( QListWidgetItem* item )
WelcomeWidget::onPlaylistActivated( const QModelIndex& item )
{
qDebug() << Q_FUNC_INFO;
PlaylistWidgetItem* pwi = dynamic_cast<PlaylistWidgetItem*>(item);
if( Tomahawk::dynplaylist_ptr dynplaylist = pwi->playlist().dynamicCast< Tomahawk::DynamicPlaylist >() )
Tomahawk::playlist_ptr pl = item.data( WelcomePlaylistModel::PlaylistRole ).value< Tomahawk::playlist_ptr >();
if( Tomahawk::dynplaylist_ptr dynplaylist = pl.dynamicCast< Tomahawk::DynamicPlaylist >() )
ViewManager::instance()->show( dynplaylist );
else
ViewManager::instance()->show( pwi->playlist() );
ViewManager::instance()->show( pl );
}
@@ -159,42 +156,6 @@ WelcomeWidget::changeEvent( QEvent* e )
}
}
QVariant
PlaylistWidgetItem::data( int role ) const
{
if ( role == ArtistRole )
{
if ( m_artists.isEmpty() )
{
QStringList artists;
foreach( const Tomahawk::plentry_ptr& entry, m_playlist->entries() )
{
if ( !artists.contains( entry->query()->artist() ) )
artists << entry->query()->artist();
}
m_artists = artists.join( ", " );
}
return m_artists;
}
if ( role == TrackCountRole )
{
return m_playlist->entries().count();
}
if ( role == Qt::DisplayRole )
{
return m_playlist->title();
}
return QListWidgetItem::data( role );
}
QSize
PlaylistDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const
{
@@ -228,9 +189,9 @@ PlaylistDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option,
painter->drawPixmap( option.rect.adjusted( 10, 13, -option.rect.width() + 48, -13 ), m_playlistIcon );
painter->drawText( option.rect.adjusted( 56, 26, -100, -8 ), index.data( PlaylistWidgetItem::ArtistRole ).toString() );
painter->drawText( option.rect.adjusted( 56, 26, -100, -8 ), index.data( WelcomePlaylistModel::ArtistRole ).toString() );
QString trackCount = tr( "%1 tracks" ).arg( index.data( PlaylistWidgetItem::TrackCountRole ).toString() );
QString trackCount = tr( "%1 tracks" ).arg( index.data( WelcomePlaylistModel::TrackCountRole ).toString() );
painter->drawText( option.rect.adjusted( option.rect.width() - 96, 2, 0, -2 ), trackCount, to );
painter->setFont( boldFont );
@@ -241,7 +202,7 @@ PlaylistDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option,
PlaylistWidget::PlaylistWidget( QWidget* parent )
: QListWidget( parent )
: QListView( parent )
{
m_overlay = new OverlayWidget( this );
}

View File

@@ -59,28 +59,7 @@ private:
QPixmap m_playlistIcon;
};
class DLLEXPORT PlaylistWidgetItem : public QListWidgetItem
{
public:
enum ItemRoles
{ ArtistRole = Qt::UserRole, TrackCountRole };
PlaylistWidgetItem( const Tomahawk::playlist_ptr& playlist ) : QListWidgetItem() { m_playlist = playlist; }
~PlaylistWidgetItem() {}
virtual QVariant data( int role ) const;
Tomahawk::playlist_ptr playlist() const { return m_playlist; }
private:
Tomahawk::playlist_ptr m_playlist;
mutable QString m_artists;
};
class DLLEXPORT PlaylistWidget : public QListWidget
class DLLEXPORT PlaylistWidget : public QListView
{
public:
PlaylistWidget( QWidget* parent = 0 );
@@ -118,11 +97,10 @@ signals:
public slots:
void updatePlaylists();
void refresh();
private slots:
void onSourceAdded( const Tomahawk::source_ptr& source );
void onPlaylistActivated( QListWidgetItem* item );
void onPlaylistActivated( const QModelIndex& );
void onPlaybackFinished( const Tomahawk::query_ptr& query );
void checkQueries();

View File

@@ -55,6 +55,12 @@ main( int argc, char *argv[] )
translator.load( QString( ":/lang/tomahawk_" ) + locale );
a.installTranslator( &translator );
if ( argc > 1 )
{
QString arg = a.arguments()[ 1 ];
a.loadUrl( arg );
}
return a.exec();
}

View File

@@ -128,6 +128,7 @@ JabberPlugin::onConnected()
emit addMenu( m_menu );
}
emit connected();
}

View File

@@ -29,6 +29,8 @@
#include <jreen/capabilities.h>
#include <jreen/vcardupdate.h>
#include <jreen/vcard.h>
#include <jreen/directconnection.h>
#include <jreen/tcpconnection.h>
#include <qjson/parser.h>
#include <qjson/serializer.h>
@@ -81,6 +83,8 @@ JabberPlugin::JabberPlugin( const QString& pluginId )
// general client setup
m_client = new Jreen::Client( jid, m_currentPassword );
setupClientHelper();
m_client->registerStanzaExtension(new TomahawkSipMessageFactory);
m_currentResource = QString::fromAscii( "tomahawk%1" ).arg( QString::number( qrand() % 10000 ) );
m_client->setResource( m_currentResource );
@@ -88,6 +92,9 @@ JabberPlugin::JabberPlugin( const QString& pluginId )
// add VCardUpdate extension to own presence
m_client->presence().addExtension( new Jreen::VCardUpdate() );
// initaliaze the roster
m_roster = new Jreen::SimpleRoster( m_client );
// initialize the AvatarManager
m_avatarManager = new AvatarManager( m_client );
@@ -111,9 +118,14 @@ JabberPlugin::JabberPlugin( const QString& pluginId )
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(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_roster, SIGNAL(presenceReceived(Jreen::RosterItem::Ptr,Jreen::Presence)),
SLOT(onPresenceReceived(Jreen::RosterItem::Ptr,Jreen::Presence)));
connect(m_roster, SIGNAL(subscriptionReceived(Jreen::RosterItem::Ptr,Jreen::Presence)),
SLOT(onSubscriptionReceived(Jreen::RosterItem::Ptr,Jreen::Presence)));
connect(m_avatarManager, SIGNAL(newAvatar(QString)), SLOT(onNewAvatar(QString)));
}
@@ -123,9 +135,22 @@ JabberPlugin::~JabberPlugin()
}
void
JabberPlugin::setProxy( QNetworkProxy* proxy )
JabberPlugin::setProxy( const QNetworkProxy &proxy )
{
qDebug() << Q_FUNC_INFO << "Not implemented";
if(m_currentServer.isEmpty() || !(m_currentPort > 0))
{
// patches are welcome in Jreen that implement jdns through proxy
qDebug() << Q_FUNC_INFO << "Jreen proxy only works when you explicitly set host and port";
Q_ASSERT(false);
return;
}
if(!m_client->connection())
{
m_client->setConnection(new Jreen::TcpConnection(m_currentServer, m_currentPort));
}
qobject_cast<Jreen::DirectConnection*>(m_client->connection())->setProxy(proxy);
}
@@ -174,18 +199,20 @@ JabberPlugin::connectPlugin( bool startup )
if ( startup && !readAutoConnect() )
return false;
QString jid = m_currentUsername = accountName();
QString server = m_currentServer = readServer();
QString password = m_currentPassword = readPassword();
unsigned int port = m_currentPort = readPort();
if(m_client->isConnected())
{
qDebug() << Q_FUNC_INFO << "Already connected to server, not connecting again...";
return true; //FIXME: should i return false here?!
}
qDebug() << "Connecting to the XMPP server...";
qDebug() << "Connecting to the XMPP server..." << (m_state == Connected);
qDebug() << m_client->jid().full();
//m_client->setServer( m_client->jid().domain() );
qDebug() << m_client->server() << m_client->port();
//FIXME: we're badly workarounding some missing reconnection api here, to be fixed soon
QTimer::singleShot(1000, m_client, SLOT( connectToServer() ) );
//m_client->connectToServer();
m_state = Connecting;
emit stateChanged( m_state );
@@ -195,9 +222,7 @@ JabberPlugin::connectPlugin( bool startup )
void
JabberPlugin::disconnectPlugin()
{
qDebug() << Q_FUNC_INFO << (m_state == Connected);
if( m_state == Disconnected )
if(!m_client->isConnected())
return;
foreach(const Jreen::JID &peer, m_peers.keys())
@@ -239,7 +264,6 @@ JabberPlugin::onConnect()
m_client->setPingInterval(1000);
// 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
@@ -392,8 +416,7 @@ JabberPlugin::sendMsg(const QString& to, const QString& msg)
sipMessage = new TomahawkSipMessage(m["ip"].toString(),
m["port"].toInt(),
m["uniqname"].toString(),
m["key"].toString(),
m["visible"].toBool()
m["key"].toString()
);
}
else
@@ -474,17 +497,34 @@ JabberPlugin::checkSettings()
m_currentServer = readServer();
m_currentPort = readPort();
Jreen::JID jid = Jreen::JID( accountName() );
m_client->setJID( jid );
m_client->setPassword( m_currentPassword );
m_client->setServer( m_currentServer );
m_client->setPort( m_currentPort );
setupClientHelper();
qDebug() << Q_FUNC_INFO << "Updated settings";
connectPlugin( false );
}
}
void JabberPlugin::setupClientHelper()
{
Jreen::JID jid = Jreen::JID( m_currentUsername );
m_client->setJID( jid );
m_client->setPassword( m_currentPassword );
if( !m_currentServer.isEmpty() )
{
// set explicit server details
m_client->setServer( m_currentServer );
m_client->setPort( m_currentPort );
}
else
{
// let jreen find out server and port via jdns
m_client->setServer( jid.domain() );
m_client->setPort( -1 );
}
}
void JabberPlugin::addMenuHelper()
{
if( !m_menu )
@@ -539,8 +579,10 @@ void JabberPlugin::onNewMessage(const Jreen::Message& message)
}
void JabberPlugin::onNewPresence( const Jreen::Presence& presence)
void JabberPlugin::onPresenceReceived( const Jreen::RosterItem::Ptr &item, const Jreen::Presence& presence )
{
Q_UNUSED(item);
Jreen::JID jid = presence.from();
QString fulljid( jid.full() );
@@ -582,6 +624,93 @@ void JabberPlugin::onNewPresence( const Jreen::Presence& presence)
}
}
void JabberPlugin::onSubscriptionReceived(const Jreen::RosterItem::Ptr& item, const Jreen::Presence& presence)
{
qDebug() << Q_FUNC_INFO << "presence type: " << presence.subtype();
if(item)
qDebug() << Q_FUNC_INFO << presence.from().full() << "subs" << item->subscription() << "ask" << item->ask();
else
qDebug() << Q_FUNC_INFO << "item empty";
// don't do anything if the contact is already subscribed to us
if( presence.subtype() != Jreen::Presence::Subscribe ||
(
item && (item->subscription() == Jreen::RosterItem::From || item->subscription() == Jreen::RosterItem::Both)
)
)
{
return;
}
// check if the requester is already on the roster
if(item &&
(
item->subscription() == Jreen::RosterItem::To ||
( item->subscription() == Jreen::RosterItem::None && !item->ask().isEmpty() )
)
)
{
qDebug() << Q_FUNC_INFO << presence.from().bare() << "already on the roster so we assume ack'ing subscription request is okay...";
m_roster->allowSubscription(presence.from(), true);
return;
}
qDebug() << Q_FUNC_INFO << presence.from().bare() << "open subscription request box";
// preparing the confirm box for the user
QMessageBox *confirmBox = new QMessageBox(
QMessageBox::Question,
tr( "Authorize User" ),
QString( tr( "Do you want to grant <b>%1</b> access to your Collection?" ) ).arg(presence.from().bare()),
QMessageBox::Yes | QMessageBox::No,
0
);
// add confirmBox to m_subscriptionConfirmBoxes
m_subscriptionConfirmBoxes.insert( presence.from(), confirmBox );
// display the box and wait for the answer
confirmBox->open( this, SLOT( onSubscriptionRequestConfirmed( int ) ) );
}
void
JabberPlugin::onSubscriptionRequestConfirmed( int result )
{
qDebug() << Q_FUNC_INFO << result;
QList< QMessageBox* > confirmBoxes = m_subscriptionConfirmBoxes.values();
Jreen::JID jid;
foreach( QMessageBox* currentBox, confirmBoxes )
{
if( currentBox == sender() )
{
jid = m_subscriptionConfirmBoxes.key( currentBox );
}
}
qDebug() << Q_FUNC_INFO << "box confirmed for" << jid.bare();
// we got an answer, deleting the box
m_subscriptionConfirmBoxes.remove( jid );
sender()->deleteLater();
QMessageBox::StandardButton allowSubscription = static_cast<QMessageBox::StandardButton>( result );
if ( allowSubscription == QMessageBox::Yes )
{
qDebug() << Q_FUNC_INFO << jid.bare() << "accepted by user, adding to roster";
addContact(jid, "");
}
else
{
qDebug() << Q_FUNC_INFO << jid.bare() << "declined by user";
}
m_roster->allowSubscription( jid, allowSubscription == QMessageBox::Yes );
}
void JabberPlugin::onNewIq(const Jreen::IQ& iq, int context)
{
if( context == RequestDisco )

View File

@@ -38,6 +38,7 @@
#include <jreen/mucroom.h>
#include <QNetworkProxy>
#include <QMessageBox>
#define MYNAME "SIPJREEN"
#define TOMAHAWK_FEATURE QLatin1String( "tomahawk:sip:v1" )
@@ -81,7 +82,6 @@ public:
virtual QWidget* configWidget();
virtual void saveConfig();
void setProxy( QNetworkProxy* proxy );
signals:
void jidChanged( const QString& );
@@ -92,6 +92,7 @@ public slots:
void sendMsg( const QString& to, const QString& msg );
void broadcastMsg( const QString &msg );
void addContact( const QString &jid, const QString& msg = QString() );
void setProxy( const QNetworkProxy &proxy );
protected:
Ui_JabberConfig* m_ui; // so the google wrapper can change the config dialog a bit
@@ -102,7 +103,10 @@ private slots:
void onDisconnect(Jreen::Client::DisconnectReason reason);
void onAuthError(int code, const QString &msg);
void onNewPresence( const Jreen::Presence& presence );
void onPresenceReceived( const Jreen::RosterItem::Ptr &item, const Jreen::Presence& presence );
void onSubscriptionReceived( const Jreen::RosterItem::Ptr &item, const Jreen::Presence& presence );
void onSubscriptionRequestConfirmed( int result );
void onNewMessage( const Jreen::Message& message );
void onError( const Jreen::Connection::SocketError& e )
{
@@ -117,6 +121,7 @@ private:
bool readAutoConnect();
int readPort();
void setupClientHelper();
void addMenuHelper();
void removeMenuHelper();
@@ -142,6 +147,7 @@ private:
Jreen::MUCRoom *m_room;
Jreen::SimpleRoster *m_roster;
QHash<Jreen::JID, Jreen::Presence::Type> m_peers;
QHash<Jreen::JID, QMessageBox*> m_subscriptionConfirmBoxes;
enum IqContext { NoContext, RequestDisco, RequestedDisco, SipMessageSent, RequestedVCard };
QStringList m_legacy_peers;
AvatarManager *m_avatarManager;

View File

@@ -26,14 +26,14 @@ public:
bool visible;
};
TomahawkSipMessage::TomahawkSipMessage(QString ip, unsigned int port, QString uniqname, QString key, bool visible) : d_ptr(new TomahawkSipMessagePrivate)
TomahawkSipMessage::TomahawkSipMessage(const QString &ip, unsigned int port, const QString &uniqname, const QString &key) : d_ptr(new TomahawkSipMessagePrivate)
{
Q_D(TomahawkSipMessage);
d->ip = ip;
d->port = port;
d->uniqname = uniqname;
d->key = key;
d->visible = visible;
d->visible = true;
}
TomahawkSipMessage::TomahawkSipMessage() : d_ptr(new TomahawkSipMessagePrivate)
@@ -58,12 +58,12 @@ unsigned int TomahawkSipMessage::port() const
return d_func()->port;
}
QString TomahawkSipMessage::uniqname() const
const QString TomahawkSipMessage::uniqname() const
{
return d_func()->uniqname;
}
QString TomahawkSipMessage::key() const
const QString TomahawkSipMessage::key() const
{
return d_func()->key;
}

View File

@@ -11,15 +11,17 @@ 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 true
TomahawkSipMessage(const QString &ip, unsigned int port, const QString &uniqname, const QString &key);
// 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;
const QString uniqname() const;
const QString key() const;
bool visible() const;
private:
QScopedPointer<TomahawkSipMessagePrivate> d_ptr;

View File

@@ -120,5 +120,8 @@ void TomahawkSipMessageFactory::serialize(StanzaExtension *extension, QXmlStream
StanzaExtension::Ptr TomahawkSipMessageFactory::createExtension()
{
return StanzaExtension::Ptr(new TomahawkSipMessage(m_ip, m_port, m_uniqname, m_key, m_visible));
if(m_visible)
return StanzaExtension::Ptr(new TomahawkSipMessage(m_ip, m_port, m_uniqname, m_key));
else
return StanzaExtension::Ptr(new TomahawkSipMessage());
}

View File

@@ -310,6 +310,7 @@ TwitterPlugin::connectTimerFired()
{
peerData["lastseen"] = QDateTime::currentMSecsSinceEpoch();
m_cachedPeers[screenName] = peerData;
continue;
}
if ( QDateTime::currentMSecsSinceEpoch() - peerData["lastseen"].toLongLong() > 1209600000 ) // 2 weeks

View File

@@ -167,7 +167,6 @@ CategoryItem::insertItems( QList< SourceTreeItem* > items )
curCount--;
beginRowsAdded( curCount, curCount + items.size() - 1 );
foreach( SourceTreeItem* item, items ) {
int index = m_showAdd ? children().count() - 1 : children().count();
insertChild( children().count() - 1, item );
}
endRowsAdded();

View File

@@ -55,26 +55,26 @@ CollectionItem::CollectionItem( SourcesModel* mdl, SourceTreeItem* parent, cons
// load auto playlists and stations!
connect( source.data(), SIGNAL( stats( QVariantMap ) ), this, SIGNAL( updated() ) );
connect( source.data(), SIGNAL( playbackStarted( Tomahawk::query_ptr ) ), this, SIGNAL( updated() ) );
connect( source.data(), SIGNAL( stateChanged() ), this, SIGNAL( updated() ) );
connect( source.data(), SIGNAL( offline() ), this, SIGNAL( updated() ) );
connect( source.data(), SIGNAL( online() ), this, SIGNAL( updated() ) );
connect( source.data(), SIGNAL( stats( QVariantMap ) ), this, SIGNAL( updated() ) );
connect( source.data(), SIGNAL( playbackStarted( Tomahawk::query_ptr ) ), this, SIGNAL( updated() ) );
connect( source.data(), SIGNAL( stateChanged() ), this, SIGNAL( updated() ) );
connect( source.data(), SIGNAL( offline() ), this, SIGNAL( updated() ) );
connect( source.data(), SIGNAL( online() ), this, SIGNAL( updated() ) );
connect( source->collection().data(), SIGNAL( playlistsAdded( QList<Tomahawk::playlist_ptr> ) ),
SLOT( onPlaylistsAdded( QList<Tomahawk::playlist_ptr> ) ), Qt::QueuedConnection );
connect( source->collection().data(), SIGNAL( playlistsDeleted( QList<Tomahawk::playlist_ptr> ) ),
SLOT( onPlaylistsDeleted( QList<Tomahawk::playlist_ptr> ) ), Qt::QueuedConnection );
connect( source->collection().data(), SIGNAL( playlistsAdded( QList<Tomahawk::playlist_ptr> ) ),
SLOT( onPlaylistsAdded( QList<Tomahawk::playlist_ptr> ) ), Qt::QueuedConnection );
connect( source->collection().data(), SIGNAL( playlistsDeleted( QList<Tomahawk::playlist_ptr> ) ),
SLOT( onPlaylistsDeleted( QList<Tomahawk::playlist_ptr> ) ), Qt::QueuedConnection );
connect( source->collection().data(), SIGNAL( autoPlaylistsAdded( QList< Tomahawk::dynplaylist_ptr > ) ),
SLOT( onAutoPlaylistsAdded( QList<Tomahawk::dynplaylist_ptr> ) ), Qt::QueuedConnection );
connect( source->collection().data(), SIGNAL( autoPlaylistsDeleted( QList<Tomahawk::dynplaylist_ptr> ) ),
SLOT( onAutoPlaylistsDeleted( QList<Tomahawk::dynplaylist_ptr> ) ), Qt::QueuedConnection );
connect( source->collection().data(), SIGNAL( autoPlaylistsAdded( QList< Tomahawk::dynplaylist_ptr > ) ),
SLOT( onAutoPlaylistsAdded( QList<Tomahawk::dynplaylist_ptr> ) ), Qt::QueuedConnection );
connect( source->collection().data(), SIGNAL( autoPlaylistsDeleted( QList<Tomahawk::dynplaylist_ptr> ) ),
SLOT( onAutoPlaylistsDeleted( QList<Tomahawk::dynplaylist_ptr> ) ), Qt::QueuedConnection );
connect( source->collection().data(), SIGNAL( stationsAdded( QList<Tomahawk::dynplaylist_ptr> ) ),
SLOT( onStationsAdded( QList<Tomahawk::dynplaylist_ptr> ) ), Qt::QueuedConnection );
connect( source->collection().data(), SIGNAL( stationsDeleted( QList<Tomahawk::dynplaylist_ptr> ) ),
SLOT( onStationsDeleted( QList<Tomahawk::dynplaylist_ptr> ) ), Qt::QueuedConnection );
connect( source->collection().data(), SIGNAL( stationsAdded( QList<Tomahawk::dynplaylist_ptr> ) ),
SLOT( onStationsAdded( QList<Tomahawk::dynplaylist_ptr> ) ), Qt::QueuedConnection );
connect( source->collection().data(), SIGNAL( stationsDeleted( QList<Tomahawk::dynplaylist_ptr> ) ),
SLOT( onStationsDeleted( QList<Tomahawk::dynplaylist_ptr> ) ), Qt::QueuedConnection );
}
Tomahawk::source_ptr

View File

@@ -44,7 +44,7 @@ SourcesModel::SourcesModel( QObject* parent )
appendItem( source_ptr() );
// add misc children of root node
GenericPageItem* recent = new GenericPageItem( this, m_rootItem->children().at( 0 ), tr( "Recently Played" ), QIcon( RESPATH "images/recently-played.png" ),
new GenericPageItem( this, m_rootItem->children().at( 0 ), tr( "Recently Played" ), QIcon( RESPATH "images/recently-played.png" ),
boost::bind( &ViewManager::showWelcomePage, ViewManager::instance() ),
boost::bind( &ViewManager::welcomeWidget, ViewManager::instance() )
);
@@ -193,10 +193,9 @@ SourcesModel::flags( const QModelIndex& index ) const
void
SourcesModel::appendItem( const Tomahawk::source_ptr& source )
{
beginInsertRows( QModelIndex(), rowCount(), rowCount() );
// append to end
CollectionItem* item = new CollectionItem( this, m_rootItem, source );
new CollectionItem( this, m_rootItem, source );
endInsertRows();
}
@@ -339,7 +338,7 @@ SourcesModel::linkSourceItemToPage( SourceTreeItem* item, ViewPage* p )
// TODO handle removal
m_sourceTreeLinks[ p ] = item;
if( m_viewPageDelayedCacheItem = p )
if( m_viewPageDelayedCacheItem == p )
emit selectRequest( indexFromItem( item ) );
m_viewPageDelayedCacheItem = 0;

View File

@@ -224,10 +224,10 @@ TomahawkApp::init()
qDebug() << "Setting NAM.";
TomahawkUtils::setNam( lastfm::nam() );
#else
#else
qDebug() << "Setting NAM.";
TomahawkUtils::setNam( new QNetworkAccessManager() );
#endif
#endif
// Set up proxy
//FIXME: This overrides the lastfm proxy above?

View File

@@ -218,11 +218,15 @@ lastfm::setNetworkAccessManager( QNetworkAccessManager* nam )
QMutexLocker l( &namAccessMutex );
QThread* thread = QThread::currentThread();
QNetworkAccessManager* oldNam = 0;
if ( threadNamHash.contains( thread ) && ourNamHash.contains( thread ) && ourNamHash[thread] )
delete threadNamHash[thread];
oldNam = threadNamHash[thread];
threadNamHash[thread] = nam;
ourNamHash[thread] = false;
if ( oldNam )
delete oldNam;
}