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