1 /***************************************************************************
2 * Copyright (C) 2011-2021 by Ilya Kotov *
3 * forkotov02@ya.ru *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
19 ***************************************************************************/
20
21 #include <QGridLayout>
22 #include <QVBoxLayout>
23 #include <QHBoxLayout>
24 #include <QSlider>
25 #include <QCheckBox>
26 #include <QPushButton>
27 #include <QComboBox>
28 #include <QLabel>
29 #include <QPainter>
30 #include <QDialogButtonBox>
31 #include <QSettings>
32 #include <QMessageBox>
33 #include <QDir>
34 #include <qmmp/qmmpsettings.h>
35 #include "equalizer.h"
36
37 #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
38 #define horizontalAdvance width
39 #endif
40
Equalizer(QWidget * parent)41 Equalizer::Equalizer(QWidget *parent) : QDialog(parent)
42 {
43 setWindowTitle(tr("Equalizer"));
44
45 m_layout = new QVBoxLayout(this);
46 setLayout(m_layout);
47 m_layout->setSpacing(5);
48 m_layout->setMargin(5);
49
50 QHBoxLayout *buttonsLayout = new QHBoxLayout;
51 buttonsLayout->setSpacing(5);
52 m_enabled = new QCheckBox(tr("Enable equalizer"), this);
53 buttonsLayout->addWidget(m_enabled);
54
55 buttonsLayout->addSpacerItem(new QSpacerItem(30, 0, QSizePolicy::Fixed, QSizePolicy::Fixed));
56
57 QLabel *label = new QLabel(this);
58 label->setText(tr("Preset:"));
59 buttonsLayout->addWidget(label);
60
61 m_presetComboBox = new QComboBox(this);
62 m_presetComboBox->setEditable(true);
63 connect(m_presetComboBox, SIGNAL(activated(int)), SLOT(loadPreset(int)));
64 buttonsLayout->addWidget(m_presetComboBox);
65
66 QPushButton *saveButton = new QPushButton(tr("Save"), this);
67 connect(saveButton, SIGNAL(pressed()), SLOT(savePreset()));
68 buttonsLayout->addWidget(saveButton);
69
70 QPushButton *deleteButton = new QPushButton(tr("Delete"), this);
71 connect(deleteButton, SIGNAL(pressed()), SLOT(deletePreset()));
72 buttonsLayout->addWidget(deleteButton);
73
74 QPushButton *reset = new QPushButton(tr("Reset"), this);
75 connect(reset, SIGNAL(clicked()), SLOT(resetSettings()));
76 buttonsLayout->addWidget(reset);
77
78 QDialogButtonBox *dialogButtons = new QDialogButtonBox(QDialogButtonBox::Close, Qt::Horizontal, this);
79 dialogButtons->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
80 connect(dialogButtons, SIGNAL(rejected()), SLOT(reject()));
81 buttonsLayout->addWidget(dialogButtons);
82
83 QGridLayout *slidersLayout = new QGridLayout;
84 slidersLayout->setSpacing(5);
85
86 QStringList names;
87 names << tr("Preamp") << "25" << "40" << "63" << "100" << "160" << "250"
88 << "400" << "630" << "1k" << "1,6k" << "2,5k"
89 << "4k" << "6,3k" << "10k" << "16k";
90
91 for(int i = 0; i < 16; ++i)
92 {
93 QSlider *slider = new QSlider(this);
94 slider->setRange(-20, 20);
95 slider->setTickPosition(QSlider::TicksLeft);
96 slider->setTickInterval(10);
97 QLabel *eqLabel = new QLabel(this);
98 eqLabel->setFrameShape(QFrame::Box);
99 eqLabel->setText(names.at(i));
100 slidersLayout->addWidget(slider, 1, i, Qt::AlignHCenter);
101 slidersLayout->addWidget(eqLabel, 2, i, Qt::AlignHCenter);
102
103 QLabel *label2 = new QLabel(this);
104 label2->setText(tr("%1dB").arg(0));
105 label2->setFrameShape(QFrame::Box);
106 label2->setMinimumWidth(fontMetrics().horizontalAdvance(tr("+%1dB").arg(20)) + 5);
107 label2->setAlignment(Qt::AlignCenter);
108 slidersLayout->addWidget(label2, 0, i, Qt::AlignHCenter);
109 connect(slider, SIGNAL(valueChanged(int)), SLOT(updateLabel()));
110 m_sliders << slider;
111 m_labels << label2;
112 }
113 m_layout->addItem(slidersLayout);
114 m_layout->addItem(buttonsLayout);
115 setMinimumHeight(300);
116 for(const QSlider *slider : qAsConst(m_sliders))
117 {
118 connect(slider, SIGNAL(valueChanged(int)), SLOT(applySettings()));
119 }
120 connect(m_enabled, SIGNAL(clicked()), SLOT(applySettings()));
121 readSettigs();
122 loadPresets();
123 }
124
~Equalizer()125 Equalizer::~Equalizer()
126 {
127 savePresets();
128 qDeleteAll(m_presets);
129 m_presets.clear();
130 }
131
readSettigs()132 void Equalizer::readSettigs()
133 {
134 EqSettings settings = QmmpSettings::instance()->eqSettings();
135 m_enabled->setChecked(settings.isEnabled());
136 m_sliders.at(0)->setValue(settings.preamp());
137 for(int i = 0; i < EqSettings::EQ_BANDS_15; ++i)
138 {
139 m_sliders.at(i+1)->setValue(settings.gain(i));
140 }
141 }
142
loadPresets()143 void Equalizer::loadPresets()
144 {
145 m_presetComboBox->clear();
146 //equalizer presets
147 QString preset_path = Qmmp::configDir() + "/eq15.preset";
148 if(!QFile::exists(preset_path))
149 preset_path = ":/qsui/eq15.preset";
150 QSettings eq_preset (preset_path, QSettings::IniFormat);
151 int i = 0;
152 while(eq_preset.contains("Presets/Preset"+QString("%1").arg(++i)))
153 {
154 QString name = eq_preset.value(QString("Presets/Preset%1").arg(i), tr("preset")).toString();
155 EQPreset *preset = new EQPreset();
156 //preset->setText(name);
157 eq_preset.beginGroup(name);
158 for (int j = 0; j < EqSettings::EQ_BANDS_15; ++j)
159 {
160 preset->setGain(j,eq_preset.value(QString("Band%1").arg(j), 0).toDouble());
161 }
162 preset->setPreamp(eq_preset.value("Preamp",0).toDouble());
163 m_presets.append(preset);
164 m_presetComboBox->addItem(name);
165 eq_preset.endGroup();
166 }
167 m_presetComboBox->clearEditText();
168 }
169
applySettings()170 void Equalizer::applySettings()
171 {
172 EqSettings settings = QmmpSettings::instance()->eqSettings();
173 settings.setPreamp(m_sliders.at(0)->value());
174 settings.setEnabled(m_enabled->isChecked());
175 for(int i = 0; i < EqSettings::EQ_BANDS_15; ++i)
176 {
177 settings.setGain(i, m_sliders.at(i+1)->value());
178 }
179 QmmpSettings::instance()->setEqSettings(settings);
180 }
181
resetSettings()182 void Equalizer::resetSettings()
183 {
184 for(QSlider *slider : qAsConst(m_sliders))
185 {
186 slider->setValue(0);
187 }
188 applySettings();
189 m_presetComboBox->setCurrentIndex(-1);
190 }
191
updateLabel()192 void Equalizer::updateLabel()
193 {
194 QSlider *slider = qobject_cast<QSlider *>(sender());
195 int index = m_sliders.indexOf(slider);
196 if(index < 0)
197 return;
198 if(slider->value() > 0)
199 m_labels[index]->setText(tr("+%1dB").arg(slider->value()));
200 else
201 m_labels[index]->setText(tr("%1dB").arg(slider->value()));
202 }
203
loadPreset(int index)204 void Equalizer::loadPreset(int index)
205 {
206 EQPreset *preset = m_presets.at(index);
207 m_sliders.at(0)->setValue(preset->preamp());
208 for(int i = 0; i < EqSettings::EQ_BANDS_15; ++i)
209 {
210 m_sliders.at(i+1)->setValue(preset->gain(i));
211 }
212 applySettings();
213 }
214
savePreset()215 void Equalizer::savePreset()
216 {
217 QString name = m_presetComboBox->currentText();
218 if(name.isEmpty())
219 return;
220
221 int index = m_presetComboBox->findText(name);
222 if(index != -1)
223 {
224 if(QMessageBox::question(this, tr("Overwrite Request"),
225 tr("Preset '%1' already exists. Overwrite?").arg(name),
226 QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
227 return;
228 m_presets[index]->setPreamp(m_sliders.at(0)->value());
229 for(int i = 0; i < EqSettings::EQ_BANDS_15; ++i)
230 {
231 m_presets[index]->setGain(i, m_sliders.at(i+1)->value());
232 }
233 }
234 else
235 {
236 m_presetComboBox->addItem(name);
237 EQPreset *preset = new EQPreset();
238 preset->setPreamp(m_sliders.at(0)->value());
239 for(int i = 0; i < EqSettings::EQ_BANDS_15; ++i)
240 {
241 preset->setGain(i, m_sliders.at(i+1)->value());
242 }
243 m_presets.append(preset);
244 }
245 m_presetComboBox->clearEditText();
246 }
247
savePresets()248 void Equalizer::savePresets()
249 {
250 QSettings eq_preset (Qmmp::configDir() + "/eq15.preset", QSettings::IniFormat);
251 eq_preset.clear ();
252 for (int i = 0; i < m_presets.size(); ++i)
253 {
254 eq_preset.setValue(QString("Presets/Preset%1").arg(i+1), m_presetComboBox->itemText(i));
255 eq_preset.beginGroup(m_presetComboBox->itemText(i));
256 for (int j = 0; j < EqSettings::EQ_BANDS_15; ++j)
257 {
258 eq_preset.setValue(QString("Band%1").arg(j),m_presets.at(i)->gain(j));
259 }
260 eq_preset.setValue("Preamp",m_presets.at(i)->preamp());
261 eq_preset.endGroup();
262 }
263 }
264
deletePreset()265 void Equalizer::deletePreset()
266 {
267 QString name = m_presetComboBox->currentText();
268 if(name.isEmpty())
269 return;
270
271 int index = m_presetComboBox->findText(name);
272 if(index != -1)
273 {
274 m_presetComboBox->removeItem(index);
275 delete m_presets.takeAt(index);
276 }
277 m_presetComboBox->clearEditText();
278 }
279