SVN commit 999402 by shanachie: Refactor UserPlaylists a bit further. With the groupingproxy not enabled the view updates correctly now. M +37 -0 browsers/playlistbrowser/UserPlaylistModel.cpp M +7 -1 browsers/playlistbrowser/UserPlaylistModel.h M +5 -13 context/applets/serviceinfo/ServiceInfo.cpp M +1 -3 context/applets/serviceinfo/ServiceInfo.h M +43 -22 meta/Playlist.h M +5 -9 meta/SqlPlaylist.cpp M +0 -2 meta/SqlPlaylist.h M +0 -2 meta/XSPFPlaylist.cpp --- trunk/extragear/multimedia/amarok/src/browsers/playlistbrowser/UserPlaylistModel.cpp #999401:999402 @@ -123,6 +123,7 @@ { Meta::PlaylistPtr playlist = Meta::PlaylistPtr::staticCast( i.next() ); m_playlists << playlist; + playlist->subscribe( this ); } } @@ -315,9 +316,12 @@ } beginRemoveRows( parent, row, row + count - 1 ); + //ignore notifications while removing tracks + playlist->unsubscribe( this ); for( int i = row; i < row + count; i++ ) //deleting a track moves the next track up, so use the same row number each time playlist->removeTrack( row ); + playlist->subscribe( this ); endRemoveRows(); return true; @@ -555,4 +559,37 @@ return playlist->tracks()[index.row()]; } +void +PlaylistBrowserNS::UserModel::trackAdded( Meta::PlaylistPtr playlist, Meta::TrackPtr track, int position ) +{ + DEBUG_BLOCK + debug() << "From playlist: " << playlist->prettyName(); + debug() << "Track: " << track->prettyName() << "position: " << position; + int indexNumber = m_playlists.indexOf( playlist ); + if( indexNumber == -1 ) + { + debug() << "Error: this playlist is not in the list of this model."; + return; + } + QModelIndex playlistIdx = index( indexNumber, 0, QModelIndex() ); + rowsInserted( playlistIdx, position, position ); +} + +void +PlaylistBrowserNS::UserModel::trackRemoved( Meta::PlaylistPtr playlist, int position ) +{ + DEBUG_BLOCK + debug() << "From playlist: " << playlist->prettyName(); + debug() << "position: " << position; + int indexNumber = m_playlists.indexOf( playlist ); + if( indexNumber == -1 ) + { + debug() << "Error: this playlist is not in the list of this model."; + return; + } + QModelIndex playlistIdx = index( indexNumber, 0, QModelIndex() ); + beginRemoveRows( playlistIdx, position, position ); + endRemoveRows(); +} + #include "UserPlaylistModel.moc" --- trunk/extragear/multimedia/amarok/src/browsers/playlistbrowser/UserPlaylistModel.h #999401:999402 @@ -34,7 +34,8 @@ /** @author Nikolaj Hald Nielsen */ -class UserModel : public QAbstractItemModel, public MetaPlaylistModel +class UserModel : public QAbstractItemModel, public MetaPlaylistModel, + public Meta::PlaylistObserver { Q_OBJECT public: @@ -81,6 +82,11 @@ Meta::PlaylistList selectedPlaylists() { return m_selectedPlaylists; } Meta::TrackList selectedTracks() { return m_selectedTracks; } + /* Meta::PlaylistObserver methods */ + virtual void trackAdded( Meta::PlaylistPtr playlist, Meta::TrackPtr track, + int position ); + virtual void trackRemoved( Meta::PlaylistPtr playlist, int position ); + public slots: void slotLoad(); void slotAppend(); --- trunk/extragear/multimedia/amarok/src/context/applets/serviceinfo/ServiceInfo.cpp #999401:999402 @@ -154,24 +154,16 @@ { debug() << "Link clicked: " << url.toString(); - if ( url.toString().startsWith( "amarok://", Qt::CaseInsensitive ) ) { + if ( url.toString().startsWith( "amarok://", Qt::CaseInsensitive ) ) + { AmarokUrl aUrl( url.toString() ); aUrl.run(); - } else if ( url.toString().contains( ".xspf", Qt::CaseInsensitive ) ) { - + } + else if ( url.toString().contains( ".xspf", Qt::CaseInsensitive ) ) + { Meta::XSPFPlaylist * playlist = new Meta::XSPFPlaylist( url ); - playlist->subscribe( this ); - } } -void ServiceInfo::trackListChanged( Meta::Playlist * playlist ) -{ - playlist->unsubscribe( this ); - Meta::PlaylistPtr playlistPtr( playlist ); - The::playlistController()->insertOptioned( playlistPtr, Playlist::Append ); -} - - #include "ServiceInfo.moc" --- trunk/extragear/multimedia/amarok/src/context/applets/serviceinfo/ServiceInfo.h #999401:999402 @@ -39,7 +39,7 @@ class QSpinBox; class QCheckBox; -class ServiceInfo : public Context::Applet, public Meta::PlaylistObserver +class ServiceInfo : public Context::Applet { Q_OBJECT public: @@ -49,8 +49,6 @@ void paintInterface( QPainter *painter, const QStyleOptionGraphicsItem *option, const QRect &contentsRect ); void constraintsEvent( Plasma::Constraints constraints = Plasma::AllConstraints ); - virtual void trackListChanged( Meta::Playlist* playlist ); - public slots: void dataUpdated( const QString& name, const Plasma::DataEngine::Data &data ); private slots: --- trunk/extragear/multimedia/amarok/src/meta/Playlist.h #999401:999402 @@ -36,7 +36,6 @@ namespace Meta { - class Playlist; typedef KSharedPtr PlaylistPtr; @@ -45,10 +44,20 @@ class AMAROK_EXPORT PlaylistObserver { public: - /** This method is called when a playlist has changed. + void subscribeTo( PlaylistPtr ); + void unsubscribeFrom( PlaylistPtr ); + + /** This method is called when a track has been added to the playlist. */ - virtual void trackListChanged( Playlist* playlist ) = 0; + virtual void trackAdded( PlaylistPtr playlist, TrackPtr track, int position ) = 0; + /** This method is called when a track is removed from to the playlist. + */ + virtual void trackRemoved( PlaylistPtr playlist, int position ) = 0; + virtual ~PlaylistObserver() {} + + private: + QSet m_playlistSubscriptions; }; class AMAROK_EXPORT Playlist : public virtual QSharedData @@ -91,24 +100,19 @@ virtual Capability* createCapabilityInterface( Capability::Type type ) = 0; - virtual KUrl retrievableUrl() { return KUrl(); } - - virtual bool load( QTextStream &stream ) { Q_UNUSED( stream ); return false; } - virtual bool save( const QString &location, bool relative ) { Q_UNUSED( location); Q_UNUSED( relative); return false; } - /** * Retrieves a specialized interface which represents a capability of this - * MetaBase object. - * - * @returns a pointer to the capability interface if it exists, 0 otherwise - */ - template CapIface *create() - { - Meta::Capability::Type type = CapIface::capabilityInterfaceType(); - Meta::Capability *iface = createCapabilityInterface(type); - return qobject_cast(iface); + * MetaBase object. + * + * @returns a pointer to the capability interface if it exists, 0 otherwise + */ + template CapIface *create() + { + Meta::Capability::Type type = CapIface::capabilityInterfaceType(); + Meta::Capability *iface = createCapabilityInterface(type); + return qobject_cast(iface); } - + /** * Tests if a MetaBase object provides a given capability interface. * @@ -119,13 +123,30 @@ return hasCapabilityInterface( CapIface::capabilityInterfaceType() ); } + virtual KUrl retrievableUrl() { return KUrl(); } + + virtual bool load( QTextStream &stream ) { Q_UNUSED( stream ); return false; } + virtual bool save( const QString &location, bool relative ) { Q_UNUSED( location); Q_UNUSED( relative); return false; } + protected: - virtual void notifyObservers() const { - foreach( PlaylistObserver *observer, m_observers ) - observer->trackListChanged( const_cast( this ) ); + inline void notifyObserversTrackAdded( Meta::TrackPtr track, int position ) + { + foreach( Meta::PlaylistObserver *observer, m_observers ) + { + if( m_observers.contains( observer ) ) // guard against observers removing themselves in destructors + observer->trackAdded( Meta::PlaylistPtr( this ), track, position ); + } } - protected: + inline void notifyObserversTrackRemoved( int position ) + { + foreach( Meta::PlaylistObserver *observer, m_observers ) + { + if( m_observers.contains( observer ) ) // guard against observers removing themselves in destructors + observer->trackRemoved( Meta::PlaylistPtr( this ), position ); + } + } + QSet m_observers; QString m_name; }; --- trunk/extragear/multimedia/amarok/src/meta/SqlPlaylist.cpp #999401:999402 @@ -214,13 +214,18 @@ DEBUG_BLOCK int insertAt = (position == -1) ? m_tracks.count() : position; m_tracks.insert( insertAt, track ); + notifyObserversTrackAdded( track, position ); } void Meta::SqlPlaylist::removeTrack( int position ) { DEBUG_BLOCK + debug() << "position: " << position; + if( position < 0 || position >= m_tracks.size() ) + return; m_tracks.removeAt( position ); + notifyObserversTrackRemoved( position ); } void @@ -261,7 +266,6 @@ //debug() << "added track: " << trackPtr->name(); } - } m_tracksLoaded = true; @@ -292,11 +296,3 @@ { return m_dbId; } - -/* -void -Meta::SqlPlaylist::reparent( SqlPlaylistGroupPtr parent ) -{ - m_parent = parent; - saveToDb( false ); -}*/ --- trunk/extragear/multimedia/amarok/src/meta/SqlPlaylist.h #999401:999402 @@ -73,8 +73,6 @@ void removeFromDb(); - //bool load(); - private: void loadTracks(); void saveTracks(); --- trunk/extragear/multimedia/amarok/src/meta/XSPFPlaylist.cpp #999401:999402 @@ -148,8 +148,6 @@ return false; } - notifyObservers(); - return true; }