1 /* GUI_Equalizer.cpp */
2
3 /* Copyright (C) 2011-2020 Michael Lugmair (Lucio Carreras)
4 *
5 * This file is part of sayonara player
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21
22 /*
23 * GUI_Equalizer.cpp
24 *
25 * Created on: May 18, 2011
26 * Author: Michael Lugmair (Lucio Carreras)
27 */
28
29 #include "GUI_Equalizer.h"
30 #include "EqualizerSlider.h"
31 #include "Gui/Plugins/ui_GUI_Equalizer.h"
32 #include "Gui/Utils/InputDialog/LineInputDialog.h"
33
34 #include "Components/Equalizer/Equalizer.h"
35
36 #include "Utils/Algorithm.h"
37 #include "Utils/EqualizerSetting.h"
38 #include "Utils/Language/Language.h"
39 #include "Utils/Message/Message.h"
40
41 #include <QLineEdit>
42 #include <array>
43
44 namespace Algorithm = Util::Algorithm;
45
46 using Gui::ContextMenu;
47 using Gui::MenuToolButton;
48 using Gui::EqualizerSlider;
49
50 using SliderArray = std::array<EqualizerSlider*, 10>;
51
52 struct GUI_Equalizer::Private
53 {
54 Equalizer* equalizer = nullptr;
55 QAction* actionGauss = nullptr;
56 SliderArray sliders;
57
PrivateGUI_Equalizer::Private58 Private(Equalizer* equalizer) :
59 equalizer(equalizer) {}
60
applySettingGUI_Equalizer::Private61 void applySetting(const EqualizerSetting& equalizer)
62 {
63 int band = 0;
64 for(const auto value : equalizer)
65 {
66 auto* slider = this->sliders[band];
67
68 slider->setSilent(true);
69 slider->setEqualizerValue(value);
70 slider->setSilent(false);
71
72 band++;
73 }
74 }
75 };
76
GUI_Equalizer(Equalizer * equalizer,QWidget * parent)77 GUI_Equalizer::GUI_Equalizer(Equalizer* equalizer, QWidget* parent) :
78 PlayerPlugin::Base(parent)
79 {
80 m = Pimpl::make<Private>(equalizer);
81
82 connect(m->equalizer, &Equalizer::sigValueChanged,
83 this, &GUI_Equalizer::valueChanged);
84 }
85
~GUI_Equalizer()86 GUI_Equalizer::~GUI_Equalizer()
87 {
88 if(ui)
89 {
90 delete ui;
91 ui = nullptr;
92 }
93 }
94
initUi()95 void GUI_Equalizer::initUi()
96 {
97 setupParent(this, &ui);
98
99 ui->sli_0->setLabel(0, ui->label);
100 ui->sli_1->setLabel(1, ui->label_2);
101 ui->sli_2->setLabel(2, ui->label_3);
102 ui->sli_3->setLabel(3, ui->label_4);
103 ui->sli_4->setLabel(4, ui->label_5);
104 ui->sli_5->setLabel(5, ui->label_6);
105 ui->sli_6->setLabel(6, ui->label_7);
106 ui->sli_7->setLabel(7, ui->label_8);
107 ui->sli_8->setLabel(8, ui->label_9);
108 ui->sli_9->setLabel(9, ui->label_10);
109
110 m->sliders = SliderArray
111 {{
112 ui->sli_0, ui->sli_1, ui->sli_2, ui->sli_3, ui->sli_4,
113 ui->sli_5, ui->sli_6, ui->sli_7, ui->sli_8, ui->sli_9
114 }};
115
116 m->actionGauss = new QAction(ui->btn_tool);
117 m->actionGauss->setCheckable(true);
118 m->actionGauss->setChecked(m->equalizer->isGaussEnabled());
119 m->actionGauss->setText(tr("Linked sliders"));
120
121 ui->btn_tool->registerAction(m->actionGauss);
122
123 for(auto* slider : Algorithm::AsConst(m->sliders))
124 {
125 connect(slider, &EqualizerSlider::sigValueChanged,
126 this, &GUI_Equalizer::sliderValueChanged);
127 connect(slider, &EqualizerSlider::sigSliderGotFocus,
128 this, &GUI_Equalizer::sliderPressed);
129 connect(slider, &EqualizerSlider::sigSliderLostFocus,
130 this, &GUI_Equalizer::sliderReleased);
131 }
132
133 connect(ui->btn_tool, &MenuToolButton::sigSaveAs,
134 this, &GUI_Equalizer::btnSaveAsClicked);
135 connect(ui->btn_tool, &MenuToolButton::sigDelete,
136 this, &GUI_Equalizer::btnDeleteClicked);
137 connect(ui->btn_tool, &MenuToolButton::sigDefault,
138 this, &GUI_Equalizer::btnDefaultClicked);
139 connect(ui->btn_tool, &MenuToolButton::sigRename,
140 this, &GUI_Equalizer::btnRenameClicked);
141
142 connect(m->actionGauss, &QAction::toggled,
143 this, &GUI_Equalizer::checkboxGaussToggled);
144
145 fillEqualizerPresets();
146
147 currentEqualizerChanged(m->equalizer->currentIndex());
148 }
149
name() const150 QString GUI_Equalizer::name() const
151 {
152 return "Equalizer";
153 }
154
displayName() const155 QString GUI_Equalizer::displayName() const
156 {
157 return tr("Equalizer");
158 }
159
retranslate()160 void GUI_Equalizer::retranslate()
161 {
162 ui->retranslateUi(this);
163
164 if(m->actionGauss)
165 {
166 m->actionGauss->setText(tr("Linked sliders"));
167 }
168 }
169
sliderPressed()170 void GUI_Equalizer::sliderPressed()
171 {
172 m->equalizer->startValueChange();
173 }
174
sliderReleased()175 void GUI_Equalizer::sliderReleased()
176 {
177 m->equalizer->endValueChange();
178 }
179
sliderValueChanged(int band,int newValue)180 void GUI_Equalizer::sliderValueChanged(int band, int newValue)
181 {
182 if(!Util::between(band, m->sliders))
183 {
184 return;
185 }
186
187 ui->btn_tool->showAction(ContextMenu::EntryDefault, true);
188 m->equalizer->changeValue(m->equalizer->currentIndex(), band, newValue);
189 }
190
valueChanged(int band,int newValue)191 void GUI_Equalizer::valueChanged(int band, int newValue)
192 {
193 auto* slider = m->sliders[size_t(band)];
194
195 slider->setSilent(true);
196 slider->setEqualizerValue(newValue);
197 slider->setSilent(false);
198 }
199
fillEqualizerPresets()200 void GUI_Equalizer::fillEqualizerPresets()
201 {
202 if(!isUiInitialized())
203 {
204 return;
205 }
206
207 const auto presetNames = m->equalizer->names();
208 for(const auto& preset : presetNames)
209 {
210 ui->combo_presets->addItem(preset);
211 }
212
213 const auto activeIndex = m->equalizer->currentIndex();
214 ui->combo_presets->setCurrentIndex(activeIndex);
215
216 connect(ui->combo_presets,
217 combo_current_index_changed_int,
218 this,
219 &GUI_Equalizer::currentEqualizerChanged);
220 }
221
currentEqualizerChanged(int index)222 void GUI_Equalizer::currentEqualizerChanged(int index)
223 {
224 const auto presetNames = m->equalizer->names();
225 if(!Util::between(index, presetNames))
226 {
227 ui->btn_tool->showActions(ContextMenu::EntryNone);
228 return;
229 }
230
231 m->equalizer->setCurrentIndex(index);
232
233 const auto& currentEqualizer = m->equalizer->currentSetting();
234 const auto isDefault = currentEqualizer.isDefault();
235 const auto isFactoryPreset = m->equalizer->defaultNames().contains(
236 currentEqualizer.name());
237
238 ui->btn_tool->showAction(ContextMenu::EntryDefault, !isDefault);
239 ui->btn_tool->showAction(ContextMenu::EntryDelete, !isFactoryPreset);
240 ui->btn_tool->showAction(ContextMenu::EntryRename, !isFactoryPreset);
241 ui->btn_tool->showAction(ContextMenu::EntrySaveAs, true);
242
243 m->applySetting(currentEqualizer);
244 }
245
checkboxGaussToggled(bool b)246 void GUI_Equalizer::checkboxGaussToggled(bool b)
247 {
248 m->equalizer->setGaussEnabled(b);
249 }
250
btnDefaultClicked()251 void GUI_Equalizer::btnDefaultClicked()
252 {
253 m->equalizer->resetPreset(ui->combo_presets->currentIndex());
254 ui->btn_tool->showAction(ContextMenu::EntryDefault, false);
255 }
256
257 template<typename Callback>
showDialog(GUI_Equalizer * parent,Lang::Term term,Callback callback)258 static void showDialog(GUI_Equalizer* parent, Lang::Term term, Callback callback)
259 {
260 auto* dialog =
261 new Gui::LineInputDialog(Lang::get(term), Lang::get(term), "", parent);
262
263 dialog->setModal(true);
264 parent->connect(dialog, &QDialog::accepted, parent, callback);
265 dialog->show();
266 }
267
btnSaveAsClicked()268 void GUI_Equalizer::btnSaveAsClicked()
269 {
270 showDialog(this, Lang::SaveAs, &GUI_Equalizer::saveAsOkClicked);
271 }
272
btnRenameClicked()273 void GUI_Equalizer::btnRenameClicked()
274 {
275 showDialog(this, Lang::Rename, &GUI_Equalizer::renameOkClicked);
276 }
277
btnDeleteClicked()278 void GUI_Equalizer::btnDeleteClicked()
279 {
280 const auto currentIndex = ui->combo_presets->currentIndex();
281 if(m->equalizer->deletePreset(currentIndex))
282 {
283 ui->combo_presets->removeItem(currentIndex);
284 ui->combo_presets->setCurrentIndex(m->equalizer->currentIndex());
285 }
286 }
287
getInputDialogText(QObject * possibleDialog)288 static QString getInputDialogText(QObject* possibleDialog)
289 {
290 auto* dialog = dynamic_cast<Gui::LineInputDialog*>(possibleDialog);
291 if(!dialog)
292 {
293 return QString();
294 }
295
296 const auto text = dialog->text();
297 dialog->deleteLater();
298
299 return text;
300 }
301
saveAsOkClicked()302 void GUI_Equalizer::saveAsOkClicked()
303 {
304 const auto newName = getInputDialogText(sender());
305 const auto err = m->equalizer->saveCurrentEqualizerAs(newName);
306
307 if(err == Equalizer::RenameError::NoError)
308 {
309 const auto lastIndex = m->equalizer->count() - 1;
310 const auto equalizer = m->equalizer->equalizerSetting(lastIndex);
311 ui->combo_presets->addItem(equalizer.name(), equalizer.id());
312 }
313 }
314
renameOkClicked()315 void GUI_Equalizer::renameOkClicked()
316 {
317 const auto newName = getInputDialogText(sender());
318 const auto currentIndex = m->equalizer->currentIndex();
319 const auto err = m->equalizer->renamePreset(currentIndex, newName);
320
321 if(err == Equalizer::RenameError::NoError)
322 {
323 ui->combo_presets->setItemText(currentIndex, newName);
324 }
325 }