18 #include <QGridLayout> 22 #include <QDoubleSpinBox> 24 #include <QPushButton> 25 #include <QHBoxLayout> 27 #include <QDialogButtonBox> 28 #include <QMessageBox> 31 #include <QFileDialog> 33 #include <QListWidget> 38 #include "widgets/WindowTypeSelector.h" 39 #include "widgets/IconLoader.h" 40 #include "widgets/ColourMapComboBox.h" 41 #include "widgets/ColourComboBox.h" 42 #include "widgets/PluginPathConfigurator.h" 43 #include "widgets/WidgetScale.h" 44 #include "base/Preferences.h" 45 #include "base/ResourceFinder.h" 46 #include "layer/ColourMapper.h" 47 #include "layer/ColourDatabase.h" 49 #include "bqaudioio/AudioFactory.h" 51 #include "../version.h" 57 m_audioImplementation(0),
58 m_audioPlaybackDevice(0),
59 m_audioRecordDevice(0),
60 m_audioDeviceChanged(false),
61 m_coloursChanged(false),
62 m_changesOnRestart(false)
64 setWindowTitle(tr(
"Sonic Visualiser: Application Preferences"));
66 Preferences *prefs = Preferences::getInstance();
68 QGridLayout *grid =
new QGridLayout;
72 grid->addWidget(
m_tabs, 0, 0);
74 m_tabs->setTabPosition(QTabWidget::North);
84 int min, max, deflt, i;
86 m_windowType = WindowType(prefs->getPropertyRangeAndValue
87 (
"Window Type", &min, &max, &deflt));
93 QCheckBox *vampProcessSeparation =
new QCheckBox;
97 connect(vampProcessSeparation, SIGNAL(stateChanged(
int)),
100 QComboBox *smoothing =
new QComboBox;
102 int sm = prefs->getPropertyRangeAndValue(
"Spectrogram Y Smoothing", &min, &max,
106 for (i = min; i <= max; ++i) {
107 smoothing->addItem(prefs->getPropertyValueLabel(
"Spectrogram Y Smoothing", i));
110 smoothing->setCurrentIndex(sm);
112 connect(smoothing, SIGNAL(currentIndexChanged(
int)),
115 QComboBox *xsmoothing =
new QComboBox;
117 int xsm = prefs->getPropertyRangeAndValue(
"Spectrogram X Smoothing", &min, &max,
121 for (i = min; i <= max; ++i) {
122 xsmoothing->addItem(prefs->getPropertyValueLabel(
"Spectrogram X Smoothing", i));
125 xsmoothing->setCurrentIndex(xsm);
127 connect(xsmoothing, SIGNAL(currentIndexChanged(
int)),
130 QComboBox *propertyLayout =
new QComboBox;
131 int pl = prefs->getPropertyRangeAndValue(
"Property Box Layout", &min, &max,
135 for (i = min; i <= max; ++i) {
136 propertyLayout->addItem(prefs->getPropertyValueLabel(
"Property Box Layout", i));
139 propertyLayout->setCurrentIndex(pl);
141 connect(propertyLayout, SIGNAL(currentIndexChanged(
int)),
145 settings.beginGroup(
"Preferences");
147 int(ColourMapper::Green)).toInt());
149 int(ColourMapper::Sunset)).toInt());
151 int(ColourMapper::Green)).toInt());
154 if (settings.contains(
"overview-colour")) {
160 SVCERR <<
"loaded colour " <<
m_overviewColour.name() <<
" from settings" << endl;
164 ColourMapComboBox *spectrogramGColour =
new ColourMapComboBox(
true);
167 ColourMapComboBox *spectrogramMColour =
new ColourMapComboBox(
true);
170 ColourMapComboBox *colour3DColour =
new ColourMapComboBox(
true);
177 int overviewColourIndex =
179 if (overviewColourIndex >= 0) {
186 connect(spectrogramGColour, SIGNAL(colourMapChanged(
int)),
188 connect(spectrogramMColour, SIGNAL(colourMapChanged(
int)),
190 connect(colour3DColour, SIGNAL(colourMapChanged(
int)),
197 QDoubleSpinBox *frequency =
new QDoubleSpinBox;
198 frequency->setMinimum(100.0);
199 frequency->setMaximum(5000.0);
200 frequency->setSuffix(
" Hz");
201 frequency->setSingleStep(1);
203 frequency->setDecimals(2);
205 connect(frequency, SIGNAL(valueChanged(
double)),
208 QComboBox *octaveSystem =
new QComboBox;
209 int oct = prefs->getPropertyRangeAndValue
210 (
"Octave Numbering System", &min, &max, &deflt);
212 for (i = min; i <= max; ++i) {
213 octaveSystem->addItem(prefs->getPropertyValueLabel
214 (
"Octave Numbering System", i));
216 octaveSystem->setCurrentIndex(oct);
218 connect(octaveSystem, SIGNAL(currentIndexChanged(
int)),
221 settings.beginGroup(
"Preferences");
223 QComboBox *audioImplementation =
new QComboBox;
224 connect(audioImplementation, SIGNAL(currentIndexChanged(
int)),
235 vector<string> implementationNames =
236 breakfastquay::AudioFactory::getImplementationNames();
238 QString implementationName = settings.value(
"audio-target",
"").toString();
239 if (implementationName ==
"auto") implementationName =
"";
240 if (implementationName ==
"" && implementationNames.size() == 1) {
242 implementationName = implementationNames[0].c_str();
245 audioImplementation->addItem(tr(
"(auto)"));
248 for (
int i = 0; in_range_for(implementationNames, i); ++i) {
249 audioImplementation->addItem
250 (breakfastquay::AudioFactory::getImplementationDescription
251 (implementationNames[i]).c_str());
252 if (implementationName.toStdString() == implementationNames[i]) {
253 audioImplementation->setCurrentIndex(i+1);
263 QCheckBox *resampleOnLoad =
new QCheckBox;
267 connect(resampleOnLoad, SIGNAL(stateChanged(
int)),
270 QCheckBox *gaplessMode =
new QCheckBox;
272 gaplessMode->setCheckState(
m_gapless ? Qt::Checked : Qt::Unchecked);
273 connect(gaplessMode, SIGNAL(stateChanged(
int)),
277 QString dir = prefs->getTemporaryDirectoryRoot();
279 dir.replace(
"$HOME", tr(
"<home directory>"));
282 QPushButton *tempDirButton =
new QPushButton;
283 tempDirButton->setIcon(IconLoader().load(
"fileopen"));
284 connect(tempDirButton, SIGNAL(clicked()),
286 tempDirButton->setFixedSize(WidgetScale::scaleQSize(QSize(24, 24)));
288 QCheckBox *showSplash =
new QCheckBox;
290 showSplash->setCheckState(
m_showSplash ? Qt::Checked : Qt::Unchecked);
291 connect(showSplash, SIGNAL(stateChanged(
int)),
295 QComboBox *bgMode =
new QComboBox;
296 int bg = prefs->getPropertyRangeAndValue(
"Background Mode", &min, &max,
299 for (i = min; i <= max; ++i) {
300 bgMode->addItem(prefs->getPropertyValueLabel(
"Background Mode", i));
302 bgMode->setCurrentIndex(bg);
304 connect(bgMode, SIGNAL(currentIndexChanged(
int)),
308 settings.beginGroup(
"Preferences");
311 m_retina = settings.value(
"scaledHiDpi",
true).toBool();
312 QCheckBox *retina =
new QCheckBox;
313 retina->setCheckState(
m_retina ? Qt::Checked : Qt::Unchecked);
314 connect(retina, SIGNAL(stateChanged(
int)),
this, SLOT(
retinaChanged(
int)));
319 QString userLocale = settings.value(
"locale",
"").toString();
322 QString permishTag = QString(
"network-permission-%1").arg(SV_VERSION);
327 QComboBox *locale =
new QComboBox;
328 QStringList localeFiles = QDir(
":i18n").entryList(QStringList() <<
"*.qm");
329 locale->addItem(tr(
"Follow system locale"));
331 if (userLocale ==
"") {
332 locale->setCurrentIndex(0);
334 foreach (QString f, localeFiles) {
336 f.replace(
"sonic-visualiser_",
"").replace(
".qm",
"");
338 SVCERR <<
"INFO: Unexpected filename " << f <<
" in i18n resource directory" << endl;
343 if (f ==
"ru") displayText = tr(
"Russian");
344 else if (f ==
"en_GB") displayText = tr(
"British English");
345 else if (f ==
"en_US") displayText = tr(
"American English");
346 else if (f ==
"cs_CZ") displayText = tr(
"Czech");
347 else displayText = f;
348 locale->addItem(QString(
"%1 [%2]").arg(displayText).arg(f));
349 if (userLocale == f) {
350 locale->setCurrentIndex(locale->count() - 1);
354 connect(locale, SIGNAL(currentIndexChanged(
int)),
357 QCheckBox *networkPermish =
new QCheckBox;
359 connect(networkPermish, SIGNAL(stateChanged(
int)),
362 QSpinBox *fontSize =
new QSpinBox;
363 int fs = prefs->getPropertyRangeAndValue(
"View Font Size", &min, &max,
366 fontSize->setMinimum(min);
367 fontSize->setMaximum(max);
368 fontSize->setSuffix(
" pt");
369 fontSize->setSingleStep(1);
370 fontSize->setValue(fs);
372 connect(fontSize, SIGNAL(valueChanged(
int)),
375 QComboBox *ttMode =
new QComboBox;
376 int tt = prefs->getPropertyRangeAndValue(
"Time To Text Mode", &min, &max,
379 for (i = min; i <= max; ++i) {
380 ttMode->addItem(prefs->getPropertyValueLabel(
"Time To Text Mode", i));
382 ttMode->setCurrentIndex(tt);
384 connect(ttMode, SIGNAL(currentIndexChanged(
int)),
387 QCheckBox *hms =
new QCheckBox;
388 int showHMS = prefs->getPropertyRangeAndValue
389 (
"Show Hours And Minutes", &min, &max, &deflt);
391 hms->setCheckState(
m_showHMS ? Qt::Checked : Qt::Unchecked);
392 connect(hms, SIGNAL(stateChanged(
int)),
395 QFrame *frame =
nullptr;
396 QGridLayout *subgrid =
nullptr;
402 subgrid =
new QGridLayout;
403 frame->setLayout(subgrid);
407 if (devicePixelRatio() > 1) {
408 subgrid->addWidget(
new QLabel(tr(
"Draw layers at Retina resolution:")), row, 0);
409 subgrid->addWidget(retina, row++, 1, 1, 1);
414 subgrid->addWidget(
new QLabel(tr(
"%1:").arg(prefs->getPropertyLabel
415 (
"Background Mode"))),
417 subgrid->addWidget(bgMode, row++, 1, 1, 2);
420 subgrid->addWidget(
new QLabel(tr(
"%1:").arg(prefs->getPropertyLabel
421 (
"Property Box Layout"))),
423 subgrid->addWidget(propertyLayout, row++, 1, 1, 2);
425 subgrid->addWidget(
new QLabel(tr(
"Default spectrogram colour:")),
427 subgrid->addWidget(spectrogramGColour, row++, 1, 1, 2);
429 subgrid->addWidget(
new QLabel(tr(
"Default melodic spectrogram colour:")),
431 subgrid->addWidget(spectrogramMColour, row++, 1, 1, 2);
433 subgrid->addWidget(
new QLabel(tr(
"Default colour 3D plot colour:")),
435 subgrid->addWidget(colour3DColour, row++, 1, 1, 2);
437 subgrid->addWidget(
new QLabel(tr(
"Overview waveform colour:")),
441 subgrid->addWidget(
new QLabel(tr(
"%1:").arg(prefs->getPropertyLabel
442 (
"View Font Size"))),
444 subgrid->addWidget(fontSize, row++, 1, 1, 2);
446 subgrid->addWidget(
new QLabel(tr(
"%1:").arg(prefs->getPropertyLabel
447 (
"Time To Text Mode"))),
449 subgrid->addWidget(ttMode, row++, 1, 1, 2);
451 subgrid->addWidget(
new QLabel(tr(
"%1:").arg(prefs->getPropertyLabel
452 (
"Show Hours And Minutes"))),
454 subgrid->addWidget(hms, row++, 1, 1, 1);
456 subgrid->setRowStretch(row, 10);
459 m_tabs->addTab(frame, tr(
"&Appearance"));
464 subgrid =
new QGridLayout;
465 frame->setLayout(subgrid);
468 subgrid->addWidget(
new QLabel(tr(
"%1:").arg(prefs->getPropertyLabel
469 (
"Tuning Frequency"))),
471 subgrid->addWidget(frequency, row++, 1, 1, 2);
473 subgrid->addWidget(
new QLabel(tr(
"%1:").arg(prefs->getPropertyLabel
474 (
"Octave Numbering System"))),
476 subgrid->addWidget(octaveSystem, row++, 1, 1, 2);
478 subgrid->addWidget(
new QLabel(prefs->getPropertyLabel
479 (
"Spectrogram Y Smoothing")),
481 subgrid->addWidget(smoothing, row++, 1, 1, 2);
483 subgrid->addWidget(
new QLabel(prefs->getPropertyLabel
484 (
"Spectrogram X Smoothing")),
486 subgrid->addWidget(xsmoothing, row++, 1, 1, 2);
488 subgrid->addWidget(
new QLabel(tr(
"%1:").arg(prefs->getPropertyLabel
491 subgrid->addWidget(m_windowTypeSelector, row++, 1, 2, 2);
493 subgrid->setRowStretch(row, 10);
496 subgrid->addWidget(
new QLabel(tr(
"Run Vamp plugins in separate process:")),
498 subgrid->addWidget(vampProcessSeparation, row++, 1, 1, 1);
500 subgrid->setRowStretch(row, 10);
503 m_tabs->addTab(frame, tr(
"Anal&ysis"));
508 subgrid =
new QGridLayout;
509 frame->setLayout(subgrid);
512 subgrid->addWidget(
new QLabel(tr(
"Default session template when loading audio files:")), row++, 0);
514 QListWidget *lw =
new QListWidget();
515 subgrid->addWidget(lw, row, 0);
516 subgrid->setRowStretch(row, 10);
519 subgrid->addWidget(
new QLabel(tr(
"(Use \"%1\" in the File menu to add to these.)")
520 .arg(tr(
"Export Session as Template..."))),
523 settings.beginGroup(
"MainWindow");
527 lw->addItem(tr(
"Standard Waveform"));
529 lw->setCurrentRow(lw->count()-1);
533 QStringList templates = ResourceFinder().getResourceFiles(
"templates",
"svt");
536 foreach (QString t, templates) {
537 byName.insert(QFileInfo(t).baseName());
540 foreach (QString t, byName) {
541 if (t.toLower() ==
"default")
continue;
545 lw->setCurrentRow(lw->count()-1);
552 m_tabs->addTab(frame, tr(
"Session &Template"));
557 subgrid =
new QGridLayout;
558 frame->setLayout(subgrid);
561 if (implementationNames.size() > 1) {
562 subgrid->addWidget(
new QLabel(tr(
"Audio service:")), row, 0);
563 subgrid->addWidget(audioImplementation, row++, 1, 1, 2);
566 subgrid->addWidget(
new QLabel(tr(
"Audio playback device:")), row, 0);
569 subgrid->addWidget(
new QLabel(tr(
"Audio record device:")), row, 0);
572 subgrid->addWidget(
new QLabel(tr(
"%1:").arg(prefs->getPropertyLabel
573 (
"Use Gapless Mode"))),
575 subgrid->addWidget(gaplessMode, row++, 1, 1, 1);
577 subgrid->addWidget(
new QLabel(tr(
"%1:").arg(prefs->getPropertyLabel
578 (
"Resample On Load"))),
580 subgrid->addWidget(resampleOnLoad, row++, 1, 1, 1);
582 subgrid->setRowStretch(row, 10);
585 m_tabs->addTab(frame, tr(
"A&udio I/O"));
600 subgrid =
new QGridLayout;
601 frame->setLayout(subgrid);
604 subgrid->addWidget(
new QLabel(tr(
"%1:").arg(tr(
"User interface language"))),
606 subgrid->addWidget(locale, row++, 1, 1, 1);
608 subgrid->addWidget(
new QLabel(tr(
"%1:").arg(tr(
"Allow network usage"))),
610 subgrid->addWidget(networkPermish, row++, 1, 1, 1);
612 subgrid->addWidget(
new QLabel(tr(
"%1:").arg(prefs->getPropertyLabel
613 (
"Show Splash Screen"))),
615 subgrid->addWidget(showSplash, row++, 1, 1, 1);
617 subgrid->addWidget(
new QLabel(tr(
"%1:").arg(prefs->getPropertyLabel
618 (
"Temporary Directory Root"))),
621 subgrid->addWidget(tempDirButton, row, 2, 1, 1);
624 subgrid->setRowStretch(row, 10);
627 m_tabs->addTab(frame, tr(
"&Other"));
629 QDialogButtonBox *bb =
new QDialogButtonBox(Qt::Horizontal);
630 grid->addWidget(bb, 1, 0);
632 QPushButton *ok =
new QPushButton(tr(
"OK"));
633 QPushButton *cancel =
new QPushButton(tr(
"Cancel"));
634 bb->addButton(ok, QDialogButtonBox::AcceptRole);
636 bb->addButton(cancel, QDialogButtonBox::RejectRole);
637 connect(ok, SIGNAL(clicked()),
this, SLOT(
okClicked()));
639 connect(cancel, SIGNAL(clicked()),
this, SLOT(
cancelClicked()));
646 SVDEBUG <<
"PreferencesDialog::~PreferencesDialog()" << endl;
653 settings.beginGroup(
"Preferences");
655 vector<string> names = breakfastquay::AudioFactory::getImplementationNames();
656 string implementationName;
663 if (implementationName !=
"") {
664 suffix =
"-" + QString(implementationName.c_str());
667 names = breakfastquay::AudioFactory::getPlaybackDeviceNames(implementationName);
668 QString playbackDeviceName = settings.value
669 (
"audio-playback-device" + suffix,
"").toString();
674 for (
int i = 0; in_range_for(names, i); ++i) {
676 if (playbackDeviceName.toStdString() == names[i]) {
682 names = breakfastquay::AudioFactory::getRecordDeviceNames(implementationName);
683 QString recordDeviceName = settings.value
684 (
"audio-record-device" + suffix,
"").toString();
689 for (
int i = 0; in_range_for(names, i); ++i) {
691 if (recordDeviceName.toStdString() == names[i]) {
881 QString dir = QFileDialog::getExistingDirectory
882 (
this, tr(
"Select a directory to create cache subdirectory in"),
884 if (dir ==
"")
return;
903 if (overviewColour >= 0) {
904 int plainColours = 6;
906 if (mode == Preferences::DarkBackground &&
907 overviewColour < plainColours) {
908 overviewColour += plainColours;
910 if (mode == Preferences::LightBackground &&
911 overviewColour >= plainColours) {
912 overviewColour -= plainColours;
965 Preferences *prefs = Preferences::getInstance();
967 prefs->setSpectrogramSmoothing(Preferences::SpectrogramSmoothing
969 prefs->setSpectrogramXSmoothing(Preferences::SpectrogramXSmoothing
971 prefs->setPropertyBoxLayout(Preferences::PropertyBoxLayout
987 settings.beginGroup(
"Preferences");
988 QString permishTag = QString(
"network-permission-%1").arg(SV_VERSION);
991 vector<string> names = breakfastquay::AudioFactory::getImplementationNames();
992 string implementationName;
999 settings.setValue(
"audio-target", implementationName.c_str());
1002 if (implementationName !=
"") {
1003 suffix =
"-" + QString(implementationName.c_str());
1006 names = breakfastquay::AudioFactory::getPlaybackDeviceNames(implementationName);
1014 settings.setValue(
"audio-playback-device" + suffix, deviceName.c_str());
1016 names = breakfastquay::AudioFactory::getRecordDeviceNames(implementationName);
1024 settings.setValue(
"audio-record-device" + suffix, deviceName.c_str());
1028 settings.setValue(
"scaledHiDpi",
m_retina);
1036 settings.remove(
"overview-colour");
1038 settings.endGroup();
1040 settings.beginGroup(
"MainWindow");
1042 settings.endGroup();
1047 QMessageBox::information(
this, tr(
"Preferences"),
1048 tr(
"<b>Restart required</b><p>One or more of the application preferences you have changed may not take full effect until Sonic Visualiser is restarted.</p><p>Please exit and restart the application now if you want these changes to take effect immediately.</p>"));
1080 int rv = QMessageBox::warning
1081 (
this, tr(
"Preferences Changed"),
1082 tr(
"Some preferences have been changed but not applied.\n" 1083 "Apply them before closing?"),
1084 QMessageBox::Apply | QMessageBox::Discard,
1085 QMessageBox::Discard);
1086 if (rv == QMessageBox::Apply) {
QString m_currentTemplate
void tempDirButtonClicked()
void colour3DColourChanged(int state)
void timeToTextModeChanged(int mode)
virtual ~PreferencesDialog()
int m_spectrogramXSmoothing
void overviewColourChanged(int state)
QPushButton * m_applyButton
int m_spectrogramSmoothing
void octaveSystemChanged(int system)
QComboBox * m_audioRecordDeviceCombo
QComboBox * m_audioPlaybackDeviceCombo
void audioPlaybackDeviceChanged(int device)
void networkPermissionChanged(int state)
void showSplashChanged(int state)
int m_audioPlaybackDevice
void rebuildDeviceCombos()
void propertyLayoutChanged(int layout)
ColourComboBox * m_overviewColourCombo
void audioImplementationChanged(int impl)
void defaultTemplateChanged(int)
int m_audioImplementation
void windowTypeChanged(WindowType type)
QLineEdit * m_tempDirRootEdit
void spectrogramXSmoothingChanged(int state)
void viewFontSizeChanged(int sz)
void spectrogramMColourChanged(int state)
void spectrogramSmoothingChanged(int state)
void backgroundModeChanged(int mode)
void audioRecordDeviceChanged(int device)
void gaplessModeChanged(int state)
void resampleOnLoadChanged(int state)
QMap< Tab, int > m_tabOrdering
void switchToTab(Tab tab)
WindowTypeSelector * m_windowTypeSelector
PreferencesDialog(QWidget *parent=0)
void showHMSChanged(int state)
void tuningFrequencyChanged(double freq)
bool m_overviewColourIsSet
void vampProcessSeparationChanged(int state)
void retinaChanged(int state)
void applicationClosing(bool quickly)
PluginPathConfigurator * m_pluginPathConfigurator
void pluginPathsChanged()
void audioDeviceChanged()
void tempDirRootChanged(QString root)
void spectrogramGColourChanged(int state)
bool m_audioDeviceChanged
bool m_runPluginsInProcess