From 44585933dc8d727561ceac01e485ac92b7627f7b Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser <muesli@gmail.com> Date: Thu, 12 May 2011 00:35:05 +0200 Subject: [PATCH] * Auto advance to the next track in TreeView. * Show proper icon for TreeView. * Drag operations for tracks in TreeView / -Model. * Various shutdown fixes. * Properly hook up SipHandler signals again. --- include/tomahawk/tomahawkapp.h | 1 - src/libtomahawk/network/controlconnection.cpp | 9 ++- src/libtomahawk/pipeline.cpp | 30 +++++++-- src/libtomahawk/pipeline.h | 8 ++- src/libtomahawk/playlist/artistview.cpp | 66 ++++++++++--------- src/libtomahawk/playlist/artistview.h | 8 +-- src/libtomahawk/playlist/playlistmodel.cpp | 25 ++++++- src/libtomahawk/playlist/trackproxymodel.cpp | 1 - src/libtomahawk/playlist/trackview.cpp | 14 ++++ src/libtomahawk/playlist/treemodel.cpp | 57 ++++++++++++---- src/libtomahawk/playlist/treemodel.h | 4 ++ src/libtomahawk/playlist/treeproxymodel.cpp | 23 ++++++- src/libtomahawk/playlist/treeproxymodel.h | 5 ++ src/libtomahawk/result.cpp | 22 +++++-- src/libtomahawk/result.h | 4 +- src/libtomahawk/sip/SipHandler.cpp | 24 +++++-- src/libtomahawk/sip/SipPlugin.h | 2 +- src/libtomahawk/sourcelist.cpp | 1 - src/libtomahawk/sourcelist.h | 2 +- src/resolvers/qtscriptresolver.cpp | 2 +- src/sip/jreen/jabber.cpp | 29 ++++++-- src/sourcetree/items/playlistitems.cpp | 66 ++++++++++++------- src/sourcetree/sourcesmodel.cpp | 21 ++++++ src/sourcetree/sourcetreeview.cpp | 14 ++-- src/tomahawkapp.cpp | 16 +++-- src/tomahawkwindow.cpp | 10 +-- 26 files changed, 341 insertions(+), 123 deletions(-) diff --git a/include/tomahawk/tomahawkapp.h b/include/tomahawk/tomahawkapp.h index d814ea32d..ea51dfa12 100644 --- a/include/tomahawk/tomahawkapp.h +++ b/include/tomahawk/tomahawkapp.h @@ -82,7 +82,6 @@ public: void init(); static TomahawkApp* instance(); - SipHandler* sipHandler(); XMPPBot* xmppBot() { return m_xmppBot; } #ifndef TOMAHAWK_HEADLESS diff --git a/src/libtomahawk/network/controlconnection.cpp b/src/libtomahawk/network/controlconnection.cpp index 1982ee8d7..2d143d0f7 100644 --- a/src/libtomahawk/network/controlconnection.cpp +++ b/src/libtomahawk/network/controlconnection.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === - * + * * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org> * * Tomahawk is free software: you can redistribute it and/or modify @@ -53,11 +53,10 @@ ControlConnection::~ControlConnection() if ( !m_source.isNull() ) m_source->setOffline(); - + delete m_pingtimer; - m_servent->unregisterControlConnection(this); - if( m_dbsyncconn ) - m_dbsyncconn->deleteLater(); + m_servent->unregisterControlConnection( this ); + delete m_dbsyncconn; } diff --git a/src/libtomahawk/pipeline.cpp b/src/libtomahawk/pipeline.cpp index 97606389f..a996ef24f 100644 --- a/src/libtomahawk/pipeline.cpp +++ b/src/libtomahawk/pipeline.cpp @@ -41,29 +41,43 @@ Pipeline::instance() Pipeline::Pipeline( QObject* parent ) : QObject( parent ) - , m_index_ready( false ) + , m_running( false ) { s_instance = this; } +Pipeline::~Pipeline() +{ + m_running = false; +} + + void Pipeline::databaseReady() { - connect( Database::instance(), SIGNAL( indexReady() ), this, SLOT( indexReady() ), Qt::QueuedConnection ); + connect( Database::instance(), SIGNAL( indexReady() ), this, SLOT( start() ), Qt::QueuedConnection ); Database::instance()->loadIndex(); } -void Pipeline::indexReady() +void +Pipeline::start() { qDebug() << Q_FUNC_INFO << "shunting this many pending queries:" << m_queries_pending.size(); - m_index_ready = true; + m_running = true; shuntNext(); } +void +Pipeline::stop() +{ + m_running = false; +} + + void Pipeline::removeResolver( Resolver* r ) { @@ -210,7 +224,7 @@ Pipeline::reportResults( QID qid, const QList< result_ptr >& results ) void Pipeline::shuntNext() { - if ( !m_index_ready ) + if ( !m_running ) return; query_ptr q; @@ -245,6 +259,9 @@ Pipeline::shuntNext() void Pipeline::timeoutShunt( const query_ptr& q ) { + if ( !m_running ) + return; + // are we still waiting for a timeout? if ( m_qidsTimeout.contains( q->id() ) ) { @@ -259,6 +276,9 @@ Pipeline::timeoutShunt( const query_ptr& q ) void Pipeline::shunt( const query_ptr& q ) { + if ( !m_running ) + return; + qDebug() << Q_FUNC_INFO << q->solved() << q->toString() << q->id(); unsigned int lastweight = 0; unsigned int lasttimeout = 0; diff --git a/src/libtomahawk/pipeline.h b/src/libtomahawk/pipeline.h index 7f845f2e9..d07608747 100644 --- a/src/libtomahawk/pipeline.h +++ b/src/libtomahawk/pipeline.h @@ -44,6 +44,7 @@ public: static Pipeline* instance(); explicit Pipeline( QObject* parent = 0 ); + virtual ~Pipeline(); void reportResults( QID qid, const QList< result_ptr >& results ); @@ -67,6 +68,9 @@ public slots: void resolve( const query_ptr& q, bool prioritized = false ); void resolve( const QList<query_ptr>& qlist, bool prioritized = false ); void resolve( QID qid, bool prioritized = false ); + + void start(); + void stop(); void databaseReady(); signals: @@ -77,8 +81,6 @@ private slots: void shunt( const query_ptr& q ); void shuntNext(); - void indexReady(); - private: void setQIDState( const Tomahawk::query_ptr& query, int state ); int incQIDState( const Tomahawk::query_ptr& query ); @@ -95,7 +97,7 @@ private: // store queries here until DB index is loaded, then shunt them all QList< query_ptr > m_queries_pending; - bool m_index_ready; + bool m_running; static Pipeline* s_instance; }; diff --git a/src/libtomahawk/playlist/artistview.cpp b/src/libtomahawk/playlist/artistview.cpp index a3ae3232b..8d558f8fe 100644 --- a/src/libtomahawk/playlist/artistview.cpp +++ b/src/libtomahawk/playlist/artistview.cpp @@ -125,33 +125,14 @@ ArtistView::onItemActivated( const QModelIndex& index ) else if ( !item->album().isNull() ) ViewManager::instance()->show( item->album() ); else if ( !item->result().isNull() ) - AudioEngine::instance()->playItem( 0, item->result() ); + { + m_model->setCurrentItem( item->index ); + AudioEngine::instance()->playItem( m_proxyModel, item->result() ); + } } } -void -ArtistView::dragEnterEvent( QDragEnterEvent* event ) -{ - qDebug() << Q_FUNC_INFO; - QTreeView::dragEnterEvent( event ); -} - - -void -ArtistView::dragMoveEvent( QDragMoveEvent* event ) -{ - QTreeView::dragMoveEvent( event ); -} - - -void -ArtistView::dropEvent( QDropEvent* event ) -{ - QTreeView::dropEvent( event ); -} - - void ArtistView::paintEvent( QPaintEvent* event ) { @@ -178,15 +159,32 @@ ArtistView::onFilterChanged( const QString& ) void ArtistView::startDrag( Qt::DropActions supportedActions ) { - Q_UNUSED( supportedActions ); -} + QList<QPersistentModelIndex> pindexes; + QModelIndexList indexes; + foreach( const QModelIndex& idx, selectedIndexes() ) + { + if ( ( m_proxyModel->flags( idx ) & Qt::ItemIsDragEnabled ) ) + { + indexes << idx; + pindexes << idx; + } + } + if ( indexes.count() == 0 ) + return; -QPixmap -ArtistView::createDragPixmap( int itemCount ) const -{ - Q_UNUSED( itemCount ); - return QPixmap(); + qDebug() << "Dragging" << indexes.count() << "indexes"; + QMimeData* data = m_proxyModel->mimeData( indexes ); + if ( !data ) + return; + + QDrag* drag = new QDrag( this ); + drag->setMimeData( data ); + const QPixmap p = TomahawkUtils::createDragPixmap( indexes.count() ); + drag->setPixmap( p ); + drag->setHotSpot( QPoint( -20, -20 ) ); + + drag->exec( supportedActions, Qt::CopyAction ); } @@ -232,3 +230,11 @@ ArtistView::onScrollTimeout() QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ), Tomahawk::InfoSystem::InfoCustomData() ); } } + + +bool +ArtistView::jumpToCurrentTrack() +{ + scrollTo( m_proxyModel->currentItem(), QAbstractItemView::PositionAtCenter ); + return true; +} diff --git a/src/libtomahawk/playlist/artistview.h b/src/libtomahawk/playlist/artistview.h index e02107cbb..6123905ec 100644 --- a/src/libtomahawk/playlist/artistview.h +++ b/src/libtomahawk/playlist/artistview.h @@ -51,11 +51,12 @@ public: virtual QString title() const { return m_model->title(); } virtual QString description() const { return m_model->description(); } + virtual QPixmap pixmap() const { return QPixmap( RESPATH "images/music-icon.png" ); } virtual bool showStatsBar() const { return false; } virtual bool showModes() const { return true; } - virtual bool jumpToCurrentTrack() { return false; } + virtual bool jumpToCurrentTrack(); QString guid() const { return QString( "ArtistView" ); } @@ -64,9 +65,6 @@ public slots: protected: virtual void startDrag( Qt::DropActions supportedActions ); - virtual void dragEnterEvent( QDragEnterEvent* event ); - virtual void dragMoveEvent( QDragMoveEvent* event ); - virtual void dropEvent( QDropEvent* event ); virtual void resizeEvent( QResizeEvent* event ); void paintEvent( QPaintEvent* event ); @@ -77,8 +75,6 @@ private slots: void onScrollTimeout(); private: - QPixmap createDragPixmap( int itemCount ) const; - TreeHeader* m_header; TreeModel* m_model; TreeProxyModel* m_proxyModel; diff --git a/src/libtomahawk/playlist/playlistmodel.cpp b/src/libtomahawk/playlist/playlistmodel.cpp index 2d7e5ab1a..c6b246749 100644 --- a/src/libtomahawk/playlist/playlistmodel.cpp +++ b/src/libtomahawk/playlist/playlistmodel.cpp @@ -300,6 +300,7 @@ PlaylistModel::onRevisionLoaded( Tomahawk::PlaylistRevision revision ) bool PlaylistModel::dropMimeData( const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent ) { + qDebug() << "LALALA"; Q_UNUSED( column ); if ( action == Qt::IgnoreAction || isReadOnly() ) return true; @@ -319,11 +320,30 @@ PlaylistModel::dropMimeData( const QMimeData* data, Qt::DropAction action, int r qDebug() << data->formats(); + QList<Tomahawk::query_ptr> queries; + if ( data->hasFormat( "application/tomahawk.result.list" ) ) + { + QByteArray itemData = data->data( "application/tomahawk.result.list" ); + QDataStream stream( &itemData, QIODevice::ReadOnly ); + + while ( !stream.atEnd() ) + { + qlonglong qptr; + stream >> qptr; + + Tomahawk::result_ptr* result = reinterpret_cast<Tomahawk::result_ptr*>(qptr); + if ( result && !result->isNull() ) + { + qDebug() << "Dropped result item:" << result->data()->artist() << "-" << result->data()->track() << action; + queries << result->data()->toQuery(); + } + } + } + if ( data->hasFormat( "application/tomahawk.query.list" ) ) { QByteArray itemData = data->data( "application/tomahawk.query.list" ); QDataStream stream( &itemData, QIODevice::ReadOnly ); - QList<Tomahawk::query_ptr> queries; while ( !stream.atEnd() ) { @@ -337,7 +357,10 @@ PlaylistModel::dropMimeData( const QMimeData* data, Qt::DropAction action, int r queries << *query; } } + } + if ( queries.count() ) + { emit beginInsertRows( QModelIndex(), beginRow, beginRow + queries.count() - 1 ); foreach( const Tomahawk::query_ptr& query, queries ) { diff --git a/src/libtomahawk/playlist/trackproxymodel.cpp b/src/libtomahawk/playlist/trackproxymodel.cpp index 2ed2c94b1..91f082ecd 100644 --- a/src/libtomahawk/playlist/trackproxymodel.cpp +++ b/src/libtomahawk/playlist/trackproxymodel.cpp @@ -143,7 +143,6 @@ TrackProxyModel::siblingItem( int itemsAway ) if ( idx.isValid() ) do { TrackModelItem* item = itemFromIndex( mapToSource( idx ) ); - qDebug() << item->query()->toString(); if ( item && item->query()->playable() ) { qDebug() << "Next PlaylistItem found:" << item->query()->toString() << item->query()->results().at( 0 )->url(); diff --git a/src/libtomahawk/playlist/trackview.cpp b/src/libtomahawk/playlist/trackview.cpp index db7a619f4..daf3627f0 100644 --- a/src/libtomahawk/playlist/trackview.cpp +++ b/src/libtomahawk/playlist/trackview.cpp @@ -285,6 +285,19 @@ TrackView::dropEvent( QDropEvent* event ) qDebug() << "Drop Event accepted at row:" << index.row(); event->acceptProposedAction(); + if ( !model()->isReadOnly() ) + { + model()->dropMimeData( event->mimeData(), event->proposedAction(), index.row(), 0, index.parent() ); + } + } + else if ( event->mimeData()->hasFormat( "application/tomahawk.result.list" ) ) + { + const QPoint pos = event->pos(); + const QModelIndex index = indexAt( pos ); + + qDebug() << "Drop Event accepted at row:" << index.row(); + event->acceptProposedAction(); + if ( !model()->isReadOnly() ) { model()->dropMimeData( event->mimeData(), event->proposedAction(), index.row(), 0, index.parent() ); @@ -345,6 +358,7 @@ TrackView::onFilterChanged( const QString& ) m_overlay->hide(); } + void TrackView::copyLink() { diff --git a/src/libtomahawk/playlist/treemodel.cpp b/src/libtomahawk/playlist/treemodel.cpp index 8830e0bfe..28feb59d8 100644 --- a/src/libtomahawk/playlist/treemodel.cpp +++ b/src/libtomahawk/playlist/treemodel.cpp @@ -55,6 +55,29 @@ TreeModel::~TreeModel() } +void +TreeModel::setCurrentItem( const QModelIndex& index ) +{ + qDebug() << Q_FUNC_INFO; + TreeModelItem* oldEntry = itemFromIndex( m_currentIndex ); + if ( oldEntry ) + { +// oldEntry->setIsPlaying( false ); + } + + TreeModelItem* entry = itemFromIndex( index ); + if ( entry ) + { + m_currentIndex = index; +// entry->setIsPlaying( true ); + } + else + { + m_currentIndex = QModelIndex(); + } +} + + QModelIndex TreeModel::index( int row, int column, const QModelIndex& parent ) const { @@ -257,9 +280,13 @@ TreeModel::flags( const QModelIndex& index ) const Qt::ItemFlags defaultFlags = QAbstractItemModel::flags( index ); if ( index.isValid() && index.column() == 0 ) - return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags; - else - return defaultFlags; + { + TreeModelItem* item = itemFromIndex( index ); + if ( item && !item->result().isNull() ) + return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags; + } + + return defaultFlags; } @@ -267,7 +294,7 @@ QStringList TreeModel::mimeTypes() const { QStringList types; - types << "application/tomahawk.query.list"; + types << "application/tomahawk.result.list"; return types; } @@ -277,8 +304,8 @@ TreeModel::mimeData( const QModelIndexList &indexes ) const { qDebug() << Q_FUNC_INFO; - QByteArray queryData; - QDataStream queryStream( &queryData, QIODevice::WriteOnly ); + QByteArray resultData; + QDataStream resultStream( &resultData, QIODevice::WriteOnly ); foreach ( const QModelIndex& i, indexes ) { @@ -287,15 +314,15 @@ TreeModel::mimeData( const QModelIndexList &indexes ) const QModelIndex idx = index( i.row(), 0, i.parent() ); TreeModelItem* item = itemFromIndex( idx ); - if ( item ) + if ( item && !item->result().isNull() ) { - const album_ptr& album = item->album(); - queryStream << qlonglong( &album ); + const result_ptr& result = item->result(); + resultStream << qlonglong( &result ); } } QMimeData* mimeData = new QMimeData(); - mimeData->setData( "application/tomahawk.query.list", queryData ); + mimeData->setData( "application/tomahawk.result.list", resultData ); return mimeData; } @@ -396,7 +423,10 @@ TreeModel::addCollection( const collection_ptr& collection ) Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) ); - m_title = tr( "All Artists from %1" ).arg( collection->source()->friendlyName() ); + if ( collection->source()->isLocal() ) + setTitle( tr( "Your Collection" ) ); + else + setTitle( tr( "Collection of %1" ).arg( collection->source()->friendlyName() ) ); } @@ -418,7 +448,10 @@ TreeModel::addFilteredCollection( const collection_ptr& collection, unsigned int Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) ); - m_title = tr( "All albums from %1" ).arg( collection->source()->friendlyName() ); + if ( collection->source()->isLocal() ) + setTitle( tr( "Your Collection" ) ); + else + setTitle( tr( "Collection of %1" ).arg( collection->source()->friendlyName() ) ); } diff --git a/src/libtomahawk/playlist/treemodel.h b/src/libtomahawk/playlist/treemodel.h index 68f23bd98..002471f1b 100644 --- a/src/libtomahawk/playlist/treemodel.h +++ b/src/libtomahawk/playlist/treemodel.h @@ -74,6 +74,8 @@ public: virtual QStringList mimeTypes() const; virtual Qt::ItemFlags flags( const QModelIndex& index ) const; + virtual QPersistentModelIndex currentItem() { return m_currentIndex; } + void addAllCollections(); void addCollection( const Tomahawk::collection_ptr& collection ); void addFilteredCollection( const Tomahawk::collection_ptr& collection, unsigned int amount, DatabaseCommand_AllArtists::SortOrder order ); @@ -97,6 +99,8 @@ public: } public slots: + virtual void setCurrentItem( const QModelIndex& index ); + virtual void setRepeatMode( PlaylistInterface::RepeatMode /*mode*/ ) {} virtual void setShuffled( bool /*shuffled*/ ) {} diff --git a/src/libtomahawk/playlist/treeproxymodel.cpp b/src/libtomahawk/playlist/treeproxymodel.cpp index 3f8b86b16..82570805d 100644 --- a/src/libtomahawk/playlist/treeproxymodel.cpp +++ b/src/libtomahawk/playlist/treeproxymodel.cpp @@ -140,7 +140,28 @@ Tomahawk::result_ptr TreeProxyModel::siblingItem( int itemsAway ) { qDebug() << Q_FUNC_INFO; - return Tomahawk::result_ptr( 0 ); + + QModelIndex idx = currentItem(); + + // Try to find the next available PlaylistItem (with results) + if ( idx.isValid() ) do + { + idx = index( idx.row() + ( itemsAway > 0 ? 1 : -1 ), 0, idx.parent() ); + if ( !idx.isValid() ) + break; + + TreeModelItem* item = itemFromIndex( mapToSource( idx ) ); + if ( item && item->result()->isOnline() ) + { + qDebug() << "Next PlaylistItem found:" << item->result()->url(); + setCurrentItem( idx ); + return item->result(); + } + } + while ( idx.isValid() ); + + setCurrentItem( QModelIndex() ); + return Tomahawk::result_ptr(); } diff --git a/src/libtomahawk/playlist/treeproxymodel.h b/src/libtomahawk/playlist/treeproxymodel.h index b441e155b..34444dc6e 100644 --- a/src/libtomahawk/playlist/treeproxymodel.h +++ b/src/libtomahawk/playlist/treeproxymodel.h @@ -36,6 +36,9 @@ public: virtual TreeModel* sourceModel() const { return m_model; } virtual void setSourceModel( TreeModel* sourceModel ); + virtual QPersistentModelIndex currentItem() const { return mapFromSource( m_model->currentItem() ); } + virtual void setCurrentItem( const QModelIndex& index ) { m_model->setCurrentItem( mapToSource( index ) ); } + virtual QList<Tomahawk::query_ptr> tracks() { Q_ASSERT( FALSE ); QList<Tomahawk::query_ptr> queries; return queries; } virtual int unfilteredTrackCount() const { return sourceModel()->rowCount( QModelIndex() ); } @@ -53,6 +56,8 @@ public: virtual bool shuffled() const { return m_shuffled; } virtual PlaylistInterface::ViewMode viewMode() const { return PlaylistInterface::Tree; } + TreeModelItem* itemFromIndex( const QModelIndex& index ) const { return sourceModel()->itemFromIndex( index ); } + signals: void repeatModeChanged( PlaylistInterface::RepeatMode mode ); void shuffleModeChanged( bool enabled ); diff --git a/src/libtomahawk/result.cpp b/src/libtomahawk/result.cpp index 9f655f149..9bfae38f7 100644 --- a/src/libtomahawk/result.cpp +++ b/src/libtomahawk/result.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === - * + * * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org> * * Tomahawk is free software: you can redistribute it and/or modify @@ -30,7 +30,14 @@ using namespace Tomahawk; Result::Result() : QObject() + , m_duration( 0 ) + , m_bitrate( 0 ) + , m_size( 0 ) + , m_albumpos( 0 ) + , m_modtime( 0 ) , m_year( 0 ) + , m_score( 0 ) + , m_id( 0 ) { } @@ -40,21 +47,21 @@ Result::~Result() } -artist_ptr +artist_ptr Result::artist() const { return m_artist; } -album_ptr +album_ptr Result::album() const { return m_album; } -collection_ptr +collection_ptr Result::collection() const { return m_collection; @@ -87,6 +94,13 @@ Result::id() const } +bool +Result::isOnline() const +{ + return ( !collection().isNull() && collection()->source()->isOnline() ); +} + + QVariant Result::toVariant() const { diff --git a/src/libtomahawk/result.h b/src/libtomahawk/result.h index aff9604ba..ce2c69542 100644 --- a/src/libtomahawk/result.h +++ b/src/libtomahawk/result.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === - * + * * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org> * * Tomahawk is free software: you can redistribute it and/or modify @@ -55,6 +55,8 @@ public: float score() const; RID id() const; + bool isOnline() const; + collection_ptr collection() const; Tomahawk::artist_ptr artist() const; Tomahawk::album_ptr album() const; diff --git a/src/libtomahawk/sip/SipHandler.cpp b/src/libtomahawk/sip/SipHandler.cpp index 3ff86aa7b..e106f21f5 100644 --- a/src/libtomahawk/sip/SipHandler.cpp +++ b/src/libtomahawk/sip/SipHandler.cpp @@ -40,13 +40,16 @@ SipHandler* SipHandler::s_instance = 0; -SipHandler* SipHandler::instance() +SipHandler* +SipHandler::instance() { - if( s_instance == 0 ) - s_instance = new SipHandler( 0 ); + if ( !s_instance ) + new SipHandler( 0 ); + return s_instance; } + SipHandler::SipHandler( QObject* parent ) : QObject( parent ) , m_connected( false ) @@ -61,10 +64,14 @@ SipHandler::SipHandler( QObject* parent ) SipHandler::~SipHandler() { + qDebug() << Q_FUNC_INFO; disconnectAll(); + qDeleteAll( m_allPlugins ); } -const QPixmap SipHandler::avatar( const QString& name ) const + +const QPixmap +SipHandler::avatar( const QString& name ) const { qDebug() << Q_FUNC_INFO << "Getting avatar" << name << m_usernameAvatars.keys(); if( m_usernameAvatars.keys().contains( name ) ) @@ -80,12 +87,14 @@ const QPixmap SipHandler::avatar( const QString& name ) const } } + const SipInfo SipHandler::sipInfo(const QString& peerId) const { return m_peersSipInfos.value( peerId ); } + void SipHandler::onSettingsChanged() { @@ -554,10 +563,11 @@ SipHandler::onStateChanged( SipPlugin::ConnectionState state ) { m_connectedPlugins.removeAll( sip ); emit disconnected( sip ); - } else if ( sip->connectionState() == SipPlugin::Connected ) + } + else if ( sip->connectionState() == SipPlugin::Connected ) { - m_connectedPlugins.removeAll( sip ); - emit disconnected( sip ); + m_connectedPlugins << sip; + emit connected( sip ); } emit stateChanged( sip, state ); diff --git a/src/libtomahawk/sip/SipPlugin.h b/src/libtomahawk/sip/SipPlugin.h index 3ac9fd2cc..dc1b4a9e8 100644 --- a/src/libtomahawk/sip/SipPlugin.h +++ b/src/libtomahawk/sip/SipPlugin.h @@ -59,7 +59,7 @@ class DLLEXPORT SipPlugin : public QObject public: enum SipErrorCode { AuthError, ConnectionError }; // Placeholder for errors, to be defined - enum ConnectionState { Disconnected, Connecting, Connected }; + enum ConnectionState { Disconnected, Connecting, Connected, Disconnecting }; explicit SipPlugin( const QString& pluginId, QObject* parent = 0 ); virtual ~SipPlugin() {} diff --git a/src/libtomahawk/sourcelist.cpp b/src/libtomahawk/sourcelist.cpp index 0f3576808..44ba6d8af 100644 --- a/src/libtomahawk/sourcelist.cpp +++ b/src/libtomahawk/sourcelist.cpp @@ -45,7 +45,6 @@ SourceList::instance() SourceList::SourceList( QObject* parent ) : QObject( parent ) { - loadSources(); } diff --git a/src/libtomahawk/sourcelist.h b/src/libtomahawk/sourcelist.h index 7073f713d..d4757095b 100644 --- a/src/libtomahawk/sourcelist.h +++ b/src/libtomahawk/sourcelist.h @@ -43,6 +43,7 @@ public: void setWebSource( const Tomahawk::source_ptr& websrc ); const Tomahawk::source_ptr webSource() const; + void loadSources(); void removeAllRemote(); QList<Tomahawk::source_ptr> sources( bool onlyOnline = false ) const; @@ -62,7 +63,6 @@ private slots: void sourceSynced(); private: - void loadSources(); void add( const Tomahawk::source_ptr& source ); QMap< QString, Tomahawk::source_ptr > m_sources; diff --git a/src/resolvers/qtscriptresolver.cpp b/src/resolvers/qtscriptresolver.cpp index 78375c522..53debfafc 100644 --- a/src/resolvers/qtscriptresolver.cpp +++ b/src/resolvers/qtscriptresolver.cpp @@ -60,7 +60,7 @@ QtScriptResolver::QtScriptResolver( const QString& scriptPath ) QtScriptResolver::~QtScriptResolver() { Tomahawk::Pipeline::instance()->removeResolver( this ); - delete m_engine; +// delete m_engine; } diff --git a/src/sip/jreen/jabber.cpp b/src/sip/jreen/jabber.cpp index 392da18fe..fabcd9846 100644 --- a/src/sip/jreen/jabber.cpp +++ b/src/sip/jreen/jabber.cpp @@ -96,7 +96,7 @@ JabberPlugin::JabberPlugin( const QString& pluginId ) // instantiate XmlConsole if( readXmlConsoleEnabled() ) { - m_xmlConsole = new XmlConsole( m_client ); + m_xmlConsole = new XmlConsole( m_client ); m_xmlConsole->show(); } @@ -141,7 +141,11 @@ JabberPlugin::JabberPlugin( const QString& pluginId ) JabberPlugin::~JabberPlugin() { - + delete m_avatarManager; + delete m_roster; + delete m_client; + delete m_xmlConsole; + delete m_ui; } void @@ -222,7 +226,6 @@ JabberPlugin::connectPlugin( bool startup ) //FIXME: we're badly workarounding some missing reconnection api here, to be fixed soon QTimer::singleShot( 1000, m_client, SLOT( connectToServer() ) ); - connect(m_client->connection(), SIGNAL(error(Jreen::Connection::SocketError)), SLOT(onError(Jreen::Connection::SocketError))); m_state = Connecting; @@ -251,7 +254,9 @@ JabberPlugin::disconnectPlugin() m_peers.clear(); m_legacy_peers.clear(); - m_client->disconnectFromServer(true); + m_client->disconnectFromServer( true ); + m_state = Disconnecting; + emit stateChanged( m_state ); } void @@ -572,6 +577,11 @@ void JabberPlugin::removeMenuHelper() void JabberPlugin::onNewMessage(const Jreen::Message& message) { + if ( m_state != Connected ) + return; + + qDebug() << Q_FUNC_INFO << "message type" << message.subtype(); + QString from = message.from().full(); QString msg = message.body(); @@ -608,6 +618,8 @@ void JabberPlugin::onNewMessage(const Jreen::Message& message) void JabberPlugin::onPresenceReceived( const Jreen::RosterItem::Ptr &item, const Jreen::Presence& presence ) { Q_UNUSED(item); + if ( m_state != Connected ) + return; Jreen::JID jid = presence.from(); QString fulljid( jid.full() ); @@ -652,6 +664,9 @@ void JabberPlugin::onPresenceReceived( const Jreen::RosterItem::Ptr &item, const void JabberPlugin::onSubscriptionReceived(const Jreen::RosterItem::Ptr& item, const Jreen::Presence& presence) { + if ( m_state != Connected ) + return; + qDebug() << Q_FUNC_INFO << "presence type: " << presence.subtype(); if(item) qDebug() << Q_FUNC_INFO << presence.from().full() << "subs" << item->subscription() << "ask" << item->ask(); @@ -739,6 +754,9 @@ JabberPlugin::onSubscriptionRequestConfirmed( int result ) void JabberPlugin::onNewIq(const Jreen::IQ& iq, int context) { + if ( m_state != Connected ) + return; + if( context == RequestDisco ) { qDebug() << Q_FUNC_INFO << "Received disco IQ..."; @@ -885,6 +903,9 @@ void JabberPlugin::handlePeerStatus(const Jreen::JID& jid, Jreen::Presence::Type void JabberPlugin::onNewAvatar(const QString& jid) { qDebug() << Q_FUNC_INFO << jid; + if ( m_state != Connected ) + return; + Q_ASSERT(!m_avatarManager->avatar( jid ).isNull()); // find peers for the jid diff --git a/src/sourcetree/items/playlistitems.cpp b/src/sourcetree/items/playlistitems.cpp index ce5de4277..d73d6ada0 100644 --- a/src/sourcetree/items/playlistitems.cpp +++ b/src/sourcetree/items/playlistitems.cpp @@ -111,36 +111,56 @@ PlaylistItem::willAcceptDrag( const QMimeData* data ) const bool PlaylistItem::dropMimeData( const QMimeData* data, Qt::DropAction action ) { - if( data->hasFormat( "application/tomahawk.query.list" ) ) { - if ( !m_playlist.isNull() && m_playlist->author()->isLocal() ) { + QList< Tomahawk::query_ptr > queries; + if ( data->hasFormat( "application/tomahawk.result.list" ) ) + { + QByteArray itemData = data->data( "application/tomahawk.result.list" ); + QDataStream stream( &itemData, QIODevice::ReadOnly ); - QByteArray itemData = data->data( "application/tomahawk.query.list" ); - QDataStream stream( &itemData, QIODevice::ReadOnly ); - QList< Tomahawk::query_ptr > queries; + while ( !stream.atEnd() ) + { + qlonglong qptr; + stream >> qptr; - while ( !stream.atEnd() ) + Tomahawk::result_ptr* result = reinterpret_cast<Tomahawk::result_ptr*>(qptr); + if ( result && !result->isNull() ) { - qlonglong qptr; - stream >> qptr; - - Tomahawk::query_ptr* query = reinterpret_cast<Tomahawk::query_ptr*>(qptr); - if ( query && !query->isNull() ) - { - qDebug() << "Dropped query item:" << query->data()->artist() << "-" << query->data()->track(); - queries << *query; - } + qDebug() << "Dropped result item:" << result->data()->artist() << "-" << result->data()->track(); + queries << result->data()->toQuery(); } - - qDebug() << "on playlist:" << m_playlist->title() << m_playlist->guid(); - - // TODO do we need to use this in the refactor? - // QString rev = item->currentlyLoadedPlaylistRevision( playlist->guid() ); - m_playlist->addEntries( queries, m_playlist->currentrevision() ); - - return true; } } + if ( data->hasFormat( "application/tomahawk.query.list" ) ) + { + QByteArray itemData = data->data( "application/tomahawk.query.list" ); + QDataStream stream( &itemData, QIODevice::ReadOnly ); + + while ( !stream.atEnd() ) + { + qlonglong qptr; + stream >> qptr; + + Tomahawk::query_ptr* query = reinterpret_cast<Tomahawk::query_ptr*>(qptr); + if ( query && !query->isNull() ) + { + qDebug() << "Dropped query item:" << query->data()->artist() << "-" << query->data()->track(); + queries << *query; + } + } + } + + if ( queries.count() && !m_playlist.isNull() && m_playlist->author()->isLocal() ) + { + qDebug() << "on playlist:" << m_playlist->title() << m_playlist->guid(); + + // TODO do we need to use this in the refactor? + // QString rev = item->currentlyLoadedPlaylistRevision( playlist->guid() ); + m_playlist->addEntries( queries, m_playlist->currentrevision() ); + + return true; + } + return false; } diff --git a/src/sourcetree/sourcesmodel.cpp b/src/sourcetree/sourcesmodel.cpp index 61adc5f0b..e152d29b9 100644 --- a/src/sourcetree/sourcesmodel.cpp +++ b/src/sourcetree/sourcesmodel.cpp @@ -87,12 +87,14 @@ SourcesModel::data( const QModelIndex& index, int role ) const return QVariant(); } + int SourcesModel::columnCount( const QModelIndex& parent ) const { return 1; } + int SourcesModel::rowCount( const QModelIndex& parent ) const { @@ -103,6 +105,7 @@ SourcesModel::rowCount( const QModelIndex& parent ) const return itemFromIndex( parent )->children().count(); } + QModelIndex SourcesModel::parent( const QModelIndex& child ) const { @@ -119,6 +122,7 @@ SourcesModel::parent( const QModelIndex& child ) const return createIndex( rowForItem( parent ), 0, parent ); } + QModelIndex SourcesModel::index( int row, int column, const QModelIndex& parent ) const { @@ -137,6 +141,7 @@ SourcesModel::index( int row, int column, const QModelIndex& parent ) const } + bool SourcesModel::setData( const QModelIndex& index, const QVariant& value, int role ) { @@ -144,14 +149,17 @@ SourcesModel::setData( const QModelIndex& index, const QVariant& value, int role return item->setData( value, role ); } + QStringList SourcesModel::mimeTypes() const { QStringList types; types << "application/tomahawk.query.list"; + types << "application/tomahawk.result.list"; return types; } + QMimeData* SourcesModel::mimeData( const QModelIndexList& indexes ) const { @@ -159,6 +167,7 @@ SourcesModel::mimeData( const QModelIndexList& indexes ) const return new QMimeData(); } + bool SourcesModel::dropMimeData( const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent ) { @@ -173,12 +182,14 @@ SourcesModel::dropMimeData( const QMimeData* data, Qt::DropAction action, int ro return item->dropMimeData( data, action ); } + Qt::DropActions SourcesModel::supportedDropActions() const { return Qt::CopyAction; } + Qt::ItemFlags SourcesModel::flags( const QModelIndex& index ) const { @@ -200,6 +211,7 @@ SourcesModel::appendItem( const Tomahawk::source_ptr& source ) endInsertRows(); } + bool SourcesModel::removeItem( const Tomahawk::source_ptr& source ) { @@ -228,6 +240,7 @@ SourcesModel::removeItem( const Tomahawk::source_ptr& source ) return false; } + void SourcesModel::viewPageActivated( Tomahawk::ViewPage* page ) { @@ -244,6 +257,7 @@ SourcesModel::viewPageActivated( Tomahawk::ViewPage* page ) } } + void SourcesModel::loadSources() { @@ -275,6 +289,7 @@ SourcesModel::onSourceRemoved( const source_ptr& source ) removeItem( source ); } + void SourcesModel::itemUpdated() { @@ -303,6 +318,7 @@ SourcesModel::onItemRowsAddedBegin( int first, int last ) beginInsertRows( idx, first, last ); } + void SourcesModel::onItemRowsAddedDone() { @@ -311,6 +327,7 @@ SourcesModel::onItemRowsAddedDone() endInsertRows(); } + void SourcesModel::onItemRowsRemovedBegin( int first, int last ) { @@ -324,6 +341,7 @@ SourcesModel::onItemRowsRemovedBegin( int first, int last ) beginRemoveRows( idx, first, last ); } + void SourcesModel::onItemRowsRemovedDone() { @@ -332,6 +350,7 @@ SourcesModel::onItemRowsRemovedDone() endRemoveRows(); } + void SourcesModel::linkSourceItemToPage( SourceTreeItem* item, ViewPage* p ) { @@ -356,6 +375,7 @@ SourcesModel::itemFromIndex( const QModelIndex& idx ) const return reinterpret_cast< SourceTreeItem* >( idx.internalPointer() ); } + QModelIndex SourcesModel::indexFromItem( SourceTreeItem* item ) const { @@ -396,6 +416,7 @@ SourcesModel::indexFromItem( SourceTreeItem* item ) const return idx; } + int SourcesModel::rowForItem( SourceTreeItem* item ) const { diff --git a/src/sourcetree/sourcetreeview.cpp b/src/sourcetree/sourcetreeview.cpp index a504126ed..5ff59ead9 100644 --- a/src/sourcetree/sourcetreeview.cpp +++ b/src/sourcetree/sourcetreeview.cpp @@ -160,6 +160,7 @@ SourceTreeView::hideOfflineSources() m_proxyModel->hideOfflineSources(); } + void SourceTreeView::onItemActivated( const QModelIndex& index ) { @@ -182,6 +183,7 @@ SourceTreeView::onItemExpanded( const QModelIndex& idx ) } } + void SourceTreeView::selectRequest( const QModelIndex& idx ) { @@ -260,7 +262,8 @@ SourceTreeView::dragEnterEvent( QDragEnterEvent* event ) qDebug() << Q_FUNC_INFO; QTreeView::dragEnterEvent( event ); - if ( event->mimeData()->hasFormat( "application/tomahawk.query.list" ) ) + if ( event->mimeData()->hasFormat( "application/tomahawk.query.list" ) + || event->mimeData()->hasFormat( "application/tomahawk.result.list" ) ) { m_dragging = true; m_dropRect = QRect(); @@ -278,7 +281,8 @@ SourceTreeView::dragMoveEvent( QDragMoveEvent* event ) bool accept = false; QTreeView::dragMoveEvent( event ); - if ( event->mimeData()->hasFormat( "application/tomahawk.query.list" ) ) + if ( event->mimeData()->hasFormat( "application/tomahawk.query.list" ) + || event->mimeData()->hasFormat( "application/tomahawk.result.list" ) ) { setDirtyRegion( m_dropRect ); const QPoint pos = event->pos(); @@ -292,7 +296,9 @@ SourceTreeView::dragMoveEvent( QDragMoveEvent* event ) const SourceTreeItem* item = itemFromIndex< SourceTreeItem >( index ); if( item->willAcceptDrag( event->mimeData() ) ) accept = true; - } else { + } + else + { m_dropRect = QRect(); } @@ -344,6 +350,7 @@ SourceTreeView::drawRow( QPainter* painter, const QStyleOptionViewItem& option, QTreeView::drawRow( painter, option, index ); } + template< typename T > T* SourceTreeView::itemFromIndex( const QModelIndex& index ) const { @@ -389,7 +396,6 @@ SourceDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, co } } - SourcesModel::RowType type = static_cast< SourcesModel::RowType >( index.data( SourcesModel::SourceTreeItemTypeRole ).toInt() ); SourceTreeItem* item = index.data( SourcesModel::SourceTreeItemRole ).value< SourceTreeItem* >(); Q_ASSERT( item ); diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index 1fcac1d34..c0ffad1c2 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -323,8 +323,14 @@ TomahawkApp::~TomahawkApp() delete m_mainwindow; delete m_audioEngine; #endif - delete m_infoSystem; + + delete SipHandler::instance(); + Pipeline::instance()->stop(); + delete m_database; + delete m_infoSystem; + + qDebug() << "Finished shutdown."; } @@ -343,11 +349,6 @@ TomahawkApp::audioControls() } #endif -SipHandler* -TomahawkApp::sipHandler() -{ - return SipHandler::instance(); -} void TomahawkApp::registerMetaTypes() @@ -476,6 +477,7 @@ TomahawkApp::disableScriptResolver( const QString& path ) } } + Tomahawk::ExternalResolver* TomahawkApp::resolverForPath( const QString& scriptPath ) { @@ -499,6 +501,7 @@ TomahawkApp::initLocalCollection() collection_ptr dummycol( new WebCollection( dummy ) ); dummy->addCollection( dummycol ); SourceList::instance()->setWebSource( dummy ); + SourceList::instance()->loadSources(); // to make the stats signal be emitted by our local source // this will update the sidebar, etc. @@ -521,6 +524,7 @@ TomahawkApp::startServent() } } + void TomahawkApp::setupSIP() { diff --git a/src/tomahawkwindow.cpp b/src/tomahawkwindow.cpp index 4d963c24a..7c464c3bc 100644 --- a/src/tomahawkwindow.cpp +++ b/src/tomahawkwindow.cpp @@ -186,7 +186,7 @@ TomahawkWindow::TomahawkWindow( QWidget* parent ) // propagate sip menu connect( SipHandler::instance(), SIGNAL( pluginAdded( SipPlugin* ) ), this, SLOT( onSipPluginAdded( SipPlugin* ) ) ); connect( SipHandler::instance(), SIGNAL( pluginRemoved( SipPlugin* ) ), this, SLOT( onSipPluginRemoved( SipPlugin* ) ) ); - foreach( SipPlugin *plugin, APP->sipHandler()->allPlugins() ) + foreach( SipPlugin *plugin, SipHandler::instance()->allPlugins() ) { connect( plugin, SIGNAL( addMenu( QMenu* ) ), this, SLOT( pluginMenuAdded( QMenu* ) ) ); connect( plugin, SIGNAL( removeMenu( QMenu* ) ), this, SLOT( pluginMenuRemoved( QMenu* ) ) ); @@ -267,7 +267,7 @@ TomahawkWindow::setupSignals() // <Menu Items> connect( ui->actionPreferences, SIGNAL( triggered() ), SLOT( showSettingsDialog() ) ); connect( ui->actionDiagnostics, SIGNAL( triggered() ), SLOT( showDiagnosticsDialog() ) ); - connect( ui->actionToggleConnect, SIGNAL( triggered() ), APP->sipHandler(), SLOT( toggleConnect() ) ); + connect( ui->actionToggleConnect, SIGNAL( triggered() ), SipHandler::instance(), SLOT( toggleConnect() ) ); // connect( ui->actionAddPeerManually, SIGNAL( triggered() ), SLOT( addPeerManually() ) ); connect( ui->actionRescanCollection, SIGNAL( triggered() ), SLOT( updateCollectionManually() ) ); connect( ui->actionLoadXSPF, SIGNAL( triggered() ), SLOT( loadSpiff() )); @@ -285,9 +285,9 @@ TomahawkWindow::setupSignals() #endif // <SipHandler> - connect( APP->sipHandler(), SIGNAL( connected() ), SLOT( onSipConnected() ) ); - connect( APP->sipHandler(), SIGNAL( disconnected() ), SLOT( onSipDisconnected() ) ); - connect( APP->sipHandler(), SIGNAL( authError() ), SLOT( onSipError() ) ); + connect( SipHandler::instance(), SIGNAL( connected( SipPlugin* ) ), SLOT( onSipConnected() ) ); + connect( SipHandler::instance(), SIGNAL( disconnected( SipPlugin* ) ), SLOT( onSipDisconnected() ) ); + connect( SipHandler::instance(), SIGNAL( authError( SipPlugin* ) ), SLOT( onSipError() ) ); // set initial connection state onSipDisconnected();