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@0: Chris@9: #include "widgets/WindowTypeSelector.h" Chris@180: #include "widgets/IconLoader.h" Chris@0: #include "base/Preferences.h" Chris@0: Chris@0: PreferencesDialog::PreferencesDialog(QWidget *parent, Qt::WFlags flags) : Chris@180: QDialog(parent, flags), 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@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@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@180: Chris@225: QSpinBox *fontSize = new QSpinBox; Chris@225: int fs = prefs->getPropertyRangeAndValue("View Font Size", &min, &max, Chris@225: &deflt); 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@0: ("Property Box Layout"))), Chris@0: row, 0); Chris@0: subgrid->addWidget(propertyLayout, row++, 1, 1, 2); Chris@0: 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@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@180: ("Resample On Load"))), Chris@180: row, 0); Chris@180: subgrid->addWidget(resampleOnLoad, row++, 1, 1, 1); Chris@0: Chris@32: subgrid->addWidget(new QLabel(tr("%1:").arg(prefs->getPropertyLabel Chris@32: ("Resample Quality"))), Chris@32: row, 0); Chris@32: subgrid->addWidget(resampleQuality, row++, 1, 1, 2); Chris@32: Chris@180: subgrid->addWidget(new QLabel(tr("%1:").arg(prefs->getPropertyLabel Chris@180: ("Temporary Directory Root"))), Chris@180: row, 0); Chris@180: subgrid->addWidget(m_tempDirRootEdit, row, 1, 1, 1); Chris@180: subgrid->addWidget(tempDirButton, row, 2, 1, 1); Chris@180: row++; Chris@180: Chris@180: subgrid->setRowStretch(row, 10); Chris@180: Chris@180: tab->addTab(frame, tr("&General")); 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@180: tab->addTab(frame, tr("&Analysis")); 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@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@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@180: prefs->setTemporaryDirectoryRoot(m_tempDirRoot); Chris@180: prefs->setBackgroundMode(Preferences::BackgroundMode(m_backgroundMode)); Chris@225: prefs->setViewFontSize(m_viewFontSize); Chris@180: Chris@0: m_applyButton->setEnabled(false); Chris@180: Chris@180: if (m_changesOnRestart) { Chris@180: QMessageBox::information(this, tr("Preferences"), Chris@180: tr("One or more of the application preferences you have changed may not take full effect until Sonic Visualiser is restarted.\nPlease 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: