Skip to content
This repository
Browse code

Merge pull request #2738 from Montellese/fix_videoscreen_settings

settings: move dependency handling into CSettingsManager and fix videoscreen settings
  • Loading branch information...
commit 9ac3e4c18bb9b3ea95d26d923022b39c558ec209 2 parents 95b23de + c3be62c
Sascha Montellese authored May 23, 2013

Showing 34 changed files with 420 additions and 296 deletions. Show diff stats Hide diff stats

  1. 6  system/settings/settings.xml
  2. 3  xbmc/Application.cpp
  3. 1  xbmc/GUIPassword.cpp
  4. 1  xbmc/LangInfo.cpp
  5. 1  xbmc/addons/Skin.cpp
  6. 2  xbmc/cores/AudioEngine/AEFactory.cpp
  7. 1  xbmc/epg/EpgContainer.cpp
  8. 1  xbmc/guilib/GUIAudioManager.cpp
  9. 2  xbmc/guilib/GraphicContext.cpp
  10. 1  xbmc/input/SDLJoystick.cpp
  11. 1  xbmc/interfaces/Builtins.cpp
  12. 1  xbmc/linux/LinuxTimezone.cpp
  13. 1  xbmc/network/NetworkServices.cpp
  14. 1  xbmc/osx/XBMCHelper.cpp
  15. 2  xbmc/peripherals/dialogs/GUIDialogPeripheralSettings.cpp
  16. 1  xbmc/powermanagement/PowerManager.cpp
  17. 1  xbmc/pvr/PVRManager.cpp
  18. 1  xbmc/pvr/channels/PVRChannelGroup.cpp
  19. 1  xbmc/settings/AdvancedSettings.cpp
  20. 52  xbmc/settings/DisplaySettings.cpp
  21. 2  xbmc/settings/DisplaySettings.h
  22. 11  xbmc/settings/ISettingCallback.h
  23. 129  xbmc/settings/Setting.cpp
  24. 28  xbmc/settings/Setting.h
  25. 15  xbmc/settings/Settings.cpp
  26. 35  xbmc/settings/Settings.h
  27. 81  xbmc/settings/SettingsManager.cpp
  28. 10  xbmc/settings/SettingsManager.h
  29. 169  xbmc/settings/windows/GUIControlSettings.cpp
  30. 16  xbmc/settings/windows/GUIControlSettings.h
  31. 131  xbmc/settings/windows/GUIWindowSettingsCategory.cpp
  32. 6  xbmc/settings/windows/GUIWindowSettingsCategory.h
  33. 1  xbmc/utils/Weather.cpp
  34. 1  xbmc/windowing/WinSystem.cpp
6  system/settings/settings.xml
@@ -1842,7 +1842,11 @@
1842 1842
           <constraints>
1843 1843
             <options>screens</options>
1844 1844
           </constraints>
1845  
-          <control type="spinner" format="string" delayed="true" />
  1845
+          <control type="spinner" format="string" delayed="true">
  1846
+            <dependencies>
  1847
+              <dependency type="update" setting="videoscreen.screenmode" />
  1848
+            </dependencies>
  1849
+          </control>
1846 1850
         </setting>
1847 1851
         <setting id="videoscreen.resolution" type="integer" label="169" help="36352">
1848 1852
           <level>0</level>
3  xbmc/Application.cpp
@@ -505,10 +505,7 @@ bool CApplication::OnEvent(XBMC_Event& newEvent)
505 505
         // when fullscreen, remain fullscreen and resize to the dimensions of the new screen
506 506
         RESOLUTION newRes = (RESOLUTION) g_Windowing.DesktopResolution(g_Windowing.GetCurrentScreen());
507 507
         if (newRes != g_graphicsContext.GetVideoResolution())
508  
-        {
509 508
           CDisplaySettings::Get().SetCurrentResolution(newRes, true);
510  
-          g_graphicsContext.SetVideoResolution(newRes);
511  
-        }
512 509
       }
513 510
       else
514 511
 #endif
1  xbmc/GUIPassword.cpp
@@ -30,6 +30,7 @@
30 30
 #include "profiles/dialogs/GUIDialogProfileSettings.h"
31 31
 #include "Util.h"
32 32
 #include "settings/MediaSourceSettings.h"
  33
+#include "settings/Setting.h"
33 34
 #include "settings/Settings.h"
34 35
 #include "guilib/GUIWindowManager.h"
35 36
 #include "FileItem.h"
1  xbmc/LangInfo.cpp
@@ -27,6 +27,7 @@
27 27
 #include "guilib/LocalizeStrings.h"
28 28
 #include "pvr/PVRManager.h"
29 29
 #include "settings/AdvancedSettings.h"
  30
+#include "settings/Setting.h"
30 31
 #include "settings/Settings.h"
31 32
 #include "utils/CharsetConverter.h"
32 33
 #include "utils/log.h"
1  xbmc/addons/Skin.cpp
@@ -25,6 +25,7 @@
25 25
 #include "filesystem/File.h"
26 26
 #include "filesystem/SpecialProtocol.h"
27 27
 #include "guilib/WindowIDs.h"
  28
+#include "settings/Setting.h"
28 29
 #include "settings/Settings.h"
29 30
 #include "utils/URIUtils.h"
30 31
 #include "utils/log.h"
2  xbmc/cores/AudioEngine/AEFactory.cpp
@@ -343,7 +343,7 @@ void CAEFactory::SettingOptionsAudioDevicesFillerGeneral(const CSetting *setting
343 343
         firstDevice = sink->second;
344 344
 
345 345
 #if defined(TARGET_DARWIN)
346  
-      list.push_back(StringSettingOption(sink->first, sink->first));
  346
+      list.push_back(std::make_pair(sink->first, sink->first));
347 347
 #else
348 348
       list.push_back(std::make_pair(sink->first, sink->second));
349 349
 #endif
1  xbmc/epg/EpgContainer.cpp
@@ -21,6 +21,7 @@
21 21
 #include "Application.h"
22 22
 #include "threads/SingleLock.h"
23 23
 #include "settings/AdvancedSettings.h"
  24
+#include "settings/Setting.h"
24 25
 #include "settings/Settings.h"
25 26
 #include "dialogs/GUIDialogExtendedProgressBar.h"
26 27
 #include "dialogs/GUIDialogProgress.h"
1  xbmc/guilib/GUIAudioManager.cpp
@@ -22,6 +22,7 @@
22 22
 #include "GUIAudioManager.h"
23 23
 #include "Key.h"
24 24
 #include "input/ButtonTranslator.h"
  25
+#include "settings/Setting.h"
25 26
 #include "threads/SingleLock.h"
26 27
 #include "utils/URIUtils.h"
27 28
 #include "utils/XBMCTinyXML.h"
2  xbmc/guilib/GraphicContext.cpp
@@ -25,6 +25,7 @@
25 25
 #include "ApplicationMessenger.h"
26 26
 #include "settings/AdvancedSettings.h"
27 27
 #include "settings/DisplaySettings.h"
  28
+#include "settings/Setting.h"
28 29
 #include "settings/Settings.h"
29 30
 #include "cores/VideoRenderers/RenderManager.h"
30 31
 #include "windowing/WindowingFactory.h"
@@ -857,7 +858,6 @@ bool CGraphicContext::ToggleFullScreenRoot ()
857 858
 #endif
858 859
   }
