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 }