Allow to hide listened podcast episodes and show only n number of episodes.

Fixes #3696
Fixes #3475
This commit is contained in:
Krzysztof Sobiecki 2014-12-11 01:25:56 +01:00
parent a7e8c927f4
commit 958cb42e98
7 changed files with 94 additions and 9 deletions

View File

@ -143,7 +143,11 @@ void InternetModel::AddService(InternetService* service) {
SIGNAL(ScrollToIndex(QModelIndex)));
connect(service, SIGNAL(destroyed()), SLOT(ServiceDeleted()));
service->ReloadSettings();
if (service->hasLoadSettings()) {
service->LoadSettings();
} else {
service->ReloadSettings();
}
}
void InternetModel::RemoveService(InternetService* service) {

View File

@ -48,7 +48,8 @@ class InternetService : public QObject {
virtual QStandardItem* CreateRootItem() = 0;
virtual void LazyPopulate(QStandardItem* parent) = 0;
virtual bool hasLoadSettings() const { return false; }
virtual void LoadSettings() {}
virtual void ShowContextMenu(const QPoint& global_pos) {}
virtual void ItemDoubleClicked(QStandardItem* item) {}
// Create a generator for smart playlists

View File

@ -225,7 +225,8 @@ PodcastEpisodeList PodcastBackend::GetEpisodes(int podcast_id) {
QSqlQuery q("SELECT ROWID, " + PodcastEpisode::kColumnSpec +
" FROM podcast_episodes"
" WHERE podcast_id = :id",
" WHERE podcast_id = :id"
" ORDER BY publication_date DESC" ,
db);
q.bindValue(":db", podcast_id);
q.exec();

View File

@ -58,6 +58,8 @@ class PodcastSortProxyModel : public QSortFilterProxyModel {
PodcastService::PodcastService(Application* app, InternetModel* parent)
: InternetService(kServiceName, app, parent, parent),
use_pretty_covers_(true),
hide_listened_(false),
show_episodes_(0),
icon_loader_(new StandardItemIconLoader(app->album_cover_loader(), this)),
backend_(app->podcast_backend()),
model_(new PodcastServiceModel(this)),
@ -232,6 +234,10 @@ void PodcastService::PopulatePodcastList(QStandardItem* parent) {
}
}
void PodcastService::ClearPodcastList(QStandardItem* parent) {
parent->removeRows(0, parent->rowCount());
}
void PodcastService::UpdatePodcastText(QStandardItem* item,
int unlistened_count) const {
const Podcast podcast = item->data(Role_Podcast).value<Podcast>();
@ -349,13 +355,23 @@ QStandardItem* PodcastService::CreatePodcastItem(const Podcast& podcast) {
// Add the episodes in this podcast and gather aggregate stats.
int unlistened_count = 0;
qint64 number = 0;
for (const PodcastEpisode& episode :
backend_->GetEpisodes(podcast.database_id())) {
if (!episode.listened()) {
unlistened_count++;
}
item->appendRow(CreatePodcastEpisodeItem(episode));
if (episode.listened() && hide_listened_) {
continue;
} else {
item->appendRow(CreatePodcastEpisodeItem(episode));
++number;
}
if ((number >= show_episodes_) && (show_episodes_ != 0)) {
break;
}
}
item->setIcon(default_icon_);
@ -535,10 +551,20 @@ void PodcastService::RemoveSelectedPodcast() {
}
void PodcastService::ReloadSettings() {
LoadSettings();
ClearPodcastList(model_->invisibleRootItem());
PopulatePodcastList(model_->invisibleRootItem());
}
void PodcastService::LoadSettings() {
QSettings s;
s.beginGroup(LibraryView::kSettingsGroup);
use_pretty_covers_ = s.value("pretty_covers", true).toBool();
s.endGroup();
s.beginGroup(kSettingsGroup);
hide_listened_ = s.value("hide_listened", false).toBool();
show_episodes_ = s.value("show_episodes", 0).toInt();
s.endGroup();
// TODO(notme): reload the podcast icons that are already loaded?
}
@ -598,7 +624,6 @@ void PodcastService::EpisodesAdded(const PodcastEpisodeList& episodes) {
if (!parent) continue;
parent->appendRow(CreatePodcastEpisodeItem(episode));
if (!seen_podcast_ids.contains(database_id)) {
// Update the unlistened count text once for each podcast
int unlistened_count = 0;
@ -611,6 +636,8 @@ void PodcastService::EpisodesAdded(const PodcastEpisodeList& episodes) {
UpdatePodcastText(parent, unlistened_count);
seen_podcast_ids.insert(database_id);
}
const Podcast podcast = parent->data(Role_Podcast).value<Podcast>();
ReloadPodcast(podcast);
}
}
@ -622,7 +649,6 @@ void PodcastService::EpisodesUpdated(const PodcastEpisodeList& episodes) {
QStandardItem* item = episodes_by_database_id_[episode.database_id()];
QStandardItem* parent = podcasts_by_database_id_[podcast_database_id];
if (!item || !parent) continue;
// Update the episode data on the item, and update the item's text.
item->setData(QVariant::fromValue(episode), Role_Episode);
UpdateEpisodeText(item);
@ -641,6 +667,8 @@ void PodcastService::EpisodesUpdated(const PodcastEpisodeList& episodes) {
UpdatePodcastText(parent, unlistened_count);
seen_podcast_ids.insert(podcast_database_id);
}
const Podcast podcast = parent->data(Role_Podcast).value<Podcast>();
ReloadPodcast(podcast);
}
}
@ -780,3 +808,13 @@ void PodcastService::SubscribeAndShow(const QVariant& podcast_or_opml) {
add_podcast_dialog_->ShowWithOpml(podcast_or_opml.value<OpmlContainer>());
}
}
void PodcastService::ReloadPodcast(const Podcast& podcast) {
if (!(hide_listened_ || (show_episodes_ > 0))) {
return;
}
QStandardItem* item = podcasts_by_database_id_[podcast.database_id()];
model_->invisibleRootItem()->removeRow(item->row());
model_->invisibleRootItem()->appendRow(CreatePodcastItem(podcast));
}

View File

@ -58,10 +58,10 @@ class PodcastService : public InternetService {
QStandardItem* CreateRootItem();
void LazyPopulate(QStandardItem* parent);
bool hasLoadSettings() const { return true; }
void ShowContextMenu(const QPoint& global_pos);
void ReloadSettings();
void LoadSettings();
// Called by SongLoader when the user adds a Podcast URL directly. Adds a
// subscription to the podcast and displays it in the UI. If the QVariant
// contains an OPML file then this displays it in the Add Podcast dialog.
@ -73,6 +73,7 @@ class PodcastService : public InternetService {
private slots:
void UpdateSelectedPodcast();
void ReloadPodcast(const Podcast& podcast);
void RemoveSelectedPodcast();
void DownloadSelectedEpisode();
void DeleteDownloadedData();
@ -103,6 +104,7 @@ class PodcastService : public InternetService {
void UpdatePodcastListenedStateAsync(const Song& metadata);
void PopulatePodcastList(QStandardItem* parent);
void ClearPodcastList(QStandardItem* parent);
void UpdatePodcastText(QStandardItem* item, int unlistened_count) const;
void UpdateEpisodeText(
QStandardItem* item,
@ -126,6 +128,8 @@ class PodcastService : public InternetService {
private:
bool use_pretty_covers_;
bool hide_listened_;
qint64 show_episodes_;
StandardItemIconLoader* icon_loader_;
// The podcast icon

View File

@ -75,7 +75,9 @@ void PodcastSettingsPage::Load() {
s.value("download_dir", default_download_dir).toString()));
ui_->auto_download->setChecked(s.value("auto_download", false).toBool());
ui_->hide_listened->setChecked(s.value("hide_listened", false).toBool());
ui_->delete_after->setValue(s.value("delete_after", 0).toInt() / kSecsPerDay);
ui_->show_episodes->setValue(s.value("show_episodes", 0).toInt());
ui_->username->setText(s.value("gpodder_username").toString());
ui_->device_name->setText(
s.value("gpodder_device_name", GPodderSync::DefaultDeviceName())
@ -98,7 +100,9 @@ void PodcastSettingsPage::Save() {
s.setValue("download_dir",
QDir::fromNativeSeparators(ui_->download_dir->text()));
s.setValue("auto_download", ui_->auto_download->isChecked());
s.setValue("hide_listened", ui_->hide_listened->isChecked());
s.setValue("delete_after", ui_->delete_after->value() * kSecsPerDay);
s.setValue("show_episodes", ui_->show_episodes->value());
s.setValue("gpodder_device_name", ui_->device_name->text());
}

View File

@ -144,6 +144,39 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>Appearance</string>
</property>
<layout class="QFormLayout" name="formLayout_4">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="QCheckBox" name="hide_listened">
<property name="text">
<string>Don't show listened episodes</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="show_episodes">
<property name="specialValueText">
<string>All</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Number of episodes to show</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="title">