859 860
 
860  
-  SetVideoResolution(newRes);
861 861
   CDisplaySettings::Get().SetCurrentResolution(uiRes, true);
862 862
 
863 863
   return m_bFullScreenRoot;
1  xbmc/input/SDLJoystick.cpp
@@ -23,6 +23,7 @@
23 23
 #include "ButtonTranslator.h"
24 24
 #include "peripherals/devices/PeripheralImon.h"
25 25
 #include "settings/AdvancedSettings.h"
  26
+#include "settings/Setting.h"
26 27
 #include "utils/log.h"
27 28
 
28 29
 #include <math.h>
1  xbmc/interfaces/Builtins.cpp
@@ -473,7 +473,6 @@ int CBuiltins::Execute(const CStdString& execString)
473 473
     if (g_graphicsContext.IsValidResolution(res))
474 474
     {
475 475
       CDisplaySettings::Get().SetCurrentResolution(res, true);
476  
-      g_graphicsContext.SetVideoResolution(res);
477 476
       g_application.ReloadSkin();
478 477
     }
479 478
   }
1  xbmc/linux/LinuxTimezone.cpp
@@ -35,6 +35,7 @@
35 35
 
36 36
 #include "Util.h"
37 37
 #include "XBDateTime.h"
  38
+#include "settings/Setting.h"
38 39
 #include "settings/Settings.h"
39 40
 
40 41
 using namespace std;
1  xbmc/network/NetworkServices.cpp
@@ -74,6 +74,7 @@
74 74
 #endif
75 75
 
76 76
 #include "settings/AdvancedSettings.h"
  77
+#include "settings/Setting.h"
77 78
 #include "settings/Settings.h"
78 79
 #include "utils/log.h"
79 80
 #include "utils/RssManager.h"
1  xbmc/osx/XBMCHelper.cpp
@@ -32,6 +32,7 @@
32 32
 #include "dialogs/GUIDialogYesNo.h"
33 33
 #include "utils/log.h"
34 34
 #include "system.h"
  35
+#include "settings/Setting.h"
35 36
 #include "settings/Settings.h"
36 37
 #include "utils/SystemInfo.h"
37 38
 
2  xbmc/peripherals/dialogs/GUIDialogPeripheralSettings.cpp
@@ -106,7 +106,7 @@ void CGUIDialogPeripheralSettings::CreateSettings()
106 106
               {
107 107
                 m_intTextSettings.insert(make_pair(CStdString(intSetting->GetId()), intSetting->GetValue()));
108 108
                 vector<pair<int, int> > entries;
109  
-                SettingOptions::const_iterator entriesItr = intSetting->GetOptions().begin();
  109
+                StaticIntegerSettingOptions::const_iterator entriesItr = intSetting->GetOptions().begin();
110 110
                 while (entriesItr != intSetting->GetOptions().end())
111 111
                 {
112 112
                   entries.push_back(make_pair(entriesItr->first, entriesItr->second));
1  xbmc/powermanagement/PowerManager.cpp
@@ -23,6 +23,7 @@
23 23
 #include "Application.h"
24 24
 #include "cores/AudioEngine/AEFactory.h"
25 25
 #include "input/KeyboardStat.h"
  26
+#include "settings/Setting.h"
26 27
 #include "settings/Settings.h"
27 28
 #include "windowing/WindowingFactory.h"
28 29
 #include "utils/log.h"
1  xbmc/pvr/PVRManager.cpp
@@ -32,6 +32,7 @@
32 32
 #include "music/tags/MusicInfoTag.h"
33 33
 #include "settings/AdvancedSettings.h"
34 34
 #include "settings/MediaSettings.h"
  35
+#include "settings/Setting.h"
35 36
 #include "settings/Settings.h"
36 37
 #include "threads/SingleLock.h"
37 38
 #include "windows/GUIWindowPVR.h"
1  xbmc/pvr/channels/PVRChannelGroup.cpp
@@ -24,6 +24,7 @@
24 24
  */
25 25
 
26 26
 #include "settings/AdvancedSettings.h"
  27
+#include "settings/Setting.h"
27 28
 #include "settings/Settings.h"
28 29
 #include "guilib/GUIWindowManager.h"
29 30
 #include "dialogs/GUIDialogYesNo.h"
1  xbmc/settings/AdvancedSettings.cpp
@@ -28,6 +28,7 @@
28 28
 #include "utils/LangCodeExpander.h"
29 29
 #include "LangInfo.h"
30 30
 #include "profiles/ProfilesManager.h"
  31
+#include "settings/Setting.h"
31 32
 #include "settings/Settings.h"
32 33
 #include "utils/StringUtils.h"
33 34
 #include "utils/SystemInfo.h"
52  xbmc/settings/DisplaySettings.cpp
@@ -27,6 +27,7 @@
27 27
 #include "guilib/gui3d.h"
28 28
 #include "guilib/LocalizeStrings.h"
29 29
 #include "settings/AdvancedSettings.h"
  30
+#include "settings/Setting.h"
30 31
 #include "settings/Settings.h"
31 32
 #include "threads/SingleLock.h"
32 33
 #include "utils/log.h"
@@ -204,6 +205,7 @@ bool CDisplaySettings::OnSettingChanging(const CSetting *setting)
204 205
     if (m_ignoreSettingChanging.find(make_pair(settingId, true)) == m_ignoreSettingChanging.end())
205 206
     {
206 207
       RESOLUTION newRes = RES_DESKTOP;
  208
+      DisplayMode oldDisplayMode = GetCurrentDisplayMode();
207 209
       if (settingId == "videoscreen.resolution")
208 210
         newRes = (RESOLUTION)((CSettingInt*)setting)->GetValue();
209 211
       else if (settingId == "videoscreen.screen")
@@ -221,28 +223,30 @@ bool CDisplaySettings::OnSettingChanging(const CSetting *setting)
221 223
       SetCurrentResolution(newRes, save);
222 224
       g_graphicsContext.SetVideoResolution(newRes);
223 225
 
224  
-      // check if this setting is temporarily blocked from showing the dialog
225  
-      if (m_ignoreSettingChanging.find(make_pair(settingId, false)) == m_ignoreSettingChanging.end())
  226
+      // check if the old or the new resolution was/is windowed
  227
+      // in which case we don't show any prompt to the user
  228
+      if (newRes != RES_WINDOW && oldDisplayMode != DM_WINDOWED)
226 229
       {
227  
-        bool cancelled = false;
228  
-        if (!CGUIDialogYesNo::ShowAndGetInput(13110, 13111, 20022, 20022, -1, -1, cancelled, 10000))
  230
+        // check if this setting is temporarily blocked from showing the dialog
  231
+        if (newRes != RES_WINDOW &&
  232
+            m_ignoreSettingChanging.find(make_pair(settingId, false)) == m_ignoreSettingChanging.end())
229 233
         {
230  
-          // we need to ignore the next OnSettingChanging() call for
231  
-          // the same setting which is executed to broadcast that
232  
-          // changing the setting has failed
233  
-          m_ignoreSettingChanging.insert(make_pair(settingId, false));
234  
-          return false;
  234
+          bool cancelled = false;
  235
+          if (!CGUIDialogYesNo::ShowAndGetInput(13110, 13111, 20022, 20022, -1, -1, cancelled, 10000))
  236
+          {
  237
+            // we need to ignore the next OnSettingChanging() call for
  238
+            // the same setting which is executed to broadcast that
  239
+            // changing the setting has failed
  240
+            m_ignoreSettingChanging.insert(make_pair(settingId, false));
  241
+            return false;
  242
+          }
235 243
         }
  244
+        else
  245
+          m_ignoreSettingChanging.erase(make_pair(settingId, false));
236 246
       }
237  
-      else
238  
-        m_ignoreSettingChanging.erase(make_pair(settingId, false));
239 247
 
240 248
       if (settingId == "videoscreen.screen")
241  
-      {
242 249
         m_ignoreSettingChanging.insert(make_pair("videoscreen.resolution", true));
243  
-        if (CSettings::Get().GetSetting("videoscreen.screenmode")->IsVisible())
244  
-          m_ignoreSettingChanging.insert(make_pair("videoscreen.screenmode", true));
245  
-      }
246 250
     }
247 251
     else
248 252
       m_ignoreSettingChanging.erase(make_pair(settingId, true));
@@ -412,6 +416,14 @@ void CDisplaySettings::UpdateCalibrations()
412 416
   }
413 417
 }
