svcore
1.9
|
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 00002 00003 /* 00004 Sonic Visualiser 00005 An audio file viewer and annotation editor. 00006 Centre for Digital Music, Queen Mary, University of London. 00007 This file copyright 2006 Chris Cannam and QMUL. 00008 00009 This program is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU General Public License as 00011 published by the Free Software Foundation; either version 2 of the 00012 License, or (at your option) any later version. See the file 00013 COPYING included with this distribution for more information. 00014 */ 00015 00016 #include "Preferences.h" 00017 00018 #include "Exceptions.h" 00019 00020 #include "TempDirectory.h" 00021 00022 #include <QDir> 00023 #include <QFileInfo> 00024 #include <QMutex> 00025 #include <QSettings> 00026 00027 Preferences * 00028 Preferences::m_instance = 0; 00029 00030 Preferences * 00031 Preferences::getInstance() 00032 { 00033 if (!m_instance) m_instance = new Preferences(); 00034 return m_instance; 00035 } 00036 00037 Preferences::Preferences() : 00038 m_spectrogramSmoothing(SpectrogramInterpolated), 00039 m_spectrogramXSmoothing(SpectrogramXInterpolated), 00040 m_tuningFrequency(440), 00041 m_propertyBoxLayout(VerticallyStacked), 00042 m_windowType(HanningWindow), 00043 m_resampleQuality(1), 00044 m_omitRecentTemps(true), 00045 m_tempDirRoot(""), 00046 m_fixedSampleRate(0), 00047 m_resampleOnLoad(false), 00048 m_normaliseAudio(false), 00049 m_viewFontSize(10), 00050 m_backgroundMode(BackgroundFromTheme), 00051 m_timeToTextMode(TimeToTextMs), 00052 m_octave(4), 00053 m_showSplash(true) 00054 { 00055 QSettings settings; 00056 settings.beginGroup("Preferences"); 00057 m_spectrogramSmoothing = SpectrogramSmoothing 00058 (settings.value("spectrogram-y-smoothing", int(m_spectrogramSmoothing)).toInt()); 00059 m_spectrogramXSmoothing = SpectrogramXSmoothing 00060 (settings.value("spectrogram-x-smoothing", int(m_spectrogramXSmoothing)).toInt()); 00061 m_tuningFrequency = settings.value("tuning-frequency", 440.f).toDouble(); 00062 m_propertyBoxLayout = PropertyBoxLayout 00063 (settings.value("property-box-layout", int(VerticallyStacked)).toInt()); 00064 m_windowType = WindowType 00065 (settings.value("window-type", int(HanningWindow)).toInt()); 00066 m_resampleQuality = settings.value("resample-quality", 1).toInt(); 00067 m_fixedSampleRate = settings.value("fixed-sample-rate", 0).toInt(); 00068 m_resampleOnLoad = settings.value("resample-on-load", false).toBool(); 00069 m_normaliseAudio = settings.value("normalise-audio", false).toBool(); 00070 m_backgroundMode = BackgroundMode 00071 (settings.value("background-mode", int(BackgroundFromTheme)).toInt()); 00072 m_timeToTextMode = TimeToTextMode 00073 (settings.value("time-to-text-mode", int(TimeToTextMs)).toInt()); 00074 m_octave = (settings.value("octave-of-middle-c", 4)).toInt(); 00075 m_viewFontSize = settings.value("view-font-size", 10).toInt(); 00076 m_showSplash = settings.value("show-splash", true).toBool(); 00077 settings.endGroup(); 00078 00079 settings.beginGroup("TempDirectory"); 00080 m_tempDirRoot = settings.value("create-in", "$HOME").toString(); 00081 settings.endGroup(); 00082 } 00083 00084 Preferences::~Preferences() 00085 { 00086 } 00087 00088 Preferences::PropertyList 00089 Preferences::getProperties() const 00090 { 00091 PropertyList props; 00092 props.push_back("Spectrogram Y Smoothing"); 00093 props.push_back("Spectrogram X Smoothing"); 00094 props.push_back("Tuning Frequency"); 00095 props.push_back("Property Box Layout"); 00096 props.push_back("Window Type"); 00097 props.push_back("Resample Quality"); 00098 props.push_back("Omit Temporaries from Recent Files"); 00099 props.push_back("Resample On Load"); 00100 props.push_back("Normalise Audio"); 00101 props.push_back("Fixed Sample Rate"); 00102 props.push_back("Temporary Directory Root"); 00103 props.push_back("Background Mode"); 00104 props.push_back("Time To Text Mode"); 00105 props.push_back("Octave Numbering System"); 00106 props.push_back("View Font Size"); 00107 props.push_back("Show Splash Screen"); 00108 return props; 00109 } 00110 00111 QString 00112 Preferences::getPropertyLabel(const PropertyName &name) const 00113 { 00114 if (name == "Spectrogram Y Smoothing") { 00115 return tr("Spectrogram y-axis interpolation:"); 00116 } 00117 if (name == "Spectrogram X Smoothing") { 00118 return tr("Spectrogram x-axis interpolation:"); 00119 } 00120 if (name == "Tuning Frequency") { 00121 return tr("Frequency of concert A"); 00122 } 00123 if (name == "Property Box Layout") { 00124 return tr("Property box layout"); 00125 } 00126 if (name == "Window Type") { 00127 return tr("Spectral analysis window shape"); 00128 } 00129 if (name == "Resample Quality") { 00130 return tr("Playback resampler type"); 00131 } 00132 if (name == "Normalise Audio") { 00133 return tr("Normalise audio signal when reading from audio file"); 00134 } 00135 if (name == "Omit Temporaries from Recent Files") { 00136 return tr("Omit temporaries from Recent Files menu"); 00137 } 00138 if (name == "Resample On Load") { 00139 return tr("Resample mismatching files on import"); 00140 } 00141 if (name == "Fixed Sample Rate") { 00142 return tr("Single fixed sample rate to resample all files to"); 00143 } 00144 if (name == "Temporary Directory Root") { 00145 return tr("Location for cache file directory"); 00146 } 00147 if (name == "Background Mode") { 00148 return tr("Background colour preference"); 00149 } 00150 if (name == "Time To Text Mode") { 00151 return tr("Time display format"); 00152 } 00153 if (name == "Octave Numbering System") { 00154 return tr("Label middle C as"); 00155 } 00156 if (name == "View Font Size") { 00157 return tr("Font size for text overlays"); 00158 } 00159 if (name == "Show Splash Screen") { 00160 return tr("Show splash screen on startup"); 00161 } 00162 return name; 00163 } 00164 00165 Preferences::PropertyType 00166 Preferences::getPropertyType(const PropertyName &name) const 00167 { 00168 if (name == "Spectrogram Y Smoothing") { 00169 return ValueProperty; 00170 } 00171 if (name == "Spectrogram X Smoothing") { 00172 return ValueProperty; 00173 } 00174 if (name == "Tuning Frequency") { 00175 return RangeProperty; 00176 } 00177 if (name == "Property Box Layout") { 00178 return ValueProperty; 00179 } 00180 if (name == "Window Type") { 00181 return ValueProperty; 00182 } 00183 if (name == "Resample Quality") { 00184 return ValueProperty; 00185 } 00186 if (name == "Normalise Audio") { 00187 return ToggleProperty; 00188 } 00189 if (name == "Omit Temporaries from Recent Files") { 00190 return ToggleProperty; 00191 } 00192 if (name == "Resample On Load") { 00193 return ToggleProperty; 00194 } 00195 if (name == "Fixed Sample Rate") { 00196 return ValueProperty; 00197 } 00198 if (name == "Temporary Directory Root") { 00199 // It's an arbitrary string, we don't have a set of values for this 00200 return InvalidProperty; 00201 } 00202 if (name == "Background Mode") { 00203 return ValueProperty; 00204 } 00205 if (name == "Time To Text Mode") { 00206 return ValueProperty; 00207 } 00208 if (name == "Octave Numbering System") { 00209 return ValueProperty; 00210 } 00211 if (name == "View Font Size") { 00212 return RangeProperty; 00213 } 00214 if (name == "Show Splash Screen") { 00215 return ToggleProperty; 00216 } 00217 return InvalidProperty; 00218 } 00219 00220 int 00221 Preferences::getPropertyRangeAndValue(const PropertyName &name, 00222 int *min, int *max, int *deflt) const 00223 { 00224 if (name == "Spectrogram Y Smoothing") { 00225 if (min) *min = 0; 00226 if (max) *max = 3; 00227 if (deflt) *deflt = int(SpectrogramInterpolated); 00228 return int(m_spectrogramSmoothing); 00229 } 00230 if (name == "Spectrogram X Smoothing") { 00231 if (min) *min = 0; 00232 if (max) *max = 1; 00233 if (deflt) *deflt = int(SpectrogramXInterpolated); 00234 return int(m_spectrogramXSmoothing); 00235 } 00236 00238 00239 if (name == "Property Box Layout") { 00240 if (min) *min = 0; 00241 if (max) *max = 1; 00242 if (deflt) *deflt = 0; 00243 return m_propertyBoxLayout == Layered ? 1 : 0; 00244 } 00245 00246 if (name == "Window Type") { 00247 if (min) *min = int(RectangularWindow); 00248 if (max) *max = int(BlackmanHarrisWindow); 00249 if (deflt) *deflt = int(HanningWindow); 00250 return int(m_windowType); 00251 } 00252 00253 if (name == "Resample Quality") { 00254 if (min) *min = 0; 00255 if (max) *max = 2; 00256 if (deflt) *deflt = 1; 00257 return m_resampleQuality; 00258 } 00259 00260 if (name == "Omit Temporaries from Recent Files") { 00261 if (deflt) *deflt = 1; 00262 } 00263 00264 if (name == "Background Mode") { 00265 if (min) *min = 0; 00266 if (max) *max = 2; 00267 if (deflt) *deflt = 0; 00268 return int(m_backgroundMode); 00269 } 00270 00271 if (name == "Time To Text Mode") { 00272 if (min) *min = 0; 00273 if (max) *max = 6; 00274 if (deflt) *deflt = 0; 00275 return int(m_timeToTextMode); 00276 } 00277 00278 if (name == "Octave Numbering System") { 00279 // we don't support arbitrary octaves in the gui, because we 00280 // want to be able to label what the octave system comes 00281 // from. so we support 0, 3, 4 and 5. 00282 if (min) *min = 0; 00283 if (max) *max = 3; 00284 if (deflt) *deflt = 2; 00285 return int(getSystemWithMiddleCInOctave(m_octave)); 00286 } 00287 00288 if (name == "View Font Size") { 00289 if (min) *min = 3; 00290 if (max) *max = 48; 00291 if (deflt) *deflt = 10; 00292 return int(m_viewFontSize); 00293 } 00294 00295 if (name == "Show Splash Screen") { 00296 if (deflt) *deflt = 1; 00297 } 00298 00299 return 0; 00300 } 00301 00302 QString 00303 Preferences::getPropertyValueLabel(const PropertyName &name, 00304 int value) const 00305 { 00306 if (name == "Property Box Layout") { 00307 if (value == 0) return tr("Show boxes for all panes"); 00308 else return tr("Show box for current pane only"); 00309 } 00310 if (name == "Window Type") { 00311 switch (WindowType(value)) { 00312 case RectangularWindow: return tr("Rectangular"); 00313 case BartlettWindow: return tr("Triangular"); 00314 case HammingWindow: return tr("Hamming"); 00315 case HanningWindow: return tr("Hann"); 00316 case BlackmanWindow: return tr("Blackman"); 00317 case GaussianWindow: return tr("Gaussian"); 00318 case ParzenWindow: return tr("Parzen"); 00319 case NuttallWindow: return tr("Nuttall"); 00320 case BlackmanHarrisWindow: return tr("Blackman-Harris"); 00321 } 00322 } 00323 if (name == "Resample Quality") { 00324 switch (value) { 00325 case 0: return tr("Fastest"); 00326 case 1: return tr("Standard"); 00327 case 2: return tr("Highest quality"); 00328 } 00329 } 00330 if (name == "Spectrogram Y Smoothing") { 00331 switch (value) { 00332 case NoSpectrogramSmoothing: return tr("None"); 00333 case SpectrogramInterpolated: return tr("Linear interpolation"); 00334 case SpectrogramZeroPadded: return tr("4 x Oversampling"); 00335 case SpectrogramZeroPaddedAndInterpolated: return tr("4 x Oversampling with interpolation"); 00336 } 00337 } 00338 if (name == "Spectrogram X Smoothing") { 00339 switch (value) { 00340 case NoSpectrogramXSmoothing: return tr("None"); 00341 case SpectrogramXInterpolated: return tr("Linear interpolation"); 00342 } 00343 } 00344 if (name == "Background Mode") { 00345 switch (value) { 00346 case BackgroundFromTheme: return tr("Follow desktop theme"); 00347 case DarkBackground: return tr("Dark background"); 00348 case LightBackground: return tr("Light background"); 00349 } 00350 } 00351 if (name == "Time To Text Mode") { 00352 switch (value) { 00353 case TimeToTextMs: return tr("Standard (to millisecond)"); 00354 case TimeToTextUs: return tr("High resolution (to microsecond)"); 00355 case TimeToText24Frame: return tr("24 FPS"); 00356 case TimeToText25Frame: return tr("25 FPS"); 00357 case TimeToText30Frame: return tr("30 FPS"); 00358 case TimeToText50Frame: return tr("50 FPS"); 00359 case TimeToText60Frame: return tr("60 FPS"); 00360 } 00361 } 00362 if (name == "Octave Numbering System") { 00363 switch (value) { 00364 case C0_Centre: return tr("C0 - middle of octave scale"); 00365 case C3_Logic: return tr("C3 - common MIDI sequencer convention"); 00366 case C4_ASA: return tr("C4 - ASA American standard"); 00367 case C5_Sonar: return tr("C5 - used in Cakewalk and others"); 00368 } 00369 } 00370 00371 return ""; 00372 } 00373 00374 QString 00375 Preferences::getPropertyContainerName() const 00376 { 00377 return tr("Preferences"); 00378 } 00379 00380 QString 00381 Preferences::getPropertyContainerIconName() const 00382 { 00383 return "preferences"; 00384 } 00385 00386 void 00387 Preferences::setProperty(const PropertyName &name, int value) 00388 { 00389 if (name == "Spectrogram Y Smoothing") { 00390 setSpectrogramSmoothing(SpectrogramSmoothing(value)); 00391 } else if (name == "Spectrogram X Smoothing") { 00392 setSpectrogramXSmoothing(SpectrogramXSmoothing(value)); 00393 } else if (name == "Tuning Frequency") { 00395 } else if (name == "Property Box Layout") { 00396 setPropertyBoxLayout(value == 0 ? VerticallyStacked : Layered); 00397 } else if (name == "Window Type") { 00398 setWindowType(WindowType(value)); 00399 } else if (name == "Resample Quality") { 00400 setResampleQuality(value); 00401 } else if (name == "Omit Temporaries from Recent Files") { 00402 setOmitTempsFromRecentFiles(value ? true : false); 00403 } else if (name == "Background Mode") { 00404 setBackgroundMode(BackgroundMode(value)); 00405 } else if (name == "Time To Text Mode") { 00406 setTimeToTextMode(TimeToTextMode(value)); 00407 } else if (name == "Octave Numbering System") { 00408 setOctaveOfMiddleC(getOctaveOfMiddleCInSystem 00409 (OctaveNumberingSystem(value))); 00410 } else if (name == "View Font Size") { 00411 setViewFontSize(value); 00412 } else if (name == "Show Splash Screen") { 00413 setShowSplash(value ? true : false); 00414 } 00415 } 00416 00417 void 00418 Preferences::setSpectrogramSmoothing(SpectrogramSmoothing smoothing) 00419 { 00420 if (m_spectrogramSmoothing != smoothing) { 00421 00422 // "smoothing" is one of those words that looks increasingly 00423 // ridiculous the more you see it. Smoothing smoothing smoothing. 00424 m_spectrogramSmoothing = smoothing; 00425 00426 QSettings settings; 00427 settings.beginGroup("Preferences"); 00428 settings.setValue("spectrogram-y-smoothing", int(smoothing)); 00429 settings.endGroup(); 00430 emit propertyChanged("Spectrogram Y Smoothing"); 00431 } 00432 } 00433 00434 void 00435 Preferences::setSpectrogramXSmoothing(SpectrogramXSmoothing smoothing) 00436 { 00437 if (m_spectrogramXSmoothing != smoothing) { 00438 00439 // "smoothing" is one of those words that looks increasingly 00440 // ridiculous the more you see it. Smoothing smoothing smoothing. 00441 m_spectrogramXSmoothing = smoothing; 00442 00443 QSettings settings; 00444 settings.beginGroup("Preferences"); 00445 settings.setValue("spectrogram-x-smoothing", int(smoothing)); 00446 settings.endGroup(); 00447 emit propertyChanged("Spectrogram X Smoothing"); 00448 } 00449 } 00450 00451 void 00452 Preferences::setTuningFrequency(float freq) 00453 { 00454 if (m_tuningFrequency != freq) { 00455 m_tuningFrequency = freq; 00456 QSettings settings; 00457 settings.beginGroup("Preferences"); 00458 settings.setValue("tuning-frequency", freq); 00459 settings.endGroup(); 00460 emit propertyChanged("Tuning Frequency"); 00461 } 00462 } 00463 00464 void 00465 Preferences::setPropertyBoxLayout(PropertyBoxLayout layout) 00466 { 00467 if (m_propertyBoxLayout != layout) { 00468 m_propertyBoxLayout = layout; 00469 QSettings settings; 00470 settings.beginGroup("Preferences"); 00471 settings.setValue("property-box-layout", int(layout)); 00472 settings.endGroup(); 00473 emit propertyChanged("Property Box Layout"); 00474 } 00475 } 00476 00477 void 00478 Preferences::setWindowType(WindowType type) 00479 { 00480 if (m_windowType != type) { 00481 m_windowType = type; 00482 QSettings settings; 00483 settings.beginGroup("Preferences"); 00484 settings.setValue("window-type", int(type)); 00485 settings.endGroup(); 00486 emit propertyChanged("Window Type"); 00487 } 00488 } 00489 00490 void 00491 Preferences::setResampleQuality(int q) 00492 { 00493 if (m_resampleQuality != q) { 00494 m_resampleQuality = q; 00495 QSettings settings; 00496 settings.beginGroup("Preferences"); 00497 settings.setValue("resample-quality", q); 00498 settings.endGroup(); 00499 emit propertyChanged("Resample Quality"); 00500 } 00501 } 00502 00503 void 00504 Preferences::setOmitTempsFromRecentFiles(bool omit) 00505 { 00506 if (m_omitRecentTemps != omit) { 00507 m_omitRecentTemps = omit; 00508 QSettings settings; 00509 settings.beginGroup("Preferences"); 00510 settings.setValue("omit-recent-temporaries", omit); 00511 settings.endGroup(); 00512 emit propertyChanged("Omit Temporaries from Recent Files"); 00513 } 00514 } 00515 00516 void 00517 Preferences::setTemporaryDirectoryRoot(QString root) 00518 { 00519 if (root == QDir::home().absolutePath()) { 00520 root = "$HOME"; 00521 } 00522 if (m_tempDirRoot != root) { 00523 m_tempDirRoot = root; 00524 QSettings settings; 00525 settings.beginGroup("TempDirectory"); 00526 settings.setValue("create-in", root); 00527 settings.endGroup(); 00528 emit propertyChanged("Temporary Directory Root"); 00529 } 00530 } 00531 00532 void 00533 Preferences::setResampleOnLoad(bool resample) 00534 { 00535 if (m_resampleOnLoad != resample) { 00536 m_resampleOnLoad = resample; 00537 QSettings settings; 00538 settings.beginGroup("Preferences"); 00539 settings.setValue("resample-on-load", resample); 00540 settings.endGroup(); 00541 emit propertyChanged("Resample On Load"); 00542 } 00543 } 00544 00545 void 00546 Preferences::setFixedSampleRate(int rate) 00547 { 00548 if (m_fixedSampleRate != rate) { 00549 m_fixedSampleRate = rate; 00550 QSettings settings; 00551 settings.beginGroup("Preferences"); 00552 settings.setValue("fixed-sample-rate", rate); 00553 settings.endGroup(); 00554 emit propertyChanged("Fixed Sample Rate"); 00555 } 00556 } 00557 00558 void 00559 Preferences::setNormaliseAudio(bool norm) 00560 { 00561 if (m_normaliseAudio != norm) { 00562 m_normaliseAudio = norm; 00563 QSettings settings; 00564 settings.beginGroup("Preferences"); 00565 settings.setValue("normalise-audio", norm); 00566 settings.endGroup(); 00567 emit propertyChanged("Normalise Audio"); 00568 } 00569 } 00570 00571 void 00572 Preferences::setBackgroundMode(BackgroundMode mode) 00573 { 00574 if (m_backgroundMode != mode) { 00575 00576 m_backgroundMode = mode; 00577 00578 QSettings settings; 00579 settings.beginGroup("Preferences"); 00580 settings.setValue("background-mode", int(mode)); 00581 settings.endGroup(); 00582 emit propertyChanged("Background Mode"); 00583 } 00584 } 00585 00586 void 00587 Preferences::setTimeToTextMode(TimeToTextMode mode) 00588 { 00589 if (m_timeToTextMode != mode) { 00590 00591 m_timeToTextMode = mode; 00592 00593 QSettings settings; 00594 settings.beginGroup("Preferences"); 00595 settings.setValue("time-to-text-mode", int(mode)); 00596 settings.endGroup(); 00597 emit propertyChanged("Time To Text Mode"); 00598 } 00599 } 00600 00601 void 00602 Preferences::setOctaveOfMiddleC(int oct) 00603 { 00604 if (m_octave != oct) { 00605 00606 m_octave = oct; 00607 00608 QSettings settings; 00609 settings.beginGroup("Preferences"); 00610 settings.setValue("octave-of-middle-c", int(oct)); 00611 settings.endGroup(); 00612 emit propertyChanged("Octave Numbering System"); 00613 } 00614 } 00615 00616 int 00617 Preferences::getOctaveOfMiddleCInSystem(OctaveNumberingSystem s) 00618 { 00619 switch (s) { 00620 case C0_Centre: return 0; 00621 case C3_Logic: return 3; 00622 case C4_ASA: return 4; 00623 case C5_Sonar: return 5; 00624 default: return 4; 00625 } 00626 } 00627 00628 Preferences::OctaveNumberingSystem 00629 Preferences::getSystemWithMiddleCInOctave(int o) 00630 { 00631 switch (o) { 00632 case 0: return C0_Centre; 00633 case 3: return C3_Logic; 00634 case 4: return C4_ASA; 00635 case 5: return C5_Sonar; 00636 default: return C4_ASA; 00637 } 00638 } 00639 00640 void 00641 Preferences::setViewFontSize(int size) 00642 { 00643 if (m_viewFontSize != size) { 00644 00645 m_viewFontSize = size; 00646 00647 QSettings settings; 00648 settings.beginGroup("Preferences"); 00649 settings.setValue("view-font-size", size); 00650 settings.endGroup(); 00651 emit propertyChanged("View Font Size"); 00652 } 00653 } 00654 00655 void 00656 Preferences::setShowSplash(bool show) 00657 { 00658 if (m_showSplash != show) { 00659 00660 m_showSplash = show; 00661 00662 QSettings settings; 00663 settings.beginGroup("Preferences"); 00664 settings.setValue("show-splash", show); 00665 settings.endGroup(); 00666 emit propertyChanged("Show Splash Screen"); 00667 } 00668 } 00669