Mercurial > hg > sonic-visualiser
view main/PreferencesDialog.cpp @ 932:c2734beb9b15 cxx11
Subrepo state
author | Chris Cannam |
---|---|
date | Wed, 11 Mar 2015 13:55:15 +0000 |
parents | 6de549288477 |
children | c9d87032f3da 28ccb621d1af |
line wrap: on
line source
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ /* Sonic Visualiser An audio file viewer and annotation editor. Centre for Digital Music, Queen Mary, University of London. This file copyright 2006 Chris Cannam. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. See the file COPYING included with this distribution for more information. */ #include "PreferencesDialog.h" #include <QGridLayout> #include <QComboBox> #include <QCheckBox> #include <QGroupBox> #include <QDoubleSpinBox> #include <QLabel> #include <QPushButton> #include <QHBoxLayout> #include <QString> #include <QDialogButtonBox> #include <QMessageBox> #include <QTabWidget> #include <QLineEdit> #include <QFileDialog> #include <QMessageBox> #include <QSpinBox> #include <QListWidget> #include <QSettings> #include <set> #include "widgets/WindowTypeSelector.h" #include "widgets/IconLoader.h" #include "base/Preferences.h" #include "audioio/AudioTargetFactory.h" #include "base/ResourceFinder.h" #include "version.h" PreferencesDialog::PreferencesDialog(QWidget *parent) : QDialog(parent), m_audioDevice(0), m_changesOnRestart(false) { setWindowTitle(tr("Sonic Visualiser: Application Preferences")); Preferences *prefs = Preferences::getInstance(); QGridLayout *grid = new QGridLayout; setLayout(grid); m_tabs = new QTabWidget; grid->addWidget(m_tabs, 0, 0); m_tabs->setTabPosition(QTabWidget::North); // Create this first, as slots that get called from the ctor will // refer to it m_applyButton = new QPushButton(tr("Apply")); // Create all the preference widgets first, then create the // individual tab widgets and place the preferences in their // appropriate places in one go afterwards int min, max, deflt, i; m_windowType = WindowType(prefs->getPropertyRangeAndValue ("Window Type", &min, &max, &deflt)); m_windowTypeSelector = new WindowTypeSelector(m_windowType); connect(m_windowTypeSelector, SIGNAL(windowTypeChanged(WindowType)), this, SLOT(windowTypeChanged(WindowType))); QComboBox *smoothing = new QComboBox; int sm = prefs->getPropertyRangeAndValue("Spectrogram Y Smoothing", &min, &max, &deflt); m_spectrogramSmoothing = sm; for (i = min; i <= max; ++i) { smoothing->addItem(prefs->getPropertyValueLabel("Spectrogram Y Smoothing", i)); } smoothing->setCurrentIndex(sm); connect(smoothing, SIGNAL(currentIndexChanged(int)), this, SLOT(spectrogramSmoothingChanged(int))); QComboBox *xsmoothing = new QComboBox; int xsm = prefs->getPropertyRangeAndValue("Spectrogram X Smoothing", &min, &max, &deflt); m_spectrogramXSmoothing = xsm; for (i = min; i <= max; ++i) { xsmoothing->addItem(prefs->getPropertyValueLabel("Spectrogram X Smoothing", i)); } xsmoothing->setCurrentIndex(xsm); connect(xsmoothing, SIGNAL(currentIndexChanged(int)), this, SLOT(spectrogramXSmoothingChanged(int))); QComboBox *propertyLayout = new QComboBox; int pl = prefs->getPropertyRangeAndValue("Property Box Layout", &min, &max, &deflt); m_propertyLayout = pl; for (i = min; i <= max; ++i) { propertyLayout->addItem(prefs->getPropertyValueLabel("Property Box Layout", i)); } propertyLayout->setCurrentIndex(pl); connect(propertyLayout, SIGNAL(currentIndexChanged(int)), this, SLOT(propertyLayoutChanged(int))); m_tuningFrequency = prefs->getTuningFrequency(); QDoubleSpinBox *frequency = new QDoubleSpinBox; frequency->setMinimum(100.0); frequency->setMaximum(5000.0); frequency->setSuffix(" Hz"); frequency->setSingleStep(1); frequency->setValue(m_tuningFrequency); frequency->setDecimals(2); connect(frequency, SIGNAL(valueChanged(double)), this, SLOT(tuningFrequencyChanged(double))); QComboBox *octaveSystem = new QComboBox; int oct = prefs->getPropertyRangeAndValue ("Octave Numbering System", &min, &max, &deflt); m_octaveSystem = oct; for (i = min; i <= max; ++i) { octaveSystem->addItem(prefs->getPropertyValueLabel ("Octave Numbering System", i)); } octaveSystem->setCurrentIndex(oct); connect(octaveSystem, SIGNAL(currentIndexChanged(int)), this, SLOT(octaveSystemChanged(int))); QComboBox *audioDevice = new QComboBox; std::vector<QString> devices = AudioTargetFactory::getInstance()->getCallbackTargetNames(); QSettings settings; settings.beginGroup("Preferences"); QString targetName = settings.value("audio-target", "").toString(); settings.endGroup(); for (int i = 0; i < (int)devices.size(); ++i) { audioDevice->addItem(AudioTargetFactory::getInstance() ->getCallbackTargetDescription(devices[i])); if (targetName == devices[i]) audioDevice->setCurrentIndex(i); } connect(audioDevice, SIGNAL(currentIndexChanged(int)), this, SLOT(audioDeviceChanged(int))); QComboBox *resampleQuality = new QComboBox; int rsq = prefs->getPropertyRangeAndValue("Resample Quality", &min, &max, &deflt); m_resampleQuality = rsq; for (i = min; i <= max; ++i) { resampleQuality->addItem(prefs->getPropertyValueLabel("Resample Quality", i)); } resampleQuality->setCurrentIndex(rsq); connect(resampleQuality, SIGNAL(currentIndexChanged(int)), this, SLOT(resampleQualityChanged(int))); QCheckBox *resampleOnLoad = new QCheckBox; m_resampleOnLoad = prefs->getResampleOnLoad(); resampleOnLoad->setCheckState(m_resampleOnLoad ? Qt::Checked : Qt::Unchecked); connect(resampleOnLoad, SIGNAL(stateChanged(int)), this, SLOT(resampleOnLoadChanged(int))); m_tempDirRootEdit = new QLineEdit; QString dir = prefs->getTemporaryDirectoryRoot(); m_tempDirRoot = dir; dir.replace("$HOME", tr("<home directory>")); m_tempDirRootEdit->setText(dir); m_tempDirRootEdit->setReadOnly(true); QPushButton *tempDirButton = new QPushButton; tempDirButton->setIcon(IconLoader().load("fileopen")); connect(tempDirButton, SIGNAL(clicked()), this, SLOT(tempDirButtonClicked())); tempDirButton->setFixedSize(QSize(24, 24)); QCheckBox *showSplash = new QCheckBox; m_showSplash = prefs->getShowSplash(); showSplash->setCheckState(m_showSplash ? Qt::Checked : Qt::Unchecked); connect(showSplash, SIGNAL(stateChanged(int)), this, SLOT(showSplashChanged(int))); #ifndef Q_OS_MAC QComboBox *bgMode = new QComboBox; int bg = prefs->getPropertyRangeAndValue("Background Mode", &min, &max, &deflt); m_backgroundMode = bg; for (i = min; i <= max; ++i) { bgMode->addItem(prefs->getPropertyValueLabel("Background Mode", i)); } bgMode->setCurrentIndex(bg); connect(bgMode, SIGNAL(currentIndexChanged(int)), this, SLOT(backgroundModeChanged(int))); #endif settings.beginGroup("Preferences"); QString userLocale = settings.value("locale", "").toString(); m_currentLocale = userLocale; QString permishTag = QString("network-permission-%1").arg(SV_VERSION); m_networkPermission = settings.value(permishTag, false).toBool(); settings.endGroup(); QComboBox *locale = new QComboBox; QStringList localeFiles = QDir(":i18n").entryList(QStringList() << "*.qm"); locale->addItem(tr("Follow system locale")); m_locales.push_back(""); if (userLocale == "") { locale->setCurrentIndex(0); } foreach (QString f, localeFiles) { QString f0 = f; f.replace("sonic-visualiser_", "").replace(".qm", ""); if (f == f0) { // our expectations about filename format were not met cerr << "INFO: Unexpected filename " << f << " in i18n resource directory" << endl; } else { m_locales.push_back(f); QString displayText; // Add new translations here if (f == "ru") displayText = tr("Russian"); else if (f == "en_GB") displayText = tr("British English"); else if (f == "en_US") displayText = tr("American English"); else if (f == "cs_CZ") displayText = tr("Czech"); else displayText = f; locale->addItem(QString("%1 [%2]").arg(displayText).arg(f)); if (userLocale == f) { locale->setCurrentIndex(locale->count() - 1); } } } connect(locale, SIGNAL(currentIndexChanged(int)), this, SLOT(localeChanged(int))); QCheckBox *networkPermish = new QCheckBox; networkPermish->setCheckState(m_networkPermission ? Qt::Checked : Qt::Unchecked); connect(networkPermish, SIGNAL(stateChanged(int)), this, SLOT(networkPermissionChanged(int))); QSpinBox *fontSize = new QSpinBox; int fs = prefs->getPropertyRangeAndValue("View Font Size", &min, &max, &deflt); m_viewFontSize = fs; fontSize->setMinimum(min); fontSize->setMaximum(max); fontSize->setSuffix(" pt"); fontSize->setSingleStep(1); fontSize->setValue(fs); connect(fontSize, SIGNAL(valueChanged(int)), this, SLOT(viewFontSizeChanged(int))); QComboBox *ttMode = new QComboBox; int tt = prefs->getPropertyRangeAndValue("Time To Text Mode", &min, &max, &deflt); m_timeToTextMode = tt; for (i = min; i <= max; ++i) { ttMode->addItem(prefs->getPropertyValueLabel("Time To Text Mode", i)); } ttMode->setCurrentIndex(tt); connect(ttMode, SIGNAL(currentIndexChanged(int)), this, SLOT(timeToTextModeChanged(int))); QCheckBox *hms = new QCheckBox; int showHMS = prefs->getPropertyRangeAndValue ("Show Hours And Minutes", &min, &max, &deflt); m_showHMS = (showHMS != 0); hms->setCheckState(m_showHMS ? Qt::Checked : Qt::Unchecked); connect(hms, SIGNAL(stateChanged(int)), this, SLOT(showHMSChanged(int))); // General tab QFrame *frame = new QFrame; QGridLayout *subgrid = new QGridLayout; frame->setLayout(subgrid); int row = 0; subgrid->addWidget(new QLabel(tr("%1:").arg(tr("User interface language"))), row, 0); subgrid->addWidget(locale, row++, 1, 1, 1); subgrid->addWidget(new QLabel(tr("%1:").arg(tr("Allow network usage"))), row, 0); subgrid->addWidget(networkPermish, row++, 1, 1, 1); subgrid->addWidget(new QLabel(tr("%1:").arg(prefs->getPropertyLabel ("Temporary Directory Root"))), row, 0); subgrid->addWidget(m_tempDirRootEdit, row, 1, 1, 1); subgrid->addWidget(tempDirButton, row, 2, 1, 1); row++; subgrid->addWidget(new QLabel(tr("%1:").arg(prefs->getPropertyLabel ("Resample On Load"))), row, 0); subgrid->addWidget(resampleOnLoad, row++, 1, 1, 1); subgrid->addWidget(new QLabel(tr("Playback audio device:")), row, 0); subgrid->addWidget(audioDevice, row++, 1, 1, 2); subgrid->addWidget(new QLabel(tr("%1:").arg(prefs->getPropertyLabel ("Resample Quality"))), row, 0); subgrid->addWidget(resampleQuality, row++, 1, 1, 2); subgrid->setRowStretch(row, 10); m_tabOrdering[GeneralTab] = m_tabs->count(); m_tabs->addTab(frame, tr("&General")); // Appearance tab frame = new QFrame; subgrid = new QGridLayout; frame->setLayout(subgrid); row = 0; subgrid->addWidget(new QLabel(tr("%1:").arg(prefs->getPropertyLabel ("Show Splash Screen"))), row, 0); subgrid->addWidget(showSplash, row++, 1, 1, 1); subgrid->addWidget(new QLabel(tr("%1:").arg(prefs->getPropertyLabel ("Property Box Layout"))), row, 0); subgrid->addWidget(propertyLayout, row++, 1, 1, 2); #ifndef Q_OS_MAC subgrid->addWidget(new QLabel(tr("%1:").arg(prefs->getPropertyLabel ("Background Mode"))), row, 0); subgrid->addWidget(bgMode, row++, 1, 1, 2); #endif subgrid->addWidget(new QLabel(tr("%1:").arg(prefs->getPropertyLabel ("View Font Size"))), row, 0); subgrid->addWidget(fontSize, row++, 1, 1, 2); subgrid->addWidget(new QLabel(tr("%1:").arg(prefs->getPropertyLabel ("Time To Text Mode"))), row, 0); subgrid->addWidget(ttMode, row++, 1, 1, 2); subgrid->addWidget(new QLabel(tr("%1:").arg(prefs->getPropertyLabel ("Show Hours And Minutes"))), row, 0); subgrid->addWidget(hms, row++, 1, 1, 1); subgrid->setRowStretch(row, 10); m_tabOrdering[AppearanceTab] = m_tabs->count(); m_tabs->addTab(frame, tr("&Appearance")); // Analysis tab frame = new QFrame; subgrid = new QGridLayout; frame->setLayout(subgrid); row = 0; subgrid->addWidget(new QLabel(tr("%1:").arg(prefs->getPropertyLabel ("Tuning Frequency"))), row, 0); subgrid->addWidget(frequency, row++, 1, 1, 2); subgrid->addWidget(new QLabel(tr("%1:").arg(prefs->getPropertyLabel ("Octave Numbering System"))), row, 0); subgrid->addWidget(octaveSystem, row++, 1, 1, 2); subgrid->addWidget(new QLabel(prefs->getPropertyLabel ("Spectrogram Y Smoothing")), row, 0); subgrid->addWidget(smoothing, row++, 1, 1, 2); subgrid->addWidget(new QLabel(prefs->getPropertyLabel ("Spectrogram X Smoothing")), row, 0); subgrid->addWidget(xsmoothing, row++, 1, 1, 2); subgrid->addWidget(new QLabel(tr("%1:").arg(prefs->getPropertyLabel ("Window Type"))), row, 0); subgrid->addWidget(m_windowTypeSelector, row++, 1, 2, 2); subgrid->setRowStretch(row, 10); row++; subgrid->setRowStretch(row, 10); m_tabOrdering[AnalysisTab] = m_tabs->count(); m_tabs->addTab(frame, tr("Anal&ysis")); // Template tab frame = new QFrame; subgrid = new QGridLayout; frame->setLayout(subgrid); row = 0; subgrid->addWidget(new QLabel(tr("Default session template for audio files:")), row++, 0); QListWidget *lw = new QListWidget(); subgrid->addWidget(lw, row, 0); subgrid->setRowStretch(row, 10); row++; settings.beginGroup("MainWindow"); m_currentTemplate = settings.value("sessiontemplate", "").toString(); settings.endGroup(); lw->addItem(tr("Standard Waveform")); if (m_currentTemplate == "" || m_currentTemplate == "default") { lw->setCurrentRow(lw->count()-1); } m_templates.push_back(""); QStringList templates = ResourceFinder().getResourceFiles("templates", "svt"); std::set<QString> byName; foreach (QString t, templates) { byName.insert(QFileInfo(t).baseName()); } foreach (QString t, byName) { if (t.toLower() == "default") continue; m_templates.push_back(t); lw->addItem(t); if (m_currentTemplate == t) { lw->setCurrentRow(lw->count()-1); } } connect(lw, SIGNAL(currentRowChanged(int)), this, SLOT(defaultTemplateChanged(int))); m_tabOrdering[TemplateTab] = m_tabs->count(); m_tabs->addTab(frame, tr("Session &Template")); QDialogButtonBox *bb = new QDialogButtonBox(Qt::Horizontal); grid->addWidget(bb, 1, 0); QPushButton *ok = new QPushButton(tr("OK")); QPushButton *cancel = new QPushButton(tr("Cancel")); bb->addButton(ok, QDialogButtonBox::AcceptRole); bb->addButton(m_applyButton, QDialogButtonBox::ApplyRole); bb->addButton(cancel, QDialogButtonBox::RejectRole); connect(ok, SIGNAL(clicked()), this, SLOT(okClicked())); connect(m_applyButton, SIGNAL(clicked()), this, SLOT(applyClicked())); connect(cancel, SIGNAL(clicked()), this, SLOT(cancelClicked())); m_applyButton->setEnabled(false); } PreferencesDialog::~PreferencesDialog() { SVDEBUG << "PreferencesDialog::~PreferencesDialog()" << endl; } void PreferencesDialog::switchToTab(Tab t) { if (m_tabOrdering.contains(t)) { m_tabs->setCurrentIndex(m_tabOrdering[t]); } } void PreferencesDialog::windowTypeChanged(WindowType type) { m_windowType = type; m_applyButton->setEnabled(true); } void PreferencesDialog::spectrogramSmoothingChanged(int smoothing) { m_spectrogramSmoothing = smoothing; m_applyButton->setEnabled(true); } void PreferencesDialog::spectrogramXSmoothingChanged(int smoothing) { m_spectrogramXSmoothing = smoothing; m_applyButton->setEnabled(true); } void PreferencesDialog::propertyLayoutChanged(int layout) { m_propertyLayout = layout; m_applyButton->setEnabled(true); } void PreferencesDialog::tuningFrequencyChanged(double freq) { m_tuningFrequency = freq; m_applyButton->setEnabled(true); } void PreferencesDialog::audioDeviceChanged(int s) { m_audioDevice = s; m_applyButton->setEnabled(true); m_changesOnRestart = true; } void PreferencesDialog::resampleQualityChanged(int q) { m_resampleQuality = q; m_applyButton->setEnabled(true); } void PreferencesDialog::resampleOnLoadChanged(int state) { m_resampleOnLoad = (state == Qt::Checked); m_applyButton->setEnabled(true); m_changesOnRestart = true; } void PreferencesDialog::networkPermissionChanged(int state) { m_networkPermission = (state == Qt::Checked); m_applyButton->setEnabled(true); m_changesOnRestart = true; } void PreferencesDialog::showSplashChanged(int state) { m_showSplash = (state == Qt::Checked); m_applyButton->setEnabled(true); m_changesOnRestart = true; } void PreferencesDialog::defaultTemplateChanged(int i) { m_currentTemplate = m_templates[i]; m_applyButton->setEnabled(true); } void PreferencesDialog::localeChanged(int i) { m_currentLocale = m_locales[i]; m_applyButton->setEnabled(true); m_changesOnRestart = true; } void PreferencesDialog::tempDirRootChanged(QString r) { m_tempDirRoot = r; m_applyButton->setEnabled(true); } void PreferencesDialog::tempDirButtonClicked() { QString dir = QFileDialog::getExistingDirectory (this, tr("Select a directory to create cache subdirectory in"), m_tempDirRoot); if (dir == "") return; m_tempDirRootEdit->setText(dir); tempDirRootChanged(dir); m_changesOnRestart = true; } void PreferencesDialog::backgroundModeChanged(int mode) { m_backgroundMode = mode; m_applyButton->setEnabled(true); m_changesOnRestart = true; } void PreferencesDialog::timeToTextModeChanged(int mode) { m_timeToTextMode = mode; m_applyButton->setEnabled(true); } void PreferencesDialog::showHMSChanged(int state) { m_showHMS = (state == Qt::Checked); m_applyButton->setEnabled(true); } void PreferencesDialog::octaveSystemChanged(int system) { m_octaveSystem = system; m_applyButton->setEnabled(true); } void PreferencesDialog::viewFontSizeChanged(int sz) { m_viewFontSize = sz; m_applyButton->setEnabled(true); } void PreferencesDialog::okClicked() { applyClicked(); accept(); } void PreferencesDialog::applyClicked() { Preferences *prefs = Preferences::getInstance(); prefs->setWindowType(WindowType(m_windowType)); prefs->setSpectrogramSmoothing(Preferences::SpectrogramSmoothing (m_spectrogramSmoothing)); prefs->setSpectrogramXSmoothing(Preferences::SpectrogramXSmoothing (m_spectrogramXSmoothing)); prefs->setPropertyBoxLayout(Preferences::PropertyBoxLayout (m_propertyLayout)); prefs->setTuningFrequency(m_tuningFrequency); prefs->setResampleQuality(m_resampleQuality); prefs->setResampleOnLoad(m_resampleOnLoad); prefs->setShowSplash(m_showSplash); prefs->setTemporaryDirectoryRoot(m_tempDirRoot); prefs->setBackgroundMode(Preferences::BackgroundMode(m_backgroundMode)); prefs->setTimeToTextMode(Preferences::TimeToTextMode(m_timeToTextMode)); prefs->setShowHMS(m_showHMS); prefs->setViewFontSize(m_viewFontSize); prefs->setProperty("Octave Numbering System", m_octaveSystem); std::vector<QString> devices = AudioTargetFactory::getInstance()->getCallbackTargetNames(); QSettings settings; settings.beginGroup("Preferences"); QString permishTag = QString("network-permission-%1").arg(SV_VERSION); settings.setValue(permishTag, m_networkPermission); settings.setValue("audio-target", devices[m_audioDevice]); settings.setValue("locale", m_currentLocale); settings.endGroup(); settings.beginGroup("MainWindow"); settings.setValue("sessiontemplate", m_currentTemplate); settings.endGroup(); m_applyButton->setEnabled(false); if (m_changesOnRestart) { QMessageBox::information(this, tr("Preferences"), 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>")); m_changesOnRestart = false; } } void PreferencesDialog::cancelClicked() { reject(); } void PreferencesDialog::applicationClosing(bool quickly) { if (quickly) { reject(); return; } if (m_applyButton->isEnabled()) { int rv = QMessageBox::warning (this, tr("Preferences Changed"), tr("Some preferences have been changed but not applied.\n" "Apply them before closing?"), QMessageBox::Apply | QMessageBox::Discard, QMessageBox::Discard); if (rv == QMessageBox::Apply) { applyClicked(); accept(); } else { reject(); } } else { accept(); } }