414 418
 
  419
+DisplayMode CDisplaySettings::GetCurrentDisplayMode() const
  420
+{
  421
+  if (GetCurrentResolution() == RES_WINDOW)
  422
+    return DM_WINDOWED;
  423
+
  424
+  return GetCurrentResolutionInfo().iScreen;
  425
+}
  426
+
415 427
 RESOLUTION CDisplaySettings::GetResolutionFromString(const std::string &strResolution)
416 428
 {
417 429
   if (strResolution == "DESKTOP")
@@ -570,6 +582,16 @@ void CDisplaySettings::SettingOptionsScreensFiller(const CSetting *setting, std:
570 582
     int screen = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP + idx).iScreen;
571 583
     list.push_back(make_pair(StringUtils::Format(g_localizeStrings.Get(241), screen + 1), screen));
572 584
   }
  585
+
  586
+  RESOLUTION res = CDisplaySettings::Get().GetDisplayResolution();
  587
+
  588
+  if (res == RES_WINDOW)
  589
+    current = DM_WINDOWED;
  590
+  else
  591
+  {
  592
+    RESOLUTION_INFO resInfo = CDisplaySettings::Get().GetResolutionInfo(res);
  593
+    current = resInfo.iScreen;
  594
+  }
573 595
 }
574 596
 
575 597
 void CDisplaySettings::SettingOptionsVerticalSyncsFiller(const CSetting *setting, std::vector< std::pair<std::string, int> > &list, int &current)
2  xbmc/settings/DisplaySettings.h
@@ -99,6 +99,8 @@ class CDisplaySettings : public ISettingCallback, public ISubSettings,
99 99
   CDisplaySettings const& operator=(CDisplaySettings const&);
100 100
   virtual ~CDisplaySettings();
101 101
 
  102
+  DisplayMode GetCurrentDisplayMode() const;
  103
+
102 104
   static RESOLUTION GetResolutionFromString(const std::string &strResolution);
103 105
   static std::string GetStringFromResolution(RESOLUTION resolution, float refreshrate = 0.0f);
104 106
   static RESOLUTION GetResolutionForScreen();
11  xbmc/settings/ISettingCallback.h
@@ -73,4 +73,15 @@ class ISettingCallback
73 73
    \return True if the setting has been successfully updated otherwise false
74 74
    */
75 75
   virtual bool OnSettingUpdate(CSetting* &setting, const char *oldSettingId, const TiXmlNode *oldSettingNode) { return false; }
  76
+
  77
+  /*!
  78
+   \brief The given property of the given setting has changed
  79
+
  80
+   This callback is triggered when a property (e.g. enabled or the list of
  81
+   dynamic options) has changed.
  82
+
  83
+   \param setting The setting which has a changed property
  84
+   \param propertyName The string representation of the changed property
  85
+   */
  86
+  virtual void OnSettingPropertyChanged(const CSetting *setting, const char *propertyName) { }
76 87
 };
129  xbmc/settings/Setting.cpp
@@ -21,6 +21,7 @@
21 21
 #include <sstream>
22 22
 
23 23
 #include "Setting.h"
  24
+#include "SettingsManager.h"
24 25
 #include "threads/SingleLock.h"
25 26
 #include "utils/log.h"
26 27
 #include "utils/StringUtils.h"
@@ -143,6 +144,24 @@ bool CSetting::Deserialize(const TiXmlNode *node, bool update /* = false */)
143 144
   return true;
144 145
 }
145 146
   
  147
+bool CSetting::IsEnabled() const
  148
+{
  149
+  bool enabled = true;
  150
+  for (SettingDependencies::const_iterator depIt = m_dependencies.begin(); depIt != m_dependencies.end(); ++depIt)
  151
+  {
  152
+    if (depIt->GetType() != SettingDependencyTypeEnable)
  153
+      continue;
  154
+
  155
+    if (!depIt->Check())
  156
+    {
  157
+      enabled = false;
  158
+      break;
  159
+    }
  160
+  }
  161
+
  162
+  return enabled;
  163
+}
  164
+
146 165
 bool CSetting::OnSettingChanging(const CSetting *setting)
147 166
 {
148 167
   if (m_callback == NULL)
@@ -175,6 +194,14 @@ bool CSetting::OnSettingUpdate(CSetting* &setting, const char *oldSettingId, con
175 194
   return m_callback->OnSettingUpdate(setting, oldSettingId, oldSettingNode);
176 195
 }
177 196
 
  197
+void CSetting::OnSettingPropertyChanged(const CSetting *setting, const char *propertyName)
  198
+{
  199
+  if (m_callback == NULL)
  200
+    return;
  201
+
  202
+  m_callback->OnSettingPropertyChanged(setting, propertyName);
  203
+}
  204
+
178 205
 void CSetting::Copy(const CSetting &setting)
179 206
 {
180 207
   SetVisible(setting.IsVisible());
@@ -378,7 +405,7 @@ CSettingInt::CSettingInt(const std::string &id, int label, int value, int minimu
378 405
   m_control.SetAttributes(SettingControlAttributeNone);
379 406
 }
380 407
 
381  
-CSettingInt::CSettingInt(const std::string &id, int label, int value, const SettingOptions &options, CSettingsManager *settingsManager /* = NULL */)
  408
+CSettingInt::CSettingInt(const std::string &id, int label, int value, const StaticIntegerSettingOptions &options, CSettingsManager *settingsManager /* = NULL */)
382 409
   : CSetting(id, settingsManager),
383 410
     m_value(value), m_default(value),
384 411
     m_min(0), m_step(1), m_max(0),
@@ -511,7 +538,7 @@ bool CSettingInt::CheckValidity(int value) const
511 538
   {
512 539
     //if the setting is an std::map, check if we got a valid value before assigning it
513 540
     bool ok = false;
514  
-    for (SettingOptions::const_iterator it = m_options.begin(); it != m_options.end(); it++)
  541
+    for (StaticIntegerSettingOptions::const_iterator it = m_options.begin(); it != m_options.end(); it++)
515 542
     {
516 543
       if (it->second == value)
517 544
       {
@@ -569,6 +596,55 @@ void CSettingInt::SetDefault(int value)
569 596
     m_value = m_default;
570 597
 }
571 598
 
  599
+SettingOptionsType CSettingInt::GetOptionsType() const
  600
+{
  601
+  if (!m_options.empty())
  602
+    return SettingOptionsTypeStatic;
  603
+  if (!m_optionsFiller.empty())
  604
+    return SettingOptionsTypeDynamic;
  605
+
  606
+  return SettingOptionsTypeNone;
  607
+}
  608
+
  609
+DynamicIntegerSettingOptions CSettingInt::UpdateDynamicOptions()
  610
+{
  611
+  DynamicIntegerSettingOptions options;
  612
+  if (m_optionsFiller.empty() || m_settingsManager == NULL)
  613
+    return options;
  614
+
  615
+  IntegerSettingOptionsFiller filler = (IntegerSettingOptionsFiller)m_settingsManager->GetSettingOptionsFiller(this);
  616
+  if (filler == NULL)
  617
+    return options;
  618
+
  619
+  int bestMatchingValue = m_value;
  620
+  filler(this, options, bestMatchingValue);
  621
+
  622
+  if (bestMatchingValue != m_value)
  623
+    SetValue(bestMatchingValue);
  624
+
  625
+  bool changed = m_dynamicOptions.size() != options.size();
  626
+  if (!changed)
  627
+  {
  628
+    for (size_t index = 0; index < options.size(); index++)
  629
+    {
  630
+      if (options[index].first.compare(m_dynamicOptions[index].first) != 0 ||
  631
+          options[index].second != m_dynamicOptions[index].second)
  632
+      {
  633
+        changed = true;
  634
+        break;
  635
+      }
  636
+    }
  637
+  }
  638
+
  639
+  if (changed)
  640
+  {
  641
+    m_dynamicOptions = options;
  642
+    OnSettingPropertyChanged(this, "options");
  643
+  }
  644
+
  645
+  return options;
  646
+}
  647
+
572 648
 void CSettingInt::copy(const CSettingInt &setting)
573 649
 {
574 650
   CSetting::Copy(setting);
@@ -881,6 +957,55 @@ void CSettingString::SetDefault(const std::string &value)
881 957
     m_value = m_default;
882 958
 }
883 959
 
  960
+SettingOptionsType CSettingString::GetOptionsType() const
  961
+{
  962
+  if (!m_optionsFiller.empty())
  963
+    return SettingOptionsTypeDynamic;
  964
+
  965
+  return SettingOptionsTypeNone;
  966
+}
  967
+
  968
+DynamicStringSettingOptions CSettingString::UpdateDynamicOptions()
  969
+{
  970
+  DynamicStringSettingOptions options;
  971
+  if (m_optionsFiller.empty() || m_settingsManager == NULL)
  972
+    return options;
  973
+
  974
+  StringSettingOptionsFiller filler = (StringSettingOptionsFiller)m_settingsManager->GetSettingOptionsFiller(this);
  975
+  if (filler == NULL)
  976
+    return options;
  977
+
  978
+  std::string bestMatchingValue = m_value;
  979
+  filler(this, options, bestMatchingValue);
  980
+
  981
+  bool updated = false;
  982
+  if (bestMatchingValue != m_value)
  983
+    updated = SetValue(bestMatchingValue);
  984
+
  985
+  // check if the list of items has changed
  986
+  bool changed = m_dynamicOptions.size() != options.size();
  987
+  if (!changed)
  988
+  {
  989
+    for (size_t index = 0; index < options.size(); index++)
  990
+    {
  991
+      if (options[index].first.compare(m_dynamicOptions[index].first) != 0 ||
  992
+          options[index].second.compare(m_dynamicOptions[index].second) != 0)
  993
+      {
  994
+        changed = true;
  995
+        break;
  996
+      }
  997
+    }
  998
+  }
  999
+
  1000
+  if (changed)
  1001
+  {
  1002
+    m_dynamicOptions = options;
  1003
+    OnSettingPropertyChanged(this, "options");
  1004
+  }
  1005
+
  1006
+  return options;
  1007
+}
  1008
+
884 1009
 void CSettingString::copy(const CSettingString &setting)
885 1010
 {
886 1011
   CSetting::Copy(setting);
28  xbmc/settings/Setting.h
@@ -56,8 +56,18 @@ typedef enum {
56 56
   SettingLevelInternal
57 57
 } SettingLevel;
58 58
 
59  
-typedef std::pair<int, int> SettingOption;
60  
-typedef std::vector<SettingOption> SettingOptions;
  59
+typedef enum {
  60
+  SettingOptionsTypeNone = 0,
  61
+  SettingOptionsTypeStatic,
  62
+  SettingOptionsTypeDynamic
  63
+} SettingOptionsType;
  64
+
  65
+typedef std::pair<int, int> StaticIntegerSettingOption;
  66
+typedef std::vector<StaticIntegerSettingOption> StaticIntegerSettingOptions;
  67
+typedef std::pair<std::string, int> DynamicIntegerSettingOption;
  68
+typedef std::vector<DynamicIntegerSettingOption> DynamicIntegerSettingOptions;
  69
+typedef std::pair<std::string, std::string> DynamicStringSettingOption;
  70
+typedef std::vector<DynamicStringSettingOption> DynamicStringSettingOptions;
61 71
 
62 72
 /*!
63 73
  \ingroup settings
@@ -83,6 +93,7 @@ class CSetting : public ISetting,
83 93
 
84 94
   int GetLabel() const { return m_label; }
85 95
   int GetHelp() const { return m_help; }
  96
+  bool IsEnabled() const;
86 97
   SettingLevel GetLevel() const { return m_level; }
87 98
   const CSettingControl& GetControl() const { return m_control; }
88 99
   const SettingDependencies& GetDependencies() const { return m_dependencies; }
@@ -95,6 +106,7 @@ class CSetting : public ISetting,
95 106
   virtual void OnSettingChanged(const CSetting *setting);
96 107
   virtual void OnSettingAction(const CSetting *setting);
97 108
   virtual bool OnSettingUpdate(CSetting* &setting, const char *oldSettingId, const TiXmlNode *oldSettingNode);
  109
+  virtual void OnSettingPropertyChanged(const CSetting *setting, const char *propertyName);
98 110
 
99 111
   void Copy(const CSetting &setting);
100 112
 
@@ -158,7 +170,7 @@ class CSettingInt : public CSetting
158 170
   CSettingInt(const std::string &id, const CSettingInt &setting);
159 171
   CSettingInt(const std::string &id, int label, int value, int minimum, int step, int maximum, int format, int minimumLabel, CSettingsManager *settingsManager = NULL);
160 172
   CSettingInt(const std::string &id, int label, int value, int minimum, int step, int maximum, const std::string &format, CSettingsManager *settingsManager = NULL);
161  
-  CSettingInt(const std::string &id, int label, int value, const SettingOptions &options, CSettingsManager *settingsManager = NULL);
  173
+  CSettingInt(const std::string &id, int label, int value, const StaticIntegerSettingOptions &options, CSettingsManager *settingsManager = NULL);
162 174
   virtual ~CSettingInt() { }
163 175
 
164 176
   virtual bool Deserialize(const TiXmlNode *node, bool update = false);
@@ -183,8 +195,10 @@ class CSettingInt : public CSetting
183 195
   int GetFormat() const { return m_format; }
184 196
   int GetMinimumLabel() const { return m_labelMin; }
185 197
   const std::string& GetFormatString() const { return m_strFormat; }
186  
-  const SettingOptions& GetOptions() const { return m_options; }
  198
+  SettingOptionsType GetOptionsType() const;
  199
+  const StaticIntegerSettingOptions& GetOptions() const { return m_options; }
187 200
   const std::string& GetOptionsFiller() const { return m_optionsFiller; }
  201
+  DynamicIntegerSettingOptions UpdateDynamicOptions();
188 202
 
189 203
 private:
190 204
   void copy(const CSettingInt &setting);
@@ -198,8 +212,9 @@ class CSettingInt : public CSetting
198 212
   int m_format;
199 213
   int m_labelMin;
200 214
   std::string m_strFormat;
201  
-  SettingOptions m_options;
  215
+  StaticIntegerSettingOptions m_options;
202 216
   std::string m_optionsFiller;
  217
+  DynamicIntegerSettingOptions m_dynamicOptions;
203 218
 };
204 219
 
205 220
 /*!
@@ -275,7 +290,9 @@ class CSettingString : public CSetting
275 290
   virtual bool AllowEmpty() const { return m_allowEmpty; }
276 291
   virtual int GetHeading() const { return m_heading; }
277 292
 
  293
+  SettingOptionsType GetOptionsType() const;
278 294
   const std::string& GetOptionsFiller() const { return m_optionsFiller; }
  295
+  DynamicStringSettingOptions UpdateDynamicOptions();
279 296
 
280 297
 protected:
281 298
   virtual void copy(const CSettingString &setting);
@@ -285,6 +302,7 @@ class CSettingString : public CSetting
285 302
   bool m_allowEmpty;
286 303
   int m_heading;
287 304
   std::string m_optionsFiller;
  305
+  DynamicStringSettingOptions m_dynamicOptions;
288 306
 };
289 307
 
290 308
 /*!
15  xbmc/settings/Settings.cpp
@@ -457,21 +457,6 @@ CSettingSection* CSettings::GetSection(const std::string &section) const
457 457
   return m_settingsManager->GetSection(section);
458 458
 }
459 459
 
460  
-SettingDependencyMap CSettings::GetDependencies(const std::string &id) const
461  
-{
462  
-  return m_settingsManager->GetDependencies(id);
463  
-}
464  
-
465  
-SettingDependencyMap CSettings::GetDependencies(const CSetting *setting) const
466  
-{
467  
-  return m_settingsManager->GetDependencies(setting);
468  
-}
469  
-
470  
-void* CSettings::GetSettingOptionsFiller(const CSetting *setting)
471  
-{
472  
-  return m_settingsManager->GetSettingOptionsFiller(setting);
473  
-}
474  
-
475 460
 bool CSettings::GetBool(const std::string &id) const
476 461
 {
477 462
   return m_settingsManager->GetBool(id);
35  xbmc/settings/Settings.h
@@ -24,9 +24,9 @@
24 24
 
25 25
 #include "settings/ISettingCallback.h"
26 26
 #include "settings/ISettingCreator.h"
27  
-#include "settings/Setting.h"
28 27
 #include "threads/CriticalSection.h"
29 28
 
  29
+class CSetting;
30 30
 class CSettingSection;
31 31
 class CSettingsManager;
32 32
 class TiXmlElement;
@@ -152,39 +152,6 @@ class CSettings : public ISettingCreator
152 152
    \return Setting section with the given identifier or NULL if the identifier is unknown
153 153
    */
154 154
   CSettingSection* GetSection(const std::string &section) const;
155  
-  /*!
156  
-   \brief Gets a map of settings (and their dependencies) which depend on
157  
-   the setting with the given identifier.
158  
-
159  
-   It is important to note that the returned dependencies are not the
160  
-   dependencies of the setting with the given identifier but the settings
161  
-   (and their dependencies) which depend on the setting with the given
162  
-   identifier.
163  
-
164  
-   \param id Setting identifier
165  
-   \return Map of settings (and their dependencies) which depend on the setting with the given identifier
166  
-   */
167  
-  SettingDependencyMap GetDependencies(const std::string &id) const;
168  
-  /*!
169  
-   \brief Gets a map of settings (and their dependencies) which depend on
170  
-   the given setting.
171  
-
172  
-   It is important to note that the returned dependencies are not the
173  
-   dependencies of the given setting but the settings (and their dependencies)
174  
-   which depend on the given setting.
175  
-
176  
-   \param setting Setting object
177  
-   \return Map of settings (and their dependencies) which depend on the given setting
178  
-   */
179  
-  SettingDependencyMap GetDependencies(const CSetting *setting) const;
180  
-  /*!
181  
-   \brief Gets the implementation of the setting options filler used by the
182  
-   given setting.
183  
-
184  
-   \param setting Setting object
185  
-   \return Implementation of the setting options filler (either IntegerSettingOptionsFiller or StringSettingOptionsFiller)
186  
-   */
187  
-  void* GetSettingOptionsFiller(const CSetting *setting);
188 155
 
189 156
   /*!
190 157
    \brief Gets the boolean value of the setting with the given identifier.
81  xbmc/settings/SettingsManager.cpp
@@ -132,7 +132,19 @@ bool CSettingsManager::Initialize(const TiXmlElement *root)
132 132
         if (setting == m_settings.end())
133 133
           continue;
134 134
 
135  
-        setting->second.dependencies[itSettingDep->first].push_back(*depIt);
  135
+        bool newDep = true;
  136
+        SettingDependencies &settingDeps = setting->second.dependencies[itSettingDep->first];
  137
+        for (SettingDependencies::const_iterator itDeps = settingDeps.begin(); itDeps != settingDeps.end(); ++itDeps)
  138
+        {
  139
+          if (itDeps->GetType() == depIt->GetType())
  140
+          {
  141
+            newDep = false;
  142
+            break;
  143
+          }
  144
+        }
  145
+
  146
+        if (newDep)
  147
+          settingDeps.push_back(*depIt);
136 148
       }
137 149
     }
138 150
   }
@@ -665,6 +677,14 @@ void CSettingsManager::OnSettingChanged(const CSetting *setting)
665 677
         callback != settingData.callbacks.end();
666 678
         callback++)
667 679
     (*callback)->OnSettingChanged(setting);
  680
+
  681
+  // now handle any settings which depend on the changed setting
  682
+  const SettingDependencyMap& deps = GetDependencies(setting);
  683
+  for (SettingDependencyMap::const_iterator depsIt = deps.begin(); depsIt != deps.end(); depsIt++)
  684
+  {
  685
+    for (SettingDependencies::const_iterator depIt = depsIt->second.begin(); depIt != depsIt->second.end(); depIt++)
  686
+      UpdateSettingByDependency(depsIt->first, *depIt);
  687
+  }
668 688
 }
669 689
 
670 690
 void CSettingsManager::OnSettingAction(const CSetting *setting)
@@ -710,6 +730,26 @@ bool CSettingsManager::OnSettingUpdate(CSetting* &setting, const char *oldSettin
710 730
   return ret;
711 731
 }
712 732
 
  733
+void CSettingsManager::OnSettingPropertyChanged(const CSetting *setting, const char *propertyName)
  734
+{
  735
+  CSingleLock lock(m_critical);
  736
+  if (!m_loaded || setting == NULL)
  737
+    return;
  738
+
  739
+  SettingMap::const_iterator settingIt = m_settings.find(setting->GetId());
  740
+  if (settingIt == m_settings.end())
  741
+    return;
  742
+
  743
+  Setting settingData = settingIt->second;
  744
+  // now that we have a copy of the setting's data, we can leave the lock
  745
+  lock.Leave();
  746
+
  747
+  for (CallbackSet::iterator callback = settingData.callbacks.begin();
  748
+        callback != settingData.callbacks.end();
  749
+        callback++)
  750
+    (*callback)->OnSettingPropertyChanged(setting, propertyName);
  751
+}
  752
+
713 753
 CSetting* CSettingsManager::CreateSetting(const std::string &settingType, const std::string &settingId, CSettingsManager *settingsManager /* = NULL */) const
714 754
 {
715 755
   if (StringUtils::EqualsNoCase(settingType, "boolean"))
@@ -871,6 +911,45 @@ bool CSettingsManager::UpdateSetting(const TiXmlNode *node, CSetting *setting, c
871 911
   return updated;
872 912
 }
873 913
 
  914
+void CSettingsManager::UpdateSettingByDependency(const std::string &settingId, const CSettingDependency &dependency)
  915
+{
  916
+  CSetting *setting = GetSetting(settingId);
  917
+  if (setting == NULL)
  918
+    return;
  919
+
  920
+  switch (dependency.GetType())
  921
+  {
  922
+    case SettingDependencyTypeEnable:
  923
+      // just trigger the property changed callback and a call to
  924
+      // CSetting::IsEnabled() will automatically determine the new
  925
+      // enabled state
  926
+      OnSettingPropertyChanged(setting, "enabled");
  927
+      break;
  928
+
  929
+    case SettingDependencyTypeUpdate:
  930
+    {
  931
+      SettingType type = (SettingType)setting->GetType();
  932
+      if (type == SettingTypeInteger)
  933
+      {
  934
+        CSettingInt *settingInt = ((CSettingInt*)setting);
  935
+        if (settingInt->GetOptionsType() == SettingOptionsTypeDynamic)
  936
+          settingInt->UpdateDynamicOptions();
  937
+      }
  938
+      else if (type == SettingTypeString)
  939
+      {
  940
+        CSettingString *settingString = ((CSettingString*)setting);
  941
+        if (settingString->GetOptionsType() == SettingOptionsTypeDynamic)
  942
+          settingString->UpdateDynamicOptions();
  943
+      }
  944
+      break;
  945
+    }
  946
+
  947
+    case SettingDependencyTypeNone:
  948
+    default:
  949
+      break;
  950
+  }
  951
+}
  952
+
874 953
 void CSettingsManager::RegisterSettingOptionsFiller(const std::string &identifier, void *filler, SettingOptionsFillerType type)
875 954
 {
876 955
   SettingOptionsFillerMap::const_iterator it = m_optionsFillers.find(identifier);
10  xbmc/settings/SettingsManager.h
@@ -38,12 +38,8 @@ class CSettingUpdate;
38 38
 class TiXmlElement;
39 39
 class TiXmlNode;
40 40
 
41  
-typedef std::pair<std::string, int> IntegerSettingOption;
42  
-typedef std::pair<std::string, std::string> StringSettingOption;
43  
-typedef std::vector<IntegerSettingOption> IntegerSettingOptions;
44  
-typedef std::vector<StringSettingOption> StringSettingOptions;
45  
-typedef void (*IntegerSettingOptionsFiller)(const CSetting *setting, IntegerSettingOptions &list, int &current);
46  
-typedef void (*StringSettingOptionsFiller)(const CSetting *setting, StringSettingOptions &list, std::string &current);
  41
+typedef void (*IntegerSettingOptionsFiller)(const CSetting *setting, std::vector< std::pair<std::string, int> > &list, int &current);
  42
+typedef void (*StringSettingOptionsFiller)(const CSetting *setting, std::vector< std::pair<std::string, std::string> > &list, std::string &current);
47 43
 
48 44
 /*!
49 45
  \ingroup settings
@@ -353,6 +349,7 @@ class CSettingsManager : public ISettingCreator, private ISettingCallback,
353 349
   virtual void OnSettingChanged(const CSetting *setting);
354 350
   virtual void OnSettingAction(const CSetting *setting);
355 351
   virtual bool OnSettingUpdate(CSetting* &setting, const char *oldSettingId, const TiXmlNode *oldSettingNode);
  352
+  virtual void OnSettingPropertyChanged(const CSetting *setting, const char *propertyName);
356 353
 
357 354
   // implementation of ISettingsHandler
358 355
   virtual bool OnSettingsLoading();
@@ -370,6 +367,7 @@ class CSettingsManager : public ISettingCreator, private ISettingCallback,
370 367
   bool LoadSetting(const TiXmlNode *node, CSetting *setting);
371 368
   bool UpdateSettings(const TiXmlNode *root);
372 369
   bool UpdateSetting(const TiXmlNode *node, CSetting *setting, const CSettingUpdate& update);
  370
+  void UpdateSettingByDependency(const std::string &settingId, const CSettingDependency &dependency);
373 371
 
374 372
   typedef enum {
375 373
     SettingOptionsFillerTypeNone = 0,
169  xbmc/settings/windows/GUIControlSettings.cpp
@@ -44,7 +44,11 @@ CGUIControlBaseSetting::CGUIControlBaseSetting(int id, CSetting *pSetting)
44 44
   m_id = id;
45 45
   m_pSetting = pSetting;
46 46
   m_delayed = false;
47  
-  m_enabled = true;
  47
+}
  48
+
  49
+bool CGUIControlBaseSetting::IsEnabled() const
  50
+{
  51
+  return m_pSetting != NULL && m_pSetting->IsEnabled();
48 52
 }
49 53
 
50 54
 void CGUIControlBaseSetting::Update()
@@ -86,60 +90,7 @@ CGUIControlSpinExSetting::CGUIControlSpinExSetting(CGUISpinControlEx *pSpin, int
86 90
   m_pSpin = pSpin;
87 91
   m_pSpin->SetID(id);
88 92
   
89  
-  switch (pSetting->GetControl().GetFormat())
90  
-  {
91  
-    case SettingControlFormatNumber:
92  
-    {
93  
-      CSettingNumber *pSettingNumber = (CSettingNumber *)pSetting;
94  
-      m_pSpin->SetType(SPIN_CONTROL_TYPE_FLOAT);
95  
-      m_pSpin->SetFloatRange((float)pSettingNumber->GetMinimum(), (float)pSettingNumber->GetMaximum());
96  
-      m_pSpin->SetFloatInterval((float)pSettingNumber->GetStep());
97  
-      break;
98  
-    }
99  
-
100  
-    case SettingControlFormatInteger:
101  
-    case SettingControlFormatString:
102  
-    {
103  
-      m_pSpin->SetType(SPIN_CONTROL_TYPE_TEXT);
104  
-      m_pSpin->Clear();
105  
-
106  
-      if (pSetting->GetType() == SettingTypeInteger)
107  
-      {
108  
-        CSettingInt *pSettingInt = (CSettingInt *)pSetting;
109  
-
110  
-        const SettingOptions& options = pSettingInt->GetOptions();
111  
-        if (!options.empty())
112  
-        {
113  
-          for (SettingOptions::const_iterator it = options.begin(); it != options.end(); it++)
114  
-            m_pSpin->AddLabel(g_localizeStrings.Get(it->first), it->second);
115  
-          m_pSpin->SetValue(pSettingInt->GetValue());
116  
-        }
117  
-        else
118  
-        {
119  
-          std::string strLabel;
120  
-          int i = pSettingInt->GetMinimum();
121  
-          if (pSettingInt->GetMinimumLabel() > -1)
122  
-          {
123  
-            strLabel = g_localizeStrings.Get(pSettingInt->GetMinimumLabel());
124  
-            m_pSpin->AddLabel(strLabel, pSettingInt->GetMinimum());
125  
-            i += pSettingInt->GetStep();
126  
-          }
127  
-          for (; i <= pSettingInt->GetMaximum(); i += pSettingInt->GetStep())
128  
-          {
129  
-            if (pSettingInt->GetFormat() > -1)
130  
-              strLabel = StringUtils::Format(g_localizeStrings.Get(pSettingInt->GetFormat()).c_str(), i);
131  
-            else
132  
-              strLabel = StringUtils::Format(pSettingInt->GetFormatString().c_str(), i);
133  
-            m_pSpin->AddLabel(strLabel, i);
134  
-          }
135  
-        }
136  
-      }
137  
-      break;
138  
-    }
139  
-
140  
-    default:
141  
-      break;
142  
-  }
  93
+  FillControl();
143 94
 }
144 95
 
145 96
 CGUIControlSpinExSetting::~CGUIControlSpinExSetting()
@@ -176,27 +127,111 @@ void CGUIControlSpinExSetting::Update()
176 127
 
177 128
   CGUIControlBaseSetting::Update();
178 129
 
179  
-  switch (m_pSetting->GetType())
  130
+  FillControl();
  131
+
  132
+  // disable the spinner if it has less than two items
  133
+  if (!m_pSpin->IsDisabled() && (m_pSpin->GetMaximum() - m_pSpin->GetMinimum()) == 0)
  134
+    m_pSpin->SetEnabled(false);
  135
+}
  136
+
  137
+void CGUIControlSpinExSetting::FillControl()
  138
+{
  139
+  m_pSpin->Clear();
  140
+
  141
+  switch (m_pSetting->GetControl().GetFormat())
180 142
   {
181  
-    case SettingTypeInteger:
182  
-      m_pSpin->SetValue(((CSettingInt *)m_pSetting)->GetValue());
  143
+    case SettingControlFormatNumber:
  144
+    {
  145
+      CSettingNumber *pSettingNumber = (CSettingNumber *)m_pSetting;
  146
+      m_pSpin->SetType(SPIN_CONTROL_TYPE_FLOAT);
  147
+      m_pSpin->SetFloatRange((float)pSettingNumber->GetMinimum(), (float)pSettingNumber->GetMaximum());
  148
+      m_pSpin->SetFloatInterval((float)pSettingNumber->GetStep());
  149
+
  150
+      m_pSpin->SetFloatValue((float)pSettingNumber->GetValue());
183 151
       break;
  152
+    }
184 153
 
185  
-    case SettingTypeNumber:
186  
-      m_pSpin->SetFloatValue((float)((CSettingNumber *)m_pSetting)->GetValue());
  154
+    case SettingControlFormatInteger:
  155
+    {
  156
+      m_pSpin->SetType(SPIN_CONTROL_TYPE_TEXT);
  157
+      FillIntegerSettingControl();
187 158
       break;
188  
-      
189  
-    case SettingTypeString:
190  
-      m_pSpin->SetStringValue(((CSettingString *)m_pSetting)->GetValue());
  159
+    }
  160
+
  161
+    case SettingControlFormatString:
  162
+    {
  163
+      m_pSpin->SetType(SPIN_CONTROL_TYPE_TEXT);
  164
+
  165
+      if (m_pSetting->GetType() == SettingTypeInteger)
  166
+        FillIntegerSettingControl();
  167
+      else if (m_pSetting->GetType() == SettingTypeString)
  168
+      {
  169
+        CSettingString *pSettingString = (CSettingString *)m_pSetting;
  170
+        if (pSettingString->GetOptionsType() == SettingOptionsTypeDynamic)
  171
+        {
  172
+          DynamicStringSettingOptions options = pSettingString->UpdateDynamicOptions();
  173
+          for (std::vector< std::pair<std::string, std::string> >::const_iterator option = options.begin(); option != options.end(); option++)
  174
+            m_pSpin->AddLabel(option->first, option->second);
  175
+
  176
+          m_pSpin->SetStringValue(pSettingString->GetValue());
  177
+        }
  178
+      }
191 179
       break;
192  
-      
  180
+    }
  181
+
193 182
     default:
194 183
       break;
195 184
   }
  185
+}
196 186
 
197  
-  // disable the spinner if it has less than two items
198  
-  if (!m_pSpin->IsDisabled() && (m_pSpin->GetMaximum() - m_pSpin->GetMinimum()) == 0)
199  
-    m_pSpin->SetEnabled(false);
  187
+void CGUIControlSpinExSetting::FillIntegerSettingControl()
  188
+{
  189
+  CSettingInt *pSettingInt = (CSettingInt *)m_pSetting;
  190
+  switch (pSettingInt->GetOptionsType())
  191
+  {
  192
+    case SettingOptionsTypeStatic:
  193
+    {
  194
+      const StaticIntegerSettingOptions& options = pSettingInt->GetOptions();
  195
+      for (StaticIntegerSettingOptions::const_iterator it = options.begin(); it != options.end(); it++)
  196
+        m_pSpin->AddLabel(g_localizeStrings.Get(it->first), it->second);
  197
+
  198
+      break;
  199
+    }
  200
+
  201
+    case SettingOptionsTypeDynamic:
  202
+    {
  203
+      DynamicIntegerSettingOptions options = pSettingInt->UpdateDynamicOptions();
  204
+      for (DynamicIntegerSettingOptions::const_iterator option = options.begin(); option != options.end(); option++)
  205
+        m_pSpin->AddLabel(option->first, option->second);
  206
+
  207
+      break;
  208
+    }
  209
+
  210
+    case SettingOptionsTypeNone:
  211
+    default:
  212
+    {
  213
+      std::string strLabel;
  214
+      int i = pSettingInt->GetMinimum();
  215
+      if (pSettingInt->GetMinimumLabel() > -1)
  216
+      {
  217
+        strLabel = g_localizeStrings.Get(pSettingInt->GetMinimumLabel());
  218
+        m_pSpin->AddLabel(strLabel, pSettingInt->GetMinimum());
  219
+        i += pSettingInt->GetStep();
  220
+      }
  221
+      for (; i <= pSettingInt->GetMaximum(); i += pSettingInt->GetStep())
  222
+      {
  223
+        if (pSettingInt->GetFormat() > -1)
  224
+          strLabel = StringUtils::Format(g_localizeStrings.Get(pSettingInt->GetFormat()).c_str(), i);
  225
+        else
  226
+          strLabel = StringUtils::Format(pSettingInt->GetFormatString().c_str(), i);
  227
+        m_pSpin->AddLabel(strLabel, i);
  228
+      }
  229
+
  230
+      break;
  231
+    }
  232
+  }
  233
+
  234
+  m_pSpin->SetValue(pSettingInt->GetValue());
200 235
 }
201 236
 
202 237
 CGUIControlButtonSetting::CGUIControlButtonSetting(CGUIButtonControl *pButton, int id, CSetting *pSetting)
16  xbmc/settings/windows/GUIControlSettings.h
@@ -58,17 +58,6 @@ class CGUIControlBaseSetting
58 58
   bool IsDelayed() const { return m_delayed; }
59 59
 
60 60
   /*!
61  
-   \brief Specifies that this setting is enabled or disabled
62  
-   This is used for settings which are enabled/disabled based
63  
-   on conditions involving other settings and their values.
64  
-   It must not be confused with a setting spin control being
65  
-   disabled because it contains less than two items.
66  
-   \param enabled Whether the setting is enabled or disabled
67  
-   \sa IsEnabled()
68  
-   */
69  
-  void SetEnabled(bool enabled) { m_enabled = enabled; }
70  
-
71  
-  /*!
72 61
    \brief Returns whether this setting is enabled or disabled
73 62
    This state is independent of the real enabled state of a
74 63
    setting control but represents the enabled state of the
@@ -76,7 +65,7 @@ class CGUIControlBaseSetting
76 65
    \return true if the setting is enabled otherwise false
77 66
    \sa SetEnabled()
78 67
    */
79  
-  bool IsEnabled() const { return m_enabled; }
  68
+  bool IsEnabled() const;
80 69
 
81 70
   virtual CGUIControl* GetControl() { return NULL; }
82 71
   virtual bool OnClick() { return false; }
@@ -86,7 +75,6 @@ class CGUIControlBaseSetting
86 75
   int m_id;
87 76
   CSetting* m_pSetting;
88 77
   bool m_delayed;
89  
-  bool m_enabled;
90 78
 };
91 79
 
92 80
 class CGUIControlRadioButtonSetting : public CGUIControlBaseSetting
@@ -116,6 +104,8 @@ class CGUIControlSpinExSetting : public CGUIControlBaseSetting
116 104
   virtual void Update();
117 105
   virtual void Clear() { m_pSpin = NULL; }
118 106
 private:
  107
+  void FillControl();
  108
+  void FillIntegerSettingControl();
119 109
   CGUISpinControlEx *m_pSpin;
120 110
 };
121 111
 
131  xbmc/settings/windows/GUIWindowSettingsCategory.cpp
@@ -519,68 +519,19 @@ void CGUIWindowSettingsCategory::OnSettingChanged(const CSetting *setting)
519 519
   if (pControl == NULL)
520 520
     return;
521 521
 
522  
-  const SettingDependencyMap& deps = m_settings.GetDependencies(setting->GetId());
523  
-  for (SettingDependencyMap::const_iterator depsIt = deps.begin(); depsIt != deps.end(); depsIt++)
524  
-  {
525  
-    for (SettingDependencies::const_iterator depIt = depsIt->second.begin(); depIt != depsIt->second.end(); depIt++)
526  
-      UpdateControl(depsIt->first, *depIt);
527  
-  }
528  
-  
529  
-  // update GUI of the changed setting as the change could have been triggered by something else
530 522
   pControl->Update();
531 523
 }
532 524
 
533  
-void CGUIWindowSettingsCategory::UpdateControl(const std::string &dependingSetting, const CSettingDependency &dependency)
  525
+void CGUIWindowSettingsCategory::OnSettingPropertyChanged(const CSetting *setting, const char *propertyName)
534 526
 {
535  
-  if (dependingSetting.empty())
  527
+  if (setting == NULL || propertyName == NULL)
536 528
     return;
537 529
 
538  
-  BaseSettingControlPtr pControl = GetSettingControl(dependingSetting);
539  
-  if (pControl == NULL)
540  
-    return;
541  
-
542  
-  CSetting *pSetting = pControl->GetSetting();
543  
-  if (pSetting == NULL)
  530
+  BaseSettingControlPtr settingControl = GetSettingControl(setting->GetId());
  531
+  if (settingControl == NULL)
544 532
     return;
545 533
 
546  
-  CheckDependency(pControl, dependency);
547  
-
548  
-  const SettingDependencyMap& deps = m_settings.GetDependencies(pSetting->GetId());
549  
-  for (SettingDependencyMap::const_iterator depsIt = deps.begin(); depsIt != deps.end(); depsIt++)
550  
-  {
551  
-    for (SettingDependencies::const_iterator depIt = depsIt->second.begin(); depIt != depsIt->second.end(); depIt++)
552  
-      UpdateControl(depsIt->first, *depIt);
553  
-  }
554  
-
555  
-  // update GUI of the changed setting as the change could have been triggered by something else
556  
-  pControl->Update();
557  
-}
558  
-
559  
-void CGUIWindowSettingsCategory::CheckDependency(BaseSettingControlPtr pSettingControl, const CSettingDependency &dependency)
560  
-{
561  
-  if (pSettingControl == NULL || pSettingControl->GetControl() == NULL)
562  
-    return;
563  
-
564  
-  CSetting *pSetting = pSettingControl->GetSetting();