1 /*
2 * Strawberry Music Player
3 * This file was part of Clementine.
4 * Copyright 2010, David Sansome <me@davidsansome.com>
5 *
6 * Strawberry is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * Strawberry is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
21 #include "config.h"
22
23 #include <QWizard>
24 #include <QWizardPage>
25 #include <QLabel>
26 #include <QRadioButton>
27 #include <QVBoxLayout>
28
29 #include "core/logging.h"
30 #include "core/iconloader.h"
31
32 #include "smartplaylistquerywizardplugin.h"
33 #include "smartplaylistwizard.h"
34 #include "smartplaylistwizardplugin.h"
35 #include "ui_smartplaylistwizardfinishpage.h"
36
37 class SmartPlaylistWizard::TypePage : public QWizardPage { // clazy:exclude=missing-qobject-macro
38 public:
TypePage(QWidget * parent)39 explicit TypePage(QWidget *parent) : QWizardPage(parent), next_id_(-1) {}
40
nextId() const41 int nextId() const override { return next_id_; }
42 int next_id_;
43 };
44
45 class SmartPlaylistWizard::FinishPage : public QWizardPage { // clazy:exclude=missing-qobject-macro
46 public:
FinishPage(QWidget * parent)47 explicit FinishPage(QWidget *parent) : QWizardPage(parent), ui_(new Ui_SmartPlaylistWizardFinishPage) {
48 ui_->setupUi(this);
49 QObject::connect(ui_->name, &QLineEdit::textChanged, this, &SmartPlaylistWizard::FinishPage::completeChanged);
50 }
51
~FinishPage()52 ~FinishPage() override { delete ui_; }
53
nextId() const54 int nextId() const override { return -1; }
isComplete() const55 bool isComplete() const override { return !ui_->name->text().isEmpty(); }
56
57 Ui_SmartPlaylistWizardFinishPage *ui_;
58
59 };
60
SmartPlaylistWizard(Application * app,CollectionBackend * collection,QWidget * parent)61 SmartPlaylistWizard::SmartPlaylistWizard(Application *app, CollectionBackend *collection, QWidget *parent)
62 : QWizard(parent),
63 app_(app),
64 collection_(collection),
65 type_page_(new TypePage(this)),
66 finish_page_(new FinishPage(this)),
67 type_index_(-1) {
68
69 setWindowIcon(IconLoader::Load("strawberry"));
70 setWindowTitle(tr("Smart playlist"));
71
72 resize(788, 628);
73
74 #ifdef Q_OS_MACOS
75 // MacStyle leaves an ugly empty space on the left side of the dialog.
76 setWizardStyle(QWizard::ClassicStyle);
77 #endif
78
79 // Type page
80 type_page_->setTitle(tr("Playlist type"));
81 type_page_->setSubTitle(tr("A smart playlist is a dynamic list of songs that come from your collection. There are different types of smart playlist that offer different ways of selecting songs."));
82 type_page_->setStyleSheet("QRadioButton { font-weight: bold; } QLabel { margin-bottom: 1em; margin-left: 24px; }");
83 addPage(type_page_);
84
85 // Finish page
86 finish_page_->setTitle(tr("Finish"));
87 finish_page_->setSubTitle(tr("Choose a name for your smart playlist"));
88 finish_id_ = addPage(finish_page_);
89
90 new QVBoxLayout(type_page_);
91 AddPlugin(new SmartPlaylistQueryWizardPlugin(app_, collection_, this));
92
93 // Skip the type page - remove this when we have more than one type
94 setStartId(2);
95
96 }
97
~SmartPlaylistWizard()98 SmartPlaylistWizard::~SmartPlaylistWizard() {
99 qDeleteAll(plugins_);
100 }
101
SetGenerator(PlaylistGeneratorPtr gen)102 void SmartPlaylistWizard::SetGenerator(PlaylistGeneratorPtr gen) {
103
104 // Find the right type and jump to the start page
105 for (int i = 0; i < plugins_.count(); ++i) {
106 if (plugins_[i]->type() == gen->type()) {
107 TypeChanged(i);
108 // TODO: Put this back in when the setStartId is removed from the ctor next();
109 break;
110 }
111 }
112
113 if (type_index_ == -1) {
114 qLog(Error) << "Plugin was not found for generator type" << gen->type();
115 return;
116 }
117
118 // Set the name
119 if (!gen->name().isEmpty()) {
120 setWindowTitle(windowTitle() + " - " + gen->name());
121 }
122 finish_page_->ui_->name->setText(gen->name());
123 finish_page_->ui_->dynamic->setChecked(gen->is_dynamic());
124
125 // Tell the plugin to load
126 plugins_[type_index_]->SetGenerator(gen);
127
128 }
129
AddPlugin(SmartPlaylistWizardPlugin * plugin)130 void SmartPlaylistWizard::AddPlugin(SmartPlaylistWizardPlugin *plugin) {
131
132 const int index = plugins_.count();
133 plugins_ << plugin;
134 plugin->Init(this, finish_id_);
135
136 // Create the radio button
137 QRadioButton *radio_button = new QRadioButton(plugin->name(), type_page_);
138 QLabel *description = new QLabel(plugin->description(), type_page_);
139 type_page_->layout()->addWidget(radio_button);
140 type_page_->layout()->addWidget(description);
141
142 QObject::connect(radio_button, &QRadioButton::clicked, this, [this, index]() { TypeChanged(index); });
143
144 if (index == 0) {
145 radio_button->setChecked(true);
146 TypeChanged(0);
147 }
148
149 }
150
TypeChanged(const int index)151 void SmartPlaylistWizard::TypeChanged(const int index) {
152
153 type_index_ = index;
154 type_page_->next_id_ = plugins_[type_index_]->start_page();
155
156 }
157
CreateGenerator() const158 PlaylistGeneratorPtr SmartPlaylistWizard::CreateGenerator() const {
159
160 PlaylistGeneratorPtr ret;
161 if (type_index_ == -1) return ret;
162
163 ret = plugins_[type_index_]->CreateGenerator();
164 if (!ret) return ret;
165
166 ret->set_name(finish_page_->ui_->name->text());
167 ret->set_dynamic(finish_page_->ui_->dynamic->isChecked());
168 return ret;
169
170 }
171
initializePage(const int id)172 void SmartPlaylistWizard::initializePage(const int id) {
173
174 if (id == finish_id_) {
175 finish_page_->ui_->dynamic_container->setEnabled(plugins_[type_index_]->is_dynamic());
176 }
177 QWizard::initializePage(id);
178
179 }
180