2012-03-05 19:15:45 +01:00
|
|
|
/* This file is part of Clementine.
|
|
|
|
Copyright 2012, David Sansome <me@davidsansome.com>
|
2014-02-07 16:34:20 +01:00
|
|
|
|
2012-03-05 19:15:45 +01:00
|
|
|
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.
|
2014-02-07 16:34:20 +01:00
|
|
|
|
2012-03-05 19:15:45 +01:00
|
|
|
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.
|
2014-02-07 16:34:20 +01:00
|
|
|
|
2012-03-05 19:15:45 +01:00
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "addpodcastdialog.h"
|
|
|
|
#include "addpodcastbyurl.h"
|
2012-03-07 16:31:12 +01:00
|
|
|
#include "fixedopmlpage.h"
|
2012-03-06 22:25:16 +01:00
|
|
|
#include "gpoddersearchpage.h"
|
2012-03-06 01:35:55 +01:00
|
|
|
#include "gpoddertoptagspage.h"
|
2012-03-07 13:27:31 +01:00
|
|
|
#include "itunessearchpage.h"
|
2012-03-06 19:37:46 +01:00
|
|
|
#include "podcastbackend.h"
|
2012-03-05 19:15:45 +01:00
|
|
|
#include "podcastdiscoverymodel.h"
|
|
|
|
#include "ui_addpodcastdialog.h"
|
|
|
|
#include "core/application.h"
|
|
|
|
#include "ui/iconloader.h"
|
2012-03-06 12:39:29 +01:00
|
|
|
#include "widgets/widgetfadehelper.h"
|
2012-03-05 19:15:45 +01:00
|
|
|
|
2012-06-16 23:58:33 +02:00
|
|
|
#include <QFileDialog>
|
2012-03-05 19:15:45 +01:00
|
|
|
#include <QPushButton>
|
2012-03-09 20:12:45 +01:00
|
|
|
#include <QTimer>
|
2012-03-05 19:15:45 +01:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
const char* AddPodcastDialog::kBbcOpmlUrl =
|
|
|
|
"http://www.bbc.co.uk/podcasts.opml";
|
2012-03-07 16:31:12 +01:00
|
|
|
|
2012-03-05 19:15:45 +01:00
|
|
|
AddPodcastDialog::AddPodcastDialog(Application* app, QWidget* parent)
|
2014-02-07 16:34:20 +01:00
|
|
|
: QDialog(parent),
|
|
|
|
app_(app),
|
|
|
|
ui_(new Ui_AddPodcastDialog),
|
|
|
|
last_opml_path_(QDir::homePath()) {
|
2012-03-05 19:15:45 +01:00
|
|
|
ui_->setupUi(this);
|
|
|
|
ui_->details->SetApplication(app);
|
2012-03-06 17:37:15 +01:00
|
|
|
ui_->results->SetExpandOnReset(false);
|
2012-03-11 00:38:54 +01:00
|
|
|
ui_->results->SetAddOnDoubleClick(false);
|
2012-03-05 19:15:45 +01:00
|
|
|
ui_->results_stack->setCurrentWidget(ui_->results_page);
|
|
|
|
|
2012-03-06 12:39:29 +01:00
|
|
|
fader_ = new WidgetFadeHelper(ui_->details_scroll_area);
|
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(ui_->provider_list, SIGNAL(currentRowChanged(int)),
|
|
|
|
SLOT(ChangePage(int)));
|
2012-03-06 12:39:29 +01:00
|
|
|
connect(ui_->details, SIGNAL(LoadingFinished()), fader_, SLOT(StartFade()));
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(ui_->results, SIGNAL(doubleClicked(QModelIndex)),
|
|
|
|
SLOT(PodcastDoubleClicked(QModelIndex)));
|
2012-03-05 19:15:45 +01:00
|
|
|
|
2012-03-07 12:22:43 +01:00
|
|
|
// Create Add and Remove Podcast buttons
|
2014-02-07 16:34:20 +01:00
|
|
|
add_button_ =
|
|
|
|
new QPushButton(IconLoader::Load("list-add"), tr("Add Podcast"), this);
|
2012-03-05 19:15:45 +01:00
|
|
|
add_button_->setEnabled(false);
|
|
|
|
connect(add_button_, SIGNAL(clicked()), SLOT(AddPodcast()));
|
2012-03-06 22:25:16 +01:00
|
|
|
ui_->button_box->addButton(add_button_, QDialogButtonBox::ActionRole);
|
2012-03-05 19:15:45 +01:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
remove_button_ =
|
|
|
|
new QPushButton(IconLoader::Load("list-remove"), tr("Unsubscribe"), this);
|
2012-03-07 12:22:43 +01:00
|
|
|
remove_button_->setEnabled(false);
|
|
|
|
connect(remove_button_, SIGNAL(clicked()), SLOT(RemovePodcast()));
|
|
|
|
ui_->button_box->addButton(remove_button_, QDialogButtonBox::ActionRole);
|
|
|
|
|
2012-03-10 23:39:24 +01:00
|
|
|
QPushButton* settings_button = new QPushButton(
|
2014-02-07 16:34:20 +01:00
|
|
|
IconLoader::Load("configure"), tr("Configure podcasts..."), this);
|
2012-03-10 23:39:24 +01:00
|
|
|
connect(settings_button, SIGNAL(clicked()), SLOT(OpenSettingsPage()));
|
|
|
|
ui_->button_box->addButton(settings_button, QDialogButtonBox::ResetRole);
|
|
|
|
|
2012-06-16 23:58:33 +02:00
|
|
|
// Create an Open OPML file button
|
|
|
|
QPushButton* open_opml_button = new QPushButton(
|
2014-02-07 16:34:20 +01:00
|
|
|
IconLoader::Load("document-open"), tr("Open OPML file..."), this);
|
2012-06-16 23:58:33 +02:00
|
|
|
connect(open_opml_button, SIGNAL(clicked()), this, SLOT(OpenOPMLFile()));
|
|
|
|
ui_->button_box->addButton(open_opml_button, QDialogButtonBox::ResetRole);
|
|
|
|
|
2012-03-05 19:15:45 +01:00
|
|
|
// Add providers
|
2012-03-11 18:57:15 +01:00
|
|
|
by_url_page_ = new AddPodcastByUrl(app, this);
|
|
|
|
AddPage(by_url_page_);
|
2012-03-07 16:31:12 +01:00
|
|
|
AddPage(new FixedOpmlPage(QUrl(kBbcOpmlUrl), tr("BBC Podcasts"),
|
|
|
|
QIcon(":providers/bbc.png"), app, this));
|
2012-03-06 01:35:55 +01:00
|
|
|
AddPage(new GPodderTopTagsPage(app, this));
|
2012-03-06 22:25:16 +01:00
|
|
|
AddPage(new GPodderSearchPage(app, this));
|
2012-03-07 13:27:31 +01:00
|
|
|
AddPage(new ITunesSearchPage(app, this));
|
2012-03-05 19:15:45 +01:00
|
|
|
|
|
|
|
ui_->provider_list->setCurrentRow(0);
|
|
|
|
}
|
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
AddPodcastDialog::~AddPodcastDialog() { delete ui_; }
|
2012-03-05 19:15:45 +01:00
|
|
|
|
2012-03-11 18:57:15 +01:00
|
|
|
void AddPodcastDialog::ShowWithUrl(const QUrl& url) {
|
|
|
|
by_url_page_->SetUrlAndGo(url);
|
|
|
|
ui_->provider_list->setCurrentRow(0);
|
|
|
|
show();
|
|
|
|
}
|
|
|
|
|
|
|
|
void AddPodcastDialog::ShowWithOpml(const OpmlContainer& opml) {
|
|
|
|
by_url_page_->SetOpml(opml);
|
|
|
|
ui_->provider_list->setCurrentRow(0);
|
|
|
|
show();
|
|
|
|
}
|
|
|
|
|
2012-03-05 19:15:45 +01:00
|
|
|
void AddPodcastDialog::AddPage(AddPodcastPage* page) {
|
|
|
|
pages_.append(page);
|
|
|
|
page_is_busy_.append(false);
|
|
|
|
|
|
|
|
ui_->stack->addWidget(page);
|
2014-02-07 16:34:20 +01:00
|
|
|
new QListWidgetItem(page->windowIcon(), page->windowTitle(),
|
|
|
|
ui_->provider_list);
|
2012-03-05 19:15:45 +01:00
|
|
|
|
|
|
|
connect(page, SIGNAL(Busy(bool)), SLOT(PageBusyChanged(bool)));
|
|
|
|
}
|
|
|
|
|
|
|
|
void AddPodcastDialog::ChangePage(int index) {
|
|
|
|
AddPodcastPage* page = pages_[index];
|
|
|
|
|
|
|
|
ui_->stack->setCurrentIndex(index);
|
2012-03-06 02:17:45 +01:00
|
|
|
ui_->stack->setVisible(page->has_visible_widget());
|
2012-03-05 19:15:45 +01:00
|
|
|
ui_->results->setModel(page->model());
|
|
|
|
|
|
|
|
ui_->results_stack->setCurrentWidget(
|
2014-02-07 16:34:20 +01:00
|
|
|
page_is_busy_[index] ? ui_->busy_page : ui_->results_page);
|
2012-03-05 19:15:45 +01:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(ui_->results->selectionModel(),
|
|
|
|
SIGNAL(currentRowChanged(QModelIndex, QModelIndex)),
|
2012-03-05 19:15:45 +01:00
|
|
|
SLOT(ChangePodcast(QModelIndex)));
|
|
|
|
ChangePodcast(QModelIndex());
|
2012-03-06 22:25:16 +01:00
|
|
|
CurrentPageBusyChanged(page_is_busy_[index]);
|
2012-03-06 02:17:45 +01:00
|
|
|
|
|
|
|
page->Show();
|
2012-03-05 19:15:45 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void AddPodcastDialog::ChangePodcast(const QModelIndex& current) {
|
2012-03-07 16:11:56 +01:00
|
|
|
QVariant podcast_variant = current.data(PodcastDiscoveryModel::Role_Podcast);
|
|
|
|
|
2012-03-07 12:22:43 +01:00
|
|
|
// If the selected item is invalid or not a podcast, hide the details pane.
|
2012-03-07 16:11:56 +01:00
|
|
|
if (podcast_variant.isNull()) {
|
2012-03-06 12:39:29 +01:00
|
|
|
ui_->details_scroll_area->hide();
|
2012-03-07 12:22:43 +01:00
|
|
|
add_button_->setEnabled(false);
|
|
|
|
remove_button_->setEnabled(false);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-03-07 16:11:56 +01:00
|
|
|
current_podcast_ = podcast_variant.value<Podcast>();
|
2012-03-05 19:15:45 +01:00
|
|
|
|
2012-03-07 12:22:43 +01:00
|
|
|
// Start the blur+fade if there's already a podcast in the details pane.
|
2012-03-06 12:39:29 +01:00
|
|
|
if (ui_->details_scroll_area->isVisible()) {
|
|
|
|
fader_->StartBlur();
|
|
|
|
} else {
|
|
|
|
ui_->details_scroll_area->show();
|
|
|
|
}
|
|
|
|
|
2012-03-07 12:22:43 +01:00
|
|
|
// Update the details pane
|
2012-03-06 19:37:46 +01:00
|
|
|
ui_->details->SetPodcast(current_podcast_);
|
|
|
|
|
2012-03-07 12:22:43 +01:00
|
|
|
// 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);
|
2012-03-05 19:15:45 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void AddPodcastDialog::PageBusyChanged(bool busy) {
|
|
|
|
const int index = pages_.indexOf(qobject_cast<AddPodcastPage*>(sender()));
|
2014-02-07 16:34:20 +01:00
|
|
|
if (index == -1) return;
|
2012-03-05 19:15:45 +01:00
|
|
|
|
|
|
|
page_is_busy_[index] = busy;
|
|
|
|
|
|
|
|
if (index == ui_->provider_list->currentRow()) {
|
2012-03-06 22:25:16 +01:00
|
|
|
CurrentPageBusyChanged(busy);
|
2012-03-05 19:15:45 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-06 22:25:16 +01:00
|
|
|
void AddPodcastDialog::CurrentPageBusyChanged(bool busy) {
|
2014-02-07 16:34:20 +01:00
|
|
|
ui_->results_stack->setCurrentWidget(busy ? ui_->busy_page
|
|
|
|
: ui_->results_page);
|
2012-03-06 22:25:16 +01:00
|
|
|
ui_->stack->setDisabled(busy);
|
2012-03-09 20:12:45 +01:00
|
|
|
|
|
|
|
QTimer::singleShot(0, this, SLOT(SelectFirstPodcast()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void AddPodcastDialog::SelectFirstPodcast() {
|
|
|
|
// Select the first item if there was one.
|
2014-02-07 16:34:20 +01:00
|
|
|
const PodcastDiscoveryModel* model =
|
|
|
|
pages_[ui_->provider_list->currentRow()]->model();
|
2012-03-09 20:12:45 +01:00
|
|
|
if (model->rowCount() > 0) {
|
|
|
|
ui_->results->selectionModel()->setCurrentIndex(
|
2014-02-07 16:34:20 +01:00
|
|
|
model->index(0, 0), QItemSelectionModel::ClearAndSelect);
|
2012-03-09 20:12:45 +01:00
|
|
|
}
|
2012-03-06 22:25:16 +01:00
|
|
|
}
|
|
|
|
|
2012-03-05 19:15:45 +01:00
|
|
|
void AddPodcastDialog::AddPodcast() {
|
2012-03-06 19:37:46 +01:00
|
|
|
app_->podcast_backend()->Subscribe(¤t_podcast_);
|
2012-03-07 12:22:43 +01:00
|
|
|
add_button_->setEnabled(false);
|
|
|
|
remove_button_->setEnabled(true);
|
|
|
|
}
|
|
|
|
|
2012-03-11 00:38:54 +01:00
|
|
|
void AddPodcastDialog::PodcastDoubleClicked(const QModelIndex& index) {
|
|
|
|
QVariant podcast_variant = index.data(PodcastDiscoveryModel::Role_Podcast);
|
|
|
|
if (podcast_variant.isNull()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-03-12 15:11:24 +01:00
|
|
|
current_podcast_ = podcast_variant.value<Podcast>();
|
|
|
|
app_->podcast_backend()->Subscribe(¤t_podcast_);
|
2014-02-07 16:34:20 +01:00
|
|
|
|
2012-03-12 15:11:24 +01:00
|
|
|
add_button_->setEnabled(false);
|
|
|
|
remove_button_->setEnabled(true);
|
2012-03-11 00:38:54 +01:00
|
|
|
}
|
|
|
|
|
2012-03-07 12:22:43 +01:00
|
|
|
void AddPodcastDialog::RemovePodcast() {
|
|
|
|
app_->podcast_backend()->Unsubscribe(current_podcast_);
|
2012-03-09 13:15:24 +01:00
|
|
|
current_podcast_.set_database_id(-1);
|
2012-03-07 12:22:43 +01:00
|
|
|
add_button_->setEnabled(true);
|
|
|
|
remove_button_->setEnabled(false);
|
2012-03-05 19:15:45 +01:00
|
|
|
}
|
2012-03-10 23:39:24 +01:00
|
|
|
|
|
|
|
void AddPodcastDialog::OpenSettingsPage() {
|
2012-12-05 10:36:22 +01:00
|
|
|
app_->OpenSettingsDialogAtPage(SettingsDialog::Page_Podcasts);
|
2012-03-10 23:39:24 +01:00
|
|
|
}
|
2012-06-16 23:58:33 +02:00
|
|
|
|
|
|
|
void AddPodcastDialog::OpenOPMLFile() {
|
|
|
|
const QString filename = QFileDialog::getOpenFileName(
|
2014-02-07 16:34:20 +01:00
|
|
|
this, tr("Open OPML file"), last_opml_path_, "OPML files (*.opml)");
|
2012-06-16 23:58:33 +02:00
|
|
|
|
|
|
|
if (filename.isEmpty()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
last_opml_path_ = filename;
|
|
|
|
|
|
|
|
by_url_page_->SetUrlAndGo(QUrl::fromLocalFile(last_opml_path_));
|
|
|
|
ChangePage(ui_->stack->indexOf(by_url_page_));
|
|
|
|
}
|