"remove deleted songs from playlists" action in the 'deleted songs invalidator' plugin (fixes issue #1594)

This commit is contained in:
Paweł Bara 2011-04-21 21:56:37 +00:00
parent 90470e1315
commit b8e1880854
6 changed files with 83 additions and 4 deletions

View File

@ -4,19 +4,33 @@ from PyQt4.QtCore import QObject
from PyQt4.QtCore import SIGNAL
from PyQt4.QtGui import QAction
class InvalidateDeleted(QObject):
"""
TODO: actions which are defined here should be implemented here too instead of delegating
the responsibility to Playlist Manager. Unfortunately, it cannot be done at this moment
since using PlaylistItemPtrs in Python crashes Clementine.
"""
def __init__(self):
QObject.__init__(self)
self.action = QAction("invalidate_deleted", self)
self.action.setText("Grey out deleted songs")
self.connect(self.action, SIGNAL("activated()"), self.grey_out_activated)
self.invalidate = QAction("invalidate_deleted", self)
self.invalidate.setText("Grey out deleted songs")
self.connect(self.invalidate, SIGNAL("activated()"), self.grey_out_activated)
clementine.ui.AddAction('playlist_menu', self.action)
self.delete = QAction("remove_deleted", self)
self.delete.setText("Remove deleted songs")
self.connect(self.delete, SIGNAL("activated()"), self.delete_activated)
clementine.ui.AddAction('playlist_menu', self.invalidate)
clementine.ui.AddAction('playlist_menu', self.delete)
def grey_out_activated(self):
clementine.playlists.InvalidateDeletedSongs()
def delete_activated(self):
clementine.playlists.RemoveDeletedSongs()
script = InvalidateDeleted()

View File

@ -1275,6 +1275,35 @@ bool Playlist::removeRows(int row, int count, const QModelIndex& parent) {
return true;
}
bool Playlist::removeRows(QList<int>& rows) {
if(rows.isEmpty()) {
return false;
}
// start from the end to be sure that indices won't 'move' during
// the removal process
qSort(rows.begin(), rows.end(), qGreater<int>());
QList<int> part;
while(!rows.isEmpty()) {
// we're splitting the input list into sequences of consecutive
// numbers
part.append(rows.takeFirst());
while(rows.first() == part.last() - 1) {
part.append(rows.takeFirst());
}
// and now we're removing the current sequence
if(!removeRows(part.last(), part.size())) {
return false;
}
part.clear();
}
return true;
}
PlaylistItemList Playlist::RemoveItemsWithoutUndo(int row, int count) {
if (row < 0 || row >= items_.size() || row + count > items_.size()) {
return PlaylistItemList();
@ -1672,6 +1701,21 @@ void Playlist::InvalidateDeletedSongs() {
ReloadItems(invalidated_rows);
}
void Playlist::RemoveDeletedSongs() {
QList<int> rows_to_remove;
for (int row = 0; row < items_.count(); ++row) {
PlaylistItemPtr item = items_[row];
Song song = item->Metadata();
if(!song.is_stream() && !QFile::exists(song.filename())) {
rows_to_remove.append(row);
}
}
removeRows(rows_to_remove);
}
bool Playlist::ApplyValidityOnCurrentSong(const QUrl& url, bool valid) {
PlaylistItemPtr current = current_item();

View File

@ -220,6 +220,8 @@ class Playlist : public QAbstractListModel {
// Grays out and reloads all deleted songs in all playlists. Also, "ungreys" those songs
// which were once deleted but now got restored somehow.
void InvalidateDeletedSongs();
// Removes from the playlist all local files that don't exist anymore.
void RemoveDeletedSongs();
void StopAfter(int row);
void ReloadItems(const QList<int>& rows);
@ -305,6 +307,9 @@ class Playlist : public QAbstractListModel {
void RemoveItemsNotInQueue();
// Removes rows with given indices from this playlist.
bool removeRows(QList<int>& rows);
void InformOfCurrentSongChange(const QModelIndex& top_left, const QModelIndex& bottom_right,
const Song& metadata);

View File

@ -348,6 +348,12 @@ void PlaylistManager::InvalidateDeletedSongs() {
}
}
void PlaylistManager::RemoveDeletedSongs() {
foreach(Playlist* playlist, GetAllPlaylists()) {
playlist->RemoveDeletedSongs();
}
}
QString PlaylistManager::GetNameForNewPlaylist(const SongList& songs) {
if (songs.isEmpty()) {
return tr("Playlist");

View File

@ -54,6 +54,8 @@ public:
virtual QList<Playlist*> GetAllPlaylists() const = 0;
// Grays out and reloads all deleted songs in all playlists.
virtual void InvalidateDeletedSongs() = 0;
// Removes all deleted songs from all playlists.
virtual void RemoveDeletedSongs() = 0;
virtual const QItemSelection& selection(int id) const = 0;
virtual const QItemSelection& current_selection() const = 0;
@ -137,6 +139,8 @@ public:
QList<Playlist*> GetAllPlaylists() const;
// Grays out and reloads all deleted songs in all playlists.
void InvalidateDeletedSongs();
// Removes all deleted songs from all playlists.
void RemoveDeletedSongs();
// Returns a pretty automatic name for playlist created from the given list of
// songs.

View File

@ -92,6 +92,12 @@ Returns a list containing all the playlists.
InvalidateDeletedSongs()
Grays out and reloads all deleted songs in all playlists. Also, "ungreys"
those songs which were once deleted but now got restored somehow.
%End
void RemoveDeletedSongs();
%Docstring
RemoveDeletedSongs()
Removes all deleted songs from all playlists.
%End
const QItemSelection& selection(int id) const;