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.
This commit is contained in:
Jim Broadus 2020-02-20 23:43:29 -08:00 committed by John Maguire
parent 2f36b34c33
commit 85651dd37f
2 changed files with 9 additions and 1 deletions

View File

@ -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());
}

View File

@ -86,6 +86,7 @@ class Queue : public QAbstractProxyModel {
QList<QPersistentModelIndex> source_indexes_;
const Playlist* playlist_;
quint64 total_length_ns_;
QMetaObject::Connection count_changed_;
};
#endif // QUEUE_H