annotate base/Preferences.cpp @ 458:f60360209e5c

* Fix race condition in FFTFileCache when reading from the same FFT model from multiple threads (e.g. when applying more than one plugin at once)
author Chris Cannam
date Wed, 15 Oct 2008 12:08:02 +0000
parents 7aa1de571880
children 98077b21a9e1
rev   line source
Chris@136 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@136 2
Chris@136 3 /*
Chris@136 4 Sonic Visualiser
Chris@136 5 An audio file viewer and annotation editor.
Chris@136 6 Centre for Digital Music, Queen Mary, University of London.
Chris@202 7 This file copyright 2006 Chris Cannam and QMUL.
Chris@136 8
Chris@136 9 This program is free software; you can redistribute it and/or
Chris@136 10 modify it under the terms of the GNU General Public License as
Chris@136 11 published by the Free Software Foundation; either version 2 of the
Chris@136 12 License, or (at your option) any later version. See the file
Chris@136 13 COPYING included with this distribution for more information.
Chris@136 14 */
Chris@136 15
Chris@136 16 #include "Preferences.h"
Chris@136 17
Chris@145 18 #include "Exceptions.h"
Chris@145 19
Chris@145 20 #include "TempDirectory.h"
Chris@145 21
Chris@145 22 #include <QDir>
Chris@145 23 #include <QFileInfo>
Chris@156 24 #include <QMutex>
Chris@156 25 #include <QSettings>
Chris@145 26
Chris@136 27 Preferences *
Chris@156 28 Preferences::m_instance = 0;
Chris@156 29
Chris@156 30 Preferences *
Chris@156 31 Preferences::getInstance()
Chris@156 32 {
Chris@156 33 if (!m_instance) m_instance = new Preferences();
Chris@156 34 return m_instance;
Chris@156 35 }
Chris@136 36
Chris@136 37 Preferences::Preferences() :
Chris@246 38 m_spectrogramSmoothing(SpectrogramZeroPadded),
Chris@140 39 m_tuningFrequency(440),
Chris@140 40 m_propertyBoxLayout(VerticallyStacked),
Chris@164 41 m_windowType(HanningWindow),
Chris@277 42 m_resampleQuality(1),
Chris@297 43 m_omitRecentTemps(true),
Chris@297 44 m_tempDirRoot(""),
Chris@354 45 m_resampleOnLoad(false),
Chris@354 46 m_viewFontSize(10),
Chris@372 47 m_backgroundMode(BackgroundFromTheme),
Chris@372 48 m_showSplash(true)
Chris@136 49 {
Chris@156 50 QSettings settings;
Chris@156 51 settings.beginGroup("Preferences");
Chris@246 52 m_spectrogramSmoothing = SpectrogramSmoothing
Chris@246 53 (settings.value("spectrogram-smoothing", int(m_spectrogramSmoothing)).toInt());
Chris@156 54 m_tuningFrequency = settings.value("tuning-frequency", 440.f).toDouble();
Chris@145 55 m_propertyBoxLayout = PropertyBoxLayout
Chris@156 56 (settings.value("property-box-layout", int(VerticallyStacked)).toInt());
Chris@145 57 m_windowType = WindowType
Chris@156 58 (settings.value("window-type", int(HanningWindow)).toInt());
Chris@164 59 m_resampleQuality = settings.value("resample-quality", 1).toInt();
Chris@304 60 m_resampleOnLoad = settings.value("resample-on-load", false).toBool();
Chris@297 61 m_backgroundMode = BackgroundMode
Chris@297 62 (settings.value("background-mode", int(BackgroundFromTheme)).toInt());
Chris@387 63 m_viewFontSize = settings.value("view-font-size", 10).toInt();
Chris@372 64 m_showSplash = settings.value("show-splash", true).toBool();
Chris@297 65 settings.endGroup();
Chris@297 66
Chris@297 67 settings.beginGroup("TempDirectory");
Chris@297 68 m_tempDirRoot = settings.value("create-in", "$HOME").toString();
Chris@156 69 settings.endGroup();
Chris@145 70 }
Chris@145 71
Chris@145 72 Preferences::~Preferences()
Chris@145 73 {
Chris@136 74 }
Chris@136 75
Chris@136 76 Preferences::PropertyList
Chris@136 77 Preferences::getProperties() const
Chris@136 78 {
Chris@136 79 PropertyList props;
Chris@246 80 props.push_back("Spectrogram Smoothing");
Chris@136 81 props.push_back("Tuning Frequency");
Chris@138 82 props.push_back("Property Box Layout");
Chris@140 83 props.push_back("Window Type");
Chris@164 84 props.push_back("Resample Quality");
Chris@277 85 props.push_back("Omit Temporaries from Recent Files");
Chris@297 86 props.push_back("Resample On Load");
Chris@297 87 props.push_back("Temporary Directory Root");
Chris@297 88 props.push_back("Background Mode");
Chris@354 89 props.push_back("View Font Size");
Chris@372 90 props.push_back("Show Splash Screen");
Chris@136 91 return props;
Chris@136 92 }
Chris@136 93
Chris@136 94 QString
Chris@136 95 Preferences::getPropertyLabel(const PropertyName &name) const
Chris@136 96 {
Chris@246 97 if (name == "Spectrogram Smoothing") {
Chris@372 98 return tr("Spectrogram y-axis interpolation:");
Chris@136 99 }
Chris@136 100 if (name == "Tuning Frequency") {
Chris@141 101 return tr("Frequency of concert A");
Chris@136 102 }
Chris@138 103 if (name == "Property Box Layout") {
Chris@141 104 return tr("Property box layout");
Chris@138 105 }
Chris@140 106 if (name == "Window Type") {
Chris@141 107 return tr("Spectral analysis window shape");
Chris@140 108 }
Chris@164 109 if (name == "Resample Quality") {
Chris@165 110 return tr("Playback resampler type");
Chris@164 111 }
Chris@277 112 if (name == "Omit Temporaries from Recent Files") {
Chris@297 113 return tr("Omit temporaries from Recent Files menu");
Chris@297 114 }
Chris@297 115 if (name == "Resample On Load") {
Chris@297 116 return tr("Resample mismatching files on import");
Chris@297 117 }
Chris@297 118 if (name == "Temporary Directory Root") {
Chris@297 119 return tr("Location for cache file directory");
Chris@297 120 }
Chris@297 121 if (name == "Background Mode") {
Chris@297 122 return tr("Background colour preference");
Chris@277 123 }
Chris@354 124 if (name == "View Font Size") {
Chris@354 125 return tr("Font size for text overlays");
Chris@354 126 }
Chris@372 127 if (name == "Show Splash Screen") {
Chris@372 128 return tr("Show splash screen on startup");
Chris@372 129 }
Chris@136 130 return name;
Chris@136 131 }
Chris@136 132
Chris@136 133 Preferences::PropertyType
Chris@136 134 Preferences::getPropertyType(const PropertyName &name) const
Chris@136 135 {
Chris@246 136 if (name == "Spectrogram Smoothing") {
Chris@246 137 return ValueProperty;
Chris@136 138 }
Chris@136 139 if (name == "Tuning Frequency") {
Chris@136 140 return RangeProperty;
Chris@136 141 }
Chris@138 142 if (name == "Property Box Layout") {
Chris@138 143 return ValueProperty;
Chris@138 144 }
Chris@140 145 if (name == "Window Type") {
Chris@140 146 return ValueProperty;
Chris@140 147 }
Chris@164 148 if (name == "Resample Quality") {
Chris@164 149 return ValueProperty;
Chris@164 150 }
Chris@277 151 if (name == "Omit Temporaries from Recent Files") {
Chris@277 152 return ToggleProperty;
Chris@277 153 }
Chris@297 154 if (name == "Resample On Load") {
Chris@297 155 return ToggleProperty;
Chris@297 156 }
Chris@297 157 if (name == "Temporary Directory Root") {
Chris@297 158 // It's an arbitrary string, we don't have a set of values for this
Chris@297 159 return InvalidProperty;
Chris@297 160 }
Chris@297 161 if (name == "Background Mode") {
Chris@297 162 return ValueProperty;
Chris@297 163 }
Chris@354 164 if (name == "View Font Size") {
Chris@354 165 return RangeProperty;
Chris@354 166 }
Chris@372 167 if (name == "Show Splash Screen") {
Chris@372 168 return ToggleProperty;
Chris@372 169 }
Chris@136 170 return InvalidProperty;
Chris@136 171 }
Chris@136 172
Chris@136 173 int
Chris@136 174 Preferences::getPropertyRangeAndValue(const PropertyName &name,
Chris@245 175 int *min, int *max, int *deflt) const
Chris@136 176 {
Chris@246 177 if (name == "Spectrogram Smoothing") {
Chris@136 178 if (min) *min = 0;
Chris@246 179 if (max) *max = 2;
Chris@246 180 if (deflt) *deflt = int(SpectrogramZeroPadded);
Chris@246 181 return int(m_spectrogramSmoothing);
Chris@136 182 }
Chris@136 183
Chris@136 184 //!!! freq mapping
Chris@136 185
Chris@138 186 if (name == "Property Box Layout") {
Chris@138 187 if (min) *min = 0;
Chris@138 188 if (max) *max = 1;
Chris@245 189 if (deflt) *deflt = 0;
Chris@138 190 return m_propertyBoxLayout == Layered ? 1 : 0;
Chris@138 191 }
Chris@138 192
Chris@140 193 if (name == "Window Type") {
Chris@140 194 if (min) *min = int(RectangularWindow);
Chris@142 195 if (max) *max = int(BlackmanHarrisWindow);
Chris@245 196 if (deflt) *deflt = int(HanningWindow);
Chris@140 197 return int(m_windowType);
Chris@140 198 }
Chris@140 199
Chris@164 200 if (name == "Resample Quality") {
Chris@164 201 if (min) *min = 0;
Chris@164 202 if (max) *max = 2;
Chris@245 203 if (deflt) *deflt = 1;
Chris@164 204 return m_resampleQuality;
Chris@164 205 }
Chris@164 206
Chris@277 207 if (name == "Omit Temporaries from Recent Files") {
Chris@277 208 if (deflt) *deflt = 1;
Chris@277 209 }
Chris@277 210
Chris@297 211 if (name == "Background Mode") {
Chris@297 212 if (min) *min = 0;
Chris@297 213 if (max) *max = 2;
Chris@297 214 if (deflt) *deflt = 0;
Chris@297 215 return int(m_backgroundMode);
Chris@297 216 }
Chris@297 217
Chris@354 218 if (name == "View Font Size") {
Chris@354 219 if (min) *min = 3;
Chris@354 220 if (max) *max = 48;
Chris@387 221 if (deflt) *deflt = 10;
Chris@354 222 return int(m_viewFontSize);
Chris@354 223 }
Chris@354 224
Chris@372 225 if (name == "Show Splash Screen") {
Chris@372 226 if (deflt) *deflt = 1;
Chris@372 227 }
Chris@372 228
Chris@136 229 return 0;
Chris@136 230 }
Chris@136 231
Chris@136 232 QString
Chris@136 233 Preferences::getPropertyValueLabel(const PropertyName &name,
Chris@136 234 int value) const
Chris@136 235 {
Chris@138 236 if (name == "Property Box Layout") {
Chris@141 237 if (value == 0) return tr("Show boxes for all panes");
Chris@141 238 else return tr("Show box for current pane only");
Chris@138 239 }
Chris@140 240 if (name == "Window Type") {
Chris@140 241 switch (WindowType(value)) {
Chris@140 242 case RectangularWindow: return tr("Rectangular");
Chris@141 243 case BartlettWindow: return tr("Triangular");
Chris@140 244 case HammingWindow: return tr("Hamming");
Chris@381 245 case HanningWindow: return tr("Hann");
Chris@140 246 case BlackmanWindow: return tr("Blackman");
Chris@140 247 case GaussianWindow: return tr("Gaussian");
Chris@140 248 case ParzenWindow: return tr("Parzen");
Chris@142 249 case NuttallWindow: return tr("Nuttall");
Chris@142 250 case BlackmanHarrisWindow: return tr("Blackman-Harris");
Chris@140 251 }
Chris@140 252 }
Chris@164 253 if (name == "Resample Quality") {
Chris@164 254 switch (value) {
Chris@164 255 case 0: return tr("Fastest");
Chris@165 256 case 1: return tr("Standard");
Chris@164 257 case 2: return tr("Highest quality");
Chris@164 258 }
Chris@164 259 }
Chris@246 260 if (name == "Spectrogram Smoothing") {
Chris@246 261 switch (value) {
Chris@246 262 case NoSpectrogramSmoothing: return tr("None - blocky but accurate");
Chris@372 263 case SpectrogramInterpolated: return tr("Linear - fast but fuzzy");
Chris@372 264 case SpectrogramZeroPadded: return tr("4 x Oversampled - slow but clear");
Chris@246 265 }
Chris@246 266 }
Chris@297 267 if (name == "Background Mode") {
Chris@297 268 switch (value) {
Chris@297 269 case BackgroundFromTheme: return tr("Follow desktop theme");
Chris@297 270 case DarkBackground: return tr("Dark background");
Chris@297 271 case LightBackground: return tr("Light background");
Chris@297 272 }
Chris@297 273 }
Chris@246 274
Chris@136 275 return "";
Chris@136 276 }
Chris@136 277
Chris@136 278 QString
Chris@136 279 Preferences::getPropertyContainerName() const
Chris@136 280 {
Chris@136 281 return tr("Preferences");
Chris@136 282 }
Chris@136 283
Chris@136 284 QString
Chris@136 285 Preferences::getPropertyContainerIconName() const
Chris@136 286 {
Chris@136 287 return "preferences";
Chris@136 288 }
Chris@136 289
Chris@136 290 void
Chris@136 291 Preferences::setProperty(const PropertyName &name, int value)
Chris@136 292 {
Chris@246 293 if (name == "Spectrogram Smoothing") {
Chris@246 294 setSpectrogramSmoothing(SpectrogramSmoothing(value));
Chris@136 295 } else if (name == "Tuning Frequency") {
Chris@136 296 //!!!
Chris@138 297 } else if (name == "Property Box Layout") {
Chris@138 298 setPropertyBoxLayout(value == 0 ? VerticallyStacked : Layered);
Chris@140 299 } else if (name == "Window Type") {
Chris@140 300 setWindowType(WindowType(value));
Chris@164 301 } else if (name == "Resample Quality") {
Chris@164 302 setResampleQuality(value);
Chris@277 303 } else if (name == "Omit Temporaries from Recent Files") {
Chris@277 304 setOmitTempsFromRecentFiles(value ? true : false);
Chris@297 305 } else if (name == "Background Mode") {
Chris@297 306 setBackgroundMode(BackgroundMode(value));
Chris@354 307 } else if (name == "View Font Size") {
Chris@354 308 setViewFontSize(value);
Chris@372 309 } else if (name == "Show Splash Screen") {
Chris@372 310 setShowSplash(value ? true : false);
Chris@136 311 }
Chris@136 312 }
Chris@136 313
Chris@136 314 void
Chris@246 315 Preferences::setSpectrogramSmoothing(SpectrogramSmoothing smoothing)
Chris@136 316 {
Chris@246 317 if (m_spectrogramSmoothing != smoothing) {
Chris@246 318
Chris@246 319 // "smoothing" is one of those words that looks increasingly
Chris@246 320 // ridiculous the more you see it. Smoothing smoothing smoothing.
Chris@246 321 m_spectrogramSmoothing = smoothing;
Chris@246 322
Chris@156 323 QSettings settings;
Chris@156 324 settings.beginGroup("Preferences");
Chris@246 325 settings.setValue("spectrogram-smoothing", int(smoothing));
Chris@156 326 settings.endGroup();
Chris@246 327 emit propertyChanged("Spectrogram Smoothing");
Chris@138 328 }
Chris@136 329 }
Chris@136 330
Chris@136 331 void
Chris@136 332 Preferences::setTuningFrequency(float freq)
Chris@136 333 {
Chris@138 334 if (m_tuningFrequency != freq) {
Chris@138 335 m_tuningFrequency = freq;
Chris@156 336 QSettings settings;
Chris@156 337 settings.beginGroup("Preferences");
Chris@156 338 settings.setValue("tuning-frequency", freq);
Chris@156 339 settings.endGroup();
Chris@141 340 emit propertyChanged("Tuning Frequency");
Chris@138 341 }
Chris@136 342 }
Chris@136 343
Chris@138 344 void
Chris@138 345 Preferences::setPropertyBoxLayout(PropertyBoxLayout layout)
Chris@138 346 {
Chris@138 347 if (m_propertyBoxLayout != layout) {
Chris@138 348 m_propertyBoxLayout = layout;
Chris@156 349 QSettings settings;
Chris@156 350 settings.beginGroup("Preferences");
Chris@156 351 settings.setValue("property-box-layout", int(layout));
Chris@156 352 settings.endGroup();
Chris@141 353 emit propertyChanged("Property Box Layout");
Chris@138 354 }
Chris@138 355 }
Chris@138 356
Chris@140 357 void
Chris@140 358 Preferences::setWindowType(WindowType type)
Chris@140 359 {
Chris@140 360 if (m_windowType != type) {
Chris@140 361 m_windowType = type;
Chris@156 362 QSettings settings;
Chris@156 363 settings.beginGroup("Preferences");
Chris@156 364 settings.setValue("window-type", int(type));
Chris@156 365 settings.endGroup();
Chris@141 366 emit propertyChanged("Window Type");
Chris@140 367 }
Chris@140 368 }
Chris@140 369
Chris@164 370 void
Chris@164 371 Preferences::setResampleQuality(int q)
Chris@164 372 {
Chris@164 373 if (m_resampleQuality != q) {
Chris@164 374 m_resampleQuality = q;
Chris@164 375 QSettings settings;
Chris@164 376 settings.beginGroup("Preferences");
Chris@164 377 settings.setValue("resample-quality", q);
Chris@164 378 settings.endGroup();
Chris@164 379 emit propertyChanged("Resample Quality");
Chris@164 380 }
Chris@164 381 }
Chris@277 382
Chris@277 383 void
Chris@277 384 Preferences::setOmitTempsFromRecentFiles(bool omit)
Chris@277 385 {
Chris@277 386 if (m_omitRecentTemps != omit) {
Chris@277 387 m_omitRecentTemps = omit;
Chris@277 388 QSettings settings;
Chris@277 389 settings.beginGroup("Preferences");
Chris@277 390 settings.setValue("omit-recent-temporaries", omit);
Chris@277 391 settings.endGroup();
Chris@277 392 emit propertyChanged("Omit Temporaries from Recent Files");
Chris@277 393 }
Chris@277 394 }
Chris@297 395
Chris@297 396 void
Chris@297 397 Preferences::setTemporaryDirectoryRoot(QString root)
Chris@297 398 {
Chris@297 399 if (root == QDir::home().absolutePath()) {
Chris@297 400 root = "$HOME";
Chris@297 401 }
Chris@297 402 if (m_tempDirRoot != root) {
Chris@297 403 m_tempDirRoot = root;
Chris@297 404 QSettings settings;
Chris@297 405 settings.beginGroup("TempDirectory");
Chris@297 406 settings.setValue("create-in", root);
Chris@297 407 settings.endGroup();
Chris@297 408 emit propertyChanged("Temporary Directory Root");
Chris@297 409 }
Chris@297 410 }
Chris@297 411
Chris@297 412 void
Chris@297 413 Preferences::setResampleOnLoad(bool resample)
Chris@297 414 {
Chris@297 415 if (m_resampleOnLoad != resample) {
Chris@297 416 m_resampleOnLoad = resample;
Chris@297 417 QSettings settings;
Chris@297 418 settings.beginGroup("Preferences");
Chris@297 419 settings.setValue("resample-on-load", resample);
Chris@297 420 settings.endGroup();
Chris@297 421 emit propertyChanged("Resample On Load");
Chris@297 422 }
Chris@297 423 }
Chris@297 424
Chris@297 425 void
Chris@297 426 Preferences::setBackgroundMode(BackgroundMode mode)
Chris@297 427 {
Chris@297 428 if (m_backgroundMode != mode) {
Chris@297 429
Chris@297 430 m_backgroundMode = mode;
Chris@297 431
Chris@297 432 QSettings settings;
Chris@297 433 settings.beginGroup("Preferences");
Chris@297 434 settings.setValue("background-mode", int(mode));
Chris@297 435 settings.endGroup();
Chris@297 436 emit propertyChanged("Background Mode");
Chris@297 437 }
Chris@297 438 }
Chris@297 439
Chris@354 440 void
Chris@354 441 Preferences::setViewFontSize(int size)
Chris@354 442 {
Chris@354 443 if (m_viewFontSize != size) {
Chris@297 444
Chris@354 445 m_viewFontSize = size;
Chris@354 446
Chris@354 447 QSettings settings;
Chris@354 448 settings.beginGroup("Preferences");
Chris@354 449 settings.setValue("view-font-size", size);
Chris@354 450 settings.endGroup();
Chris@354 451 emit propertyChanged("View Font Size");
Chris@354 452 }
Chris@354 453 }
Chris@354 454
Chris@372 455 void
Chris@372 456 Preferences::setShowSplash(bool show)
Chris@372 457 {
Chris@372 458 if (m_showSplash != show) {
Chris@372 459
Chris@372 460 m_showSplash = show;
Chris@372 461
Chris@372 462 QSettings settings;
Chris@372 463 settings.beginGroup("Preferences");
Chris@372 464 settings.setValue("show-splash", show);
Chris@372 465 settings.endGroup();
Chris@372 466 emit propertyChanged("Show Splash Screen");
Chris@372 467 }
Chris@372 468 }
Chris@372 469