From 7f0928e8c6b269846d55e258f5e6b1bc7d3b851d Mon Sep 17 00:00:00 2001 From: David Sansome Date: Wed, 7 Mar 2012 11:04:47 +0000 Subject: [PATCH] Sort podcasts in the model rather than in the database backend, and add new podcasts to the model immediately --- src/podcasts/podcastbackend.cpp | 5 +- src/podcasts/podcastservice.cpp | 83 ++++++++++++++++++++++----------- src/podcasts/podcastservice.h | 12 ++++- 3 files changed, 68 insertions(+), 32 deletions(-) diff --git a/src/podcasts/podcastbackend.cpp b/src/podcasts/podcastbackend.cpp index c9cb654b3..b078494ff 100644 --- a/src/podcasts/podcastbackend.cpp +++ b/src/podcasts/podcastbackend.cpp @@ -69,6 +69,8 @@ void PodcastBackend::Subscribe(Podcast* podcast) { AddEpisodes(episodes, &db); t.Commit(); + + emit SubscriptionAdded(*podcast); } void PodcastBackend::AddEpisodes(PodcastEpisodeList* episodes, QSqlDatabase* db) { @@ -93,8 +95,7 @@ void PodcastBackend::AddEpisodes(PodcastEpisodeList* episodes, QSqlDatabase* db) " LEFT JOIN podcast_episodes AS e" \ " ON p.ROWID = e.podcast_id" \ " " where_clauses \ - " GROUP BY p.ROWID" \ - " ORDER BY p.title" + " GROUP BY p.ROWID" namespace { void AddAggregatePodcastFields(const QSqlQuery& q, int column_count, Podcast* podcast) { diff --git a/src/podcasts/podcastservice.cpp b/src/podcasts/podcastservice.cpp index d627e1878..e02544dd3 100644 --- a/src/podcasts/podcastservice.cpp +++ b/src/podcasts/podcastservice.cpp @@ -20,12 +20,14 @@ #include "podcastservice.h" #include "core/application.h" #include "core/logging.h" +#include "core/mergedproxymodel.h" #include "internet/internetmodel.h" #include "library/libraryview.h" #include "ui/iconloader.h" #include "ui/standarditemiconloader.h" #include +#include const char* PodcastService::kServiceName = "Podcasts"; const char* PodcastService::kSettingsGroup = "Podcasts"; @@ -34,11 +36,19 @@ PodcastService::PodcastService(Application* app, InternetModel* parent) : InternetService(kServiceName, app, parent, parent), use_pretty_covers_(true), icon_loader_(new StandardItemIconLoader(app->album_cover_loader(), this)), + backend_(app->podcast_backend()), + model_(new QStandardItemModel(this)), + proxy_(new QSortFilterProxyModel(this)), context_menu_(NULL), - root_(NULL), - backend_(app->podcast_backend()) + root_(NULL) { - icon_loader_->SetModel(model()); + icon_loader_->SetModel(model_); + proxy_->setSourceModel(model_); + proxy_->setDynamicSortFilter(true); + proxy_->sort(0); + + connect(backend_, SIGNAL(SubscriptionAdded(Podcast)), SLOT(SubscriptionAdded(Podcast))); + connect(backend_, SIGNAL(SubscriptionRemoved(Podcast)), SLOT(SubscriptionRemoved(Podcast))); } PodcastService::~PodcastService() { @@ -53,7 +63,8 @@ QStandardItem* PodcastService::CreateRootItem() { void PodcastService::LazyPopulate(QStandardItem* parent) { switch (parent->data(InternetModel::Role_Type).toInt()) { case InternetModel::Type_Service: - PopulatePodcastList(parent); + PopulatePodcastList(model_->invisibleRootItem()); + model()->merged_model()->AddSubModel(parent->index(), proxy_); break; } } @@ -64,33 +75,37 @@ void PodcastService::PopulatePodcastList(QStandardItem* parent) { } foreach (const Podcast& podcast, backend_->GetAllSubscriptions()) { - const int unlistened_count = podcast.extra("db:unlistened_count").toInt(); - QString title = podcast.title(); - - QStandardItem* item = new QStandardItem; - - if (unlistened_count > 0) { - // Add the number of new episodes after the title. - title.append(QString(" (%1)").arg(unlistened_count)); - - // Set a bold font - QFont font(item->font()); - font.setBold(true); - item->setFont(font); - } - - item->setText(podcast.title()); - item->setIcon(default_icon_); - - // Load the podcast's image if it has one - if (podcast.image_url().isValid()) { - icon_loader_->LoadIcon(podcast.image_url().toString(), QString(), item); - } - - parent->appendRow(item); + parent->appendRow(CreatePodcastItem(podcast)); } } +QStandardItem* PodcastService::CreatePodcastItem(const Podcast& podcast) { + const int unlistened_count = podcast.extra("db:unlistened_count").toInt(); + QString title = podcast.title(); + + QStandardItem* item = new QStandardItem; + + if (unlistened_count > 0) { + // Add the number of new episodes after the title. + title.append(QString(" (%1)").arg(unlistened_count)); + + // Set a bold font + QFont font(item->font()); + font.setBold(true); + item->setFont(font); + } + + item->setText(podcast.title()); + item->setIcon(default_icon_); + + // Load the podcast's image if it has one + if (podcast.image_url().isValid()) { + icon_loader_->LoadIcon(podcast.image_url().toString(), QString(), item); + } + + return item; +} + void PodcastService::ShowContextMenu(const QModelIndex& index, const QPoint& global_pos) { if (!context_menu_) { @@ -121,3 +136,15 @@ void PodcastService::AddPodcast() { add_podcast_dialog_->show(); } + +void PodcastService::SubscriptionAdded(const Podcast& podcast) { + // If the user hasn't expanded the root node yet we don't need to do anything + if (root_->data(InternetModel::Role_CanLazyLoad).toBool()) { + return; + } + + model_->appendRow(CreatePodcastItem(podcast)); +} + +void PodcastService::SubscriptionRemoved(const Podcast& podcast) { +} diff --git a/src/podcasts/podcastservice.h b/src/podcasts/podcastservice.h index c610659a1..d5631e556 100644 --- a/src/podcasts/podcastservice.h +++ b/src/podcasts/podcastservice.h @@ -24,9 +24,12 @@ #include class AddPodcastDialog; +class Podcast; class PodcastBackend; class StandardItemIconLoader; +class QSortFilterProxyModel; + class PodcastService : public InternetService { Q_OBJECT @@ -54,20 +57,25 @@ protected: private slots: void AddPodcast(); + void SubscriptionAdded(const Podcast& podcast); + void SubscriptionRemoved(const Podcast& podcast); private: void PopulatePodcastList(QStandardItem* parent); + QStandardItem* CreatePodcastItem(const Podcast& podcast); private: bool use_pretty_covers_; QIcon default_icon_; StandardItemIconLoader* icon_loader_; + PodcastBackend* backend_; + QStandardItemModel* model_; + QSortFilterProxyModel* proxy_; + QMenu* context_menu_; QStandardItem* root_; - PodcastBackend* backend_; - QScopedPointer add_podcast_dialog_; };