diff --git a/src/podcasts/addpodcastdialog.cpp b/src/podcasts/addpodcastdialog.cpp index 0889adbe3..62d1f1ace 100644 --- a/src/podcasts/addpodcastdialog.cpp +++ b/src/podcasts/addpodcastdialog.cpp @@ -43,12 +43,17 @@ AddPodcastDialog::AddPodcastDialog(Application* app, QWidget* parent) connect(ui_->provider_list, SIGNAL(currentRowChanged(int)), SLOT(ChangePage(int))); connect(ui_->details, SIGNAL(LoadingFinished()), fader_, SLOT(StartFade())); - // Create an Add Podcast button + // Create Add and Remove Podcast buttons add_button_ = new QPushButton(IconLoader::Load("list-add"), tr("Add Podcast"), this); add_button_->setEnabled(false); connect(add_button_, SIGNAL(clicked()), SLOT(AddPodcast())); ui_->button_box->addButton(add_button_, QDialogButtonBox::ActionRole); + remove_button_ = new QPushButton(IconLoader::Load("list-remove"), tr("Unsubscribe"), this); + remove_button_->setEnabled(false); + connect(remove_button_, SIGNAL(clicked()), SLOT(RemovePodcast())); + ui_->button_box->addButton(remove_button_, QDialogButtonBox::ActionRole); + // Add providers AddPage(new AddPodcastByUrl(app, this)); AddPage(new GPodderTopTagsPage(app, this)); @@ -91,23 +96,48 @@ void AddPodcastDialog::ChangePage(int index) { } void AddPodcastDialog::ChangePodcast(const QModelIndex& current) { + // If the selected item is invalid or not a podcast, hide the details pane. if (!current.isValid() || current.data(PodcastDiscoveryModel::Role_Type).toInt() != PodcastDiscoveryModel::Type_Podcast) { ui_->details_scroll_area->hide(); + add_button_->setEnabled(false); + remove_button_->setEnabled(false); return; } + current_podcast_ = current.data(PodcastDiscoveryModel::Role_Podcast).value(); + + // Also hide the details pane if this podcast isn't valid. + if (!current_podcast_.url().isValid()) { + ui_->details_scroll_area->hide(); + add_button_->setEnabled(false); + remove_button_->setEnabled(false); + return; + } + + // Start the blur+fade if there's already a podcast in the details pane. if (ui_->details_scroll_area->isVisible()) { fader_->StartBlur(); } else { ui_->details_scroll_area->show(); } - current_podcast_ = current.data(PodcastDiscoveryModel::Role_Podcast).value(); + // Update the details pane ui_->details->SetPodcast(current_podcast_); - add_button_->setEnabled(current_podcast_.url().isValid()); + // Is the user already subscribed to this podcast? + Podcast subscribed_podcast = + app_->podcast_backend()->GetSubscriptionByUrl(current_podcast_.url()); + const bool is_subscribed = subscribed_podcast.url().isValid(); + + if (is_subscribed) { + // Use the one from the database which will contain the ID. + current_podcast_ = subscribed_podcast; + } + + add_button_->setEnabled(!is_subscribed); + remove_button_->setEnabled(is_subscribed); } void AddPodcastDialog::PageBusyChanged(bool busy) { @@ -129,4 +159,12 @@ void AddPodcastDialog::CurrentPageBusyChanged(bool busy) { void AddPodcastDialog::AddPodcast() { app_->podcast_backend()->Subscribe(¤t_podcast_); + add_button_->setEnabled(false); + remove_button_->setEnabled(true); +} + +void AddPodcastDialog::RemovePodcast() { + app_->podcast_backend()->Unsubscribe(current_podcast_); + add_button_->setEnabled(true); + remove_button_->setEnabled(false); } diff --git a/src/podcasts/addpodcastdialog.h b/src/podcasts/addpodcastdialog.h index 9a3609485..75022d8c4 100644 --- a/src/podcasts/addpodcastdialog.h +++ b/src/podcasts/addpodcastdialog.h @@ -38,6 +38,7 @@ public: private slots: void AddPodcast(); + void RemovePodcast(); void ChangePage(int index); void ChangePodcast(const QModelIndex& current); @@ -52,6 +53,7 @@ private: Ui_AddPodcastDialog* ui_; QPushButton* add_button_; + QPushButton* remove_button_; QList pages_; QList page_is_busy_; diff --git a/src/podcasts/podcastbackend.cpp b/src/podcasts/podcastbackend.cpp index b078494ff..be7953d5d 100644 --- a/src/podcasts/podcastbackend.cpp +++ b/src/podcasts/podcastbackend.cpp @@ -73,6 +73,35 @@ void PodcastBackend::Subscribe(Podcast* podcast) { emit SubscriptionAdded(*podcast); } +void PodcastBackend::Unsubscribe(const Podcast& podcast) { + // If this podcast is not already in the database, do nothing + if (!podcast.is_valid()) { + return; + } + + QMutexLocker l(db_->Mutex()); + QSqlDatabase db(db_->Connect()); + ScopedTransaction t(&db); + + // Remove the podcast. + QSqlQuery q("DELETE FROM podcasts WHERE ROWID = :id", db); + q.bindValue(":id", podcast.database_id()); + q.exec(); + if (db_->CheckErrors(q)) + return; + + // Remove all episodes in the podcast + q = QSqlQuery("DELETE FROM podcast_episodes WHERE podcast_id = :id", db); + q.bindValue(":id", podcast.database_id()); + q.exec(); + if (db_->CheckErrors(q)) + return; + + t.Commit(); + + emit SubscriptionRemoved(podcast); +} + void PodcastBackend::AddEpisodes(PodcastEpisodeList* episodes, QSqlDatabase* db) { QSqlQuery q("INSERT INTO podcast_episodes (" + PodcastEpisode::kColumnSpec + ")" " VALUES (" + PodcastEpisode::kBindSpec + ")", *db); diff --git a/src/podcasts/podcastservice.cpp b/src/podcasts/podcastservice.cpp index e02544dd3..7e1f328d8 100644 --- a/src/podcasts/podcastservice.cpp +++ b/src/podcasts/podcastservice.cpp @@ -97,6 +97,7 @@ QStandardItem* PodcastService::CreatePodcastItem(const Podcast& podcast) { item->setText(podcast.title()); item->setIcon(default_icon_); + item->setData(QVariant::fromValue(podcast), Role_Podcast); // Load the podcast's image if it has one if (podcast.image_url().isValid()) { @@ -147,4 +148,12 @@ void PodcastService::SubscriptionAdded(const Podcast& podcast) { } void PodcastService::SubscriptionRemoved(const Podcast& podcast) { + // Find the item in the model that matches this podcast. + for (int i=0 ; irowCount() ; ++i) { + Podcast item_podcast(model_->item(i)->data(Role_Podcast).value()); + if (podcast.database_id() == item_podcast.database_id()) { + model_->removeRow(i); + return; + } + } } diff --git a/src/podcasts/podcastservice.h b/src/podcasts/podcastservice.h index d5631e556..2fc2f40d7 100644 --- a/src/podcasts/podcastservice.h +++ b/src/podcasts/podcastservice.h @@ -46,6 +46,10 @@ public: Type_Episode }; + enum Role { + Role_Podcast = InternetModel::RoleCount + }; + QStandardItem* CreateRootItem(); void LazyPopulate(QStandardItem* parent);