Attempt to use BS2B when using headphones without HRTF
[openal-soft.git] / utils / alsoft-config / mainwindow.cpp
blob802cc71e0b926c4ace00170a7ce6c56d4270707e
1 #include <QFileDialog>
2 #include <QMessageBox>
3 #include <QSettings>
4 #include <QtGlobal>
5 #include "mainwindow.h"
6 #include "ui_mainwindow.h"
8 namespace {
9 static const struct {
10 char backend_name[16];
11 char menu_string[32];
12 } backendMenuList[] = {
13 #ifdef Q_OS_WIN32
14 { "mmdevapi", "Add MMDevAPI" },
15 { "dsound", "Add DirectSound" },
16 { "winmm", "Add Windows Multimedia" },
17 #endif
18 #ifdef Q_OS_MAC
19 { "core", "Add CoreAudio" },
20 #endif
21 { "pulse", "Add PulseAudio" },
22 #ifdef Q_OS_UNIX
23 { "alsa", "Add ALSA" },
24 { "oss", "Add OSS" },
25 { "solaris", "Add Solaris" },
26 { "sndio", "Add SndIO" },
27 { "qsa", "Add QSA" },
28 #endif
29 { "port", "Add PortAudio" },
30 { "opensl", "Add OpenSL" },
31 { "null", "Add Null Output" },
32 { "wave", "Add Wave Writer" },
33 { "", "" }
36 static const struct {
37 const char name[32];
38 const char value[16];
39 } speakerModeList[] = {
40 { "Autodetect", "" },
41 { "Mono", "mono" },
42 { "Stereo", "stereo" },
43 { "Quadrophonic", "quad" },
44 { "5.1 Surround (Side)", "surround51" },
45 { "5.1 Surround (Rear)", "surround51rear" },
46 { "6.1 Surround", "surround61" },
47 { "7.1 Surround", "surround71" },
49 { "", "" }
50 }, sampleTypeList[] = {
51 { "Autodetect", "" },
52 { "8-bit int", "int8" },
53 { "8-bit uint", "uint8" },
54 { "16-bit int", "int16" },
55 { "16-bit uint", "uint16" },
56 { "32-bit int", "int32" },
57 { "32-bit uint", "uint32" },
58 { "32-bit float", "float32" },
60 { "", "" }
61 }, resamplerList[] = {
62 { "Default", "" },
63 { "Point (low quality, fast)", "point" },
64 { "Linear (basic quality, fast)", "linear" },
65 { "Cubic Spline (good quality)", "cubic" },
67 { "", "" }
70 static QString getDefaultConfigName()
72 #ifdef Q_OS_WIN32
73 static const char fname[] = "alsoft.ini";
74 QByteArray base = qgetenv("AppData");
75 #else
76 static const char fname[] = "alsoft.conf";
77 QByteArray base = qgetenv("XDG_CONFIG_HOME");
78 if(base.isEmpty())
80 base = qgetenv("HOME");
81 if(base.isEmpty() == false)
82 base += "/.config";
84 #endif
85 if(base.isEmpty() == false)
86 return base +'/'+ fname;
87 return fname;
90 static QString getBaseDataPath()
92 #ifdef Q_OS_WIN32
93 QByteArray base = qgetenv("AppData");
94 #else
95 QByteArray base = qgetenv("XDG_DATA_HOME");
96 if(base.isEmpty())
98 base = qgetenv("HOME");
99 if(!base.isEmpty())
100 base += "/.local/share";
102 #endif
103 return base;
106 static QStringList getAllDataPaths(QString append=QString())
108 QStringList list;
109 list.append(getBaseDataPath());
110 #ifdef Q_OS_WIN32
111 // TODO: Common AppData path
112 #else
113 QString paths = qgetenv("XDG_DATA_DIRS");
114 if(paths.isEmpty())
115 paths = "/usr/local/share/:/usr/share/";
116 list += paths.split(QChar(':'), QString::SkipEmptyParts);
117 #endif
118 QStringList::iterator iter = list.begin();
119 while(iter != list.end())
121 if(iter->isEmpty())
122 iter = list.erase(iter);
123 else
125 iter->append(append);
126 iter++;
129 return list;
133 MainWindow::MainWindow(QWidget *parent) :
134 QMainWindow(parent),
135 ui(new Ui::MainWindow),
136 mPeriodSizeValidator(NULL),
137 mPeriodCountValidator(NULL),
138 mSourceCountValidator(NULL),
139 mEffectSlotValidator(NULL),
140 mSourceSendValidator(NULL),
141 mSampleRateValidator(NULL),
142 mReverbBoostValidator(NULL)
144 ui->setupUi(this);
146 for(int i = 0;speakerModeList[i].name[0];i++)
147 ui->channelConfigCombo->addItem(speakerModeList[i].name);
148 ui->channelConfigCombo->adjustSize();
149 for(int i = 0;sampleTypeList[i].name[0];i++)
150 ui->sampleFormatCombo->addItem(sampleTypeList[i].name);
151 ui->sampleFormatCombo->adjustSize();
152 for(int i = 0;resamplerList[i].name[0];i++)
153 ui->resamplerComboBox->addItem(resamplerList[i].name);
154 ui->resamplerComboBox->adjustSize();
156 mPeriodSizeValidator = new QIntValidator(64, 8192, this);
157 ui->periodSizeEdit->setValidator(mPeriodSizeValidator);
158 mPeriodCountValidator = new QIntValidator(2, 16, this);
159 ui->periodCountEdit->setValidator(mPeriodCountValidator);
161 mSourceCountValidator = new QIntValidator(0, 256, this);
162 ui->srcCountLineEdit->setValidator(mSourceCountValidator);
163 mEffectSlotValidator = new QIntValidator(0, 16, this);
164 ui->effectSlotLineEdit->setValidator(mEffectSlotValidator);
165 mSourceSendValidator = new QIntValidator(0, 4, this);
166 ui->srcSendLineEdit->setValidator(mSourceSendValidator);
167 mSampleRateValidator = new QIntValidator(8000, 192000, this);
168 ui->sampleRateCombo->lineEdit()->setValidator(mSampleRateValidator);
170 mReverbBoostValidator = new QDoubleValidator(-12.0, +12.0, 1, this);
171 ui->reverbBoostEdit->setValidator(mReverbBoostValidator);
173 connect(ui->actionLoad, SIGNAL(triggered()), this, SLOT(loadConfigFromFile()));
174 connect(ui->actionSave_As, SIGNAL(triggered()), this, SLOT(saveConfigAsFile()));
176 connect(ui->applyButton, SIGNAL(clicked()), this, SLOT(saveCurrentConfig()));
178 connect(ui->periodSizeSlider, SIGNAL(valueChanged(int)), this, SLOT(updatePeriodSizeEdit(int)));
179 connect(ui->periodSizeEdit, SIGNAL(editingFinished()), this, SLOT(updatePeriodSizeSlider()));
180 connect(ui->periodCountSlider, SIGNAL(valueChanged(int)), this, SLOT(updatePeriodCountEdit(int)));
181 connect(ui->periodCountEdit, SIGNAL(editingFinished()), this, SLOT(updatePeriodCountSlider()));
183 connect(ui->hrtfAddButton, SIGNAL(clicked()), this, SLOT(addHrtfFile()));
184 connect(ui->hrtfRemoveButton, SIGNAL(clicked()), this, SLOT(removeHrtfFile()));
185 connect(ui->hrtfFileList, SIGNAL(itemSelectionChanged()), this, SLOT(updateHrtfRemoveButton()));
187 ui->enabledBackendList->setContextMenuPolicy(Qt::CustomContextMenu);
188 connect(ui->enabledBackendList, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showEnabledBackendMenu(QPoint)));
190 ui->disabledBackendList->setContextMenuPolicy(Qt::CustomContextMenu);
191 connect(ui->disabledBackendList, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showDisabledBackendMenu(QPoint)));
193 connect(ui->reverbBoostSlider, SIGNAL(valueChanged(int)), this, SLOT(updateReverbBoostEdit(int)));
194 connect(ui->reverbBoostEdit, SIGNAL(textEdited(QString)), this, SLOT(updateReverbBoostSlider(QString)));
196 loadConfig(getDefaultConfigName());
199 MainWindow::~MainWindow()
201 delete ui;
202 delete mPeriodSizeValidator;
203 delete mPeriodCountValidator;
204 delete mSourceCountValidator;
205 delete mEffectSlotValidator;
206 delete mSourceSendValidator;
207 delete mSampleRateValidator;
208 delete mReverbBoostValidator;
211 void MainWindow::loadConfigFromFile()
213 QString fname = QFileDialog::getOpenFileName(this, tr("Select Files"));
214 if(fname.isEmpty() == false)
215 loadConfig(fname);
218 void MainWindow::loadConfig(const QString &fname)
220 QSettings settings(fname, QSettings::IniFormat);
222 QString sampletype = settings.value("sample-type").toString();
223 ui->sampleFormatCombo->setCurrentIndex(0);
224 if(sampletype.isEmpty() == false)
226 for(int i = 0;sampleTypeList[i].name[i];i++)
228 if(sampletype == sampleTypeList[i].value)
230 for(int j = 1;j < ui->sampleFormatCombo->count();j++)
232 QString item = ui->sampleFormatCombo->itemText(j);
233 if(item == sampleTypeList[i].name)
235 ui->sampleFormatCombo->setCurrentIndex(j);
236 break;
239 break;
244 QString channelconfig = settings.value("channels").toString();
245 ui->channelConfigCombo->setCurrentIndex(0);
246 if(channelconfig.isEmpty() == false)
248 for(int i = 0;speakerModeList[i].name[i];i++)
250 if(channelconfig == speakerModeList[i].value)
252 for(int j = 1;j < ui->channelConfigCombo->count();j++)
254 QString item = ui->channelConfigCombo->itemText(j);
255 if(item == speakerModeList[i].name)
257 ui->channelConfigCombo->setCurrentIndex(j);
258 break;
261 break;
266 QString srate = settings.value("frequency").toString();
267 if(srate.isEmpty())
268 ui->sampleRateCombo->setCurrentIndex(0);
269 else
271 ui->sampleRateCombo->lineEdit()->clear();
272 ui->sampleRateCombo->lineEdit()->insert(srate);
275 ui->srcCountLineEdit->clear();
276 ui->srcCountLineEdit->insert(settings.value("sources").toString());
277 ui->effectSlotLineEdit->clear();
278 ui->effectSlotLineEdit->insert(settings.value("slots").toString());
279 ui->srcSendLineEdit->clear();
280 ui->srcSendLineEdit->insert(settings.value("sends").toString());
282 QString resampler = settings.value("resampler").toString().trimmed();
283 ui->resamplerComboBox->setCurrentIndex(0);
284 if(resampler.isEmpty() == false)
286 for(int i = 0;resamplerList[i].name[i];i++)
288 if(resampler == resamplerList[i].value)
290 for(int j = 1;j < ui->resamplerComboBox->count();j++)
292 QString item = ui->resamplerComboBox->itemText(j);
293 if(item == resamplerList[i].name)
295 ui->resamplerComboBox->setCurrentIndex(j);
296 break;
299 break;
304 int periodsize = settings.value("period_size").toInt();
305 ui->periodSizeEdit->clear();
306 if(periodsize >= 64)
308 ui->periodSizeEdit->insert(QString::number(periodsize));
309 updatePeriodSizeSlider();
312 int periodcount = settings.value("periods").toInt();
313 ui->periodCountEdit->clear();
314 if(periodcount >= 2)
316 ui->periodCountEdit->insert(QString::number(periodcount));
317 updatePeriodCountSlider();
320 QStringList disabledCpuExts = settings.value("disable-cpu-exts").toStringList();
321 if(disabledCpuExts.size() == 1)
322 disabledCpuExts = disabledCpuExts[0].split(QChar(','));
323 std::transform(disabledCpuExts.begin(), disabledCpuExts.end(),
324 disabledCpuExts.begin(), std::mem_fun_ref(&QString::trimmed));
325 ui->enableSSECheckBox->setChecked(!disabledCpuExts.contains("sse", Qt::CaseInsensitive));
326 ui->enableSSE2CheckBox->setChecked(!disabledCpuExts.contains("sse2", Qt::CaseInsensitive));
327 ui->enableSSE41CheckBox->setChecked(!disabledCpuExts.contains("sse4.1", Qt::CaseInsensitive));
328 ui->enableNeonCheckBox->setChecked(!disabledCpuExts.contains("neon", Qt::CaseInsensitive));
330 if(settings.value("hrtf").toString() == QString())
331 ui->hrtfEnableButton->setChecked(true);
332 else
334 if(settings.value("hrtf", true).toBool())
335 ui->hrtfForceButton->setChecked(true);
336 else
337 ui->hrtfDisableButton->setChecked(true);
340 QStringList hrtf_tables = settings.value("hrtf_tables").toStringList();
341 if(hrtf_tables.size() == 1)
342 hrtf_tables = hrtf_tables[0].split(QChar(','));
343 std::transform(hrtf_tables.begin(), hrtf_tables.end(),
344 hrtf_tables.begin(), std::mem_fun_ref(&QString::trimmed));
345 ui->hrtfFileList->clear();
346 ui->hrtfFileList->addItems(hrtf_tables);
347 updateHrtfRemoveButton();
349 ui->enabledBackendList->clear();
350 ui->disabledBackendList->clear();
351 QStringList drivers = settings.value("drivers").toStringList();
352 if(drivers.size() == 0)
353 ui->backendCheckBox->setChecked(true);
354 else
356 if(drivers.size() == 1)
357 drivers = drivers[0].split(QChar(','));
358 std::transform(drivers.begin(), drivers.end(),
359 drivers.begin(), std::mem_fun_ref(&QString::trimmed));
361 bool lastWasEmpty = false;
362 foreach(const QString &backend, drivers)
364 lastWasEmpty = backend.isEmpty();
365 if(!backend.startsWith(QChar('-')) && !lastWasEmpty)
366 ui->enabledBackendList->addItem(backend);
367 else if(backend.size() > 1)
368 ui->disabledBackendList->addItem(backend.right(backend.size()-1));
370 ui->backendCheckBox->setChecked(lastWasEmpty);
373 QString defaultreverb = settings.value("default-reverb").toString().toLower();
374 ui->defaultReverbComboBox->setCurrentIndex(0);
375 if(defaultreverb.isEmpty() == false)
377 for(int i = 0;i < ui->defaultReverbComboBox->count();i++)
379 if(defaultreverb.compare(ui->defaultReverbComboBox->itemText(i).toLower()) == 0)
381 ui->defaultReverbComboBox->setCurrentIndex(i);
382 break;
387 ui->emulateEaxCheckBox->setChecked(settings.value("reverb/emulate-eax", false).toBool());
388 ui->reverbBoostEdit->clear();
389 ui->reverbBoostEdit->insert(settings.value("reverb/boost").toString());
391 QStringList excludefx = settings.value("excludefx").toStringList();
392 if(excludefx.size() == 1)
393 excludefx = excludefx[0].split(QChar(','));
394 std::transform(excludefx.begin(), excludefx.end(),
395 excludefx.begin(), std::mem_fun_ref(&QString::trimmed));
396 ui->enableEaxReverbCheck->setChecked(!excludefx.contains("eaxreverb", Qt::CaseInsensitive));
397 ui->enableStdReverbCheck->setChecked(!excludefx.contains("reverb", Qt::CaseInsensitive));
398 ui->enableChorusCheck->setChecked(!excludefx.contains("chorus", Qt::CaseInsensitive));
399 ui->enableCompressorCheck->setChecked(!excludefx.contains("compressor", Qt::CaseInsensitive));
400 ui->enableDistortionCheck->setChecked(!excludefx.contains("distortion", Qt::CaseInsensitive));
401 ui->enableEchoCheck->setChecked(!excludefx.contains("echo", Qt::CaseInsensitive));
402 ui->enableEqualizerCheck->setChecked(!excludefx.contains("equalizer", Qt::CaseInsensitive));
403 ui->enableFlangerCheck->setChecked(!excludefx.contains("flanger", Qt::CaseInsensitive));
404 ui->enableModulatorCheck->setChecked(!excludefx.contains("modulator", Qt::CaseInsensitive));
405 ui->enableDedicatedCheck->setChecked(!excludefx.contains("dedicated", Qt::CaseInsensitive));
408 void MainWindow::saveCurrentConfig()
410 saveConfig(getDefaultConfigName());
411 QMessageBox::information(this, tr("Information"),
412 tr("Applications using OpenAL need to be restarted for changes to take effect."));
415 void MainWindow::saveConfigAsFile()
417 QString fname = QFileDialog::getOpenFileName(this, tr("Select Files"));
418 if(fname.isEmpty() == false)
419 saveConfig(fname);
422 void MainWindow::saveConfig(const QString &fname) const
424 QSettings settings(fname, QSettings::IniFormat);
426 /* HACK: Compound any stringlist values into a comma-separated string. */
427 QStringList allkeys = settings.allKeys();
428 foreach(const QString &key, allkeys)
430 QStringList vals = settings.value(key).toStringList();
431 if(vals.size() > 1)
432 settings.setValue(key, vals.join(QChar(',')));
435 QString str = ui->sampleFormatCombo->currentText();
436 for(int i = 0;sampleTypeList[i].name[0];i++)
438 if(str == sampleTypeList[i].name)
440 settings.setValue("sample-type", sampleTypeList[i].value);
441 break;
445 str = ui->channelConfigCombo->currentText();
446 for(int i = 0;speakerModeList[i].name[0];i++)
448 if(str == speakerModeList[i].name)
450 settings.setValue("channels", speakerModeList[i].value);
451 break;
455 uint rate = ui->sampleRateCombo->currentText().toUInt();
456 if(!(rate > 0))
457 settings.setValue("frequency", QString());
458 else
459 settings.setValue("frequency", rate);
461 settings.setValue("period_size", ui->periodSizeEdit->text());
462 settings.setValue("periods", ui->periodCountEdit->text());
464 settings.setValue("sources", ui->srcCountLineEdit->text());
465 settings.setValue("slots", ui->effectSlotLineEdit->text());
467 str = ui->resamplerComboBox->currentText();
468 for(int i = 0;resamplerList[i].name[0];i++)
470 if(str == resamplerList[i].name)
472 settings.setValue("resampler", resamplerList[i].value);
473 break;
477 QStringList strlist;
478 if(!ui->enableSSECheckBox->isChecked())
479 strlist.append("sse");
480 if(!ui->enableSSE2CheckBox->isChecked())
481 strlist.append("sse2");
482 if(!ui->enableSSE41CheckBox->isChecked())
483 strlist.append("sse4.1");
484 if(!ui->enableNeonCheckBox->isChecked())
485 strlist.append("neon");
486 settings.setValue("disable-cpu-exts", strlist.join(QChar(',')));
488 if(ui->hrtfForceButton->isChecked())
489 settings.setValue("hrtf", "true");
490 else if(ui->hrtfDisableButton->isChecked())
491 settings.setValue("hrtf", "false");
492 else
493 settings.setValue("hrtf", QString());
495 strlist.clear();
496 QList<QListWidgetItem*> items = ui->hrtfFileList->findItems("*", Qt::MatchWildcard);
497 foreach(const QListWidgetItem *item, items)
498 strlist.append(item->text());
499 settings.setValue("hrtf_tables", strlist.join(QChar(',')));
501 strlist.clear();
502 items = ui->enabledBackendList->findItems("*", Qt::MatchWildcard);
503 foreach(const QListWidgetItem *item, items)
504 strlist.append(item->text());
505 items = ui->disabledBackendList->findItems("*", Qt::MatchWildcard);
506 foreach(const QListWidgetItem *item, items)
507 strlist.append(QChar('-')+item->text());
508 if(strlist.size() == 0 && !ui->backendCheckBox->isChecked())
509 strlist.append("-all");
510 else if(ui->backendCheckBox->isChecked())
511 strlist.append(QString());
512 settings.setValue("drivers", strlist.join(QChar(',')));
514 // TODO: Remove check when we can properly match global values.
515 if(ui->defaultReverbComboBox->currentIndex() == 0)
516 settings.setValue("default-reverb", QString());
517 else
519 str = ui->defaultReverbComboBox->currentText().toLower();
520 settings.setValue("default-reverb", str);
523 if(ui->emulateEaxCheckBox->isChecked())
524 settings.setValue("reverb/emulate-eax", "true");
525 else
526 settings.setValue("reverb/emulate-eax", QString()/*"false"*/);
528 // TODO: Remove check when we can properly match global values.
529 if(ui->reverbBoostSlider->sliderPosition() == 0)
530 settings.setValue("reverb/boost", QString());
531 else
532 settings.setValue("reverb/boost", ui->reverbBoostEdit->text());
534 strlist.clear();
535 if(!ui->enableEaxReverbCheck->isChecked())
536 strlist.append("eaxreverb");
537 if(!ui->enableStdReverbCheck->isChecked())
538 strlist.append("reverb");
539 if(!ui->enableChorusCheck->isChecked())
540 strlist.append("chorus");
541 if(!ui->enableDistortionCheck->isChecked())
542 strlist.append("distortion");
543 if(!ui->enableCompressorCheck->isChecked())
544 strlist.append("compressor");
545 if(!ui->enableEchoCheck->isChecked())
546 strlist.append("echo");
547 if(!ui->enableEqualizerCheck->isChecked())
548 strlist.append("equalizer");
549 if(!ui->enableFlangerCheck->isChecked())
550 strlist.append("flanger");
551 if(!ui->enableModulatorCheck->isChecked())
552 strlist.append("modulator");
553 if(!ui->enableDedicatedCheck->isChecked())
554 strlist.append("dedicated");
555 settings.setValue("excludefx", strlist.join(QChar(',')));
557 /* Remove empty keys
558 * FIXME: Should only remove keys whose value matches the globally-specified value.
560 allkeys = settings.allKeys();
561 foreach(const QString &key, allkeys)
563 str = settings.value(key).toString();
564 if(str == QString())
565 settings.remove(key);
570 void MainWindow::updatePeriodSizeEdit(int size)
572 ui->periodSizeEdit->clear();
573 if(size >= 64)
575 size = (size+32)&~0x3f;
576 ui->periodSizeEdit->insert(QString::number(size));
580 void MainWindow::updatePeriodSizeSlider()
582 int pos = ui->periodSizeEdit->text().toInt();
583 if(pos >= 64)
585 if(pos > 8192)
586 pos = 8192;
587 ui->periodSizeSlider->setSliderPosition(pos);
591 void MainWindow::updatePeriodCountEdit(int count)
593 ui->periodCountEdit->clear();
594 if(count >= 2)
595 ui->periodCountEdit->insert(QString::number(count));
598 void MainWindow::updatePeriodCountSlider()
600 int pos = ui->periodCountEdit->text().toInt();
601 if(pos < 2)
602 pos = 0;
603 else if(pos > 16)
604 pos = 16;
605 ui->periodCountSlider->setSliderPosition(pos);
609 void MainWindow::addHrtfFile()
611 const QStringList datapaths = getAllDataPaths("/openal/hrtf");
612 QStringList fnames = QFileDialog::getOpenFileNames(this, tr("Select Files"),
613 datapaths.empty() ? QString() : datapaths[0],
614 "HRTF Datasets(*.mhr);;All Files(*.*)");
615 if(fnames.isEmpty() == false)
617 for(QStringList::iterator iter = fnames.begin();iter != fnames.end();iter++)
619 QStringList::const_iterator path = datapaths.constBegin();
620 for(;path != datapaths.constEnd();path++)
622 QDir hrtfdir(*path);
623 if(!hrtfdir.isAbsolute())
624 continue;
626 const QString relname = hrtfdir.relativeFilePath(*iter);
627 if(!relname.startsWith(".."))
629 // If filename is within this path, use the relative pathname
630 ui->hrtfFileList->addItem(relname);
631 break;
634 if(path == datapaths.constEnd())
636 // Filename is not within any data path, use the absolute pathname
637 ui->hrtfFileList->addItem(*iter);
643 void MainWindow::removeHrtfFile()
645 QList<QListWidgetItem*> selected = ui->hrtfFileList->selectedItems();
646 foreach(QListWidgetItem *item, selected)
647 delete item;
650 void MainWindow::updateHrtfRemoveButton()
652 ui->hrtfRemoveButton->setEnabled(ui->hrtfFileList->selectedItems().size() != 0);
655 void MainWindow::showEnabledBackendMenu(QPoint pt)
657 QMap<QAction*,QString> actionMap;
659 pt = ui->enabledBackendList->mapToGlobal(pt);
661 QMenu ctxmenu;
662 QAction *removeAction = ctxmenu.addAction(QIcon::fromTheme("list-remove"), "Remove");
663 if(ui->enabledBackendList->selectedItems().size() == 0)
664 removeAction->setEnabled(false);
665 ctxmenu.addSeparator();
666 for(size_t i = 0;backendMenuList[i].backend_name[0];i++)
668 QAction *action = ctxmenu.addAction(backendMenuList[i].menu_string);
669 actionMap[action] = backendMenuList[i].backend_name;
670 if(ui->enabledBackendList->findItems(backendMenuList[i].backend_name, Qt::MatchFixedString).size() != 0 ||
671 ui->disabledBackendList->findItems(backendMenuList[i].backend_name, Qt::MatchFixedString).size() != 0)
672 action->setEnabled(false);
675 QAction *gotAction = ctxmenu.exec(pt);
676 if(gotAction == removeAction)
678 QList<QListWidgetItem*> selected = ui->enabledBackendList->selectedItems();
679 foreach(QListWidgetItem *item, selected)
680 delete item;
682 else if(gotAction != NULL)
684 QMap<QAction*,QString>::const_iterator iter = actionMap.find(gotAction);
685 if(iter != actionMap.end())
686 ui->enabledBackendList->addItem(iter.value());
690 void MainWindow::showDisabledBackendMenu(QPoint pt)
692 QMap<QAction*,QString> actionMap;
694 pt = ui->disabledBackendList->mapToGlobal(pt);
696 QMenu ctxmenu;
697 QAction *removeAction = ctxmenu.addAction(QIcon::fromTheme("list-remove"), "Remove");
698 if(ui->disabledBackendList->selectedItems().size() == 0)
699 removeAction->setEnabled(false);
700 ctxmenu.addSeparator();
701 for(size_t i = 0;backendMenuList[i].backend_name[0];i++)
703 QAction *action = ctxmenu.addAction(backendMenuList[i].menu_string);
704 actionMap[action] = backendMenuList[i].backend_name;
705 if(ui->disabledBackendList->findItems(backendMenuList[i].backend_name, Qt::MatchFixedString).size() != 0 ||
706 ui->enabledBackendList->findItems(backendMenuList[i].backend_name, Qt::MatchFixedString).size() != 0)
707 action->setEnabled(false);
710 QAction *gotAction = ctxmenu.exec(pt);
711 if(gotAction == removeAction)
713 QList<QListWidgetItem*> selected = ui->disabledBackendList->selectedItems();
714 foreach(QListWidgetItem *item, selected)
715 delete item;
717 else if(gotAction != NULL)
719 QMap<QAction*,QString>::const_iterator iter = actionMap.find(gotAction);
720 if(iter != actionMap.end())
721 ui->disabledBackendList->addItem(iter.value());
725 void MainWindow::updateReverbBoostEdit(int value)
727 ui->reverbBoostEdit->clear();
728 if(value != 0)
729 ui->reverbBoostEdit->insert(QString::number(value/10.0, 'f', 1));
732 void MainWindow::updateReverbBoostSlider(QString value)
734 int pos = int(value.toFloat()*10.0f);
735 ui->reverbBoostSlider->setSliderPosition(pos);