Chris@0: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@0: Chris@0: /* Chris@0: Sonic Visualiser Chris@0: An audio file viewer and annotation editor. Chris@0: Centre for Digital Music, Queen Mary, University of London. Chris@0: This file copyright 2006 Chris Cannam. Chris@0: Chris@0: This program is free software; you can redistribute it and/or Chris@0: modify it under the terms of the GNU General Public License as Chris@0: published by the Free Software Foundation; either version 2 of the Chris@0: License, or (at your option) any later version. See the file Chris@0: COPYING included with this distribution for more information. Chris@0: */ Chris@0: Chris@0: #include "PreferencesDialog.h" Chris@0: Chris@0: #include Chris@0: #include Chris@0: #include Chris@0: #include Chris@0: #include Chris@0: #include Chris@0: #include Chris@0: #include Chris@0: #include Chris@163: #include Chris@163: #include Chris@180: #include Chris@180: #include Chris@180: #include Chris@180: #include Chris@225: #include Chris@263: #include Chris@0: Chris@9: #include "widgets/WindowTypeSelector.h" Chris@180: #include "widgets/IconLoader.h" Chris@0: #include "base/Preferences.h" Chris@263: #include "audioio/AudioTargetFactory.h" Chris@0: Chris@0: PreferencesDialog::PreferencesDialog(QWidget *parent, Qt::WFlags flags) : Chris@180: QDialog(parent, flags), Chris@263: m_audioDevice(0), Chris@180: m_changesOnRestart(false) Chris@0: { Chris@163: setWindowTitle(tr("Sonic Visualiser: Application Preferences")); Chris@0: Chris@0: Preferences *prefs = Preferences::getInstance(); Chris@0: Chris@0: QGridLayout *grid = new QGridLayout; Chris@0: setLayout(grid); Chris@180: Chris@180: QTabWidget *tab = new QTabWidget; Chris@180: grid->addWidget(tab, 0, 0); Chris@0: Chris@180: tab->setTabPosition(QTabWidget::North); Chris@0: Chris@0: // Create this first, as slots that get called from the ctor will Chris@0: // refer to it Chris@0: m_applyButton = new QPushButton(tr("Apply")); Chris@0: Chris@180: // Create all the preference widgets first, then create the Chris@180: // individual tab widgets and place the preferences in their Chris@180: // appropriate places in one go afterwards Chris@180: Chris@114: int min, max, deflt, i; Chris@0: Chris@9: m_windowType = WindowType(prefs->getPropertyRangeAndValue Chris@114: ("Window Type", &min, &max, &deflt)); Chris@9: m_windowTypeSelector = new WindowTypeSelector(m_windowType); Chris@0: Chris@9: connect(m_windowTypeSelector, SIGNAL(windowTypeChanged(WindowType)), Chris@9: this, SLOT(windowTypeChanged(WindowType))); Chris@0: Chris@115: QComboBox *smoothing = new QComboBox; Chris@115: Chris@115: int sm = prefs->getPropertyRangeAndValue("Spectrogram Smoothing", &min, &max, Chris@115: &deflt); Chris@115: m_spectrogramSmoothing = sm; Chris@0: Chris@115: for (i = min; i <= max; ++i) { Chris@115: smoothing->addItem(prefs->getPropertyValueLabel("Spectrogram Smoothing", i)); Chris@115: } Chris@115: Chris@115: smoothing->setCurrentIndex(sm); Chris@115: Chris@115: connect(smoothing, SIGNAL(currentIndexChanged(int)), Chris@115: this, SLOT(spectrogramSmoothingChanged(int))); Chris@0: Chris@0: QComboBox *propertyLayout = new QComboBox; Chris@114: int pl = prefs->getPropertyRangeAndValue("Property Box Layout", &min, &max, Chris@115: &deflt); Chris@0: m_propertyLayout = pl; Chris@0: Chris@0: for (i = min; i <= max; ++i) { Chris@0: propertyLayout->addItem(prefs->getPropertyValueLabel("Property Box Layout", i)); Chris@0: } Chris@0: Chris@0: propertyLayout->setCurrentIndex(pl); Chris@0: Chris@0: connect(propertyLayout, SIGNAL(currentIndexChanged(int)), Chris@0: this, SLOT(propertyLayoutChanged(int))); Chris@0: Chris@0: m_tuningFrequency = prefs->getTuningFrequency(); Chris@0: Chris@0: QDoubleSpinBox *frequency = new QDoubleSpinBox; Chris@0: frequency->setMinimum(100.0); Chris@0: frequency->setMaximum(5000.0); Chris@0: frequency->setSuffix(" Hz"); Chris@0: frequency->setSingleStep(1); Chris@0: frequency->setValue(m_tuningFrequency); Chris@0: frequency->setDecimals(2); Chris@0: Chris@0: connect(frequency, SIGNAL(valueChanged(double)), Chris@0: this, SLOT(tuningFrequencyChanged(double))); Chris@0: Chris@263: QComboBox *audioDevice = new QComboBox; Chris@263: std::vector devices = Chris@263: AudioTargetFactory::getInstance()->getCallbackTargetNames(); Chris@263: Chris@263: QSettings settings; Chris@263: settings.beginGroup("Preferences"); Chris@263: QString targetName = settings.value("audio-target", "").toString(); Chris@263: settings.endGroup(); Chris@263: Chris@263: for (int i = 0; i < devices.size(); ++i) { Chris@263: audioDevice->addItem(AudioTargetFactory::getInstance() Chris@263: ->getCallbackTargetDescription(devices[i])); Chris@263: if (targetName == devices[i]) audioDevice->setCurrentIndex(i); Chris@263: } Chris@263: Chris@263: connect(audioDevice, SIGNAL(currentIndexChanged(int)), Chris@263: this, SLOT(audioDeviceChanged(int))); Chris@263: Chris@32: QComboBox *resampleQuality = new QComboBox; Chris@32: Chris@114: int rsq = prefs->getPropertyRangeAndValue("Resample Quality", &min, &max, Chris@114: &deflt); Chris@32: m_resampleQuality = rsq; Chris@32: Chris@32: for (i = min; i <= max; ++i) { Chris@32: resampleQuality->addItem(prefs->getPropertyValueLabel("Resample Quality", i)); Chris@32: } Chris@32: Chris@32: resampleQuality->setCurrentIndex(rsq); Chris@32: Chris@32: connect(resampleQuality, SIGNAL(currentIndexChanged(int)), Chris@32: this, SLOT(resampleQualityChanged(int))); Chris@32: Chris@180: QCheckBox *resampleOnLoad = new QCheckBox; Chris@180: m_resampleOnLoad = prefs->getResampleOnLoad(); Chris@180: resampleOnLoad->setCheckState(m_resampleOnLoad ? Qt::Checked : Chris@180: Qt::Unchecked); Chris@180: connect(resampleOnLoad, SIGNAL(stateChanged(int)), Chris@180: this, SLOT(resampleOnLoadChanged(int))); Chris@180: Chris@180: m_tempDirRootEdit = new QLineEdit; Chris@180: QString dir = prefs->getTemporaryDirectoryRoot(); Chris@180: m_tempDirRoot = dir; Chris@180: dir.replace("$HOME", tr("")); Chris@180: m_tempDirRootEdit->setText(dir); Chris@180: m_tempDirRootEdit->setReadOnly(true); Chris@180: QPushButton *tempDirButton = new QPushButton; Chris@180: tempDirButton->setIcon(IconLoader().load("fileopen")); Chris@180: connect(tempDirButton, SIGNAL(clicked()), Chris@180: this, SLOT(tempDirButtonClicked())); Chris@180: tempDirButton->setFixedSize(QSize(24, 24)); Chris@180: Chris@237: QCheckBox *showSplash = new QCheckBox; Chris@237: m_showSplash = prefs->getShowSplash(); Chris@237: showSplash->setCheckState(m_showSplash ? Qt::Checked : Qt::Unchecked); Chris@237: connect(showSplash, SIGNAL(stateChanged(int)), Chris@237: this, SLOT(showSplashChanged(int))); Chris@237: Chris@237: #ifndef Q_WS_MAC Chris@180: QComboBox *bgMode = new QComboBox; Chris@180: int bg = prefs->getPropertyRangeAndValue("Background Mode", &min, &max, Chris@180: &deflt); Chris@180: m_backgroundMode = bg; Chris@180: for (i = min; i <= max; ++i) { Chris@180: bgMode->addItem(prefs->getPropertyValueLabel("Background Mode", i)); Chris@180: } Chris@180: bgMode->setCurrentIndex(bg); Chris@180: Chris@180: connect(bgMode, SIGNAL(currentIndexChanged(int)), Chris@180: this, SLOT(backgroundModeChanged(int))); Chris@237: #endif Chris@180: Chris@225: QSpinBox *fontSize = new QSpinBox; Chris@225: int fs = prefs->getPropertyRangeAndValue("View Font Size", &min, &max, Chris@225: &deflt); Chris@234: m_viewFontSize = fs; Chris@225: fontSize->setMinimum(min); Chris@225: fontSize->setMaximum(max); Chris@225: fontSize->setSuffix(" pt"); Chris@225: fontSize->setSingleStep(1); Chris@225: fontSize->setValue(fs); Chris@225: Chris@225: connect(fontSize, SIGNAL(valueChanged(int)), Chris@225: this, SLOT(viewFontSizeChanged(int))); Chris@225: Chris@180: // General tab Chris@180: Chris@180: QFrame *frame = new QFrame; Chris@180: Chris@180: QGridLayout *subgrid = new QGridLayout; Chris@180: frame->setLayout(subgrid); Chris@180: Chris@0: int row = 0; Chris@0: Chris@0: subgrid->addWidget(new QLabel(tr("%1:").arg(prefs->getPropertyLabel Chris@263: ("Temporary Directory Root"))), Chris@263: row, 0); Chris@263: subgrid->addWidget(m_tempDirRootEdit, row, 1, 1, 1); Chris@263: subgrid->addWidget(tempDirButton, row, 2, 1, 1); Chris@263: row++; Chris@263: Chris@263: subgrid->addWidget(new QLabel(tr("%1:").arg(prefs->getPropertyLabel Chris@263: ("Resample On Load"))), Chris@263: row, 0); Chris@263: subgrid->addWidget(resampleOnLoad, row++, 1, 1, 1); Chris@263: Chris@263: subgrid->addWidget(new QLabel(tr("Playback audio device:")), row, 0); Chris@263: subgrid->addWidget(audioDevice, row++, 1, 1, 2); Chris@263: Chris@263: subgrid->addWidget(new QLabel(tr("%1:").arg(prefs->getPropertyLabel Chris@263: ("Resample Quality"))), Chris@263: row, 0); Chris@263: subgrid->addWidget(resampleQuality, row++, 1, 1, 2); Chris@263: Chris@263: subgrid->setRowStretch(row, 10); Chris@263: Chris@263: tab->addTab(frame, tr("&General")); Chris@263: Chris@263: // Appearance tab Chris@263: Chris@263: frame = new QFrame; Chris@263: subgrid = new QGridLayout; Chris@263: frame->setLayout(subgrid); Chris@263: row = 0; Chris@263: Chris@263: subgrid->addWidget(new QLabel(tr("%1:").arg(prefs->getPropertyLabel Chris@0: ("Property Box Layout"))), Chris@0: row, 0); Chris@0: subgrid->addWidget(propertyLayout, row++, 1, 1, 2); Chris@0: Chris@242: #ifndef Q_WS_MAC Chris@0: subgrid->addWidget(new QLabel(tr("%1:").arg(prefs->getPropertyLabel Chris@180: ("Background Mode"))), Chris@0: row, 0); Chris@180: subgrid->addWidget(bgMode, row++, 1, 1, 2); Chris@242: #endif Chris@180: Chris@180: subgrid->addWidget(new QLabel(tr("%1:").arg(prefs->getPropertyLabel Chris@225: ("View Font Size"))), Chris@225: row, 0); Chris@225: subgrid->addWidget(fontSize, row++, 1, 1, 2); Chris@225: Chris@225: subgrid->addWidget(new QLabel(tr("%1:").arg(prefs->getPropertyLabel Chris@237: ("Show Splash Screen"))), Chris@237: row, 0); Chris@237: subgrid->addWidget(showSplash, row++, 1, 1, 1); Chris@237: Chris@180: subgrid->setRowStretch(row, 10); Chris@180: Chris@263: tab->addTab(frame, tr("&Appearance")); Chris@180: Chris@180: // Analysis tab Chris@180: Chris@180: frame = new QFrame; Chris@180: subgrid = new QGridLayout; Chris@180: frame->setLayout(subgrid); Chris@180: row = 0; Chris@180: Chris@180: subgrid->addWidget(new QLabel(tr("%1:").arg(prefs->getPropertyLabel Chris@180: ("Tuning Frequency"))), Chris@180: row, 0); Chris@180: subgrid->addWidget(frequency, row++, 1, 1, 2); Chris@180: Chris@0: subgrid->addWidget(new QLabel(prefs->getPropertyLabel Chris@115: ("Spectrogram Smoothing")), Chris@115: row, 0); Chris@115: subgrid->addWidget(smoothing, row++, 1, 1, 2); Chris@0: Chris@0: subgrid->addWidget(new QLabel(tr("%1:").arg(prefs->getPropertyLabel Chris@0: ("Window Type"))), Chris@0: row, 0); Chris@9: subgrid->addWidget(m_windowTypeSelector, row++, 1, 2, 2); Chris@9: subgrid->setRowStretch(row, 10); Chris@9: row++; Chris@0: Chris@180: subgrid->setRowStretch(row, 10); Chris@180: Chris@263: tab->addTab(frame, tr("Anal&ysis")); Chris@180: Chris@163: QDialogButtonBox *bb = new QDialogButtonBox(Qt::Horizontal); Chris@163: grid->addWidget(bb, 1, 0); Chris@0: Chris@0: QPushButton *ok = new QPushButton(tr("OK")); Chris@0: QPushButton *cancel = new QPushButton(tr("Cancel")); Chris@163: bb->addButton(ok, QDialogButtonBox::AcceptRole); Chris@163: bb->addButton(m_applyButton, QDialogButtonBox::ApplyRole); Chris@163: bb->addButton(cancel, QDialogButtonBox::RejectRole); Chris@0: connect(ok, SIGNAL(clicked()), this, SLOT(okClicked())); Chris@0: connect(m_applyButton, SIGNAL(clicked()), this, SLOT(applyClicked())); Chris@0: connect(cancel, SIGNAL(clicked()), this, SLOT(cancelClicked())); Chris@0: Chris@0: m_applyButton->setEnabled(false); Chris@0: } Chris@0: Chris@0: PreferencesDialog::~PreferencesDialog() Chris@0: { Chris@0: std::cerr << "PreferencesDialog::~PreferencesDialog()" << std::endl; Chris@0: } Chris@0: Chris@0: void Chris@9: PreferencesDialog::windowTypeChanged(WindowType type) Chris@0: { Chris@0: m_windowType = type; Chris@0: m_applyButton->setEnabled(true); Chris@0: } Chris@0: Chris@0: void Chris@115: PreferencesDialog::spectrogramSmoothingChanged(int smoothing) Chris@0: { Chris@115: m_spectrogramSmoothing = smoothing; Chris@0: m_applyButton->setEnabled(true); Chris@0: } Chris@0: Chris@0: void Chris@0: PreferencesDialog::propertyLayoutChanged(int layout) Chris@0: { Chris@0: m_propertyLayout = layout; Chris@0: m_applyButton->setEnabled(true); Chris@0: } Chris@0: Chris@0: void Chris@0: PreferencesDialog::tuningFrequencyChanged(double freq) Chris@0: { Chris@0: m_tuningFrequency = freq; Chris@0: m_applyButton->setEnabled(true); Chris@0: } Chris@0: Chris@0: void Chris@263: PreferencesDialog::audioDeviceChanged(int s) Chris@263: { Chris@263: m_audioDevice = s; Chris@263: m_applyButton->setEnabled(true); Chris@263: m_changesOnRestart = true; Chris@263: } Chris@263: Chris@263: void Chris@32: PreferencesDialog::resampleQualityChanged(int q) Chris@32: { Chris@32: m_resampleQuality = q; Chris@32: m_applyButton->setEnabled(true); Chris@32: } Chris@32: Chris@32: void Chris@180: PreferencesDialog::resampleOnLoadChanged(int state) Chris@180: { Chris@180: m_resampleOnLoad = (state == Qt::Checked); Chris@180: m_applyButton->setEnabled(true); Chris@180: m_changesOnRestart = true; Chris@180: } Chris@180: Chris@180: void Chris@237: PreferencesDialog::showSplashChanged(int state) Chris@237: { Chris@237: m_showSplash = (state == Qt::Checked); Chris@237: m_applyButton->setEnabled(true); Chris@237: m_changesOnRestart = true; Chris@237: } Chris@237: Chris@237: void Chris@180: PreferencesDialog::tempDirRootChanged(QString r) Chris@180: { Chris@180: m_tempDirRoot = r; Chris@180: m_applyButton->setEnabled(true); Chris@180: } Chris@180: Chris@180: void Chris@180: PreferencesDialog::tempDirButtonClicked() Chris@180: { Chris@180: QString dir = QFileDialog::getExistingDirectory Chris@180: (this, tr("Select a directory to create cache subdirectory in"), Chris@180: m_tempDirRoot); Chris@180: if (dir == "") return; Chris@180: m_tempDirRootEdit->setText(dir); Chris@180: tempDirRootChanged(dir); Chris@180: m_changesOnRestart = true; Chris@180: } Chris@180: Chris@180: void Chris@180: PreferencesDialog::backgroundModeChanged(int mode) Chris@180: { Chris@180: m_backgroundMode = mode; Chris@180: m_applyButton->setEnabled(true); Chris@180: m_changesOnRestart = true; Chris@180: } Chris@180: Chris@180: void Chris@225: PreferencesDialog::viewFontSizeChanged(int sz) Chris@225: { Chris@225: m_viewFontSize = sz; Chris@225: m_applyButton->setEnabled(true); Chris@225: } Chris@225: Chris@225: void Chris@0: PreferencesDialog::okClicked() Chris@0: { Chris@0: applyClicked(); Chris@0: accept(); Chris@0: } Chris@0: Chris@0: void Chris@0: PreferencesDialog::applyClicked() Chris@0: { Chris@0: Preferences *prefs = Preferences::getInstance(); Chris@0: prefs->setWindowType(WindowType(m_windowType)); Chris@115: prefs->setSpectrogramSmoothing(Preferences::SpectrogramSmoothing Chris@115: (m_spectrogramSmoothing)); Chris@0: prefs->setPropertyBoxLayout(Preferences::PropertyBoxLayout Chris@0: (m_propertyLayout)); Chris@0: prefs->setTuningFrequency(m_tuningFrequency); Chris@32: prefs->setResampleQuality(m_resampleQuality); Chris@180: prefs->setResampleOnLoad(m_resampleOnLoad); Chris@237: prefs->setShowSplash(m_showSplash); Chris@180: prefs->setTemporaryDirectoryRoot(m_tempDirRoot); Chris@180: prefs->setBackgroundMode(Preferences::BackgroundMode(m_backgroundMode)); Chris@225: prefs->setViewFontSize(m_viewFontSize); Chris@263: Chris@263: std::vector devices = Chris@263: AudioTargetFactory::getInstance()->getCallbackTargetNames(); Chris@263: Chris@263: QSettings settings; Chris@263: settings.beginGroup("Preferences"); Chris@263: settings.setValue("audio-target", devices[m_audioDevice]); Chris@263: settings.endGroup(); Chris@180: Chris@0: m_applyButton->setEnabled(false); Chris@180: Chris@180: if (m_changesOnRestart) { Chris@180: QMessageBox::information(this, tr("Preferences"), Chris@255: tr("Restart required

One or more of the application preferences you have changed may not take full effect until Sonic Visualiser is restarted.

Please exit and restart the application now if you want these changes to take effect immediately.

")); Chris@180: m_changesOnRestart = false; Chris@180: } Chris@0: } Chris@0: Chris@0: void Chris@0: PreferencesDialog::cancelClicked() Chris@0: { Chris@0: reject(); Chris@0: } Chris@0: Chris@163: void Chris@163: PreferencesDialog::applicationClosing(bool quickly) Chris@163: { Chris@163: if (quickly) { Chris@163: reject(); Chris@163: return; Chris@163: } Chris@163: Chris@163: if (m_applyButton->isEnabled()) { Chris@163: int rv = QMessageBox::warning Chris@163: (this, tr("Preferences Changed"), Chris@163: tr("Some preferences have been changed but not applied.\n" Chris@163: "Apply them before closing?"), Chris@163: QMessageBox::Apply | QMessageBox::Discard, Chris@163: QMessageBox::Discard); Chris@163: if (rv == QMessageBox::Apply) { Chris@163: applyClicked(); Chris@163: accept(); Chris@163: } else { Chris@163: reject(); Chris@163: } Chris@163: } else { Chris@163: accept(); Chris@163: } Chris@163: } Chris@163: