diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9557b3a99..fe926ed99 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -231,6 +231,7 @@ set(SOURCES podcasts/addpodcastbyurl.cpp podcasts/addpodcastdialog.cpp podcasts/addpodcastpage.cpp + podcasts/gpoddersearchpage.cpp podcasts/gpoddertoptagsmodel.cpp podcasts/gpoddertoptagspage.cpp podcasts/podcast.cpp @@ -481,6 +482,7 @@ set(HEADERS podcasts/addpodcastbyurl.h podcasts/addpodcastdialog.h podcasts/addpodcastpage.h + podcasts/gpoddersearchpage.h podcasts/gpoddertoptagsmodel.h podcasts/gpoddertoptagspage.h podcasts/podcastbackend.h @@ -609,6 +611,7 @@ set(UI podcasts/addpodcastbyurl.ui podcasts/addpodcastdialog.ui + podcasts/gpoddersearchpage.ui podcasts/podcastinfowidget.ui remote/remotesettingspage.ui diff --git a/src/podcasts/addpodcastbyurl.cpp b/src/podcasts/addpodcastbyurl.cpp index c895caf7a..8a7b9f511 100644 --- a/src/podcasts/addpodcastbyurl.cpp +++ b/src/podcasts/addpodcastbyurl.cpp @@ -40,8 +40,6 @@ AddPodcastByUrl::~AddPodcastByUrl() { void AddPodcastByUrl::GoClicked() { emit Busy(true); model()->clear(); - ui_->go->setEnabled(false); - ui_->url->setEnabled(false); PodcastUrlLoaderReply* reply = loader_->Load(ui_->url->text()); ui_->url->setText(reply->url().toString()); @@ -55,8 +53,6 @@ void AddPodcastByUrl::RequestFinished(PodcastUrlLoaderReply* reply) { reply->deleteLater(); emit Busy(false); - ui_->go->setEnabled(true); - ui_->url->setEnabled(true); if (!reply->is_success()) { QMessageBox::warning(this, tr("Failed to load podcast"), diff --git a/src/podcasts/addpodcastdialog.cpp b/src/podcasts/addpodcastdialog.cpp index 61fa61c6d..0889adbe3 100644 --- a/src/podcasts/addpodcastdialog.cpp +++ b/src/podcasts/addpodcastdialog.cpp @@ -17,6 +17,7 @@ #include "addpodcastdialog.h" #include "addpodcastbyurl.h" +#include "gpoddersearchpage.h" #include "gpoddertoptagspage.h" #include "podcastbackend.h" #include "podcastdiscoverymodel.h" @@ -46,11 +47,12 @@ AddPodcastDialog::AddPodcastDialog(Application* app, QWidget* parent) 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::AcceptRole); + ui_->button_box->addButton(add_button_, QDialogButtonBox::ActionRole); // Add providers AddPage(new AddPodcastByUrl(app, this)); AddPage(new GPodderTopTagsPage(app, this)); + AddPage(new GPodderSearchPage(app, this)); ui_->provider_list->setCurrentRow(0); } @@ -83,7 +85,7 @@ void AddPodcastDialog::ChangePage(int index) { connect(ui_->results->selectionModel(), SIGNAL(currentRowChanged(QModelIndex,QModelIndex)), SLOT(ChangePodcast(QModelIndex))); ChangePodcast(QModelIndex()); - PageBusyChanged(page_is_busy_[index]); + CurrentPageBusyChanged(page_is_busy_[index]); page->Show(); } @@ -116,10 +118,15 @@ void AddPodcastDialog::PageBusyChanged(bool busy) { page_is_busy_[index] = busy; if (index == ui_->provider_list->currentRow()) { - ui_->results_stack->setCurrentWidget(busy ? ui_->busy_page : ui_->results_page); + CurrentPageBusyChanged(busy); } } +void AddPodcastDialog::CurrentPageBusyChanged(bool busy) { + ui_->results_stack->setCurrentWidget(busy ? ui_->busy_page : ui_->results_page); + ui_->stack->setDisabled(busy); +} + void AddPodcastDialog::AddPodcast() { app_->podcast_backend()->Subscribe(¤t_podcast_); } diff --git a/src/podcasts/addpodcastdialog.h b/src/podcasts/addpodcastdialog.h index c216a21d3..9a3609485 100644 --- a/src/podcasts/addpodcastdialog.h +++ b/src/podcasts/addpodcastdialog.h @@ -42,6 +42,7 @@ private slots: void ChangePodcast(const QModelIndex& current); void PageBusyChanged(bool busy); + void CurrentPageBusyChanged(bool busy); private: void AddPage(AddPodcastPage* page); diff --git a/src/podcasts/addpodcastdialog.ui b/src/podcasts/addpodcastdialog.ui index 16552f2c5..3daadbf08 100644 --- a/src/podcasts/addpodcastdialog.ui +++ b/src/podcasts/addpodcastdialog.ui @@ -11,7 +11,7 @@ - Dialog + Add podcast diff --git a/src/podcasts/gpoddersearchpage.cpp b/src/podcasts/gpoddersearchpage.cpp new file mode 100644 index 000000000..da66b0111 --- /dev/null +++ b/src/podcasts/gpoddersearchpage.cpp @@ -0,0 +1,89 @@ +/* This file is part of Clementine. + Copyright 2012, David Sansome + + Clementine is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Clementine is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Clementine. If not, see . +*/ + +#include "gpoddersearchpage.h" +#include "podcast.h" +#include "podcastdiscoverymodel.h" +#include "ui_gpoddersearchpage.h" +#include "core/closure.h" +#include "core/network.h" + +#include + +#include + +GPodderSearchPage::GPodderSearchPage(Application* app, QWidget* parent) + : AddPodcastPage(app, parent), + ui_(new Ui_GPodderSearchPage), + network_(new NetworkAccessManager(this)), + api_(new mygpo::ApiRequest(network_)) +{ + ui_->setupUi(this); + connect(ui_->search, SIGNAL(clicked()), SLOT(SearchClicked())); +} + +GPodderSearchPage::~GPodderSearchPage() { + delete ui_; + delete api_; +} + +void GPodderSearchPage::SearchClicked() { + emit Busy(true); + + mygpo::PodcastList* list = api_->search(ui_->query->text()); + NewClosure(list, SIGNAL(finished()), + this, SLOT(SearchFinished(mygpo::PodcastList*)), + list); + NewClosure(list, SIGNAL(parseError()), + this, SLOT(SearchFailed(mygpo::PodcastList*)), + list); + NewClosure(list, SIGNAL(requestError(QNetworkReply::NetworkError)), + this, SLOT(SearchFailed(mygpo::PodcastList*)), + list); +} + +void GPodderSearchPage::SearchFinished(mygpo::PodcastList* list) { + list->deleteLater(); + emit Busy(false); + + model()->clear(); + + foreach (mygpo::PodcastPtr gpo_podcast, list->list()) { + Podcast podcast; + podcast.InitFromGpo(gpo_podcast.data()); + + model()->appendRow(model()->CreatePodcastItem(podcast)); + } +} + +void GPodderSearchPage::SearchFailed(mygpo::PodcastList* list) { + list->deleteLater(); + emit Busy(false); + + model()->clear(); + + if (QMessageBox::warning( + NULL, tr("Failed to fetch podcasts"), + tr("There was a problem communicating with gpodder.net"), + QMessageBox::Retry | QMessageBox::Close, + QMessageBox::Retry) != QMessageBox::Retry) { + return; + } + + // Try doing the search again. + SearchClicked(); +} diff --git a/src/podcasts/gpoddersearchpage.h b/src/podcasts/gpoddersearchpage.h new file mode 100644 index 000000000..ce6f720c3 --- /dev/null +++ b/src/podcasts/gpoddersearchpage.h @@ -0,0 +1,52 @@ +/* This file is part of Clementine. + Copyright 2012, David Sansome + + Clementine is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Clementine is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Clementine. If not, see . +*/ + +#ifndef GPODDERSEARCHPAGE_H +#define GPODDERSEARCHPAGE_H + +#include "addpodcastpage.h" + +class QNetworkAccessManager; + +class Ui_GPodderSearchPage; + +namespace mygpo { + class ApiRequest; + class PodcastList; +} + +class GPodderSearchPage : public AddPodcastPage { + Q_OBJECT + +public: + GPodderSearchPage(Application* app, QWidget* parent = 0); + ~GPodderSearchPage(); + +private slots: + void SearchClicked(); + void SearchFinished(mygpo::PodcastList* list); + void SearchFailed(mygpo::PodcastList* list); + +private: + Ui_GPodderSearchPage* ui_; + + QNetworkAccessManager* network_; + mygpo::ApiRequest* api_; + +}; + +#endif // GPODDERSEARCHPAGE_H diff --git a/src/podcasts/gpoddersearchpage.ui b/src/podcasts/gpoddersearchpage.ui new file mode 100644 index 000000000..b89daa827 --- /dev/null +++ b/src/podcasts/gpoddersearchpage.ui @@ -0,0 +1,68 @@ + + + GPodderSearchPage + + + + 0 + 0 + 538 + 69 + + + + Search gpodder.net + + + + :/providers/mygpo32.png:/providers/mygpo32.png + + + + 0 + + + + + Enter search terms below to find podcasts on gpodder.net + + + + + + + + + + + + Search + + + + + + + + + + + + + query + returnPressed() + search + click() + + + 130 + 45 + + + 198 + 46 + + + + + diff --git a/src/podcasts/gpoddertoptagspage.cpp b/src/podcasts/gpoddertoptagspage.cpp index 1be0afca6..924b91b0c 100644 --- a/src/podcasts/gpoddertoptagspage.cpp +++ b/src/podcasts/gpoddertoptagspage.cpp @@ -31,7 +31,7 @@ GPodderTopTagsPage::GPodderTopTagsPage(Application* app, QWidget* parent) api_(new mygpo::ApiRequest(network_)), done_initial_load_(false) { - setWindowTitle(tr("Browse gpodder.net")); + setWindowTitle(tr("gpodder.net directory")); setWindowIcon(QIcon(":providers/mygpo32.png")); SetModel(new GPodderTopTagsModel(api_, app, this));