annotate base/Preferences.cpp @ 569:9773aadbae0c

* Handle zero-velocity note ons as well as note offs (can't believe I fell for that one) * Add Peek Left / Peek Right (alt+left/right) and change peek-drag (i.e. dragging without moving playback pointer or other panes) from ctrl+drag to alt+drag for symmetry
author Chris Cannam
date Thu, 26 Feb 2009 10:49:08 +0000
parents 98077b21a9e1
children 75f154085a4d
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@553 38 m_spectrogramSmoothing(SpectrogramInterpolated),
Chris@553 39 m_spectrogramXSmoothing(SpectrogramXInterpolated),
Chris@140 40 m_tuningFrequency(440),
Chris@140 41 m_propertyBoxLayout(VerticallyStacked),
Chris@164 42 m_windowType(HanningWindow),
Chris@277 43 m_resampleQuality(1),
Chris@297 44 m_omitRecentTemps(true),
Chris@297 45 m_tempDirRoot(""),
Chris@354 46 m_resampleOnLoad(false),
Chris@354 47 m_viewFontSize(10),
Chris@372 48 m_backgroundMode(BackgroundFromTheme),
Chris@372 49 m_showSplash(true)
Chris@136 50 {
Chris@156 51 QSettings settings;
Chris@156 52 settings.beginGroup("Preferences");
Chris@246 53 m_spectrogramSmoothing = SpectrogramSmoothing
Chris@553 54 (settings.value("spectrogram-y-smoothing", int(m_spectrogramSmoothing)).toInt());
Chris@553 55 m_spectrogramXSmoothing = SpectrogramXSmoothing
Chris@553 56 (settings.value("spectrogram-x-smoothing", int(m_spectrogramXSmoothing)).toInt());
Chris@156 57 m_tuningFrequency = settings.value("tuning-frequency", 440.f).toDouble();
Chris@145 58 m_propertyBoxLayout = PropertyBoxLayout
Chris@156 59 (settings.value("property-box-layout", int(VerticallyStacked)).toInt());
Chris@145 60 m_windowType = WindowType
Chris@156 61 (settings.value("window-type", int(HanningWindow)).toInt());
Chris@164 62 m_resampleQuality = settings.value("resample-quality", 1).toInt();
Chris@304 63 m_resampleOnLoad = settings.value("resample-on-load", false).toBool();
Chris@297 64 m_backgroundMode = BackgroundMode
Chris@297 65 (settings.value("background-mode", int(BackgroundFromTheme)).toInt());
Chris@387 66 m_viewFontSize = settings.value("view-font-size", 10).toInt();
Chris@372 67 m_showSplash = settings.value("show-splash", true).toBool();
Chris@297 68 settings.endGroup();
Chris@297 69
Chris@297 70 settings.beginGroup("TempDirectory");
Chris@297 71 m_tempDirRoot = settings.value("create-in", "$HOME").toString();
Chris@156 72 settings.endGroup();
Chris@145 73 }
Chris@145 74
Chris@145 75 Preferences::~Preferences()
Chris@145 76 {
Chris@136 77 }
Chris@136 78
Chris@136 79 Preferences::PropertyList
Chris@136 80 Preferences::getProperties() const
Chris@136 81 {
Chris@136 82 PropertyList props;
Chris@553 83 props.push_back("Spectrogram Y Smoothing");
Chris@553 84 props.push_back("Spectrogram X Smoothing");
Chris@136 85 props.push_back("Tuning Frequency");
Chris@138 86 props.push_back("Property Box Layout");
Chris@140 87 props.push_back("Window Type");
Chris@164 88 props.push_back("Resample Quality");
Chris@277 89 props.push_back("Omit Temporaries from Recent Files");
Chris@297 90 props.push_back("Resample On Load");
Chris@297 91 props.push_back("Temporary Directory Root");
Chris@297 92 props.push_back("Background Mode");
Chris@354 93 props.push_back("View Font Size");
Chris@372 94 props.push_back("Show Splash Screen");
Chris@136 95 return props;
Chris@136 96 }
Chris@136 97
Chris@136 98 QString
Chris@136 99 Preferences::getPropertyLabel(const PropertyName &name) const
Chris@136 100 {
Chris@553 101 if (name == "Spectrogram Y Smoothing") {
Chris@372 102 return tr("Spectrogram y-axis interpolation:");
Chris@136 103 }
Chris@553 104 if (name == "Spectrogram X Smoothing") {
Chris@553 105 return tr("Spectrogram x-axis interpolation:");
Chris@553 106 }
Chris@136 107 if (name == "Tuning Frequency") {
Chris@141 108 return tr("Frequency of concert A");
Chris@136 109 }
Chris@138 110 if (name == "Property Box Layout") {
Chris@141 111 return tr("Property box layout");
Chris@138 112 }
Chris@140 113 if (name == "Window Type") {
Chris@141 114 return tr("Spectral analysis window shape");
Chris@140 115 }
Chris@164 116 if (name == "Resample Quality") {
Chris@165 117 return tr("Playback resampler type");
Chris@164 118 }
Chris@277 119 if (name == "Omit Temporaries from Recent Files") {
Chris@297 120 return tr("Omit temporaries from Recent Files menu");
Chris@297 121 }
Chris@297 122 if (name == "Resample On Load") {
Chris@297 123 return tr("Resample mismatching files on import");
Chris@297 124 }
Chris@297 125 if (name == "Temporary Directory Root") {
Chris@297 126 return tr("Location for cache file directory");
Chris@297 127 }
Chris@297 128 if (name == "Background Mode") {
Chris@297 129 return tr("Background colour preference");
Chris@277 130 }
Chris@354 131 if (name == "View Font Size") {
Chris@354 132 return tr("Font size for text overlays");
Chris@354 133 }
Chris@372 134 if (name == "Show Splash Screen") {
Chris@372 135 return tr("Show splash screen on startup");
Chris@372 136 }
Chris@136 137 return name;
Chris@136 138 }
Chris@136 139
Chris@136 140 Preferences::PropertyType
Chris@136 141 Preferences::getPropertyType(const PropertyName &name) const
Chris@136 142 {
Chris@553 143 if (name == "Spectrogram Y Smoothing") {
Chris@553 144 return ValueProperty;
Chris@553 145 }
Chris@553 146 if (name == "Spectrogram X Smoothing") {
Chris@246 147 return ValueProperty;
Chris@136 148 }
Chris@136 149 if (name == "Tuning Frequency") {
Chris@136 150 return RangeProperty;
Chris@136 151 }
Chris@138 152 if (name == "Property Box Layout") {
Chris@138 153 return ValueProperty;
Chris@138 154 }
Chris@140 155 if (name == "Window Type") {
Chris@140 156 return ValueProperty;
Chris@140 157 }
Chris@164 158 if (name == "Resample Quality") {
Chris@164 159 return ValueProperty;
Chris@164 160 }
Chris@277 161 if (name == "Omit Temporaries from Recent Files") {
Chris@277 162 return ToggleProperty;
Chris@277 163 }
Chris@297 164 if (name == "Resample On Load") {
Chris@297 165 return ToggleProperty;
Chris@297 166 }
Chris@297 167 if (name == "Temporary Directory Root") {
Chris@297 168 // It's an arbitrary string, we don't have a set of values for this
Chris@297 169 return InvalidProperty;
Chris@297 170 }
Chris@297 171 if (name == "Background Mode") {
Chris@297 172 return ValueProperty;
Chris@297 173 }
Chris@354 174 if (name == "View Font Size") {
Chris@354 175 return RangeProperty;
Chris@354 176 }
Chris@372 177 if (name == "Show Splash Screen") {
Chris@372 178 return ToggleProperty;
Chris@372 179 }
Chris@136 180 return InvalidProperty;
Chris@136 181 }
Chris@136 182
Chris@136 183 int
Chris@136 184 Preferences::getPropertyRangeAndValue(const PropertyName &name,
Chris@245 185 int *min, int *max, int *deflt) const
Chris@136 186 {
Chris@553 187 if (name == "Spectrogram Y Smoothing") {
Chris@136 188 if (min) *min = 0;
Chris@553 189 if (max) *max = 3;
Chris@553 190 if (deflt) *deflt = int(SpectrogramInterpolated);
Chris@246 191 return int(m_spectrogramSmoothing);
Chris@136 192 }
Chris@553 193 if (name == "Spectrogram X Smoothing") {
Chris@553 194 if (min) *min = 0;
Chris@553 195 if (max) *max = 1;
Chris@553 196 if (deflt) *deflt = int(SpectrogramXInterpolated);
Chris@553 197 return int(m_spectrogramXSmoothing);
Chris@553 198 }
Chris@136 199
Chris@136 200 //!!! freq mapping
Chris@136 201
Chris@138 202 if (name == "Property Box Layout") {
Chris@138 203 if (min) *min = 0;
Chris@138 204 if (max) *max = 1;
Chris@245 205 if (deflt) *deflt = 0;
Chris@138 206 return m_propertyBoxLayout == Layered ? 1 : 0;
Chris@138 207 }
Chris@138 208
Chris@140 209 if (name == "Window Type") {
Chris@140 210 if (min) *min = int(RectangularWindow);
Chris@142 211 if (max) *max = int(BlackmanHarrisWindow);
Chris@245 212 if (deflt) *deflt = int(HanningWindow);
Chris@140 213 return int(m_windowType);
Chris@140 214 }
Chris@140 215
Chris@164 216 if (name == "Resample Quality") {
Chris@164 217 if (min) *min = 0;
Chris@164 218 if (max) *max = 2;
Chris@245 219 if (deflt) *deflt = 1;
Chris@164 220 return m_resampleQuality;
Chris@164 221 }
Chris@164 222
Chris@277 223 if (name == "Omit Temporaries from Recent Files") {
Chris@277 224 if (deflt) *deflt = 1;
Chris@277 225 }
Chris@277 226
Chris@297 227 if (name == "Background Mode") {
Chris@297 228 if (min) *min = 0;
Chris@297 229 if (max) *max = 2;
Chris@297 230 if (deflt) *deflt = 0;
Chris@297 231 return int(m_backgroundMode);
Chris@297 232 }
Chris@297 233
Chris@354 234 if (name == "View Font Size") {
Chris@354 235 if (min) *min = 3;
Chris@354 236 if (max) *max = 48;
Chris@387 237 if (deflt) *deflt = 10;
Chris@354 238 return int(m_viewFontSize);
Chris@354 239 }
Chris@354 240
Chris@372 241 if (name == "Show Splash Screen") {
Chris@372 242 if (deflt) *deflt = 1;
Chris@372 243 }
Chris@372 244
Chris@136 245 return 0;
Chris@136 246 }
Chris@136 247
Chris@136 248 QString
Chris@136 249 Preferences::getPropertyValueLabel(const PropertyName &name,
Chris@136 250 int value) const
Chris@136 251 {
Chris@138 252 if (name == "Property Box Layout") {
Chris@141 253 if (value == 0) return tr("Show boxes for all panes");
Chris@141 254 else return tr("Show box for current pane only");
Chris@138 255 }
Chris@140 256 if (name == "Window Type") {
Chris@140 257 switch (WindowType(value)) {
Chris@140 258 case RectangularWindow: return tr("Rectangular");
Chris@141 259 case BartlettWindow: return tr("Triangular");
Chris@140 260 case HammingWindow: return tr("Hamming");
Chris@381 261 case HanningWindow: return tr("Hann");
Chris@140 262 case BlackmanWindow: return tr("Blackman");
Chris@140 263 case GaussianWindow: return tr("Gaussian");
Chris@140 264 case ParzenWindow: return tr("Parzen");
Chris@142 265 case NuttallWindow: return tr("Nuttall");
Chris@142 266 case BlackmanHarrisWindow: return tr("Blackman-Harris");
Chris@140 267 }
Chris@140 268 }
Chris@164 269 if (name == "Resample Quality") {
Chris@164 270 switch (value) {
Chris@164 271 case 0: return tr("Fastest");
Chris@165 272 case 1: return tr("Standard");
Chris@164 273 case 2: return tr("Highest quality");
Chris@164 274 }
Chris@164 275 }
Chris@553 276 if (name == "Spectrogram Y Smoothing") {
Chris@246 277 switch (value) {
Chris@553 278 case NoSpectrogramSmoothing: return tr("None");
Chris@553 279 case SpectrogramInterpolated: return tr("Linear interpolation");
Chris@553 280 case SpectrogramZeroPadded: return tr("4 x Oversampling");
Chris@553 281 case SpectrogramZeroPaddedAndInterpolated: return tr("4 x Oversampling with interpolation");
Chris@553 282 }
Chris@553 283 }
Chris@553 284 if (name == "Spectrogram X Smoothing") {
Chris@553 285 switch (value) {
Chris@553 286 case NoSpectrogramXSmoothing: return tr("None");
Chris@553 287 case SpectrogramXInterpolated: return tr("Linear interpolation");
Chris@246 288 }
Chris@246 289 }
Chris@297 290 if (name == "Background Mode") {
Chris@297 291 switch (value) {
Chris@297 292 case BackgroundFromTheme: return tr("Follow desktop theme");
Chris@297 293 case DarkBackground: return tr("Dark background");
Chris@297 294 case LightBackground: return tr("Light background");
Chris@297 295 }
Chris@297 296 }
Chris@246 297
Chris@136 298 return "";
Chris@136 299 }
Chris@136 300
Chris@136 301 QString
Chris@136 302 Preferences::getPropertyContainerName() const
Chris@136 303 {
Chris@136 304 return tr("Preferences");
Chris@136 305 }
Chris@136 306
Chris@136 307 QString
Chris@136 308 Preferences::getPropertyContainerIconName() const
Chris@136 309 {
Chris@136 310 return "preferences";
Chris@136 311 }
Chris@136 312
Chris@136 313 void
Chris@136 314 Preferences::setProperty(const PropertyName &name, int value)
Chris@136 315 {
Chris@553 316 if (name == "Spectrogram Y Smoothing") {
Chris@246 317 setSpectrogramSmoothing(SpectrogramSmoothing(value));
Chris@553 318 } else if (name == "Spectrogram X Smoothing") {
Chris@553 319 setSpectrogramXSmoothing(SpectrogramXSmoothing(value));
Chris@136 320 } else if (name == "Tuning Frequency") {
Chris@136 321 //!!!
Chris@138 322 } else if (name == "Property Box Layout") {
Chris@138 323 setPropertyBoxLayout(value == 0 ? VerticallyStacked : Layered);
Chris@140 324 } else if (name == "Window Type") {
Chris@140 325 setWindowType(WindowType(value));
Chris@164 326 } else if (name == "Resample Quality") {
Chris@164 327 setResampleQuality(value);
Chris@277 328 } else if (name == "Omit Temporaries from Recent Files") {
Chris@277 329 setOmitTempsFromRecentFiles(value ? true : false);
Chris@297 330 } else if (name == "Background Mode") {
Chris@297 331 setBackgroundMode(BackgroundMode(value));
Chris@354 332 } else if (name == "View Font Size") {
Chris@354 333 setViewFontSize(value);
Chris@372 334 } else if (name == "Show Splash Screen") {
Chris@372 335 setShowSplash(value ? true : false);
Chris@136 336 }
Chris@136 337 }
Chris@136 338
Chris@136 339 void
Chris@246 340 Preferences::setSpectrogramSmoothing(SpectrogramSmoothing smoothing)
Chris@136 341 {
Chris@246 342 if (m_spectrogramSmoothing != smoothing) {
Chris@246 343
Chris@246 344 // "smoothing" is one of those words that looks increasingly
Chris@246 345 // ridiculous the more you see it. Smoothing smoothing smoothing.
Chris@246 346 m_spectrogramSmoothing = smoothing;
Chris@246 347
Chris@156 348 QSettings settings;
Chris@156 349 settings.beginGroup("Preferences");
Chris@553 350 settings.setValue("spectrogram-y-smoothing", int(smoothing));
Chris@156 351 settings.endGroup();
Chris@553 352 emit propertyChanged("Spectrogram Y Smoothing");
Chris@553 353 }
Chris@553 354 }
Chris@553 355
Chris@553 356 void
Chris@553 357 Preferences::setSpectrogramXSmoothing(SpectrogramXSmoothing smoothing)
Chris@553 358 {
Chris@553 359 if (m_spectrogramXSmoothing != smoothing) {
Chris@553 360
Chris@553 361 // "smoothing" is one of those words that looks increasingly
Chris@553 362 // ridiculous the more you see it. Smoothing smoothing smoothing.
Chris@553 363 m_spectrogramXSmoothing = smoothing;
Chris@553 364
Chris@553 365 QSettings settings;
Chris@553 366 settings.beginGroup("Preferences");
Chris@553 367 settings.setValue("spectrogram-x-smoothing", int(smoothing));
Chris@553 368 settings.endGroup();
Chris@553 369 emit propertyChanged("Spectrogram X Smoothing");
Chris@138 370 }
Chris@136 371 }
Chris@136 372
Chris@136 373 void
Chris@136 374 Preferences::setTuningFrequency(float freq)
Chris@136 375 {
Chris@138 376 if (m_tuningFrequency != freq) {
Chris@138 377 m_tuningFrequency = freq;
Chris@156 378 QSettings settings;
Chris@156 379 settings.beginGroup("Preferences");
Chris@156 380 settings.setValue("tuning-frequency", freq);
Chris@156 381 settings.endGroup();
Chris@141 382 emit propertyChanged("Tuning Frequency");
Chris@138 383 }
Chris@136 384 }
Chris@136 385
Chris@138 386 void
Chris@138 387 Preferences::setPropertyBoxLayout(PropertyBoxLayout layout)
Chris@138 388 {
Chris@138 389 if (m_propertyBoxLayout != layout) {
Chris@138 390 m_propertyBoxLayout = layout;
Chris@156 391 QSettings settings;
Chris@156 392 settings.beginGroup("Preferences");
Chris@156 393 settings.setValue("property-box-layout", int(layout));
Chris@156 394 settings.endGroup();
Chris@141 395 emit propertyChanged("Property Box Layout");
Chris@138 396 }
Chris@138 397 }
Chris@138 398
Chris@140 399 void
Chris@140 400 Preferences::setWindowType(WindowType type)
Chris@140 401 {
Chris@140 402 if (m_windowType != type) {
Chris@140 403 m_windowType = type;
Chris@156 404 QSettings settings;
Chris@156 405 settings.beginGroup("Preferences");
Chris@156 406 settings.setValue("window-type", int(type));
Chris@156 407 settings.endGroup();
Chris@141 408 emit propertyChanged("Window Type");
Chris@140 409 }
Chris@140 410 }
Chris@140 411
Chris@164 412 void
Chris@164 413 Preferences::setResampleQuality(int q)
Chris@164 414 {
Chris@164 415 if (m_resampleQuality != q) {
Chris@164 416 m_resampleQuality = q;
Chris@164 417 QSettings settings;
Chris@164 418 settings.beginGroup("Preferences");
Chris@164 419 settings.setValue("resample-quality", q);
Chris@164 420 settings.endGroup();
Chris@164 421 emit propertyChanged("Resample Quality");
Chris@164 422 }
Chris@164 423 }
Chris@277 424
Chris@277 425 void
Chris@277 426 Preferences::setOmitTempsFromRecentFiles(bool omit)
Chris@277 427 {
Chris@277 428 if (m_omitRecentTemps != omit) {
Chris@277 429 m_omitRecentTemps = omit;
Chris@277 430 QSettings settings;
Chris@277 431 settings.beginGroup("Preferences");
Chris@277 432 settings.setValue("omit-recent-temporaries", omit);
Chris@277 433 settings.endGroup();
Chris@277 434 emit propertyChanged("Omit Temporaries from Recent Files");
Chris@277 435 }
Chris@277 436 }
Chris@297 437
Chris@297 438 void
Chris@297 439 Preferences::setTemporaryDirectoryRoot(QString root)
Chris@297 440 {
Chris@297 441 if (root == QDir::home().absolutePath()) {
Chris@297 442 root = "$HOME";
Chris@297 443 }
Chris@297 444 if (m_tempDirRoot != root) {
Chris@297 445 m_tempDirRoot = root;
Chris@297 446 QSettings settings;
Chris@297 447 settings.beginGroup("TempDirectory");
Chris@297 448 settings.setValue("create-in", root);
Chris@297 449 settings.endGroup();
Chris@297 450 emit propertyChanged("Temporary Directory Root");
Chris@297 451 }
Chris@297 452 }
Chris@297 453
Chris@297 454 void
Chris@297 455 Preferences::setResampleOnLoad(bool resample)
Chris@297 456 {
Chris@297 457 if (m_resampleOnLoad != resample) {
Chris@297 458 m_resampleOnLoad = resample;
Chris@297 459 QSettings settings;
Chris@297 460 settings.beginGroup("Preferences");
Chris@297 461 settings.setValue("resample-on-load", resample);
Chris@297 462 settings.endGroup();
Chris@297 463 emit propertyChanged("Resample On Load");
Chris@297 464 }
Chris@297 465 }
Chris@297 466
Chris@297 467 void
Chris@297 468 Preferences::setBackgroundMode(BackgroundMode mode)
Chris@297 469 {
Chris@297 470 if (m_backgroundMode != mode) {
Chris@297 471
Chris@297 472 m_backgroundMode = mode;
Chris@297 473
Chris@297 474 QSettings settings;
Chris@297 475 settings.beginGroup("Preferences");
Chris@297 476 settings.setValue("background-mode", int(mode));
Chris@297 477 settings.endGroup();
Chris@297 478 emit propertyChanged("Background Mode");
Chris@297 479 }
Chris@297 480 }
Chris@297 481
Chris@354 482 void
Chris@354 483 Preferences::setViewFontSize(int size)
Chris@354 484 {
Chris@354 485 if (m_viewFontSize != size) {
Chris@297 486
Chris@354 487 m_viewFontSize = size;
Chris@354 488
Chris@354 489 QSettings settings;
Chris@354 490 settings.beginGroup("Preferences");
Chris@354 491 settings.setValue("view-font-size", size);
Chris@354 492 settings.endGroup();
Chris@354 493 emit propertyChanged("View Font Size");
Chris@354 494 }
Chris@354 495 }
Chris@354 496
Chris@372 497 void
Chris@372 498 Preferences::setShowSplash(bool show)
Chris@372 499 {
Chris@372 500 if (m_showSplash != show) {
Chris@372 501
Chris@372 502 m_showSplash = show;
Chris@372 503
Chris@372 504 QSettings settings;
Chris@372 505 settings.beginGroup("Preferences");
Chris@372 506 settings.setValue("show-splash", show);
Chris@372 507 settings.endGroup();
Chris@372 508 emit propertyChanged("Show Splash Screen");
Chris@372 509 }
Chris@372 510 }
Chris@372 511