From 85651dd37fe396acff46fd903d32b118bdc16b06 Mon Sep 17 00:00:00 2001 From: Jim Broadus Date: Thu, 20 Feb 2020 23:43:29 -0800 Subject: [PATCH] Fix assertion when deleting multiple queued items from playlist. Removal of items from a playlist is done with a single transaction. When Queue::SourceLayoutChanged is called after this, the items in the queue are checked one at a time. When an item is removed, it triggers dataChanged signal from the model, connected to the SourceDataChanged slot. There, ItemCountChanged is emitted which calls UpdateTotalLength. This method will assert when it finds an item that is in the queue, but not in the playlist. To solve this, disconnect the ItemCountChanged signal at the beginning of SourceLayoutChanged and re-enable it after cleaning the queue. The method emits the signal before returning. --- src/playlist/queue.cpp | 9 ++++++++- src/playlist/queue.h | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/playlist/queue.cpp b/src/playlist/queue.cpp index 370000f64..c633f38cc 100644 --- a/src/playlist/queue.cpp +++ b/src/playlist/queue.cpp @@ -29,7 +29,8 @@ const char* Queue::kRowsMimetype = "application/x-clementine-queue-rows"; Queue::Queue(Playlist* parent) : QAbstractProxyModel(parent), playlist_(parent), total_length_ns_(0) { - connect(this, SIGNAL(ItemCountChanged(int)), SLOT(UpdateTotalLength())); + count_changed_ = + connect(this, SIGNAL(ItemCountChanged(int)), SLOT(UpdateTotalLength())); connect(this, SIGNAL(TotalLengthChanged(quint64)), SLOT(UpdateSummaryText())); UpdateSummaryText(); @@ -91,6 +92,9 @@ void Queue::SourceDataChanged(const QModelIndex& top_left, } void Queue::SourceLayoutChanged() { + // Temporarily disconnect this signal to prevent UpdateTotalLength from + // being called when SourceDataChanged is handled during this scrub. + disconnect(count_changed_); for (int i = 0; i < source_indexes_.count(); ++i) { if (!source_indexes_[i].isValid()) { beginRemoveRows(QModelIndex(), i, i); @@ -100,6 +104,9 @@ void Queue::SourceLayoutChanged() { --i; } } + // Re-connect before emitting the signal ourselves. + count_changed_ = + connect(this, SIGNAL(ItemCountChanged(int)), SLOT(UpdateTotalLength())); emit ItemCountChanged(this->ItemCount()); } diff --git a/src/playlist/queue.h b/src/playlist/queue.h index f840e733e..73271b1d4 100644 --- a/src/playlist/queue.h +++ b/src/playlist/queue.h @@ -86,6 +86,7 @@ class Queue : public QAbstractProxyModel { QList source_indexes_; const Playlist* playlist_; quint64 total_length_ns_; + QMetaObject::Connection count_changed_; }; #endif // QUEUE_H