From a52ecfb5b897acbbeec226ee5e3dfb407d705f9a Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Tue, 5 Apr 2011 20:18:37 -0400 Subject: [PATCH 1/9] Do some explicit string emptiness checking in Twitter --- src/sip/twitter/twitter.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/sip/twitter/twitter.cpp b/src/sip/twitter/twitter.cpp index 1a5f91163..cc83c5b7b 100644 --- a/src/sip/twitter/twitter.cpp +++ b/src/sip/twitter/twitter.cpp @@ -265,6 +265,13 @@ TwitterPlugin::connectTimerFired() foreach( QString screenName, peerlist ) { QHash< QString, QVariant > peerData = m_cachedPeers[screenName].toHash(); + + if ( QDateTime::currentDateTimeUtc().toMSecsSinceEpoch() - peerData["lastseen"].toLongLong() > 1209600000 ) // 2 weeks + { + qDebug() << "Aging peer " << screenName << " out of cache"; + m_cachedPeers.remove( screenName ); + continue; + } if ( !peerData.contains( "host" ) || !peerData.contains( "port" ) || !peerData.contains( "pkey" ) ) { @@ -568,6 +575,7 @@ TwitterPlugin::registerOffer( const QString &screenName, const QHash< QString, Q if ( peersChanged ) { + _peerData["lastseen"] = QString::number( QDateTime::currentDateTimeUtc().toMSecsSinceEpoch() ); m_cachedPeers[screenName] = QVariant::fromValue< QHash< QString, QVariant > >( _peerData ); TomahawkSettings::instance()->setTwitterCachedPeers( m_cachedPeers ); } @@ -595,7 +603,8 @@ void TwitterPlugin::makeConnection( const QString &screenName, const QHash< QString, QVariant > &peerData ) { qDebug() << Q_FUNC_INFO; - if ( !peerData.contains( "host" ) || !peerData.contains( "port" ) || !peerData.contains( "pkey" ) || !peerData.contains( "node" ) ) + if ( !peerData.contains( "host" ) || !peerData.contains( "port" ) || !peerData.contains( "pkey" ) || !peerData.contains( "node" ) || + peerData["host"].toString().isEmpty() || peerData["port"].toString().isEmpty() || peerData["pkey"].toString().isEmpty() || peerData["node"].toString().isEmpty() ) { qDebug() << "TwitterPlugin could not find host and/or port and/or pkey and/or node for peer " << screenName; return; From 73d88dcf7beb64f4767f182d315cb03bbd0be49e Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Tue, 5 Apr 2011 20:50:53 -0400 Subject: [PATCH 2/9] Keep track of offered dbid to a peer and check offer key to make sure it matches --- src/sip/twitter/twitter.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/sip/twitter/twitter.cpp b/src/sip/twitter/twitter.cpp index cc83c5b7b..8e9065617 100644 --- a/src/sip/twitter/twitter.cpp +++ b/src/sip/twitter/twitter.cpp @@ -536,11 +536,14 @@ TwitterPlugin::registerOffer( const QString &screenName, const QHash< QString, Q _peerData.remove( "resend" ); } - if ( !_peerData.contains( "okey" ) ) + if ( !_peerData.contains( "okey" ) || + !_peerData.contains( "onod" ) || + ( _peerData.contains( "onod" ) && _peerData["onod"] != Database::instance()->dbid() ) ) { QString okey = QUuid::createUuid().toString().split( '-' ).last(); okey.chop( 1 ); _peerData["okey"] = QVariant::fromValue< QString >( okey ); + _peerData["onod"] = QVariant::fromValue< QString >( Database::instance()->dbid() ); peersChanged = true; needToAddToCache = true; needToSend = true; From 1ef9b7c241b3c99e2a3de8bb633720d7fa2cf71d Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Tue, 5 Apr 2011 20:58:47 -0400 Subject: [PATCH 3/9] Update twitter connect caching --- src/sip/twitter/twitter.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/sip/twitter/twitter.cpp b/src/sip/twitter/twitter.cpp index 8e9065617..af759cd25 100644 --- a/src/sip/twitter/twitter.cpp +++ b/src/sip/twitter/twitter.cpp @@ -266,7 +266,13 @@ TwitterPlugin::connectTimerFired() { QHash< QString, QVariant > peerData = m_cachedPeers[screenName].toHash(); - if ( QDateTime::currentDateTimeUtc().toMSecsSinceEpoch() - peerData["lastseen"].toLongLong() > 1209600000 ) // 2 weeks + if ( Servent::instance()->connectedToSession( peerData["node"] ) ) + { + peerData["lastseen"] = QDateTime::currentMSecsSinceEpoch(); + m_cachedPeers[screenName] = peerData; + } + + if ( QDateTime::currentMSecsSinceEpoch() - peerData["lastseen"].toLongLong() > 1209600000 ) // 2 weeks { qDebug() << "Aging peer " << screenName << " out of cache"; m_cachedPeers.remove( screenName ); @@ -578,7 +584,7 @@ TwitterPlugin::registerOffer( const QString &screenName, const QHash< QString, Q if ( peersChanged ) { - _peerData["lastseen"] = QString::number( QDateTime::currentDateTimeUtc().toMSecsSinceEpoch() ); + _peerData["lastseen"] = QString::number( QDateTime::currentMSecsSinceEpoch() ); m_cachedPeers[screenName] = QVariant::fromValue< QHash< QString, QVariant > >( _peerData ); TomahawkSettings::instance()->setTwitterCachedPeers( m_cachedPeers ); } From a1848f46bdc33d865b08c02a686c2da9ceab301b Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Tue, 5 Apr 2011 14:47:53 -0400 Subject: [PATCH 4/9] Set a query loaded from a source as already resolved --- src/libtomahawk/database/databasecommand_alltracks.cpp | 3 ++- src/libtomahawk/query.cpp | 1 - src/libtomahawk/query.h | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/libtomahawk/database/databasecommand_alltracks.cpp b/src/libtomahawk/database/databasecommand_alltracks.cpp index 5259ca64c..07072db4b 100644 --- a/src/libtomahawk/database/databasecommand_alltracks.cpp +++ b/src/libtomahawk/database/databasecommand_alltracks.cpp @@ -138,7 +138,8 @@ DatabaseCommand_AllTracks::exec( DatabaseImpl* dbi ) QList results; results << result; qry->addResults( results ); - + qry->setResolveFinished( true ); + ql << qry; } diff --git a/src/libtomahawk/query.cpp b/src/libtomahawk/query.cpp index f3f70357a..f07025411 100644 --- a/src/libtomahawk/query.cpp +++ b/src/libtomahawk/query.cpp @@ -62,7 +62,6 @@ Query::Query( const QString& artist, const QString& track, const QString& album, void Query::addResults( const QList< Tomahawk::result_ptr >& newresults ) { - bool becameSolved = false; { QMutexLocker lock( &m_mutex ); m_results.append( newresults ); diff --git a/src/libtomahawk/query.h b/src/libtomahawk/query.h index 84e057493..ddc447729 100644 --- a/src/libtomahawk/query.h +++ b/src/libtomahawk/query.h @@ -74,7 +74,8 @@ public: void setTrack( const QString& track ) { m_track = track; } void setResultHint( const QString& resultHint ) { m_resultHint = resultHint; } void setDuration( int duration ) { m_duration = duration; } - + void setResolveFinished( bool resolved ) { m_resolveFinished = resolved; } + QVariant toVariant() const; QString toString() const; From 3d93a82d0887acc1bfbadb620fb6a9f16269bd72 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Tue, 5 Apr 2011 21:04:09 -0400 Subject: [PATCH 5/9] go back to previous page in history when deleting a playlist --- src/libtomahawk/playlist.cpp | 2 + src/libtomahawk/playlist.h | 3 ++ .../playlist/dynamic/DynamicPlaylist.cpp | 2 + .../playlist/dynamic/DynamicPlaylist.h | 2 + .../dynamic/widgets/DynamicWidget.cpp | 2 + src/libtomahawk/playlist/playlistmanager.cpp | 42 ++++++++++++++----- src/libtomahawk/playlist/playlistmanager.h | 3 ++ src/libtomahawk/playlist/playlistmodel.cpp | 2 +- src/libtomahawk/viewpage.h | 6 +++ src/tomahawkapp.cpp | 2 + 10 files changed, 55 insertions(+), 11 deletions(-) diff --git a/src/libtomahawk/playlist.cpp b/src/libtomahawk/playlist.cpp index 1ca21e31e..9d35c0fe6 100644 --- a/src/libtomahawk/playlist.cpp +++ b/src/libtomahawk/playlist.cpp @@ -229,6 +229,8 @@ Playlist::reportDeleted( const Tomahawk::playlist_ptr& self ) qDebug() << Q_FUNC_INFO; Q_ASSERT( self.data() == this ); m_source->collection()->deletePlaylist( self ); + + emit deleted( self ); } diff --git a/src/libtomahawk/playlist.h b/src/libtomahawk/playlist.h index f973927cc..d0a4ee490 100644 --- a/src/libtomahawk/playlist.h +++ b/src/libtomahawk/playlist.h @@ -182,6 +182,9 @@ signals: /// renamed etc. void changed(); + /// was deleted, eh? + void deleted( const Tomahawk::playlist_ptr& pl ); + void repeatModeChanged( PlaylistInterface::RepeatMode mode ); void shuffleModeChanged( bool enabled ); diff --git a/src/libtomahawk/playlist/dynamic/DynamicPlaylist.cpp b/src/libtomahawk/playlist/dynamic/DynamicPlaylist.cpp index 6ab5eb30f..6186024ee 100644 --- a/src/libtomahawk/playlist/dynamic/DynamicPlaylist.cpp +++ b/src/libtomahawk/playlist/dynamic/DynamicPlaylist.cpp @@ -265,6 +265,8 @@ DynamicPlaylist::reportDeleted( const Tomahawk::dynplaylist_ptr& self ) Q_ASSERT( self.data() == this ); // will emit Collection::playlistDeleted(...) author()->collection()->deleteDynamicPlaylist( self ); + + emit deleted( self ); } void DynamicPlaylist::addEntries(const QList< query_ptr >& queries, const QString& oldrev) diff --git a/src/libtomahawk/playlist/dynamic/DynamicPlaylist.h b/src/libtomahawk/playlist/dynamic/DynamicPlaylist.h index 864d6a9f4..bee37900a 100644 --- a/src/libtomahawk/playlist/dynamic/DynamicPlaylist.h +++ b/src/libtomahawk/playlist/dynamic/DynamicPlaylist.h @@ -113,6 +113,8 @@ signals: /// emitted when the playlist revision changes (whenever the playlist changes) void dynamicRevisionLoaded( Tomahawk::DynamicPlaylistRevision ); + void deleted( const Tomahawk::dynplaylist_ptr& pl ); + public slots: // want to update the playlist from the model? // generate a newrev using uuid() and call this: diff --git a/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.cpp b/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.cpp index 6f1f2302a..d63fe718f 100644 --- a/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.cpp +++ b/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.cpp @@ -137,6 +137,7 @@ DynamicWidget::loadDynamicPlaylist( const Tomahawk::dynplaylist_ptr& playlist ) disconnect( m_playlist->generator().data(), SIGNAL( generated( QList ) ), this, SLOT( tracksGenerated( QList ) ) ); disconnect( m_playlist.data(), SIGNAL( dynamicRevisionLoaded( Tomahawk::DynamicPlaylistRevision) ), this, SLOT(onRevisionLoaded( Tomahawk::DynamicPlaylistRevision) ) ); disconnect( m_playlist->generator().data(), SIGNAL( error( QString, QString ) ), this, SLOT( generatorError( QString, QString ) ) ); + disconnect( m_playlist.data(), SIGNAL( deleted( Tomahawk::dynplaylist_ptr ) ), this, SLOT( deleteLater() ) ); } @@ -163,6 +164,7 @@ DynamicWidget::loadDynamicPlaylist( const Tomahawk::dynplaylist_ptr& playlist ) connect( m_playlist->generator().data(), SIGNAL( generated( QList ) ), this, SLOT( tracksGenerated( QList ) ) ); connect( m_playlist.data(), SIGNAL( dynamicRevisionLoaded( Tomahawk::DynamicPlaylistRevision ) ), this, SLOT( onRevisionLoaded( Tomahawk::DynamicPlaylistRevision ) ) ); connect( m_playlist->generator().data(), SIGNAL( error( QString, QString ) ), this, SLOT( generatorError( QString, QString ) ) ); + connect( m_playlist.data(), SIGNAL( deleted( Tomahawk::dynplaylist_ptr ) ), this, SLOT( deleteLater() ) ); } diff --git a/src/libtomahawk/playlist/playlistmanager.cpp b/src/libtomahawk/playlist/playlistmanager.cpp index c32848b13..67c82afa4 100644 --- a/src/libtomahawk/playlist/playlistmanager.cpp +++ b/src/libtomahawk/playlist/playlistmanager.cpp @@ -163,6 +163,8 @@ PlaylistManager::show( const Tomahawk::playlist_ptr& playlist ) playlist->resolve(); m_playlistViews.insert( playlist, view ); + + connect( playlist.data(), SIGNAL( deleted( Tomahawk::playlist_ptr ) ), this, SLOT( onPlaylistDeleted( Tomahawk::playlist_ptr ) ) ); } else { @@ -184,6 +186,8 @@ PlaylistManager::show( const Tomahawk::dynplaylist_ptr& playlist ) { m_dynamicWidgets[ playlist ] = new Tomahawk::DynamicWidget( playlist, m_stack ); + connect( playlist.data(), SIGNAL( deleted( Tomahawk::dynplaylist_ptr ) ), this, SLOT( onDynamicDeleted( Tomahawk::dynplaylist_ptr ) ) ); + playlist->resolve(); } @@ -335,11 +339,6 @@ PlaylistManager::show( const Tomahawk::source_ptr& source ) bool PlaylistManager::show( ViewPage* page ) { - if ( m_stack->indexOf( page->widget() ) < 0 ) - { - connect( page->widget(), SIGNAL( destroyed( QWidget* ) ), SLOT( onWidgetDestroyed( QWidget* ) ) ); - } - setPage( page ); return true; @@ -490,6 +489,7 @@ PlaylistManager::showHistory( int historyPosition ) setHistoryPosition( historyPosition ); ViewPage* page = m_pageHistory.at( historyPosition ); + qDebug() << "Showing page after a deleting:" << page->widget()->metaObject()->className(); setPage( page, false ); } @@ -556,10 +556,14 @@ PlaylistManager::setPage( ViewPage* page, bool trackHistory ) // UGH! if( QObject* obj = dynamic_cast< QObject* >( currentPage() ) ) { - if( obj->metaObject()->indexOfSignal( "descriptionChanged(QString)" ) > -1 ) // if the signal exists (just to hide the qobject runtime warning...) + // if the signal exists (just to hide the qobject runtime warning...) + if( obj->metaObject()->indexOfSignal( "descriptionChanged(QString)" ) > -1 ) connect( obj, SIGNAL( descriptionChanged( QString ) ), m_infobar, SLOT( setDescription( QString ) ) ); + + if( obj->metaObject()->indexOfSignal( "deleted()" ) > -1 ) + connect( obj, SIGNAL( deleted() ), this, SLOT( pageDeleted() ) ); } - + m_stack->setCurrentWidget( page->widget() ); updateView(); } @@ -637,11 +641,29 @@ PlaylistManager::updateView() m_infobar->setPixmap( currentPage()->pixmap() ); } +void +PlaylistManager::onDynamicDeleted( const Tomahawk::dynplaylist_ptr& pl ) +{ + QWidget* w = m_dynamicWidgets.value( pl ); + m_dynamicWidgets.remove( pl ); + + onWidgetDestroyed( w ); +} + +void +PlaylistManager::onPlaylistDeleted( const Tomahawk::playlist_ptr& pl ) +{ + QWidget* w = m_playlistViews.value( pl ); + m_playlistViews.remove( pl ); + + onWidgetDestroyed( w ); +} + void PlaylistManager::onWidgetDestroyed( QWidget* widget ) -{ - qDebug() << "Destroyed child:" << widget; +{ + qDebug() << "Destroyed child:" << widget << widget->metaObject()->className(); bool resetWidget = ( m_stack->currentWidget() == widget ); m_stack->removeWidget( widget ); @@ -657,7 +679,7 @@ PlaylistManager::onWidgetDestroyed( QWidget* widget ) break; } } - + if ( resetWidget ) { if ( m_pageHistory.count() ) diff --git a/src/libtomahawk/playlist/playlistmanager.h b/src/libtomahawk/playlist/playlistmanager.h index 278037e98..fc86acf66 100644 --- a/src/libtomahawk/playlist/playlistmanager.h +++ b/src/libtomahawk/playlist/playlistmanager.h @@ -135,6 +135,9 @@ public slots: private slots: void setFilter( const QString& filter ); void applyFilter(); + + void onPlaylistDeleted( const Tomahawk::playlist_ptr& pl ); + void onDynamicDeleted( const Tomahawk::dynplaylist_ptr& pl ); void onWidgetDestroyed( QWidget* widget ); private: diff --git a/src/libtomahawk/playlist/playlistmodel.cpp b/src/libtomahawk/playlist/playlistmodel.cpp index a676252c9..cdcad71aa 100644 --- a/src/libtomahawk/playlist/playlistmodel.cpp +++ b/src/libtomahawk/playlist/playlistmodel.cpp @@ -106,7 +106,7 @@ PlaylistModel::loadPlaylist( const Tomahawk::playlist_ptr& playlist, bool loadEn connect( plitem, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) ); - if( !entry->query()->resolvingFinished() ) { + if( !entry->query()->resolvingFinished() && entry->query()->playable() ) { m_waitingForResolved.append( entry->query().data() ); connect( entry->query().data(), SIGNAL( resolvingFinished( bool ) ), this, SLOT( trackResolved( bool ) ) ); } diff --git a/src/libtomahawk/viewpage.h b/src/libtomahawk/viewpage.h index b59695e7a..d775f451d 100644 --- a/src/libtomahawk/viewpage.h +++ b/src/libtomahawk/viewpage.h @@ -48,6 +48,12 @@ public: virtual bool jumpToCurrentTrack() = 0; + /** subclasses implementing ViewPage can emit the following signals: + * descriptionChanged( const QString& ) + * deleted() + * + * See DynamicWidget for an example + */ private: }; diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index 8af6a0457..e4198383f 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -342,6 +342,8 @@ TomahawkApp::registerMetaTypes() qRegisterMetaType< Tomahawk::query_ptr >("Tomahawk::query_ptr"); qRegisterMetaType< Tomahawk::source_ptr >("Tomahawk::source_ptr"); qRegisterMetaType< Tomahawk::dyncontrol_ptr >("Tomahawk::dyncontrol_ptr"); + qRegisterMetaType< Tomahawk::playlist_ptr >("Tomahawk::playlist_ptr"); + qRegisterMetaType< Tomahawk::dynplaylist_ptr >("Tomahawk::dynplaylist_ptr"); qRegisterMetaType< Tomahawk::geninterface_ptr >("Tomahawk::geninterface_ptr"); qRegisterMetaType< QList >("QList"); qRegisterMetaType< QList >("QList"); From 69011e3f90cd8a08ae122eb452a72a5ec7f3b419 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Tue, 5 Apr 2011 21:06:24 -0400 Subject: [PATCH 6/9] cleanup --- src/libtomahawk/playlist/playlistmanager.cpp | 49 +++++++++----------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/src/libtomahawk/playlist/playlistmanager.cpp b/src/libtomahawk/playlist/playlistmanager.cpp index 67c82afa4..eac12794f 100644 --- a/src/libtomahawk/playlist/playlistmanager.cpp +++ b/src/libtomahawk/playlist/playlistmanager.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -163,14 +163,14 @@ PlaylistManager::show( const Tomahawk::playlist_ptr& playlist ) playlist->resolve(); m_playlistViews.insert( playlist, view ); - + connect( playlist.data(), SIGNAL( deleted( Tomahawk::playlist_ptr ) ), this, SLOT( onPlaylistDeleted( Tomahawk::playlist_ptr ) ) ); } else { view = m_playlistViews.value( playlist ); } - + setPage( view ); TomahawkSettings::instance()->appendRecentlyPlayedPlaylist( playlist ); emit numSourcesChanged( SourceList::instance()->count() ); @@ -179,7 +179,7 @@ PlaylistManager::show( const Tomahawk::playlist_ptr& playlist ) } -bool +bool PlaylistManager::show( const Tomahawk::dynplaylist_ptr& playlist ) { if ( !m_dynamicWidgets.contains( playlist ) ) @@ -187,17 +187,17 @@ PlaylistManager::show( const Tomahawk::dynplaylist_ptr& playlist ) m_dynamicWidgets[ playlist ] = new Tomahawk::DynamicWidget( playlist, m_stack ); connect( playlist.data(), SIGNAL( deleted( Tomahawk::dynplaylist_ptr ) ), this, SLOT( onDynamicDeleted( Tomahawk::dynplaylist_ptr ) ) ); - + playlist->resolve(); } - + setPage( m_dynamicWidgets.value( playlist ) ); if ( playlist->mode() == Tomahawk::OnDemand ) m_queueView->hide(); else m_queueView->show(); - + TomahawkSettings::instance()->appendRecentlyPlayedPlaylist( playlist ); emit numSourcesChanged( SourceList::instance()->count() ); @@ -225,7 +225,7 @@ PlaylistManager::show( const Tomahawk::artist_ptr& artist ) { view = m_artistViews.value( artist ); } - + setPage( view ); emit numSourcesChanged( 1 ); @@ -252,7 +252,7 @@ PlaylistManager::show( const Tomahawk::album_ptr& album ) { view = m_albumViews.value( album ); } - + setPage( view ); emit numSourcesChanged( 1 ); @@ -359,10 +359,10 @@ PlaylistManager::showSuperCollection() } } m_superCollectionFlatModel->addCollections( toAdd ); - + m_superCollectionFlatModel->setTitle( tr( "All available tracks" ) ); m_superAlbumModel->setTitle( tr( "All available albums" ) ); - + if ( m_currentMode == 0 ) { setPage( m_superCollectionView ); @@ -472,7 +472,7 @@ PlaylistManager::historyForward() { if ( m_historyPosition >= m_pageHistory.count() - 1 ) return; - + showHistory( m_historyPosition + 1 ); } @@ -557,13 +557,10 @@ PlaylistManager::setPage( ViewPage* page, bool trackHistory ) // UGH! if( QObject* obj = dynamic_cast< QObject* >( currentPage() ) ) { // if the signal exists (just to hide the qobject runtime warning...) - if( obj->metaObject()->indexOfSignal( "descriptionChanged(QString)" ) > -1 ) + if( obj->metaObject()->indexOfSignal( "descriptionChanged(QString)" ) > -1 ) connect( obj, SIGNAL( descriptionChanged( QString ) ), m_infobar, SLOT( setDescription( QString ) ) ); - - if( obj->metaObject()->indexOfSignal( "deleted()" ) > -1 ) - connect( obj, SIGNAL( deleted() ), this, SLOT( pageDeleted() ) ); } - + m_stack->setCurrentWidget( page->widget() ); updateView(); } @@ -623,7 +620,7 @@ PlaylistManager::updateView() emit modeChanged( currentPlaylistInterface()->viewMode() ); } - if ( currentPage()->queueVisible() ) + if ( currentPage()->queueVisible() ) m_queueView->show(); else m_queueView->hide(); @@ -641,28 +638,28 @@ PlaylistManager::updateView() m_infobar->setPixmap( currentPage()->pixmap() ); } -void +void PlaylistManager::onDynamicDeleted( const Tomahawk::dynplaylist_ptr& pl ) { QWidget* w = m_dynamicWidgets.value( pl ); m_dynamicWidgets.remove( pl ); - + onWidgetDestroyed( w ); } -void +void PlaylistManager::onPlaylistDeleted( const Tomahawk::playlist_ptr& pl ) { QWidget* w = m_playlistViews.value( pl ); m_playlistViews.remove( pl ); - + onWidgetDestroyed( w ); } void PlaylistManager::onWidgetDestroyed( QWidget* widget ) -{ +{ qDebug() << "Destroyed child:" << widget << widget->metaObject()->className(); bool resetWidget = ( m_stack->currentWidget() == widget ); @@ -679,7 +676,7 @@ PlaylistManager::onWidgetDestroyed( QWidget* widget ) break; } } - + if ( resetWidget ) { if ( m_pageHistory.count() ) @@ -704,7 +701,7 @@ PlaylistManager::setShuffled( bool enabled ) } -void +void PlaylistManager::createPlaylist( const Tomahawk::source_ptr& src, const QVariant& contents ) { @@ -714,7 +711,7 @@ PlaylistManager::createPlaylist( const Tomahawk::source_ptr& src, } -void +void PlaylistManager::createDynamicPlaylist( const Tomahawk::source_ptr& src, const QVariant& contents ) { From dc43452bfc77828af0daa244cadaca55401538e6 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Tue, 5 Apr 2011 21:14:32 -0400 Subject: [PATCH 7/9] Fix build --- src/sip/twitter/twitter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sip/twitter/twitter.cpp b/src/sip/twitter/twitter.cpp index af759cd25..aa80d9dca 100644 --- a/src/sip/twitter/twitter.cpp +++ b/src/sip/twitter/twitter.cpp @@ -266,7 +266,7 @@ TwitterPlugin::connectTimerFired() { QHash< QString, QVariant > peerData = m_cachedPeers[screenName].toHash(); - if ( Servent::instance()->connectedToSession( peerData["node"] ) ) + if ( Servent::instance()->connectedToSession( peerData["node"].toString() ) ) { peerData["lastseen"] = QDateTime::currentMSecsSinceEpoch(); m_cachedPeers[screenName] = peerData; From ab2443792ac24d39be185d93fe34162fe2aa1edc Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Wed, 6 Apr 2011 06:18:00 +0200 Subject: [PATCH 8/9] * Don't manually delete the root item. This speeds up shut down, since the proxy will be disconnected before the root item gets deleted (automatically). --- src/libtomahawk/playlist/trackmodel.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libtomahawk/playlist/trackmodel.cpp b/src/libtomahawk/playlist/trackmodel.cpp index f96d3b026..a8dacfd26 100644 --- a/src/libtomahawk/playlist/trackmodel.cpp +++ b/src/libtomahawk/playlist/trackmodel.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -45,7 +45,7 @@ TrackModel::TrackModel( QObject* parent ) TrackModel::~TrackModel() { - delete m_rootItem; +// delete m_rootItem; } From 51a3eb39be5f4a8d5b8a76c23c592a7226ae944f Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Wed, 6 Apr 2011 07:26:57 +0200 Subject: [PATCH 9/9] * Fixed page-history related crash when deleting / creating playlists. --- .../dynamic/widgets/DynamicWidget.cpp | 145 +++++++++--------- .../playlist/dynamic/widgets/DynamicWidget.h | 46 +++--- src/libtomahawk/playlist/playlistmanager.cpp | 51 +++--- src/libtomahawk/playlist/playlistmanager.h | 22 ++- src/libtomahawk/playlist/playlistmodel.cpp | 18 ++- src/libtomahawk/playlist/playlistmodel.h | 6 +- src/libtomahawk/playlist/playlistview.cpp | 12 +- src/libtomahawk/playlist/playlistview.h | 7 +- src/libtomahawk/viewpage.h | 12 +- src/libtomahawk/widgets/newplaylistwidget.h | 4 +- 10 files changed, 176 insertions(+), 147 deletions(-) diff --git a/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.cpp b/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.cpp index d63fe718f..bd76b5683 100644 --- a/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.cpp +++ b/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -58,30 +58,30 @@ DynamicWidget::DynamicWidget( const Tomahawk::dynplaylist_ptr& playlist, QWidget , m_controls( 0 ) , m_view( 0 ) , m_model() -{ +{ m_controls = new CollapsibleControls( this ); m_layout->addWidget( m_controls ); setContentsMargins( 0, 0, 0, 1 ); // to align the bottom with the bottom of the sourcelist - + m_model = new DynamicModel( this ); m_view = new DynamicView( this ); m_view->setModel( m_model ); m_view->setContentsMargins( 0, 0, 0, 0 ); m_layout->addWidget( m_view, 1 ); - + connect( m_model, SIGNAL( collapseFromTo( int, int ) ), m_view, SLOT( collapseEntries( int, int ) ) ); - connect( m_model, SIGNAL( trackGenerationFailure( QString ) ), this, SLOT( stationFailed( QString ) ) ); - - m_loading = new LoadingSpinner( m_view ); + connect( m_model, SIGNAL( trackGenerationFailure( QString ) ), this, SLOT( stationFailed( QString ) ) ); + + m_loading = new LoadingSpinner( m_view ); connect( m_model, SIGNAL( tracksAdded() ), m_loading, SLOT( fadeOut() ) ); - + m_setup = new DynamicSetupWidget( playlist, this ); m_setup->fadeIn(); - + connect( m_model, SIGNAL( tracksAdded() ), this, SLOT( tracksAdded() ) ); - + loadDynamicPlaylist( playlist ); - + m_layout->setContentsMargins( 0, 0, 0, 0 ); m_layout->setMargin( 0 ); m_layout->setSpacing( 0 ); @@ -103,7 +103,7 @@ DynamicWidget::~DynamicWidget() { } -void +void DynamicWidget::loadDynamicPlaylist( const Tomahawk::dynplaylist_ptr& playlist ) { // special case: if we have launched multiple setRevision calls, and the number of controls is different, it means that we're getting an intermediate setRevision @@ -114,61 +114,61 @@ DynamicWidget::loadDynamicPlaylist( const Tomahawk::dynplaylist_ptr& playlist ) return; } m_seqRevLaunched = 0; - + // if we're being told to load the same dynamic playlist over again, only do it if the controls have a different number if( !m_playlist.isNull() && ( m_playlist.data() == playlist.data() ) // same playlist pointer && m_playlist->generator()->controls().size() == playlist->generator()->controls().size() ) { // we can skip our work. just let the dynamiccontrollist show the difference m_controls->setControls( m_playlist, m_playlist->author()->isLocal() ); - + m_playlist = playlist; - + if( !m_runningOnDemand ) { m_model->loadPlaylist( m_playlist ); } else if( !m_controlsChanged ) { // if the controls changed, we already dealt with that and don't want to change station yet m_model->changeStation(); } m_controlsChanged = false; - + return; } - + if( !m_playlist.isNull() ) { disconnect( m_playlist->generator().data(), SIGNAL( generated( QList ) ), this, SLOT( tracksGenerated( QList ) ) ); disconnect( m_playlist.data(), SIGNAL( dynamicRevisionLoaded( Tomahawk::DynamicPlaylistRevision) ), this, SLOT(onRevisionLoaded( Tomahawk::DynamicPlaylistRevision) ) ); disconnect( m_playlist->generator().data(), SIGNAL( error( QString, QString ) ), this, SLOT( generatorError( QString, QString ) ) ); - disconnect( m_playlist.data(), SIGNAL( deleted( Tomahawk::dynplaylist_ptr ) ), this, SLOT( deleteLater() ) ); + disconnect( m_playlist.data(), SIGNAL( deleted( Tomahawk::dynplaylist_ptr ) ), this, SLOT( onDeleted() ) ); } - - + + m_playlist = playlist; m_view->setOnDemand( m_playlist->mode() == OnDemand ); m_view->setReadOnly( !m_playlist->author()->isLocal() ); m_model->loadPlaylist( m_playlist ); m_controlsChanged = false; m_setup->setPlaylist( m_playlist ); - - + + if( !m_playlist->author()->isLocal() ) { // hide controls, as we show the description in the summary m_layout->removeWidget( m_controls ); } else if( m_layout->indexOf( m_controls ) == -1 ) { m_layout->insertWidget( 0, m_controls ); - } - + } + if( m_playlist->mode() == OnDemand && !m_playlist->generator()->controls().isEmpty() ) showPreview(); - + if( !m_playlist.isNull() ) m_controls->setControls( m_playlist, m_playlist->author()->isLocal() ); - + connect( m_playlist->generator().data(), SIGNAL( generated( QList ) ), this, SLOT( tracksGenerated( QList ) ) ); connect( m_playlist.data(), SIGNAL( dynamicRevisionLoaded( Tomahawk::DynamicPlaylistRevision ) ), this, SLOT( onRevisionLoaded( Tomahawk::DynamicPlaylistRevision ) ) ); connect( m_playlist->generator().data(), SIGNAL( error( QString, QString ) ), this, SLOT( generatorError( QString, QString ) ) ); - connect( m_playlist.data(), SIGNAL( deleted( Tomahawk::dynplaylist_ptr ) ), this, SLOT( deleteLater() ) ); + connect( m_playlist.data(), SIGNAL( deleted( Tomahawk::dynplaylist_ptr ) ), this, SLOT( onDeleted() ) ); } -void +void DynamicWidget::onRevisionLoaded( const Tomahawk::DynamicPlaylistRevision& rev ) { qDebug() << "DynamicWidget::onRevisionLoaded"; @@ -180,7 +180,7 @@ DynamicWidget::onRevisionLoaded( const Tomahawk::DynamicPlaylistRevision& rev ) } } -PlaylistInterface* +PlaylistInterface* DynamicWidget::playlistInterface() const { return m_view->proxyModel(); @@ -194,36 +194,36 @@ DynamicWidget::sizeHint() const return QSize( 5000, 5000 ); } -void +void DynamicWidget::resizeEvent(QResizeEvent* ) { layoutFloatingWidgets(); } -void +void DynamicWidget::layoutFloatingWidgets() { if( !m_runningOnDemand ) { int x = ( width() / 2 ) - ( m_setup->size().width() / 2 ); int y = height() - m_setup->size().height() - 40; // padding - + m_setup->move( x, y ); } else if( m_runningOnDemand && m_steering ) { int x = ( width() / 2 ) - ( m_steering->size().width() / 2 ); int y = height() - m_steering->size().height() - 40; // padding - + m_steering->move( x, y ); } } -void +void DynamicWidget::playlistChanged( PlaylistInterface* pl ) { if( pl == static_cast< PlaylistInterface* >( m_view->proxyModel() ) ) { // same playlist m_activePlaylist = true; } else { m_activePlaylist = false; - + // user started playing something somewhere else, so give it a rest if( m_runningOnDemand ) { stopStation( false ); @@ -231,7 +231,7 @@ DynamicWidget::playlistChanged( PlaylistInterface* pl ) } } -void +void DynamicWidget::showEvent(QShowEvent* ) { if( !m_playlist.isNull() && !m_runningOnDemand ) { @@ -240,7 +240,7 @@ DynamicWidget::showEvent(QShowEvent* ) } -void +void DynamicWidget::generate( int num ) { // get the items from the generator, and put them in the playlist @@ -249,27 +249,27 @@ DynamicWidget::generate( int num ) m_playlist->generator()->generate( num ); } -void +void DynamicWidget::stationFailed( const QString& msg ) { m_view->setDynamicWorking( false ); m_view->showMessage( msg ); m_loading->fadeOut(); - + stopStation( false ); } -void +void DynamicWidget::trackStarted() -{ +{ if( m_activePlaylist && !m_playlist.isNull() && m_playlist->mode() == OnDemand && !m_runningOnDemand ) { - + startStation(); } } -void +void DynamicWidget::tracksAdded() { if( m_playlist->mode() == OnDemand && m_runningOnDemand && m_setup->isVisible() ) @@ -277,94 +277,94 @@ DynamicWidget::tracksAdded() } -void +void DynamicWidget::stopStation( bool stopPlaying ) { m_model->stopOnDemand( stopPlaying ); m_runningOnDemand = false; - + // TODO until i add a qwidget interface QMetaObject::invokeMethod( m_steering, "fadeOut", Qt::DirectConnection ); m_setup->fadeIn(); } -void +void DynamicWidget::startStation() { m_runningOnDemand = true; m_model->startOnDemand(); - + m_setup->fadeOut(); // show the steering controls if( m_playlist->generator()->onDemandSteerable() ) { // position it horizontally centered, above the botton. m_steering = m_playlist->generator()->steeringWidget(); Q_ASSERT( m_steering ); - + int x = ( width() / 2 ) - ( m_steering->size().width() / 2 ); int y = height() - m_steering->size().height() - 40; // padding - + m_steering->setParent( this ); m_steering->move( x, y ); - + // TODO until i add a qwidget interface QMetaObject::invokeMethod( m_steering, "fadeIn", Qt::DirectConnection ); - + connect( m_steering, SIGNAL( resized() ), this, SLOT( layoutFloatingWidgets() ) ); } } -void +void DynamicWidget::playlistTypeChanged( QString ) { // TODO } -void +void DynamicWidget::tracksGenerated( const QList< query_ptr >& queries ) -{ +{ int limit = -1; // only limit the "preview" of a station if( m_playlist->author()->isLocal() && m_playlist->mode() == Static ) { m_resolveOnNextLoad = true; } else if( m_playlist->mode() == OnDemand ) limit = 5; - + if( m_playlist->mode() != OnDemand ) m_loading->fadeOut(); m_model->tracksGenerated( queries, limit ); } -void +void DynamicWidget::controlsChanged() { // controlsChanged() is emitted when a control is added or removed // in the case of addition, it's blank by default... so to avoid an error // when playing a station just ignore it till we're ready and get a controlChanged() m_controlsChanged = true; - + if( !m_playlist->author()->isLocal() ) return; m_playlist->createNewRevision(); m_seqRevLaunched++; - + emit descriptionChanged( m_playlist->generator()->sentenceSummary() ); } -void +void DynamicWidget::controlChanged( const Tomahawk::dyncontrol_ptr& control ) -{ +{ if( !m_playlist->author()->isLocal() ) - return; + return; m_playlist->createNewRevision(); m_seqRevLaunched++; - + showPreview(); - + emit descriptionChanged( m_playlist->generator()->sentenceSummary() ); } -void +void DynamicWidget::showPreview() { if( m_playlist->mode() == OnDemand && !m_runningOnDemand && m_model->rowCount( QModelIndex() ) == 0 ) { // if this is a not running station, preview matching tracks @@ -373,7 +373,7 @@ DynamicWidget::showPreview() } -void +void DynamicWidget::generatorError( const QString& title, const QString& content ) { if( m_runningOnDemand ) { @@ -386,17 +386,17 @@ DynamicWidget::generatorError( const QString& title, const QString& content ) void DynamicWidget::paintRoundedFilledRect( QPainter& p, QPalette& pal, QRect& r, qreal opacity ) -{ +{ p.setBackgroundMode( Qt::TransparentMode ); p.setRenderHint( QPainter::Antialiasing ); p.setOpacity( opacity ); - + QPen pen( pal.dark().color(), .5 ); p.setPen( pen ); p.setBrush( pal.highlight() ); - + p.drawRoundedRect( r, 10, 10 ); - + p.setOpacity( opacity + .2 ); p.setBrush( QBrush() ); p.setPen( pen ); @@ -409,3 +409,10 @@ DynamicWidget::jumpToCurrentTrack() m_view->scrollTo( m_view->proxyModel()->currentItem(), QAbstractItemView::PositionAtCenter ); return true; } + +void +DynamicWidget::onDeleted() +{ + emit destroyed( widget() ); + deleteLater(); +} diff --git a/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.h b/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.h index 1771fd07b..6b8ef96e3 100644 --- a/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.h +++ b/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -58,57 +58,59 @@ class CollapsibleControls; */ class DynamicWidget : public QWidget, public Tomahawk::ViewPage { -Q_OBJECT +Q_OBJECT public: explicit DynamicWidget( const dynplaylist_ptr& playlist, QWidget* parent = 0); virtual ~DynamicWidget(); - + void loadDynamicPlaylist( const dynplaylist_ptr& playlist ); - + virtual PlaylistInterface* playlistInterface() const; - + virtual QSize sizeHint() const; virtual void resizeEvent( QResizeEvent* ); virtual void showEvent(QShowEvent* ); - + static void paintRoundedFilledRect( QPainter& p, QPalette& pal, QRect& r, qreal opacity = .95 ); virtual QWidget* widget() { return this; } - + virtual QString title() const { return m_model->title(); } virtual QString description() const { return m_model->description(); } virtual QPixmap pixmap() const { return QPixmap( RESPATH "images/playlist-icon.png" ); } - + virtual bool jumpToCurrentTrack(); - + public slots: void onRevisionLoaded( const Tomahawk::DynamicPlaylistRevision& rev ); void playlistTypeChanged(QString); - + void startStation(); void stopStation( bool stopPlaying = true ); - + void trackStarted(); void stationFailed( const QString& ); - + void playlistChanged( PlaylistInterface* ); void tracksAdded(); - + signals: void descriptionChanged( const QString& caption ); - + void destroyed( QWidget* widget ); + private slots: void generate( int = -1 ); void tracksGenerated( const QList< Tomahawk::query_ptr>& queries ); void generatorError( const QString& title, const QString& content ); - + void controlsChanged(); void controlChanged( const Tomahawk::dyncontrol_ptr& control ); void showPreview(); - - void layoutFloatingWidgets(); -private: + void layoutFloatingWidgets(); + void onDeleted(); + +private: dynplaylist_ptr m_playlist; QVBoxLayout* m_layout; bool m_resolveOnNextLoad; @@ -117,17 +119,17 @@ private: // loading animation LoadingSpinner* m_loading; - + // setup controls DynamicSetupWidget* m_setup; - + // used in OnDemand mode bool m_runningOnDemand; bool m_controlsChanged; QWidget* m_steering; - + CollapsibleControls* m_controls; - + DynamicView* m_view; DynamicModel* m_model; }; diff --git a/src/libtomahawk/playlist/playlistmanager.cpp b/src/libtomahawk/playlist/playlistmanager.cpp index eac12794f..657f75645 100644 --- a/src/libtomahawk/playlist/playlistmanager.cpp +++ b/src/libtomahawk/playlist/playlistmanager.cpp @@ -163,8 +163,6 @@ PlaylistManager::show( const Tomahawk::playlist_ptr& playlist ) playlist->resolve(); m_playlistViews.insert( playlist, view ); - - connect( playlist.data(), SIGNAL( deleted( Tomahawk::playlist_ptr ) ), this, SLOT( onPlaylistDeleted( Tomahawk::playlist_ptr ) ) ); } else { @@ -540,11 +538,11 @@ PlaylistManager::setPage( ViewPage* page, bool trackHistory ) setHistoryPosition( m_pageHistory.count() - 1 ); } - if ( playlistForInterface( currentPlaylistInterface() ) ) + if ( !playlistForInterface( currentPlaylistInterface() ).isNull() ) emit playlistActivated( playlistForInterface( currentPlaylistInterface() ) ); - if ( dynamicPlaylistForInterface( currentPlaylistInterface() ) ) + if ( !dynamicPlaylistForInterface( currentPlaylistInterface() ).isNull() ) emit dynamicPlaylistActivated( dynamicPlaylistForInterface( currentPlaylistInterface() ) ); - if ( collectionForInterface( currentPlaylistInterface() ) ) + if ( !collectionForInterface( currentPlaylistInterface() ).isNull() ) emit collectionActivated( collectionForInterface( currentPlaylistInterface() ) ); if ( isSuperCollectionVisible() ) emit superCollectionActivated(); @@ -555,10 +553,17 @@ PlaylistManager::setPage( ViewPage* page, bool trackHistory ) AudioEngine::instance()->setPlaylist( currentPlaylistInterface() ); // UGH! - if( QObject* obj = dynamic_cast< QObject* >( currentPage() ) ) { + if ( QObject* obj = dynamic_cast< QObject* >( currentPage() ) ) + { // if the signal exists (just to hide the qobject runtime warning...) if( obj->metaObject()->indexOfSignal( "descriptionChanged(QString)" ) > -1 ) - connect( obj, SIGNAL( descriptionChanged( QString ) ), m_infobar, SLOT( setDescription( QString ) ) ); + connect( obj, SIGNAL( descriptionChanged( QString ) ), m_infobar, SLOT( setDescription( QString ) ), Qt::UniqueConnection ); + } + if ( QObject* obj = dynamic_cast< QObject* >( currentPage() ) ) + { + // if the signal exists (just to hide the qobject runtime warning...) + if( obj->metaObject()->indexOfSignal( "destroyed(QWidget*)" ) > -1 ) + connect( obj, SIGNAL( destroyed( QWidget* ) ), SLOT( onWidgetDestroyed( QWidget* ) ), Qt::UniqueConnection ); } m_stack->setCurrentWidget( page->widget() ); @@ -638,24 +643,6 @@ PlaylistManager::updateView() m_infobar->setPixmap( currentPage()->pixmap() ); } -void -PlaylistManager::onDynamicDeleted( const Tomahawk::dynplaylist_ptr& pl ) -{ - QWidget* w = m_dynamicWidgets.value( pl ); - m_dynamicWidgets.remove( pl ); - - onWidgetDestroyed( w ); -} - -void -PlaylistManager::onPlaylistDeleted( const Tomahawk::playlist_ptr& pl ) -{ - QWidget* w = m_playlistViews.value( pl ); - m_playlistViews.remove( pl ); - - onWidgetDestroyed( w ); -} - void PlaylistManager::onWidgetDestroyed( QWidget* widget ) @@ -663,11 +650,20 @@ PlaylistManager::onWidgetDestroyed( QWidget* widget ) qDebug() << "Destroyed child:" << widget << widget->metaObject()->className(); bool resetWidget = ( m_stack->currentWidget() == widget ); - m_stack->removeWidget( widget ); for ( int i = 0; i < m_pageHistory.count(); i++ ) { ViewPage* page = m_pageHistory.at( i ); + + if ( !playlistForInterface( page->playlistInterface() ).isNull() ) + { + m_playlistViews.remove( playlistForInterface( page->playlistInterface() ) ); + } + if ( !dynamicPlaylistForInterface( page->playlistInterface() ).isNull() ) + { + m_dynamicWidgets.remove( dynamicPlaylistForInterface( page->playlistInterface() ) ); + } + if ( page->widget() == widget ) { m_pageHistory.removeAt( i ); @@ -677,6 +673,8 @@ PlaylistManager::onWidgetDestroyed( QWidget* widget ) } } + m_stack->removeWidget( widget ); + if ( resetWidget ) { if ( m_pageHistory.count() ) @@ -783,6 +781,7 @@ PlaylistManager::playlistForInterface( PlaylistInterface* interface ) const { foreach ( PlaylistView* view, m_playlistViews.values() ) { + qDebug() << "LAAAA:" << view; if ( view->playlistInterface() == interface ) { return m_playlistViews.key( view ); diff --git a/src/libtomahawk/playlist/playlistmanager.h b/src/libtomahawk/playlist/playlistmanager.h index fc86acf66..6c7f66578 100644 --- a/src/libtomahawk/playlist/playlistmanager.h +++ b/src/libtomahawk/playlist/playlistmanager.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -104,7 +104,7 @@ signals: void collectionActivated( const Tomahawk::collection_ptr& collection ); void playlistActivated( const Tomahawk::playlist_ptr& playlist ); void dynamicPlaylistActivated( const Tomahawk::dynplaylist_ptr& playlist ); - + public slots: bool showSuperCollection(); void showWelcomePage(); @@ -123,21 +123,19 @@ public slots: void setRepeatMode( PlaylistInterface::RepeatMode mode ); void setShuffled( bool enabled ); - + // 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 ); - + // ugh need to set up the connection in tomahawk to libtomahawk void onPlayClicked(); void onPauseClicked(); - + private slots: void setFilter( const QString& filter ); void applyFilter(); - - void onPlaylistDeleted( const Tomahawk::playlist_ptr& pl ); - void onDynamicDeleted( const Tomahawk::dynplaylist_ptr& pl ); + void onWidgetDestroyed( QWidget* widget ); private: @@ -149,7 +147,7 @@ private: Tomahawk::playlist_ptr playlistForInterface( PlaylistInterface* interface ) const; Tomahawk::dynplaylist_ptr dynamicPlaylistForInterface( PlaylistInterface* interface ) const; Tomahawk::collection_ptr collectionForInterface( PlaylistInterface* interface ) const; - + QWidget* m_widget; InfoBar* m_infobar; TopBar* m_topbar; @@ -164,7 +162,7 @@ private: CollectionFlatModel* m_superCollectionFlatModel; CollectionView* m_superCollectionView; WelcomeWidget* m_welcomeWidget; - + QList< Tomahawk::collection_ptr > m_superCollections; QHash< Tomahawk::dynplaylist_ptr, Tomahawk::DynamicWidget* > m_dynamicWidgets; @@ -174,13 +172,13 @@ private: QHash< Tomahawk::album_ptr, PlaylistView* > m_albumViews; QHash< Tomahawk::playlist_ptr, PlaylistView* > m_playlistViews; QHash< Tomahawk::source_ptr, SourceInfoWidget* > m_sourceViews; - + QList m_pageHistory; int m_historyPosition; Tomahawk::collection_ptr m_currentCollection; int m_currentMode; - + QTimer m_filterTimer; QString m_filter; diff --git a/src/libtomahawk/playlist/playlistmodel.cpp b/src/libtomahawk/playlist/playlistmodel.cpp index cdcad71aa..9f95c554b 100644 --- a/src/libtomahawk/playlist/playlistmodel.cpp +++ b/src/libtomahawk/playlist/playlistmodel.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -71,7 +71,10 @@ void PlaylistModel::loadPlaylist( const Tomahawk::playlist_ptr& playlist, bool loadEntries ) { if ( !m_playlist.isNull() ) + { disconnect( m_playlist.data(), SIGNAL( revisionLoaded( Tomahawk::PlaylistRevision ) ), this, SLOT( onRevisionLoaded( Tomahawk::PlaylistRevision ) ) ); + disconnect( m_playlist.data(), SIGNAL( deleted( Tomahawk::playlist_ptr ) ), this, SIGNAL( playlistDeleted() ) ); + } if ( rowCount( QModelIndex() ) && loadEntries ) { @@ -80,6 +83,7 @@ PlaylistModel::loadPlaylist( const Tomahawk::playlist_ptr& playlist, bool loadEn m_playlist = playlist; connect( playlist.data(), SIGNAL( revisionLoaded( Tomahawk::PlaylistRevision ) ), SLOT( onRevisionLoaded( Tomahawk::PlaylistRevision ) ) ); + connect( playlist.data(), SIGNAL( deleted( Tomahawk::playlist_ptr ) ), this, SIGNAL( playlistDeleted() ) ); setReadOnly( !m_playlist->author()->isLocal() ); setTitle( playlist->title() ); @@ -105,7 +109,7 @@ PlaylistModel::loadPlaylist( const Tomahawk::playlist_ptr& playlist, bool loadEn plitem->index = createIndex( m_rootItem->children.count() - 1, 0, plitem ); connect( plitem, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) ); - + if( !entry->query()->resolvingFinished() && entry->query()->playable() ) { m_waitingForResolved.append( entry->query().data() ); connect( entry->query().data(), SIGNAL( resolvingFinished( bool ) ), this, SLOT( trackResolved( bool ) ) ); @@ -119,7 +123,7 @@ PlaylistModel::loadPlaylist( const Tomahawk::playlist_ptr& playlist, bool loadEn if( !m_waitingForResolved.isEmpty() ) emit loadingStarted(); - + emit trackCountChanged( rowCount( QModelIndex() ) ); } @@ -145,7 +149,7 @@ PlaylistModel::loadHistory( const Tomahawk::source_ptr& source, unsigned int amo } -void +void PlaylistModel::clear() { if ( rowCount( QModelIndex() ) ) @@ -210,15 +214,15 @@ PlaylistModel::insert( unsigned int row, const Tomahawk::query_ptr& query ) onTracksInserted( row, ql ); } -void +void PlaylistModel::trackResolved( bool ) { Tomahawk::Query* q = qobject_cast< Query* >( sender() ); Q_ASSERT( q ); - + m_waitingForResolved.removeAll( q ); disconnect( q, SIGNAL( resolvingFinished( bool ) ), this, SLOT( trackResolved( bool ) ) ); - + if( m_waitingForResolved.isEmpty() ) emit loadingFinished(); } diff --git a/src/libtomahawk/playlist/playlistmodel.h b/src/libtomahawk/playlist/playlistmodel.h index e5ce24ae4..ad9bd9411 100644 --- a/src/libtomahawk/playlist/playlistmodel.h +++ b/src/libtomahawk/playlist/playlistmodel.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -70,6 +70,9 @@ signals: void shuffleModeChanged( bool enabled ); void itemSizeChanged( const QModelIndex& index ); + + void playlistDeleted(); + private slots: void onDataChanged(); @@ -80,6 +83,7 @@ private slots: void onTracksInserted( unsigned int row, const QList& tracks ); void trackResolved( bool ); + private: QList playlistEntries() const; diff --git a/src/libtomahawk/playlist/playlistview.cpp b/src/libtomahawk/playlist/playlistview.cpp index 9b66257ad..79026e872 100644 --- a/src/libtomahawk/playlist/playlistview.cpp +++ b/src/libtomahawk/playlist/playlistview.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -58,6 +58,7 @@ PlaylistView::setModel( PlaylistModel* model ) setGuid( "playlistview" ); connect( model, SIGNAL( trackCountChanged( unsigned int ) ), SLOT( onTrackCountChanged( unsigned int ) ) ); + connect( model, SIGNAL( playlistDeleted() ), SLOT( onDeleted() ) ); } @@ -154,3 +155,12 @@ PlaylistView::jumpToCurrentTrack() scrollTo( proxyModel()->currentItem(), QAbstractItemView::PositionAtCenter ); return true; } + + +void +PlaylistView::onDeleted() +{ + qDebug() << Q_FUNC_INFO; + emit destroyed( widget() ); + deleteLater(); +} diff --git a/src/libtomahawk/playlist/playlistview.h b/src/libtomahawk/playlist/playlistview.h index 3629099b1..5fa0d3a51 100644 --- a/src/libtomahawk/playlist/playlistview.h +++ b/src/libtomahawk/playlist/playlistview.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -50,6 +50,9 @@ public: virtual bool jumpToCurrentTrack(); +signals: + void destroyed( QWidget* widget ); + protected: void keyPressEvent( QKeyEvent* event ); @@ -60,6 +63,8 @@ private slots: void addItemsToPlaylist(); void deleteItems(); + void onDeleted(); + private: void setupMenus(); diff --git a/src/libtomahawk/viewpage.h b/src/libtomahawk/viewpage.h index d775f451d..a515c47e6 100644 --- a/src/libtomahawk/viewpage.h +++ b/src/libtomahawk/viewpage.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -29,7 +29,7 @@ namespace Tomahawk { - + class DLLEXPORT ViewPage { public: @@ -45,18 +45,18 @@ public: virtual bool showStatsBar() const { return true; } virtual bool showModes() const { return false; } virtual bool queueVisible() const { return true; } - + virtual bool jumpToCurrentTrack() = 0; /** subclasses implementing ViewPage can emit the following signals: * descriptionChanged( const QString& ) - * deleted() - * + * destroyed( QWidget* widget ); + * * See DynamicWidget for an example */ private: }; - + }; // ns #endif //VIEWPAGE_H diff --git a/src/libtomahawk/widgets/newplaylistwidget.h b/src/libtomahawk/widgets/newplaylistwidget.h index bb6c27629..61799ffd6 100644 --- a/src/libtomahawk/widgets/newplaylistwidget.h +++ b/src/libtomahawk/widgets/newplaylistwidget.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -47,7 +47,7 @@ public: virtual QWidget* widget() { return this; } virtual PlaylistInterface* playlistInterface() const { return 0; } - + virtual QString title() const { return tr( "Create a new playlist" ); } virtual QString description() const { return QString(); }