Sort podcasts in the model rather than in the database backend, and add new podcasts to the model immediately

This commit is contained in:
David Sansome 2012-03-07 11:04:47 +00:00
parent bbb661b82c
commit 7f0928e8c6
3 changed files with 68 additions and 32 deletions

View File

@ -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) {

View File

@ -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 <QMenu>
#include <QSortFilterProxyModel>
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) {
}

View File

@ -24,9 +24,12 @@
#include <QScopedPointer>
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<AddPodcastDialog> add_podcast_dialog_;
};