Chris@136: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@136: Chris@136: /* Chris@136: Sonic Visualiser Chris@136: An audio file viewer and annotation editor. Chris@136: Centre for Digital Music, Queen Mary, University of London. Chris@202: This file copyright 2006 Chris Cannam and QMUL. Chris@136: Chris@136: This program is free software; you can redistribute it and/or Chris@136: modify it under the terms of the GNU General Public License as Chris@136: published by the Free Software Foundation; either version 2 of the Chris@136: License, or (at your option) any later version. See the file Chris@136: COPYING included with this distribution for more information. Chris@136: */ Chris@136: Chris@136: #include "Preferences.h" Chris@136: Chris@145: #include "Exceptions.h" Chris@145: Chris@145: #include "TempDirectory.h" Chris@145: Chris@145: #include Chris@145: #include Chris@156: #include Chris@156: #include Chris@354: #include Chris@354: #include Chris@145: Chris@136: Preferences * Chris@156: Preferences::m_instance = 0; Chris@156: Chris@156: Preferences * Chris@156: Preferences::getInstance() Chris@156: { Chris@156: if (!m_instance) m_instance = new Preferences(); Chris@156: return m_instance; Chris@156: } Chris@136: Chris@136: Preferences::Preferences() : Chris@246: m_spectrogramSmoothing(SpectrogramZeroPadded), Chris@140: m_tuningFrequency(440), Chris@140: m_propertyBoxLayout(VerticallyStacked), Chris@164: m_windowType(HanningWindow), Chris@277: m_resampleQuality(1), Chris@297: m_omitRecentTemps(true), Chris@297: m_tempDirRoot(""), Chris@354: m_resampleOnLoad(false), Chris@354: m_viewFontSize(10), Chris@354: m_backgroundMode(BackgroundFromTheme) Chris@136: { Chris@156: QSettings settings; Chris@156: settings.beginGroup("Preferences"); Chris@246: m_spectrogramSmoothing = SpectrogramSmoothing Chris@246: (settings.value("spectrogram-smoothing", int(m_spectrogramSmoothing)).toInt()); Chris@156: m_tuningFrequency = settings.value("tuning-frequency", 440.f).toDouble(); Chris@145: m_propertyBoxLayout = PropertyBoxLayout Chris@156: (settings.value("property-box-layout", int(VerticallyStacked)).toInt()); Chris@145: m_windowType = WindowType Chris@156: (settings.value("window-type", int(HanningWindow)).toInt()); Chris@164: m_resampleQuality = settings.value("resample-quality", 1).toInt(); Chris@304: m_resampleOnLoad = settings.value("resample-on-load", false).toBool(); Chris@297: m_backgroundMode = BackgroundMode Chris@297: (settings.value("background-mode", int(BackgroundFromTheme)).toInt()); Chris@354: m_viewFontSize = settings.value Chris@354: ("view-font-size", QApplication::font().pointSize() * 0.9).toInt(); Chris@297: settings.endGroup(); Chris@297: Chris@297: settings.beginGroup("TempDirectory"); Chris@297: m_tempDirRoot = settings.value("create-in", "$HOME").toString(); Chris@156: settings.endGroup(); Chris@145: } Chris@145: Chris@145: Preferences::~Preferences() Chris@145: { Chris@136: } Chris@136: Chris@136: Preferences::PropertyList Chris@136: Preferences::getProperties() const Chris@136: { Chris@136: PropertyList props; Chris@246: props.push_back("Spectrogram Smoothing"); Chris@136: props.push_back("Tuning Frequency"); Chris@138: props.push_back("Property Box Layout"); Chris@140: props.push_back("Window Type"); Chris@164: props.push_back("Resample Quality"); Chris@277: props.push_back("Omit Temporaries from Recent Files"); Chris@297: props.push_back("Resample On Load"); Chris@297: props.push_back("Temporary Directory Root"); Chris@297: props.push_back("Background Mode"); Chris@354: props.push_back("View Font Size"); Chris@136: return props; Chris@136: } Chris@136: Chris@136: QString Chris@136: Preferences::getPropertyLabel(const PropertyName &name) const Chris@136: { Chris@246: if (name == "Spectrogram Smoothing") { Chris@246: return tr("Spectrogram y-axis smoothing:"); Chris@136: } Chris@136: if (name == "Tuning Frequency") { Chris@141: return tr("Frequency of concert A"); Chris@136: } Chris@138: if (name == "Property Box Layout") { Chris@141: return tr("Property box layout"); Chris@138: } Chris@140: if (name == "Window Type") { Chris@141: return tr("Spectral analysis window shape"); Chris@140: } Chris@164: if (name == "Resample Quality") { Chris@165: return tr("Playback resampler type"); Chris@164: } Chris@277: if (name == "Omit Temporaries from Recent Files") { Chris@297: return tr("Omit temporaries from Recent Files menu"); Chris@297: } Chris@297: if (name == "Resample On Load") { Chris@297: return tr("Resample mismatching files on import"); Chris@297: } Chris@297: if (name == "Temporary Directory Root") { Chris@297: return tr("Location for cache file directory"); Chris@297: } Chris@297: if (name == "Background Mode") { Chris@297: return tr("Background colour preference"); Chris@277: } Chris@354: if (name == "View Font Size") { Chris@354: return tr("Font size for text overlays"); Chris@354: } Chris@136: return name; Chris@136: } Chris@136: Chris@136: Preferences::PropertyType Chris@136: Preferences::getPropertyType(const PropertyName &name) const Chris@136: { Chris@246: if (name == "Spectrogram Smoothing") { Chris@246: return ValueProperty; Chris@136: } Chris@136: if (name == "Tuning Frequency") { Chris@136: return RangeProperty; Chris@136: } Chris@138: if (name == "Property Box Layout") { Chris@138: return ValueProperty; Chris@138: } Chris@140: if (name == "Window Type") { Chris@140: return ValueProperty; Chris@140: } Chris@164: if (name == "Resample Quality") { Chris@164: return ValueProperty; Chris@164: } Chris@277: if (name == "Omit Temporaries from Recent Files") { Chris@277: return ToggleProperty; Chris@277: } Chris@297: if (name == "Resample On Load") { Chris@297: return ToggleProperty; Chris@297: } Chris@297: if (name == "Temporary Directory Root") { Chris@297: // It's an arbitrary string, we don't have a set of values for this Chris@297: return InvalidProperty; Chris@297: } Chris@297: if (name == "Background Mode") { Chris@297: return ValueProperty; Chris@297: } Chris@354: if (name == "View Font Size") { Chris@354: return RangeProperty; Chris@354: } Chris@136: return InvalidProperty; Chris@136: } Chris@136: Chris@136: int Chris@136: Preferences::getPropertyRangeAndValue(const PropertyName &name, Chris@245: int *min, int *max, int *deflt) const Chris@136: { Chris@246: if (name == "Spectrogram Smoothing") { Chris@136: if (min) *min = 0; Chris@246: if (max) *max = 2; Chris@246: if (deflt) *deflt = int(SpectrogramZeroPadded); Chris@246: return int(m_spectrogramSmoothing); Chris@136: } Chris@136: Chris@136: //!!! freq mapping Chris@136: Chris@138: if (name == "Property Box Layout") { Chris@138: if (min) *min = 0; Chris@138: if (max) *max = 1; Chris@245: if (deflt) *deflt = 0; Chris@138: return m_propertyBoxLayout == Layered ? 1 : 0; Chris@138: } Chris@138: Chris@140: if (name == "Window Type") { Chris@140: if (min) *min = int(RectangularWindow); Chris@142: if (max) *max = int(BlackmanHarrisWindow); Chris@245: if (deflt) *deflt = int(HanningWindow); Chris@140: return int(m_windowType); Chris@140: } Chris@140: Chris@164: if (name == "Resample Quality") { Chris@164: if (min) *min = 0; Chris@164: if (max) *max = 2; Chris@245: if (deflt) *deflt = 1; Chris@164: return m_resampleQuality; Chris@164: } Chris@164: Chris@277: if (name == "Omit Temporaries from Recent Files") { Chris@277: if (deflt) *deflt = 1; Chris@277: } Chris@277: Chris@297: if (name == "Background Mode") { Chris@297: if (min) *min = 0; Chris@297: if (max) *max = 2; Chris@297: if (deflt) *deflt = 0; Chris@297: return int(m_backgroundMode); Chris@297: } Chris@297: Chris@354: if (name == "View Font Size") { Chris@354: if (min) *min = 3; Chris@354: if (max) *max = 48; Chris@354: if (deflt) *deflt = int(QApplication::font().pointSize() * 0.9); Chris@354: return int(m_viewFontSize); Chris@354: } Chris@354: Chris@136: return 0; Chris@136: } Chris@136: Chris@136: QString Chris@136: Preferences::getPropertyValueLabel(const PropertyName &name, Chris@136: int value) const Chris@136: { Chris@138: if (name == "Property Box Layout") { Chris@141: if (value == 0) return tr("Show boxes for all panes"); Chris@141: else return tr("Show box for current pane only"); Chris@138: } Chris@140: if (name == "Window Type") { Chris@140: switch (WindowType(value)) { Chris@140: case RectangularWindow: return tr("Rectangular"); Chris@141: case BartlettWindow: return tr("Triangular"); Chris@140: case HammingWindow: return tr("Hamming"); Chris@140: case HanningWindow: return tr("Hanning"); Chris@140: case BlackmanWindow: return tr("Blackman"); Chris@140: case GaussianWindow: return tr("Gaussian"); Chris@140: case ParzenWindow: return tr("Parzen"); Chris@142: case NuttallWindow: return tr("Nuttall"); Chris@142: case BlackmanHarrisWindow: return tr("Blackman-Harris"); Chris@140: } Chris@140: } Chris@164: if (name == "Resample Quality") { Chris@164: switch (value) { Chris@164: case 0: return tr("Fastest"); Chris@165: case 1: return tr("Standard"); Chris@164: case 2: return tr("Highest quality"); Chris@164: } Chris@164: } Chris@246: if (name == "Spectrogram Smoothing") { Chris@246: switch (value) { Chris@246: case NoSpectrogramSmoothing: return tr("None - blocky but accurate"); Chris@246: case SpectrogramInterpolated: return tr("Interpolate - fast but fuzzy"); Chris@246: case SpectrogramZeroPadded: return tr("Zero pad FFT - slow but clear"); Chris@246: } Chris@246: } Chris@297: if (name == "Background Mode") { Chris@297: switch (value) { Chris@297: case BackgroundFromTheme: return tr("Follow desktop theme"); Chris@297: case DarkBackground: return tr("Dark background"); Chris@297: case LightBackground: return tr("Light background"); Chris@297: } Chris@297: } Chris@246: Chris@136: return ""; Chris@136: } Chris@136: Chris@136: QString Chris@136: Preferences::getPropertyContainerName() const Chris@136: { Chris@136: return tr("Preferences"); Chris@136: } Chris@136: Chris@136: QString Chris@136: Preferences::getPropertyContainerIconName() const Chris@136: { Chris@136: return "preferences"; Chris@136: } Chris@136: Chris@136: void Chris@136: Preferences::setProperty(const PropertyName &name, int value) Chris@136: { Chris@246: if (name == "Spectrogram Smoothing") { Chris@246: setSpectrogramSmoothing(SpectrogramSmoothing(value)); Chris@136: } else if (name == "Tuning Frequency") { Chris@136: //!!! Chris@138: } else if (name == "Property Box Layout") { Chris@138: setPropertyBoxLayout(value == 0 ? VerticallyStacked : Layered); Chris@140: } else if (name == "Window Type") { Chris@140: setWindowType(WindowType(value)); Chris@164: } else if (name == "Resample Quality") { Chris@164: setResampleQuality(value); Chris@277: } else if (name == "Omit Temporaries from Recent Files") { Chris@277: setOmitTempsFromRecentFiles(value ? true : false); Chris@297: } else if (name == "Background Mode") { Chris@297: setBackgroundMode(BackgroundMode(value)); Chris@354: } else if (name == "View Font Size") { Chris@354: setViewFontSize(value); Chris@136: } Chris@136: } Chris@136: Chris@136: void Chris@246: Preferences::setSpectrogramSmoothing(SpectrogramSmoothing smoothing) Chris@136: { Chris@246: if (m_spectrogramSmoothing != smoothing) { Chris@246: Chris@246: // "smoothing" is one of those words that looks increasingly Chris@246: // ridiculous the more you see it. Smoothing smoothing smoothing. Chris@246: m_spectrogramSmoothing = smoothing; Chris@246: Chris@156: QSettings settings; Chris@156: settings.beginGroup("Preferences"); Chris@246: settings.setValue("spectrogram-smoothing", int(smoothing)); Chris@156: settings.endGroup(); Chris@246: emit propertyChanged("Spectrogram Smoothing"); Chris@138: } Chris@136: } Chris@136: Chris@136: void Chris@136: Preferences::setTuningFrequency(float freq) Chris@136: { Chris@138: if (m_tuningFrequency != freq) { Chris@138: m_tuningFrequency = freq; Chris@156: QSettings settings; Chris@156: settings.beginGroup("Preferences"); Chris@156: settings.setValue("tuning-frequency", freq); Chris@156: settings.endGroup(); Chris@141: emit propertyChanged("Tuning Frequency"); Chris@138: } Chris@136: } Chris@136: Chris@138: void Chris@138: Preferences::setPropertyBoxLayout(PropertyBoxLayout layout) Chris@138: { Chris@138: if (m_propertyBoxLayout != layout) { Chris@138: m_propertyBoxLayout = layout; Chris@156: QSettings settings; Chris@156: settings.beginGroup("Preferences"); Chris@156: settings.setValue("property-box-layout", int(layout)); Chris@156: settings.endGroup(); Chris@141: emit propertyChanged("Property Box Layout"); Chris@138: } Chris@138: } Chris@138: Chris@140: void Chris@140: Preferences::setWindowType(WindowType type) Chris@140: { Chris@140: if (m_windowType != type) { Chris@140: m_windowType = type; Chris@156: QSettings settings; Chris@156: settings.beginGroup("Preferences"); Chris@156: settings.setValue("window-type", int(type)); Chris@156: settings.endGroup(); Chris@141: emit propertyChanged("Window Type"); Chris@140: } Chris@140: } Chris@140: Chris@164: void Chris@164: Preferences::setResampleQuality(int q) Chris@164: { Chris@164: if (m_resampleQuality != q) { Chris@164: m_resampleQuality = q; Chris@164: QSettings settings; Chris@164: settings.beginGroup("Preferences"); Chris@164: settings.setValue("resample-quality", q); Chris@164: settings.endGroup(); Chris@164: emit propertyChanged("Resample Quality"); Chris@164: } Chris@164: } Chris@277: Chris@277: void Chris@277: Preferences::setOmitTempsFromRecentFiles(bool omit) Chris@277: { Chris@277: if (m_omitRecentTemps != omit) { Chris@277: m_omitRecentTemps = omit; Chris@277: QSettings settings; Chris@277: settings.beginGroup("Preferences"); Chris@277: settings.setValue("omit-recent-temporaries", omit); Chris@277: settings.endGroup(); Chris@277: emit propertyChanged("Omit Temporaries from Recent Files"); Chris@277: } Chris@277: } Chris@297: Chris@297: void Chris@297: Preferences::setTemporaryDirectoryRoot(QString root) Chris@297: { Chris@297: if (root == QDir::home().absolutePath()) { Chris@297: root = "$HOME"; Chris@297: } Chris@297: if (m_tempDirRoot != root) { Chris@297: m_tempDirRoot = root; Chris@297: QSettings settings; Chris@297: settings.beginGroup("TempDirectory"); Chris@297: settings.setValue("create-in", root); Chris@297: settings.endGroup(); Chris@297: emit propertyChanged("Temporary Directory Root"); Chris@297: } Chris@297: } Chris@297: Chris@297: void Chris@297: Preferences::setResampleOnLoad(bool resample) Chris@297: { Chris@297: if (m_resampleOnLoad != resample) { Chris@297: m_resampleOnLoad = resample; Chris@297: QSettings settings; Chris@297: settings.beginGroup("Preferences"); Chris@297: settings.setValue("resample-on-load", resample); Chris@297: settings.endGroup(); Chris@297: emit propertyChanged("Resample On Load"); Chris@297: } Chris@297: } Chris@297: Chris@297: void Chris@297: Preferences::setBackgroundMode(BackgroundMode mode) Chris@297: { Chris@297: if (m_backgroundMode != mode) { Chris@297: Chris@297: m_backgroundMode = mode; Chris@297: Chris@297: QSettings settings; Chris@297: settings.beginGroup("Preferences"); Chris@297: settings.setValue("background-mode", int(mode)); Chris@297: settings.endGroup(); Chris@297: emit propertyChanged("Background Mode"); Chris@297: } Chris@297: } Chris@297: Chris@354: void Chris@354: Preferences::setViewFontSize(int size) Chris@354: { Chris@354: if (m_viewFontSize != size) { Chris@297: Chris@354: m_viewFontSize = size; Chris@354: Chris@354: QSettings settings; Chris@354: settings.beginGroup("Preferences"); Chris@354: settings.setValue("view-font-size", size); Chris@354: settings.endGroup(); Chris@354: emit propertyChanged("View Font Size"); Chris@354: } Chris@354: } Chris@354: