Allow to hide listened podcast episodes and show only n number of episodes.
Fixes #3696 Fixes #3475
This commit is contained in:
parent
a7e8c927f4
commit
958cb42e98
@ -143,7 +143,11 @@ void InternetModel::AddService(InternetService* service) {
|
|||||||
SIGNAL(ScrollToIndex(QModelIndex)));
|
SIGNAL(ScrollToIndex(QModelIndex)));
|
||||||
connect(service, SIGNAL(destroyed()), SLOT(ServiceDeleted()));
|
connect(service, SIGNAL(destroyed()), SLOT(ServiceDeleted()));
|
||||||
|
|
||||||
service->ReloadSettings();
|
if (service->hasLoadSettings()) {
|
||||||
|
service->LoadSettings();
|
||||||
|
} else {
|
||||||
|
service->ReloadSettings();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InternetModel::RemoveService(InternetService* service) {
|
void InternetModel::RemoveService(InternetService* service) {
|
||||||
|
@ -48,7 +48,8 @@ class InternetService : public QObject {
|
|||||||
|
|
||||||
virtual QStandardItem* CreateRootItem() = 0;
|
virtual QStandardItem* CreateRootItem() = 0;
|
||||||
virtual void LazyPopulate(QStandardItem* parent) = 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 ShowContextMenu(const QPoint& global_pos) {}
|
||||||
virtual void ItemDoubleClicked(QStandardItem* item) {}
|
virtual void ItemDoubleClicked(QStandardItem* item) {}
|
||||||
// Create a generator for smart playlists
|
// Create a generator for smart playlists
|
||||||
|
@ -225,7 +225,8 @@ PodcastEpisodeList PodcastBackend::GetEpisodes(int podcast_id) {
|
|||||||
|
|
||||||
QSqlQuery q("SELECT ROWID, " + PodcastEpisode::kColumnSpec +
|
QSqlQuery q("SELECT ROWID, " + PodcastEpisode::kColumnSpec +
|
||||||
" FROM podcast_episodes"
|
" FROM podcast_episodes"
|
||||||
" WHERE podcast_id = :id",
|
" WHERE podcast_id = :id"
|
||||||
|
" ORDER BY publication_date DESC" ,
|
||||||
db);
|
db);
|
||||||
q.bindValue(":db", podcast_id);
|
q.bindValue(":db", podcast_id);
|
||||||
q.exec();
|
q.exec();
|
||||||
|
@ -58,6 +58,8 @@ class PodcastSortProxyModel : public QSortFilterProxyModel {
|
|||||||
PodcastService::PodcastService(Application* app, InternetModel* parent)
|
PodcastService::PodcastService(Application* app, InternetModel* parent)
|
||||||
: InternetService(kServiceName, app, parent, parent),
|
: InternetService(kServiceName, app, parent, parent),
|
||||||
use_pretty_covers_(true),
|
use_pretty_covers_(true),
|
||||||
|
hide_listened_(false),
|
||||||
|
show_episodes_(0),
|
||||||
icon_loader_(new StandardItemIconLoader(app->album_cover_loader(), this)),
|
icon_loader_(new StandardItemIconLoader(app->album_cover_loader(), this)),
|
||||||
backend_(app->podcast_backend()),
|
backend_(app->podcast_backend()),
|
||||||
model_(new PodcastServiceModel(this)),
|
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,
|
void PodcastService::UpdatePodcastText(QStandardItem* item,
|
||||||
int unlistened_count) const {
|
int unlistened_count) const {
|
||||||
const Podcast podcast = item->data(Role_Podcast).value<Podcast>();
|
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.
|
// Add the episodes in this podcast and gather aggregate stats.
|
||||||
int unlistened_count = 0;
|
int unlistened_count = 0;
|
||||||
|
qint64 number = 0;
|
||||||
for (const PodcastEpisode& episode :
|
for (const PodcastEpisode& episode :
|
||||||
backend_->GetEpisodes(podcast.database_id())) {
|
backend_->GetEpisodes(podcast.database_id())) {
|
||||||
if (!episode.listened()) {
|
if (!episode.listened()) {
|
||||||
unlistened_count++;
|
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_);
|
item->setIcon(default_icon_);
|
||||||
@ -535,10 +551,20 @@ void PodcastService::RemoveSelectedPodcast() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PodcastService::ReloadSettings() {
|
void PodcastService::ReloadSettings() {
|
||||||
|
LoadSettings();
|
||||||
|
ClearPodcastList(model_->invisibleRootItem());
|
||||||
|
PopulatePodcastList(model_->invisibleRootItem());
|
||||||
|
}
|
||||||
|
|
||||||
|
void PodcastService::LoadSettings() {
|
||||||
QSettings s;
|
QSettings s;
|
||||||
s.beginGroup(LibraryView::kSettingsGroup);
|
s.beginGroup(LibraryView::kSettingsGroup);
|
||||||
|
|
||||||
use_pretty_covers_ = s.value("pretty_covers", true).toBool();
|
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?
|
// TODO(notme): reload the podcast icons that are already loaded?
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -598,7 +624,6 @@ void PodcastService::EpisodesAdded(const PodcastEpisodeList& episodes) {
|
|||||||
if (!parent) continue;
|
if (!parent) continue;
|
||||||
|
|
||||||
parent->appendRow(CreatePodcastEpisodeItem(episode));
|
parent->appendRow(CreatePodcastEpisodeItem(episode));
|
||||||
|
|
||||||
if (!seen_podcast_ids.contains(database_id)) {
|
if (!seen_podcast_ids.contains(database_id)) {
|
||||||
// Update the unlistened count text once for each podcast
|
// Update the unlistened count text once for each podcast
|
||||||
int unlistened_count = 0;
|
int unlistened_count = 0;
|
||||||
@ -611,6 +636,8 @@ void PodcastService::EpisodesAdded(const PodcastEpisodeList& episodes) {
|
|||||||
UpdatePodcastText(parent, unlistened_count);
|
UpdatePodcastText(parent, unlistened_count);
|
||||||
seen_podcast_ids.insert(database_id);
|
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* item = episodes_by_database_id_[episode.database_id()];
|
||||||
QStandardItem* parent = podcasts_by_database_id_[podcast_database_id];
|
QStandardItem* parent = podcasts_by_database_id_[podcast_database_id];
|
||||||
if (!item || !parent) continue;
|
if (!item || !parent) continue;
|
||||||
|
|
||||||
// Update the episode data on the item, and update the item's text.
|
// Update the episode data on the item, and update the item's text.
|
||||||
item->setData(QVariant::fromValue(episode), Role_Episode);
|
item->setData(QVariant::fromValue(episode), Role_Episode);
|
||||||
UpdateEpisodeText(item);
|
UpdateEpisodeText(item);
|
||||||
@ -641,6 +667,8 @@ void PodcastService::EpisodesUpdated(const PodcastEpisodeList& episodes) {
|
|||||||
UpdatePodcastText(parent, unlistened_count);
|
UpdatePodcastText(parent, unlistened_count);
|
||||||
seen_podcast_ids.insert(podcast_database_id);
|
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>());
|
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));
|
||||||
|
}
|
||||||
|
@ -58,10 +58,10 @@ class PodcastService : public InternetService {
|
|||||||
|
|
||||||
QStandardItem* CreateRootItem();
|
QStandardItem* CreateRootItem();
|
||||||
void LazyPopulate(QStandardItem* parent);
|
void LazyPopulate(QStandardItem* parent);
|
||||||
|
bool hasLoadSettings() const { return true; }
|
||||||
void ShowContextMenu(const QPoint& global_pos);
|
void ShowContextMenu(const QPoint& global_pos);
|
||||||
void ReloadSettings();
|
void ReloadSettings();
|
||||||
|
void LoadSettings();
|
||||||
// Called by SongLoader when the user adds a Podcast URL directly. Adds a
|
// 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
|
// 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.
|
// contains an OPML file then this displays it in the Add Podcast dialog.
|
||||||
@ -73,6 +73,7 @@ class PodcastService : public InternetService {
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void UpdateSelectedPodcast();
|
void UpdateSelectedPodcast();
|
||||||
|
void ReloadPodcast(const Podcast& podcast);
|
||||||
void RemoveSelectedPodcast();
|
void RemoveSelectedPodcast();
|
||||||
void DownloadSelectedEpisode();
|
void DownloadSelectedEpisode();
|
||||||
void DeleteDownloadedData();
|
void DeleteDownloadedData();
|
||||||
@ -103,6 +104,7 @@ class PodcastService : public InternetService {
|
|||||||
|
|
||||||
void UpdatePodcastListenedStateAsync(const Song& metadata);
|
void UpdatePodcastListenedStateAsync(const Song& metadata);
|
||||||
void PopulatePodcastList(QStandardItem* parent);
|
void PopulatePodcastList(QStandardItem* parent);
|
||||||
|
void ClearPodcastList(QStandardItem* parent);
|
||||||
void UpdatePodcastText(QStandardItem* item, int unlistened_count) const;
|
void UpdatePodcastText(QStandardItem* item, int unlistened_count) const;
|
||||||
void UpdateEpisodeText(
|
void UpdateEpisodeText(
|
||||||
QStandardItem* item,
|
QStandardItem* item,
|
||||||
@ -126,6 +128,8 @@ class PodcastService : public InternetService {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
bool use_pretty_covers_;
|
bool use_pretty_covers_;
|
||||||
|
bool hide_listened_;
|
||||||
|
qint64 show_episodes_;
|
||||||
StandardItemIconLoader* icon_loader_;
|
StandardItemIconLoader* icon_loader_;
|
||||||
|
|
||||||
// The podcast icon
|
// The podcast icon
|
||||||
|
@ -75,7 +75,9 @@ void PodcastSettingsPage::Load() {
|
|||||||
s.value("download_dir", default_download_dir).toString()));
|
s.value("download_dir", default_download_dir).toString()));
|
||||||
|
|
||||||
ui_->auto_download->setChecked(s.value("auto_download", false).toBool());
|
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_->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_->username->setText(s.value("gpodder_username").toString());
|
||||||
ui_->device_name->setText(
|
ui_->device_name->setText(
|
||||||
s.value("gpodder_device_name", GPodderSync::DefaultDeviceName())
|
s.value("gpodder_device_name", GPodderSync::DefaultDeviceName())
|
||||||
@ -98,7 +100,9 @@ void PodcastSettingsPage::Save() {
|
|||||||
s.setValue("download_dir",
|
s.setValue("download_dir",
|
||||||
QDir::fromNativeSeparators(ui_->download_dir->text()));
|
QDir::fromNativeSeparators(ui_->download_dir->text()));
|
||||||
s.setValue("auto_download", ui_->auto_download->isChecked());
|
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("delete_after", ui_->delete_after->value() * kSecsPerDay);
|
||||||
|
s.setValue("show_episodes", ui_->show_episodes->value());
|
||||||
s.setValue("gpodder_device_name", ui_->device_name->text());
|
s.setValue("gpodder_device_name", ui_->device_name->text());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,6 +144,39 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</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>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox_3">
|
<widget class="QGroupBox" name="groupBox_3">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user