mirror of
https://github.com/clementine-player/Clementine
synced 2024-12-16 19:31:02 +01:00
Don't reset the whole merged model when one of the submodels changes
This commit is contained in:
parent
e2355d855d
commit
bef59ffd22
@ -17,13 +17,17 @@
|
||||
#include "mergedproxymodel.h"
|
||||
|
||||
#include <QStringList>
|
||||
#include <QtDebug>
|
||||
|
||||
#include <limits>
|
||||
|
||||
std::size_t hash_value(const QModelIndex& index) {
|
||||
return qHash(index);
|
||||
}
|
||||
|
||||
MergedProxyModel::MergedProxyModel(QObject* parent)
|
||||
: QAbstractProxyModel(parent)
|
||||
: QAbstractProxyModel(parent),
|
||||
resetting_model_(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
@ -95,12 +99,25 @@ void MergedProxyModel::SourceModelReset() {
|
||||
void MergedProxyModel::SubModelReset() {
|
||||
const QAbstractItemModel* submodel = static_cast<const QAbstractItemModel*>(sender());
|
||||
|
||||
// TODO: When we require Qt 4.6, use beginResetModel() and endResetModel()
|
||||
// in LibraryModel and catch those here - that will let us do away with this
|
||||
// std::numeric_limits<int>::max() hack.
|
||||
|
||||
// Remove all the children of the item that got deleted
|
||||
QModelIndex source_parent = merge_points_.value(submodel);
|
||||
QModelIndex proxy_parent = mapFromSource(source_parent);
|
||||
|
||||
// We can't know how many children it had, since it's already disappeared...
|
||||
resetting_model_ = submodel;
|
||||
beginRemoveRows(proxy_parent, 0, std::numeric_limits<int>::max() - 1);
|
||||
endRemoveRows();
|
||||
resetting_model_ = NULL;
|
||||
|
||||
// Delete all the mappings that reference the submodel
|
||||
MappingContainer::index<tag_by_pointer>::type::iterator it =
|
||||
mappings_.get<tag_by_pointer>().begin();
|
||||
MappingContainer::index<tag_by_pointer>::type::iterator end =
|
||||
mappings_.get<tag_by_pointer>().end();
|
||||
|
||||
while (it != end) {
|
||||
if ((*it)->source_index.model() == submodel) {
|
||||
delete *it;
|
||||
@ -110,8 +127,12 @@ void MergedProxyModel::SubModelReset() {
|
||||
}
|
||||
}
|
||||
|
||||
// Reset the proxy
|
||||
reset();
|
||||
// "Insert" items from the newly reset submodel
|
||||
int count = submodel->rowCount();
|
||||
if (count) {
|
||||
beginInsertRows(proxy_parent, 0, count-1);
|
||||
endInsertRows();
|
||||
}
|
||||
}
|
||||
|
||||
QModelIndex MergedProxyModel::GetActualSourceParent(const QModelIndex& source_parent,
|
||||
@ -148,12 +169,20 @@ QModelIndex MergedProxyModel::mapToSource(const QModelIndex& proxy_index) const
|
||||
return QModelIndex();
|
||||
|
||||
Mapping* mapping = static_cast<Mapping*>(proxy_index.internalPointer());
|
||||
if (mappings_.get<tag_by_pointer>().find(mapping) ==
|
||||
mappings_.get<tag_by_pointer>().end())
|
||||
return QModelIndex();
|
||||
if (mapping->source_index.model() == resetting_model_)
|
||||
return QModelIndex();
|
||||
|
||||
return mapping->source_index;
|
||||
}
|
||||
|
||||
QModelIndex MergedProxyModel::mapFromSource(const QModelIndex& source_index) const {
|
||||
if (!source_index.isValid())
|
||||
return QModelIndex();
|
||||
if (source_index.model() == resetting_model_)
|
||||
return QModelIndex();
|
||||
|
||||
// Add a mapping if we don't have one already
|
||||
MappingContainer::index<tag_by_source>::type::iterator it =
|
||||
|
@ -85,7 +85,9 @@ class MergedProxyModel : public QAbstractProxyModel {
|
||||
void DeleteAllMappings();
|
||||
|
||||
struct Mapping {
|
||||
Mapping(const QModelIndex& _source_index) : source_index(_source_index) {}
|
||||
Mapping(const QModelIndex& _source_index)
|
||||
: source_index(_source_index) {}
|
||||
|
||||
QModelIndex source_index;
|
||||
};
|
||||
|
||||
@ -103,6 +105,7 @@ class MergedProxyModel : public QAbstractProxyModel {
|
||||
|
||||
MappingContainer mappings_;
|
||||
QMap<const QAbstractItemModel*, QModelIndex> merge_points_;
|
||||
const QAbstractItemModel* resetting_model_;
|
||||
};
|
||||
|
||||
#endif // MERGEDPROXYMODEL_H
|
||||
|
@ -31,6 +31,9 @@ RadioViewContainer::RadioViewContainer(QWidget *parent)
|
||||
{
|
||||
ui_.setupUi(this);
|
||||
|
||||
connect(ui_.tree, SIGNAL(collapsed(QModelIndex)), SLOT(Collapsed(QModelIndex)));
|
||||
connect(ui_.tree, SIGNAL(expanded(QModelIndex)), SLOT(Expanded(QModelIndex)));
|
||||
|
||||
filter_animation_->setFrameRange(0, ui_.filter->sizeHint().height());
|
||||
connect(filter_animation_, SIGNAL(frameChanged(int)), SLOT(SetFilterHeight(int)));
|
||||
|
||||
@ -47,19 +50,37 @@ void RadioViewContainer::SetModel(RadioModel* model) {
|
||||
SLOT(CurrentIndexChanged(QModelIndex)));
|
||||
}
|
||||
|
||||
void RadioViewContainer::CurrentIndexChanged(const QModelIndex& index) {
|
||||
void RadioViewContainer::ServiceChanged(const QModelIndex& index, bool changed_away) {
|
||||
RadioItem* item = model_->IndexToItem(
|
||||
model_->merged_model()->FindSourceParent(index));
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
RadioService* service = item->service;
|
||||
if (!service || service == current_service_)
|
||||
return;
|
||||
if (changed_away) {
|
||||
SetFilterVisible(false);
|
||||
} else {
|
||||
RadioService* service = item->service;
|
||||
if (!service || service == current_service_)
|
||||
return;
|
||||
current_service_ = service;
|
||||
|
||||
qDebug() << service->name();
|
||||
SetFilterVisible(service->SetupLibraryFilter(ui_.filter));
|
||||
}
|
||||
}
|
||||
|
||||
SetFilterVisible(service->SetupLibraryFilter(ui_.filter));
|
||||
void RadioViewContainer::CurrentIndexChanged(const QModelIndex& index) {
|
||||
ServiceChanged(index);
|
||||
}
|
||||
|
||||
void RadioViewContainer::Collapsed(const QModelIndex& index) {
|
||||
if (model_->merged_model()->mapToSource(index).model() == model_) {
|
||||
SetFilterVisible(false);
|
||||
current_service_ = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void RadioViewContainer::Expanded(const QModelIndex& index) {
|
||||
ServiceChanged(index);
|
||||
}
|
||||
|
||||
void RadioViewContainer::SetFilterVisible(bool visible) {
|
||||
|
@ -38,10 +38,13 @@ class RadioViewContainer : public QWidget {
|
||||
RadioView* tree() const { return ui_.tree; }
|
||||
|
||||
private slots:
|
||||
void Collapsed(const QModelIndex& index);
|
||||
void Expanded(const QModelIndex& index);
|
||||
void CurrentIndexChanged(const QModelIndex& index);
|
||||
void SetFilterHeight(int height);
|
||||
|
||||
private:
|
||||
void ServiceChanged(const QModelIndex& index, bool changed_away = false);
|
||||
void SetFilterVisible(bool visible);
|
||||
|
||||
private:
|
||||
|
Loading…
Reference in New Issue
Block a user