[cstdstring] remove IsEmpty() and replace with empty()
[vuplus_xbmc] / xbmc / settings / AdvancedSettings.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #include <limits.h>
22
23 #include "system.h"
24 #include "AdvancedSettings.h"
25 #include "Application.h"
26 #include "network/DNSNameCache.h"
27 #include "filesystem/File.h"
28 #include "utils/LangCodeExpander.h"
29 #include "LangInfo.h"
30 #include "profiles/ProfilesManager.h"
31 #include "settings/lib/Setting.h"
32 #include "settings/Settings.h"
33 #include "utils/StringUtils.h"
34 #include "utils/SystemInfo.h"
35 #include "utils/URIUtils.h"
36 #include "utils/XMLUtils.h"
37 #include "utils/log.h"
38 #include "filesystem/SpecialProtocol.h"
39 #include "addons/IAddon.h"
40 #include "addons/AddonManager.h"
41 #include "addons/GUIDialogAddonSettings.h"
42 #if defined(TARGET_DARWIN_IOS)
43 #include "osx/DarwinUtils.h"
44 #endif
45
46 using namespace ADDON;
47 using namespace XFILE;
48 using namespace std;
49
50 CAdvancedSettings::CAdvancedSettings()
51 {
52   m_initialized = false;
53 }
54
55 void CAdvancedSettings::OnSettingsLoaded()
56 {
57   // load advanced settings
58   Load();
59
60   // default players?
61   CLog::Log(LOGNOTICE, "Default DVD Player: %s", m_videoDefaultDVDPlayer.c_str());
62   CLog::Log(LOGNOTICE, "Default Video Player: %s", m_videoDefaultPlayer.c_str());
63   CLog::Log(LOGNOTICE, "Default Audio Player: %s", m_audioDefaultPlayer.c_str());
64
65   // setup any logging...
66   if (CSettings::Get().GetBool("debug.showloginfo"))
67   {
68     m_logLevel = std::max(m_logLevelHint, LOG_LEVEL_DEBUG_FREEMEM);
69     CLog::Log(LOGNOTICE, "Enabled debug logging due to GUI setting (%d)", m_logLevel);
70   }
71   else
72   {
73     m_logLevel = std::min(m_logLevelHint, LOG_LEVEL_DEBUG/*LOG_LEVEL_NORMAL*/);
74     CLog::Log(LOGNOTICE, "Disabled debug logging due to GUI setting. Level %d.", m_logLevel);
75   }
76   CLog::SetLogLevel(m_logLevel);
77 }
78
79 void CAdvancedSettings::OnSettingsUnloaded()
80 {
81   m_initialized = false;
82 }
83
84 void CAdvancedSettings::OnSettingChanged(const CSetting *setting)
85 {
86   if (setting == NULL)
87     return;
88
89   const std::string &settingId = setting->GetId();
90   if (settingId == "debug.showloginfo")
91     SetDebugMode(((CSettingBool*)setting)->GetValue());
92 }
93
94 void CAdvancedSettings::OnSettingAction(const CSetting *setting)
95 {
96   if (setting == NULL)
97     return;
98
99   const std::string settingId = setting->GetId();
100   if (settingId == "debug.setextraloglevel")
101   {
102     AddonPtr addon;
103     CAddonMgr::Get().GetAddon("xbmc.debug", addon);
104     CGUIDialogAddonSettings::ShowAndGetInput(addon, true);
105     SetExtraLogsFromAddon(addon.get());
106   }
107 }
108
109 void CAdvancedSettings::Initialize()
110 {
111   if (m_initialized)
112     return;
113
114   m_audioHeadRoom = 0;
115   m_ac3Gain = 12.0f;
116   m_audioApplyDrc = true;
117   m_dvdplayerIgnoreDTSinWAV = false;
118
119   //default hold time of 25 ms, this allows a 20 hertz sine to pass undistorted
120   m_limiterHold = 0.025f;
121   m_limiterRelease = 0.1f;
122
123   m_omxHWAudioDecode = false;
124   m_omxDecodeStartWithValidFrame = false;
125
126   m_karaokeSyncDelayCDG = 0.0f;
127   m_karaokeSyncDelayLRC = 0.0f;
128   m_karaokeChangeGenreForKaraokeSongs = false;
129   m_karaokeKeepDelay = true;
130   m_karaokeStartIndex = 1;
131   m_karaokeAlwaysEmptyOnCdgs = 1;
132   m_karaokeUseSongSpecificBackground = 0;
133
134   m_audioDefaultPlayer = "paplayer";
135   m_audioPlayCountMinimumPercent = 90.0f;
136   m_audioHost = "default";
137
138   m_videoSubsDelayRange = 10;
139   m_videoAudioDelayRange = 10;
140   m_videoSmallStepBackSeconds = 7;
141   m_videoSmallStepBackTries = 3;
142   m_videoSmallStepBackDelay = 300;
143   m_videoUseTimeSeeking = true;
144   m_videoTimeSeekForward = 30;
145   m_videoTimeSeekBackward = -30;
146   m_videoTimeSeekForwardBig = 600;
147   m_videoTimeSeekBackwardBig = -600;
148   m_videoPercentSeekForward = 2;
149   m_videoPercentSeekBackward = -2;
150   m_videoPercentSeekForwardBig = 10;
151   m_videoPercentSeekBackwardBig = -10;
152   m_videoBlackBarColour = 0;
153   m_videoPPFFmpegDeint = "linblenddeint";
154   m_videoPPFFmpegPostProc = "ha:128:7,va,dr";
155   m_videoDefaultPlayer = "dvdplayer";
156   m_videoDefaultDVDPlayer = "dvdplayer";
157   m_videoIgnoreSecondsAtStart = 3*60;
158   m_videoIgnorePercentAtEnd   = 8.0f;
159   m_videoPlayCountMinimumPercent = 90.0f;
160   m_videoVDPAUScaling = -1;
161   m_videoNonLinStretchRatio = 0.5f;
162   m_videoEnableHighQualityHwScalers = false;
163   m_videoAutoScaleMaxFps = 30.0f;
164   m_videoAllowMpeg4VDPAU = false;
165   m_videoAllowMpeg4VAAPI = false;  
166   m_videoDisableBackgroundDeinterlace = false;
167   m_videoCaptureUseOcclusionQuery = -1; //-1 is auto detect
168   m_videoVDPAUtelecine = false;
169   m_videoVDPAUdeintSkipChromaHD = false;
170   m_DXVACheckCompatibility = false;
171   m_DXVACheckCompatibilityPresent = false;
172   m_DXVAForceProcessorRenderer = true;
173   m_DXVANoDeintProcForProgressive = false;
174   m_videoFpsDetect = 1;
175   m_videoBusyDialogDelay_ms = 500;
176   m_stagefrightConfig.useAVCcodec = -1;
177   m_stagefrightConfig.useVC1codec = -1;
178   m_stagefrightConfig.useVPXcodec = -1;
179   m_stagefrightConfig.useMP4codec = -1;
180   m_stagefrightConfig.useMPEG2codec = -1;
181   m_stagefrightConfig.useSwRenderer = false;
182   m_stagefrightConfig.useInputDTS = false;
183
184   m_videoDefaultLatency = 0.0;
185   m_videoDisableHi10pMultithreading = false;
186
187   m_musicUseTimeSeeking = true;
188   m_musicTimeSeekForward = 10;
189   m_musicTimeSeekBackward = -10;
190   m_musicTimeSeekForwardBig = 60;
191   m_musicTimeSeekBackwardBig = -60;
192   m_musicPercentSeekForward = 1;
193   m_musicPercentSeekBackward = -1;
194   m_musicPercentSeekForwardBig = 10;
195   m_musicPercentSeekBackwardBig = -10;
196
197   m_slideshowPanAmount = 2.5f;
198   m_slideshowZoomAmount = 5.0f;
199   m_slideshowBlackBarCompensation = 20.0f;
200
201   m_songInfoDuration = 10;
202
203   m_cddbAddress = "freedb.freedb.org";
204
205   m_handleMounting = g_application.IsStandAlone();
206
207   m_fullScreenOnMovieStart = true;
208   m_cachePath = "special://temp/";
209
210   m_videoCleanDateTimeRegExp = "(.*[^ _\\,\\.\\(\\)\\[\\]\\-])[ _\\.\\(\\)\\[\\]\\-]+(19[0-9][0-9]|20[0-1][0-9])([ _\\,\\.\\(\\)\\[\\]\\-]|[^0-9]$)";
211
212   m_videoCleanStringRegExps.clear();
213   m_videoCleanStringRegExps.push_back("[ _\\,\\.\\(\\)\\[\\]\\-](ac3|dts|custom|dc|remastered|divx|divx5|dsr|dsrip|dutch|dvd|dvd5|dvd9|dvdrip|dvdscr|dvdscreener|screener|dvdivx|cam|fragment|fs|hdtv|hdrip|hdtvrip|internal|limited|multisubs|ntsc|ogg|ogm|pal|pdtv|proper|repack|rerip|retail|r3|r5|bd5|se|svcd|swedish|german|read.nfo|nfofix|unrated|extended|ws|telesync|ts|telecine|tc|brrip|bdrip|480p|480i|576p|576i|720p|720i|1080p|1080i|3d|hrhd|hrhdtv|hddvd|bluray|x264|h264|xvid|xvidvd|xxx|www.www|cd[1-9]|\\[.*\\])([ _\\,\\.\\(\\)\\[\\]\\-]|$)");
214   m_videoCleanStringRegExps.push_back("(\\[.*\\])");
215
216   m_moviesExcludeFromScanRegExps.clear();
217   m_moviesExcludeFromScanRegExps.push_back("-trailer");
218   m_moviesExcludeFromScanRegExps.push_back("[!-._ \\\\/]sample[-._ \\\\/]");
219   m_tvshowExcludeFromScanRegExps.push_back("[!-._ \\\\/]sample[-._ \\\\/]");
220
221   m_folderStackRegExps.clear();
222   m_folderStackRegExps.push_back("((cd|dvd|dis[ck])[0-9]+)$");
223
224   m_videoStackRegExps.clear();
225   m_videoStackRegExps.push_back("(.*?)([ _.-]*(?:cd|dvd|p(?:(?:ar)?t)|dis[ck]|d)[ _.-]*[0-9]+)(.*?)(\\.[^.]+)$");
226   m_videoStackRegExps.push_back("(.*?)([ _.-]*(?:cd|dvd|p(?:(?:ar)?t)|dis[ck]|d)[ _.-]*[a-d])(.*?)(\\.[^.]+)$");
227   m_videoStackRegExps.push_back("(.*?)([ ._-]*[a-d])(.*?)(\\.[^.]+)$");
228   // This one is a bit too greedy to enable by default.  It will stack sequels
229   // in a flat dir structure, but is perfectly safe in a dir-per-vid one.
230   //m_videoStackRegExps.push_back("(.*?)([ ._-]*[0-9])(.*?)(\\.[^.]+)$");
231
232   m_tvshowEnumRegExps.clear();
233   // foo.s01.e01, foo.s01_e01, S01E02 foo, S01 - E02
234   m_tvshowEnumRegExps.push_back(TVShowRegexp(false,"s([0-9]+)[ ._-]*e([0-9]+(?:(?:[a-i]|\\.[1-9])(?![0-9]))?)([^\\\\/]*)$"));
235   // foo.ep01, foo.EP_01
236   m_tvshowEnumRegExps.push_back(TVShowRegexp(false,"[\\._ -]()ep_?([0-9]+(?:(?:[a-i]|\\.[1-9])(?![0-9]))?)([^\\\\/]*)$"));
237   // foo.yyyy.mm.dd.* (byDate=true)
238   m_tvshowEnumRegExps.push_back(TVShowRegexp(true,"([0-9]{4})[\\.-]([0-9]{2})[\\.-]([0-9]{2})"));
239   // foo.mm.dd.yyyy.* (byDate=true)
240   m_tvshowEnumRegExps.push_back(TVShowRegexp(true,"([0-9]{2})[\\.-]([0-9]{2})[\\.-]([0-9]{4})"));
241   // foo.1x09* or just /1x09*
242   m_tvshowEnumRegExps.push_back(TVShowRegexp(false,"[\\\\/\\._ \\[\\(-]([0-9]+)x([0-9]+(?:(?:[a-i]|\\.[1-9])(?![0-9]))?)([^\\\\/]*)$"));
243   // foo.103*, 103 foo
244   m_tvshowEnumRegExps.push_back(TVShowRegexp(false,"[\\\\/\\._ -]([0-9]+)([0-9][0-9](?:(?:[a-i]|\\.[1-9])(?![0-9]))?)([\\._ -][^\\\\/]*)$"));
245   // Part I, Pt.VI
246   m_tvshowEnumRegExps.push_back(TVShowRegexp(false,"[\\/._ -]p(?:ar)?t[_. -]()([ivx]+)([._ -][^\\/]*)$"));
247
248   m_tvshowMultiPartEnumRegExp = "^[-_ex]+([0-9]+(?:(?:[a-i]|\\.[1-9])(?![0-9]))?)";
249
250   m_remoteDelay = 3;
251   m_controllerDeadzone = 0.2f;
252
253   m_playlistAsFolders = true;
254   m_detectAsUdf = false;
255
256   m_fanartRes = 1080;
257   m_imageRes = 720;
258   m_useDDSFanart = false;
259
260   m_sambaclienttimeout = 10;
261   m_sambadoscodepage = "";
262   m_sambastatfiles = true;
263
264   m_bHTTPDirectoryStatFilesize = false;
265
266   m_bFTPThumbs = false;
267
268   m_musicThumbs = "folder.jpg|Folder.jpg|folder.JPG|Folder.JPG|cover.jpg|Cover.jpg|cover.jpeg|thumb.jpg|Thumb.jpg|thumb.JPG|Thumb.JPG";
269   m_fanartImages = "fanart.jpg|fanart.png";
270
271   m_bMusicLibraryHideAllItems = false;
272   m_bMusicLibraryAllItemsOnBottom = false;
273   m_bMusicLibraryAlbumsSortByArtistThenYear = false;
274   m_bMusicLibraryCleanOnUpdate = false;
275   m_iMusicLibraryRecentlyAddedItems = 25;
276   m_strMusicLibraryAlbumFormat = "";
277   m_strMusicLibraryAlbumFormatRight = "";
278   m_prioritiseAPEv2tags = false;
279   m_musicItemSeparator = " / ";
280   m_videoItemSeparator = " / ";
281
282   m_bVideoLibraryHideAllItems = false;
283   m_bVideoLibraryAllItemsOnBottom = false;
284   m_iVideoLibraryRecentlyAddedItems = 25;
285   m_bVideoLibraryHideEmptySeries = false;
286   m_bVideoLibraryCleanOnUpdate = false;
287   m_bVideoLibraryExportAutoThumbs = false;
288   m_bVideoLibraryImportWatchedState = false;
289   m_bVideoLibraryImportResumePoint = false;
290   m_bVideoScannerIgnoreErrors = false;
291   m_iVideoLibraryDateAdded = 1; // prefer mtime over ctime and current time
292
293   m_iTuxBoxStreamtsPort = 31339;
294   m_bTuxBoxAudioChannelSelection = false;
295   m_bTuxBoxSubMenuSelection = false;
296   m_bTuxBoxPictureIcon= true;
297   m_bTuxBoxSendAllAPids= false;
298   m_iTuxBoxEpgRequestTime = 10; //seconds
299   m_iTuxBoxDefaultSubMenu = 4;
300   m_iTuxBoxDefaultRootMenu = 0; //default TV Mode
301   m_iTuxBoxZapWaitTime = 0; // Time in sec. Default 0:OFF
302   m_bTuxBoxZapstream = true;
303   m_iTuxBoxZapstreamPort = 31344;
304
305   m_iMythMovieLength = 0; // 0 == Off
306
307   m_iEpgLingerTime = 60;           /* keep 1 hour by default */
308   m_iEpgUpdateCheckInterval = 300; /* check if tables need to be updated every 5 minutes */
309   m_iEpgCleanupInterval = 900;     /* remove old entries from the EPG every 15 minutes */
310   m_iEpgActiveTagCheckInterval = 60; /* check for updated active tags every minute */
311   m_iEpgRetryInterruptedUpdateInterval = 30; /* retry an interrupted epg update after 30 seconds */
312   m_iEpgUpdateEmptyTagsInterval = 60; /* override user selectable EPG update interval for empty EPG tags */
313   m_bEpgDisplayUpdatePopup = true; /* display a progress popup while updating EPG data from clients */
314   m_bEpgDisplayIncrementalUpdatePopup = false; /* also display a progress popup while doing incremental EPG updates */
315
316   m_bEdlMergeShortCommBreaks = false;      // Off by default
317   m_iEdlMaxCommBreakLength = 8 * 30 + 10;  // Just over 8 * 30 second commercial break.
318   m_iEdlMinCommBreakLength = 3 * 30;       // 3 * 30 second commercial breaks.
319   m_iEdlMaxCommBreakGap = 4 * 30;          // 4 * 30 second commercial breaks.
320   m_iEdlMaxStartGap = 5 * 60;              // 5 minutes.
321   m_iEdlCommBreakAutowait = 0;             // Off by default
322   m_iEdlCommBreakAutowind = 0;             // Off by default
323
324   m_curlconnecttimeout = 10;
325   m_curllowspeedtime = 20;
326   m_curlretries = 2;
327   m_curlDisableIPV6 = false;      //Certain hardware/OS combinations have trouble
328                                   //with ipv6.
329
330   m_fullScreen = m_startFullScreen = false;
331   m_showExitButton = true;
332   m_splashImage = true;
333
334   m_playlistRetries = 100;
335   m_playlistTimeout = 20; // 20 seconds timeout
336   m_GLRectangleHack = false;
337   m_iSkipLoopFilter = 0;
338   m_AllowD3D9Ex = true;
339   m_ForceD3D9Ex = false;
340   m_AllowDynamicTextures = true;
341   m_RestrictCapsMask = 0;
342   m_sleepBeforeFlip = 0;
343   m_bVirtualShares = true;
344
345 //caused lots of jerks
346 //#ifdef TARGET_WINDOWS
347 //  m_ForcedSwapTime = 2.0;
348 //#else
349   m_ForcedSwapTime = 0.0;
350 //#endif
351
352   m_cpuTempCmd = "";
353   m_gpuTempCmd = "";
354 #if defined(TARGET_DARWIN)
355   // default for osx is fullscreen always on top
356   m_alwaysOnTop = true;
357 #else
358   // default for windows is not always on top
359   m_alwaysOnTop = false;
360 #endif
361
362   m_iPVRTimeCorrection             = 0;
363   m_iPVRInfoToggleInterval         = 3000;
364   m_bPVRShowEpgInfoOnEpgItemSelect = false;
365   m_iPVRMinVideoCacheLevel         = 5;
366   m_iPVRMinAudioCacheLevel         = 10;
367   m_bPVRCacheInDvdPlayer           = true;
368   m_bPVRChannelIconsAutoScan       = true;
369   m_bPVRAutoScanIconsUserSet       = false;
370   m_iPVRNumericChannelSwitchTimeout = 1000;
371
372   m_measureRefreshrate = false;
373
374   m_cacheMemBufferSize = 1024 * 1024 * 20;
375   m_networkBufferMode = 0; // Default (buffer all internet streams/filesystems)
376   // the following setting determines the readRate of a player data
377   // as multiply of the default data read rate
378   m_readBufferFactor = 1.0f;
379   m_addonPackageFolderSize = 200;
380
381   m_jsonOutputCompact = true;
382   m_jsonTcpPort = 9090;
383
384   m_enableMultimediaKeys = false;
385
386   m_canWindowed = true;
387   m_guiVisualizeDirtyRegions = false;
388   m_guiAlgorithmDirtyRegions = 3;
389   m_guiDirtyRegionNoFlipTimeout = 0;
390   m_logEnableAirtunes = false;
391   m_airTunesPort = 36666;
392   m_airPlayPort = 36667;
393
394   m_databaseMusic.Reset();
395   m_databaseVideo.Reset();
396
397   m_pictureExtensions = ".png|.jpg|.jpeg|.bmp|.gif|.ico|.tif|.tiff|.tga|.pcx|.cbz|.zip|.cbr|.rar|.dng|.nef|.cr2|.crw|.orf|.arw|.erf|.3fr|.dcr|.x3f|.mef|.raf|.mrw|.pef|.sr2|.rss";
398   m_musicExtensions = ".nsv|.m4a|.flac|.aac|.strm|.pls|.rm|.rma|.mpa|.wav|.wma|.ogg|.mp3|.mp2|.m3u|.mod|.amf|.669|.dmf|.dsm|.far|.gdm|.imf|.it|.m15|.med|.okt|.s3m|.stm|.sfx|.ult|.uni|.xm|.sid|.ac3|.dts|.cue|.aif|.aiff|.wpl|.ape|.mac|.mpc|.mp+|.mpp|.shn|.zip|.rar|.wv|.nsf|.spc|.gym|.adx|.dsp|.adp|.ymf|.ast|.afc|.hps|.xsp|.xwav|.waa|.wvs|.wam|.gcm|.idsp|.mpdsp|.mss|.spt|.rsd|.mid|.kar|.sap|.cmc|.cmr|.dmc|.mpt|.mpd|.rmt|.tmc|.tm8|.tm2|.oga|.url|.pxml|.tta|.rss|.cm3|.cms|.dlt|.brstm|.wtv|.mka";
399   m_videoExtensions = ".m4v|.3g2|.3gp|.nsv|.tp|.ts|.ty|.strm|.pls|.rm|.rmvb|.m3u|.m3u8|.ifo|.mov|.qt|.divx|.xvid|.bivx|.vob|.nrg|.img|.iso|.pva|.wmv|.asf|.asx|.ogm|.m2v|.avi|.bin|.dat|.mpg|.mpeg|.mp4|.mkv|.avc|.vp3|.svq3|.nuv|.viv|.dv|.fli|.flv|.rar|.001|.wpl|.zip|.vdr|.dvr-ms|.xsp|.mts|.m2t|.m2ts|.evo|.ogv|.sdp|.avs|.rec|.url|.pxml|.vc1|.h264|.rcv|.rss|.mpls|.webm|.bdmv|.wtv";
400   m_subtitlesExtensions = ".utf|.utf8|.utf-8|.sub|.srt|.smi|.rt|.txt|.ssa|.text|.ssa|.aqt|.jss|.ass|.idx|.ifo|.rar|.zip";
401   m_discStubExtensions = ".disc";
402   // internal music extensions
403   m_musicExtensions += "|.sidstream|.oggstream|.nsfstream|.asapstream|.cdda";
404   // internal video extensions
405   m_videoExtensions += "|.pvr";
406
407   m_stereoscopicflags_sbs = "3DSBS|3D.SBS|HSBS|H.SBS|H-SBS| SBS |FULL-SBS|FULL.SBS|FULLSBS|FSBS|HALF-SBS";
408   m_stereoscopicflags_tab = "3DTAB|3D.TAB|HTAB|H.TAB|3DOU|3D.OU|3D.HOU| HOU | OU |HALF-TAB";
409
410   m_logLevelHint = m_logLevel = LOG_LEVEL_NORMAL;
411   m_extraLogLevels = 0;
412
413   #if defined(TARGET_DARWIN)
414     CStdString logDir = getenv("HOME");
415     #if defined(TARGET_DARWIN_OSX)
416     logDir += "/Library/Logs/";
417     #else // ios/atv2
418     logDir += "/" + CStdString(DarwinGetXbmcRootFolder()) + "/";
419     #endif
420     m_logFolder = logDir;
421   #else
422     m_logFolder = "special://home/";              // log file location
423   #endif
424
425   m_userAgent = g_sysinfo.GetUserAgent();
426
427   m_initialized = true;
428 }
429
430 bool CAdvancedSettings::Load()
431 {
432   // NOTE: This routine should NOT set the default of any of these parameters
433   //       it should instead use the versions of GetString/Integer/Float that
434   //       don't take defaults in.  Defaults are set in the constructor above
435   Initialize(); // In case of profile switch.
436   ParseSettingsFile("special://xbmc/system/advancedsettings.xml");
437   for (unsigned int i = 0; i < m_settingsFiles.size(); i++)
438     ParseSettingsFile(m_settingsFiles[i]);
439   ParseSettingsFile(CProfilesManager::Get().GetUserDataItem("advancedsettings.xml"));
440
441   // Add the list of disc stub extensions (if any) to the list of video extensions
442   if (!m_discStubExtensions.empty())
443     m_videoExtensions += "|" + m_discStubExtensions;
444
445   return true;
446 }
447
448 void CAdvancedSettings::ParseSettingsFile(const CStdString &file)
449 {
450   CXBMCTinyXML advancedXML;
451   if (!CFile::Exists(file))
452   {
453     CLog::Log(LOGNOTICE, "No settings file to load (%s)", file.c_str());
454     return;
455   }
456
457   if (!advancedXML.LoadFile(file))
458   {
459     CLog::Log(LOGERROR, "Error loading %s, Line %d\n%s", file.c_str(), advancedXML.ErrorRow(), advancedXML.ErrorDesc());
460     return;
461   }
462
463   TiXmlElement *pRootElement = advancedXML.RootElement();
464   if (!pRootElement || strcmpi(pRootElement->Value(),"advancedsettings") != 0)
465   {
466     CLog::Log(LOGERROR, "Error loading %s, no <advancedsettings> node", file.c_str());
467     return;
468   }
469
470   // succeeded - tell the user it worked
471   CLog::Log(LOGNOTICE, "Loaded settings file from %s", file.c_str());
472
473   // Dump contents of AS.xml to debug log
474   TiXmlPrinter printer;
475   printer.SetLineBreak("\n");
476   printer.SetIndent("  ");
477   advancedXML.Accept(&printer);
478   CLog::Log(LOGNOTICE, "Contents of %s are...\n%s", file.c_str(), printer.CStr());
479
480   TiXmlElement *pElement = pRootElement->FirstChildElement("audio");
481   if (pElement)
482   {
483     XMLUtils::GetFloat(pElement, "ac3downmixgain", m_ac3Gain, -96.0f, 96.0f);
484     XMLUtils::GetInt(pElement, "headroom", m_audioHeadRoom, 0, 12);
485     XMLUtils::GetString(pElement, "defaultplayer", m_audioDefaultPlayer);
486     // 101 on purpose - can be used to never automark as watched
487     XMLUtils::GetFloat(pElement, "playcountminimumpercent", m_audioPlayCountMinimumPercent, 0.0f, 101.0f);
488
489     XMLUtils::GetBoolean(pElement, "usetimeseeking", m_musicUseTimeSeeking);
490     XMLUtils::GetInt(pElement, "timeseekforward", m_musicTimeSeekForward, 0, 6000);
491     XMLUtils::GetInt(pElement, "timeseekbackward", m_musicTimeSeekBackward, -6000, 0);
492     XMLUtils::GetInt(pElement, "timeseekforwardbig", m_musicTimeSeekForwardBig, 0, 6000);
493     XMLUtils::GetInt(pElement, "timeseekbackwardbig", m_musicTimeSeekBackwardBig, -6000, 0);
494
495     XMLUtils::GetInt(pElement, "percentseekforward", m_musicPercentSeekForward, 0, 100);
496     XMLUtils::GetInt(pElement, "percentseekbackward", m_musicPercentSeekBackward, -100, 0);
497     XMLUtils::GetInt(pElement, "percentseekforwardbig", m_musicPercentSeekForwardBig, 0, 100);
498     XMLUtils::GetInt(pElement, "percentseekbackwardbig", m_musicPercentSeekBackwardBig, -100, 0);
499
500     TiXmlElement* pAudioExcludes = pElement->FirstChildElement("excludefromlisting");
501     if (pAudioExcludes)
502       GetCustomRegexps(pAudioExcludes, m_audioExcludeFromListingRegExps);
503
504     pAudioExcludes = pElement->FirstChildElement("excludefromscan");
505     if (pAudioExcludes)
506       GetCustomRegexps(pAudioExcludes, m_audioExcludeFromScanRegExps);
507
508     XMLUtils::GetString(pElement, "audiohost", m_audioHost);
509     XMLUtils::GetBoolean(pElement, "applydrc", m_audioApplyDrc);
510     XMLUtils::GetBoolean(pElement, "dvdplayerignoredtsinwav", m_dvdplayerIgnoreDTSinWAV);
511
512     XMLUtils::GetFloat(pElement, "limiterhold", m_limiterHold, 0.0f, 100.0f);
513     XMLUtils::GetFloat(pElement, "limiterrelease", m_limiterRelease, 0.001f, 100.0f);
514   }
515
516   pElement = pRootElement->FirstChildElement("omx");
517   if (pElement)
518   {
519     XMLUtils::GetBoolean(pElement, "omxhwaudiodecode", m_omxHWAudioDecode);
520     XMLUtils::GetBoolean(pElement, "omxdecodestartwithvalidframe", m_omxDecodeStartWithValidFrame);
521   }
522
523   pElement = pRootElement->FirstChildElement("karaoke");
524   if (pElement)
525   {
526     XMLUtils::GetFloat(pElement, "syncdelaycdg", m_karaokeSyncDelayCDG, -3.0f, 3.0f); // keep the old name for comp
527     XMLUtils::GetFloat(pElement, "syncdelaylrc", m_karaokeSyncDelayLRC, -3.0f, 3.0f);
528     XMLUtils::GetBoolean(pElement, "alwaysreplacegenre", m_karaokeChangeGenreForKaraokeSongs );
529     XMLUtils::GetBoolean(pElement, "storedelay", m_karaokeKeepDelay );
530     XMLUtils::GetInt(pElement, "autoassignstartfrom", m_karaokeStartIndex, 1, 2000000000);
531     XMLUtils::GetBoolean(pElement, "nocdgbackground", m_karaokeAlwaysEmptyOnCdgs );
532     XMLUtils::GetBoolean(pElement, "lookupsongbackground", m_karaokeUseSongSpecificBackground );
533
534     TiXmlElement* pKaraokeBackground = pElement->FirstChildElement("defaultbackground");
535     if (pKaraokeBackground)
536     {
537       const char* attr = pKaraokeBackground->Attribute("type");
538       if ( attr )
539         m_karaokeDefaultBackgroundType = attr;
540
541       attr = pKaraokeBackground->Attribute("path");
542       if ( attr )
543         m_karaokeDefaultBackgroundFilePath = attr;
544     }
545   }
546
547   pElement = pRootElement->FirstChildElement("video");
548   if (pElement)
549   {
550     XMLUtils::GetString(pElement, "stereoscopicflagssbs", m_stereoscopicflags_sbs);
551     XMLUtils::GetString(pElement, "stereoscopicflagstab", m_stereoscopicflags_tab);
552     XMLUtils::GetFloat(pElement, "subsdelayrange", m_videoSubsDelayRange, 10, 600);
553     XMLUtils::GetFloat(pElement, "audiodelayrange", m_videoAudioDelayRange, 10, 600);
554     XMLUtils::GetInt(pElement, "blackbarcolour", m_videoBlackBarColour, 0, 255);
555     XMLUtils::GetString(pElement, "defaultplayer", m_videoDefaultPlayer);
556     XMLUtils::GetString(pElement, "defaultdvdplayer", m_videoDefaultDVDPlayer);
557     XMLUtils::GetBoolean(pElement, "fullscreenonmoviestart", m_fullScreenOnMovieStart);
558     // 101 on purpose - can be used to never automark as watched
559     XMLUtils::GetFloat(pElement, "playcountminimumpercent", m_videoPlayCountMinimumPercent, 0.0f, 101.0f);
560     XMLUtils::GetInt(pElement, "ignoresecondsatstart", m_videoIgnoreSecondsAtStart, 0, 900);
561     XMLUtils::GetFloat(pElement, "ignorepercentatend", m_videoIgnorePercentAtEnd, 0, 100.0f);
562
563     XMLUtils::GetInt(pElement, "smallstepbackseconds", m_videoSmallStepBackSeconds, 1, INT_MAX);
564     XMLUtils::GetInt(pElement, "smallstepbacktries", m_videoSmallStepBackTries, 1, 10);
565     XMLUtils::GetInt(pElement, "smallstepbackdelay", m_videoSmallStepBackDelay, 100, 5000); //MS
566
567     XMLUtils::GetBoolean(pElement, "usetimeseeking", m_videoUseTimeSeeking);
568     XMLUtils::GetInt(pElement, "timeseekforward", m_videoTimeSeekForward, 0, 6000);
569     XMLUtils::GetInt(pElement, "timeseekbackward", m_videoTimeSeekBackward, -6000, 0);
570     XMLUtils::GetInt(pElement, "timeseekforwardbig", m_videoTimeSeekForwardBig, 0, 6000);
571     XMLUtils::GetInt(pElement, "timeseekbackwardbig", m_videoTimeSeekBackwardBig, -6000, 0);
572
573     XMLUtils::GetInt(pElement, "percentseekforward", m_videoPercentSeekForward, 0, 100);
574     XMLUtils::GetInt(pElement, "percentseekbackward", m_videoPercentSeekBackward, -100, 0);
575     XMLUtils::GetInt(pElement, "percentseekforwardbig", m_videoPercentSeekForwardBig, 0, 100);
576     XMLUtils::GetInt(pElement, "percentseekbackwardbig", m_videoPercentSeekBackwardBig, -100, 0);
577
578     TiXmlElement* pVideoExcludes = pElement->FirstChildElement("excludefromlisting");
579     if (pVideoExcludes)
580       GetCustomRegexps(pVideoExcludes, m_videoExcludeFromListingRegExps);
581
582     pVideoExcludes = pElement->FirstChildElement("excludefromscan");
583     if (pVideoExcludes)
584       GetCustomRegexps(pVideoExcludes, m_moviesExcludeFromScanRegExps);
585
586     pVideoExcludes = pElement->FirstChildElement("excludetvshowsfromscan");
587     if (pVideoExcludes)
588       GetCustomRegexps(pVideoExcludes, m_tvshowExcludeFromScanRegExps);
589
590     pVideoExcludes = pElement->FirstChildElement("cleanstrings");
591     if (pVideoExcludes)
592       GetCustomRegexps(pVideoExcludes, m_videoCleanStringRegExps);
593
594     XMLUtils::GetString(pElement,"cleandatetime", m_videoCleanDateTimeRegExp);
595     XMLUtils::GetString(pElement,"ppffmpegdeinterlacing",m_videoPPFFmpegDeint);
596     XMLUtils::GetString(pElement,"ppffmpegpostprocessing",m_videoPPFFmpegPostProc);
597     XMLUtils::GetInt(pElement,"vdpauscaling",m_videoVDPAUScaling);
598     XMLUtils::GetFloat(pElement, "nonlinearstretchratio", m_videoNonLinStretchRatio, 0.01f, 1.0f);
599     XMLUtils::GetBoolean(pElement,"enablehighqualityhwscalers", m_videoEnableHighQualityHwScalers);
600     XMLUtils::GetFloat(pElement,"autoscalemaxfps",m_videoAutoScaleMaxFps, 0.0f, 1000.0f);
601     XMLUtils::GetBoolean(pElement,"allowmpeg4vdpau",m_videoAllowMpeg4VDPAU);
602     XMLUtils::GetBoolean(pElement,"disablehi10pmultithreading",m_videoDisableHi10pMultithreading);
603     XMLUtils::GetBoolean(pElement,"allowmpeg4vaapi",m_videoAllowMpeg4VAAPI);    
604     XMLUtils::GetBoolean(pElement, "disablebackgrounddeinterlace", m_videoDisableBackgroundDeinterlace);
605     XMLUtils::GetInt(pElement, "useocclusionquery", m_videoCaptureUseOcclusionQuery, -1, 1);
606     XMLUtils::GetBoolean(pElement,"vdpauInvTelecine",m_videoVDPAUtelecine);
607     XMLUtils::GetBoolean(pElement,"vdpauHDdeintSkipChroma",m_videoVDPAUdeintSkipChromaHD);
608
609     TiXmlElement* pStagefrightElem = pElement->FirstChildElement("stagefright");
610     if (pStagefrightElem)
611     {
612       XMLUtils::GetInt(pStagefrightElem,"useavccodec",m_stagefrightConfig.useAVCcodec, -1, 1);
613       XMLUtils::GetInt(pStagefrightElem,"usevc1codec",m_stagefrightConfig.useVC1codec, -1, 1);
614       XMLUtils::GetInt(pStagefrightElem,"usevpxcodec",m_stagefrightConfig.useVPXcodec, -1, 1);
615       XMLUtils::GetInt(pStagefrightElem,"usemp4codec",m_stagefrightConfig.useMP4codec, -1, 1);
616       XMLUtils::GetInt(pStagefrightElem,"usempeg2codec",m_stagefrightConfig.useMPEG2codec, -1, 1);
617       XMLUtils::GetBoolean(pStagefrightElem,"useswrenderer",m_stagefrightConfig.useSwRenderer);
618       XMLUtils::GetBoolean(pStagefrightElem,"useinputdts",m_stagefrightConfig.useInputDTS);
619     }
620
621     TiXmlElement* pAdjustRefreshrate = pElement->FirstChildElement("adjustrefreshrate");
622     if (pAdjustRefreshrate)
623     {
624       TiXmlElement* pRefreshOverride = pAdjustRefreshrate->FirstChildElement("override");
625       while (pRefreshOverride)
626       {
627         RefreshOverride override = {0};
628
629         float fps;
630         if (XMLUtils::GetFloat(pRefreshOverride, "fps", fps))
631         {
632           override.fpsmin = fps - 0.01f;
633           override.fpsmax = fps + 0.01f;
634         }
635
636         float fpsmin, fpsmax;
637         if (XMLUtils::GetFloat(pRefreshOverride, "fpsmin", fpsmin) &&
638             XMLUtils::GetFloat(pRefreshOverride, "fpsmax", fpsmax))
639         {
640           override.fpsmin = fpsmin;
641           override.fpsmax = fpsmax;
642         }
643
644         float refresh;
645         if (XMLUtils::GetFloat(pRefreshOverride, "refresh", refresh))
646         {
647           override.refreshmin = refresh - 0.01f;
648           override.refreshmax = refresh + 0.01f;
649         }
650
651         float refreshmin, refreshmax;
652         if (XMLUtils::GetFloat(pRefreshOverride, "refreshmin", refreshmin) &&
653             XMLUtils::GetFloat(pRefreshOverride, "refreshmax", refreshmax))
654         {
655           override.refreshmin = refreshmin;
656           override.refreshmax = refreshmax;
657         }
658
659         bool fpsCorrect     = (override.fpsmin > 0.0f && override.fpsmax >= override.fpsmin);
660         bool refreshCorrect = (override.refreshmin > 0.0f && override.refreshmax >= override.refreshmin);
661
662         if (fpsCorrect && refreshCorrect)
663           m_videoAdjustRefreshOverrides.push_back(override);
664         else
665           CLog::Log(LOGWARNING, "Ignoring malformed refreshrate override, fpsmin:%f fpsmax:%f refreshmin:%f refreshmax:%f",
666               override.fpsmin, override.fpsmax, override.refreshmin, override.refreshmax);
667
668         pRefreshOverride = pRefreshOverride->NextSiblingElement("override");
669       }
670
671       TiXmlElement* pRefreshFallback = pAdjustRefreshrate->FirstChildElement("fallback");
672       while (pRefreshFallback)
673       {
674         RefreshOverride fallback = {0};
675         fallback.fallback = true;
676
677         float refresh;
678         if (XMLUtils::GetFloat(pRefreshFallback, "refresh", refresh))
679         {
680           fallback.refreshmin = refresh - 0.01f;
681           fallback.refreshmax = refresh + 0.01f;
682         }
683
684         float refreshmin, refreshmax;
685         if (XMLUtils::GetFloat(pRefreshFallback, "refreshmin", refreshmin) &&
686             XMLUtils::GetFloat(pRefreshFallback, "refreshmax", refreshmax))
687         {
688           fallback.refreshmin = refreshmin;
689           fallback.refreshmax = refreshmax;
690         }
691
692         if (fallback.refreshmin > 0.0f && fallback.refreshmax >= fallback.refreshmin)
693           m_videoAdjustRefreshOverrides.push_back(fallback);
694         else
695           CLog::Log(LOGWARNING, "Ignoring malformed refreshrate fallback, fpsmin:%f fpsmax:%f refreshmin:%f refreshmax:%f",
696               fallback.fpsmin, fallback.fpsmax, fallback.refreshmin, fallback.refreshmax);
697
698         pRefreshFallback = pRefreshFallback->NextSiblingElement("fallback");
699       }
700     }
701
702     m_DXVACheckCompatibilityPresent = XMLUtils::GetBoolean(pElement,"checkdxvacompatibility", m_DXVACheckCompatibility);
703
704     XMLUtils::GetBoolean(pElement,"forcedxvarenderer", m_DXVAForceProcessorRenderer);
705     XMLUtils::GetBoolean(pElement,"dxvanodeintforprogressive", m_DXVANoDeintProcForProgressive);
706     //0 = disable fps detect, 1 = only detect on timestamps with uniform spacing, 2 detect on all timestamps
707     XMLUtils::GetInt(pElement, "fpsdetect", m_videoFpsDetect, 0, 2);
708
709     // controls the delay, in milliseconds, until
710     // the busy dialog is shown when starting video playback.
711     XMLUtils::GetInt(pElement, "busydialogdelayms", m_videoBusyDialogDelay_ms, 0, 1000);
712
713     // Store global display latency settings
714     TiXmlElement* pVideoLatency = pElement->FirstChildElement("latency");
715     if (pVideoLatency)
716     {
717       float refresh, refreshmin, refreshmax, delay;
718       TiXmlElement* pRefreshVideoLatency = pVideoLatency->FirstChildElement("refresh");
719
720       while (pRefreshVideoLatency)
721       {
722         RefreshVideoLatency videolatency = {0};
723
724         if (XMLUtils::GetFloat(pRefreshVideoLatency, "rate", refresh))
725         {
726           videolatency.refreshmin = refresh - 0.01f;
727           videolatency.refreshmax = refresh + 0.01f;
728         }
729         else if (XMLUtils::GetFloat(pRefreshVideoLatency, "min", refreshmin) &&
730                  XMLUtils::GetFloat(pRefreshVideoLatency, "max", refreshmax))
731         {
732           videolatency.refreshmin = refreshmin;
733           videolatency.refreshmax = refreshmax;
734         }
735         if (XMLUtils::GetFloat(pRefreshVideoLatency, "delay", delay, -600.0f, 600.0f))
736           videolatency.delay = delay;
737
738         if (videolatency.refreshmin > 0.0f && videolatency.refreshmax >= videolatency.refreshmin)
739           m_videoRefreshLatency.push_back(videolatency);
740         else
741           CLog::Log(LOGWARNING, "Ignoring malformed display latency <refresh> entry, min:%f max:%f", videolatency.refreshmin, videolatency.refreshmax);
742
743         pRefreshVideoLatency = pRefreshVideoLatency->NextSiblingElement("refresh");
744       }
745
746       // Get default global display latency
747       XMLUtils::GetFloat(pVideoLatency, "delay", m_videoDefaultLatency, -600.0f, 600.0f);
748     }
749   }
750
751   pElement = pRootElement->FirstChildElement("musiclibrary");
752   if (pElement)
753   {
754     XMLUtils::GetBoolean(pElement, "hideallitems", m_bMusicLibraryHideAllItems);
755     XMLUtils::GetInt(pElement, "recentlyaddeditems", m_iMusicLibraryRecentlyAddedItems, 1, INT_MAX);
756     XMLUtils::GetBoolean(pElement, "prioritiseapetags", m_prioritiseAPEv2tags);
757     XMLUtils::GetBoolean(pElement, "allitemsonbottom", m_bMusicLibraryAllItemsOnBottom);
758     XMLUtils::GetBoolean(pElement, "albumssortbyartistthenyear", m_bMusicLibraryAlbumsSortByArtistThenYear);
759     XMLUtils::GetBoolean(pElement, "cleanonupdate", m_bMusicLibraryCleanOnUpdate);
760     XMLUtils::GetString(pElement, "albumformat", m_strMusicLibraryAlbumFormat);
761     XMLUtils::GetString(pElement, "albumformatright", m_strMusicLibraryAlbumFormatRight);
762     XMLUtils::GetString(pElement, "itemseparator", m_musicItemSeparator);
763   }
764
765   pElement = pRootElement->FirstChildElement("videolibrary");
766   if (pElement)
767   {
768     XMLUtils::GetBoolean(pElement, "hideallitems", m_bVideoLibraryHideAllItems);
769     XMLUtils::GetBoolean(pElement, "allitemsonbottom", m_bVideoLibraryAllItemsOnBottom);
770     XMLUtils::GetInt(pElement, "recentlyaddeditems", m_iVideoLibraryRecentlyAddedItems, 1, INT_MAX);
771     XMLUtils::GetBoolean(pElement, "hideemptyseries", m_bVideoLibraryHideEmptySeries);
772     XMLUtils::GetBoolean(pElement, "cleanonupdate", m_bVideoLibraryCleanOnUpdate);
773     XMLUtils::GetString(pElement, "itemseparator", m_videoItemSeparator);
774     XMLUtils::GetBoolean(pElement, "exportautothumbs", m_bVideoLibraryExportAutoThumbs);
775     XMLUtils::GetBoolean(pElement, "importwatchedstate", m_bVideoLibraryImportWatchedState);
776     XMLUtils::GetBoolean(pElement, "importresumepoint", m_bVideoLibraryImportResumePoint);
777     XMLUtils::GetInt(pElement, "dateadded", m_iVideoLibraryDateAdded);
778   }
779
780   pElement = pRootElement->FirstChildElement("videoscanner");
781   if (pElement)
782   {
783     XMLUtils::GetBoolean(pElement, "ignoreerrors", m_bVideoScannerIgnoreErrors);
784   }
785
786   // Backward-compatibility of ExternalPlayer config
787   pElement = pRootElement->FirstChildElement("externalplayer");
788   if (pElement)
789   {
790     CLog::Log(LOGWARNING, "External player configuration has been removed from advancedsettings.xml.  It can now be configed in userdata/playercorefactory.xml");
791   }
792   pElement = pRootElement->FirstChildElement("slideshow");
793   if (pElement)
794   {
795     XMLUtils::GetFloat(pElement, "panamount", m_slideshowPanAmount, 0.0f, 20.0f);
796     XMLUtils::GetFloat(pElement, "zoomamount", m_slideshowZoomAmount, 0.0f, 20.0f);
797     XMLUtils::GetFloat(pElement, "blackbarcompensation", m_slideshowBlackBarCompensation, 0.0f, 50.0f);
798   }
799
800   pElement = pRootElement->FirstChildElement("network");
801   if (pElement)
802   {
803     XMLUtils::GetInt(pElement, "curlclienttimeout", m_curlconnecttimeout, 1, 1000);
804     XMLUtils::GetInt(pElement, "curllowspeedtime", m_curllowspeedtime, 1, 1000);
805     XMLUtils::GetInt(pElement, "curlretries", m_curlretries, 0, 10);
806     XMLUtils::GetBoolean(pElement,"disableipv6", m_curlDisableIPV6);
807     XMLUtils::GetUInt(pElement, "cachemembuffersize", m_cacheMemBufferSize);
808     XMLUtils::GetUInt(pElement, "buffermode", m_networkBufferMode, 0, 3);
809     XMLUtils::GetFloat(pElement, "readbufferfactor", m_readBufferFactor);
810   }
811
812   pElement = pRootElement->FirstChildElement("jsonrpc");
813   if (pElement)
814   {
815     XMLUtils::GetBoolean(pElement, "compactoutput", m_jsonOutputCompact);
816     XMLUtils::GetUInt(pElement, "tcpport", m_jsonTcpPort);
817   }
818
819   pElement = pRootElement->FirstChildElement("samba");
820   if (pElement)
821   {
822     XMLUtils::GetString(pElement,  "doscodepage",   m_sambadoscodepage);
823     XMLUtils::GetInt(pElement, "clienttimeout", m_sambaclienttimeout, 5, 100);
824     XMLUtils::GetBoolean(pElement, "statfiles", m_sambastatfiles);
825   }
826
827   pElement = pRootElement->FirstChildElement("httpdirectory");
828   if (pElement)
829     XMLUtils::GetBoolean(pElement, "statfilesize", m_bHTTPDirectoryStatFilesize);
830
831   pElement = pRootElement->FirstChildElement("ftp");
832   if (pElement)
833   {
834     XMLUtils::GetBoolean(pElement, "remotethumbs", m_bFTPThumbs);
835   }
836
837   pElement = pRootElement->FirstChildElement("loglevel");
838   if (pElement)
839   { // read the loglevel setting, so set the setting advanced to hide it in GUI
840     // as altering it will do nothing - we don't write to advancedsettings.xml
841     XMLUtils::GetInt(pRootElement, "loglevel", m_logLevelHint, LOG_LEVEL_NONE, LOG_LEVEL_MAX);
842     CSettingBool *setting = (CSettingBool *)CSettings::Get().GetSetting("debug.showloginfo");
843     if (setting != NULL)
844     {
845       const char* hide;
846       if (!((hide = pElement->Attribute("hide")) && strnicmp("false", hide, 4) == 0))
847         setting->SetVisible(false);
848     }
849     g_advancedSettings.m_logLevel = std::max(g_advancedSettings.m_logLevel, g_advancedSettings.m_logLevelHint);
850     CLog::SetLogLevel(g_advancedSettings.m_logLevel);
851   }
852
853   XMLUtils::GetString(pRootElement, "cddbaddress", m_cddbAddress);
854
855   //airtunes + airplay
856   XMLUtils::GetBoolean(pRootElement, "enableairtunesdebuglog", m_logEnableAirtunes);
857   XMLUtils::GetInt(pRootElement,     "airtunesport", m_airTunesPort);
858   XMLUtils::GetInt(pRootElement,     "airplayport", m_airPlayPort);  
859
860   XMLUtils::GetBoolean(pRootElement, "handlemounting", m_handleMounting);
861
862 #if defined(HAS_SDL) || defined(TARGET_WINDOWS)
863   XMLUtils::GetBoolean(pRootElement, "fullscreen", m_startFullScreen);
864 #endif
865   XMLUtils::GetBoolean(pRootElement, "splash", m_splashImage);
866   XMLUtils::GetBoolean(pRootElement, "showexitbutton", m_showExitButton);
867   XMLUtils::GetBoolean(pRootElement, "canwindowed", m_canWindowed);
868
869   XMLUtils::GetInt(pRootElement, "songinfoduration", m_songInfoDuration, 0, INT_MAX);
870   XMLUtils::GetInt(pRootElement, "playlistretries", m_playlistRetries, -1, 5000);
871   XMLUtils::GetInt(pRootElement, "playlisttimeout", m_playlistTimeout, 0, 5000);
872
873   XMLUtils::GetBoolean(pRootElement,"glrectanglehack", m_GLRectangleHack);
874   XMLUtils::GetInt(pRootElement,"skiploopfilter", m_iSkipLoopFilter, -16, 48);
875   XMLUtils::GetFloat(pRootElement, "forcedswaptime", m_ForcedSwapTime, 0.0, 100.0);
876
877   XMLUtils::GetBoolean(pRootElement,"allowd3d9ex", m_AllowD3D9Ex);
878   XMLUtils::GetBoolean(pRootElement,"forced3d9ex", m_ForceD3D9Ex);
879   XMLUtils::GetBoolean(pRootElement,"allowdynamictextures", m_AllowDynamicTextures);
880   XMLUtils::GetUInt(pRootElement,"restrictcapsmask", m_RestrictCapsMask);
881   XMLUtils::GetFloat(pRootElement,"sleepbeforeflip", m_sleepBeforeFlip, 0.0f, 1.0f);
882   XMLUtils::GetBoolean(pRootElement,"virtualshares", m_bVirtualShares);
883   XMLUtils::GetUInt(pRootElement, "packagefoldersize", m_addonPackageFolderSize);
884
885   //Tuxbox
886   pElement = pRootElement->FirstChildElement("tuxbox");
887   if (pElement)
888   {
889     XMLUtils::GetInt(pElement, "streamtsport", m_iTuxBoxStreamtsPort, 0, 65535);
890     XMLUtils::GetBoolean(pElement, "audiochannelselection", m_bTuxBoxAudioChannelSelection);
891     XMLUtils::GetBoolean(pElement, "submenuselection", m_bTuxBoxSubMenuSelection);
892     XMLUtils::GetBoolean(pElement, "pictureicon", m_bTuxBoxPictureIcon);
893     XMLUtils::GetBoolean(pElement, "sendallaudiopids", m_bTuxBoxSendAllAPids);
894     XMLUtils::GetInt(pElement, "epgrequesttime", m_iTuxBoxEpgRequestTime, 0, 3600);
895     XMLUtils::GetInt(pElement, "defaultsubmenu", m_iTuxBoxDefaultSubMenu, 1, 4);
896     XMLUtils::GetInt(pElement, "defaultrootmenu", m_iTuxBoxDefaultRootMenu, 0, 4);
897     XMLUtils::GetInt(pElement, "zapwaittime", m_iTuxBoxZapWaitTime, 0, 120);
898     XMLUtils::GetBoolean(pElement, "zapstream", m_bTuxBoxZapstream);
899     XMLUtils::GetInt(pElement, "zapstreamport", m_iTuxBoxZapstreamPort, 0, 65535);
900   }
901
902   // Myth TV
903   pElement = pRootElement->FirstChildElement("myth");
904   if (pElement)
905   {
906     XMLUtils::GetInt(pElement, "movielength", m_iMythMovieLength);
907   }
908
909   // EPG
910   pElement = pRootElement->FirstChildElement("epg");
911   if (pElement)
912   {
913     XMLUtils::GetInt(pElement, "lingertime", m_iEpgLingerTime);
914     XMLUtils::GetInt(pElement, "updatecheckinterval", m_iEpgUpdateCheckInterval);
915     XMLUtils::GetInt(pElement, "cleanupinterval", m_iEpgCleanupInterval);
916     XMLUtils::GetInt(pElement, "activetagcheckinterval", m_iEpgActiveTagCheckInterval);
917     XMLUtils::GetInt(pElement, "retryinterruptedupdateinterval", m_iEpgRetryInterruptedUpdateInterval);
918     XMLUtils::GetInt(pElement, "updateemptytagsinterval", m_iEpgUpdateEmptyTagsInterval);
919     XMLUtils::GetBoolean(pElement, "displayupdatepopup", m_bEpgDisplayUpdatePopup);
920     XMLUtils::GetBoolean(pElement, "displayincrementalupdatepopup", m_bEpgDisplayIncrementalUpdatePopup);
921   }
922
923   // EDL commercial break handling
924   pElement = pRootElement->FirstChildElement("edl");
925   if (pElement)
926   {
927     XMLUtils::GetBoolean(pElement, "mergeshortcommbreaks", m_bEdlMergeShortCommBreaks);
928     XMLUtils::GetInt(pElement, "maxcommbreaklength", m_iEdlMaxCommBreakLength, 0, 10 * 60); // Between 0 and 10 minutes
929     XMLUtils::GetInt(pElement, "mincommbreaklength", m_iEdlMinCommBreakLength, 0, 5 * 60);  // Between 0 and 5 minutes
930     XMLUtils::GetInt(pElement, "maxcommbreakgap", m_iEdlMaxCommBreakGap, 0, 5 * 60);        // Between 0 and 5 minutes.
931     XMLUtils::GetInt(pElement, "maxstartgap", m_iEdlMaxStartGap, 0, 10 * 60);               // Between 0 and 10 minutes
932     XMLUtils::GetInt(pElement, "commbreakautowait", m_iEdlCommBreakAutowait, 0, 10);        // Between 0 and 10 seconds
933     XMLUtils::GetInt(pElement, "commbreakautowind", m_iEdlCommBreakAutowind, 0, 10);        // Between 0 and 10 seconds
934   }
935
936   // picture exclude regexps
937   TiXmlElement* pPictureExcludes = pRootElement->FirstChildElement("pictureexcludes");
938   if (pPictureExcludes)
939     GetCustomRegexps(pPictureExcludes, m_pictureExcludeFromListingRegExps);
940
941   // picture extensions
942   TiXmlElement* pExts = pRootElement->FirstChildElement("pictureextensions");
943   if (pExts)
944     GetCustomExtensions(pExts, m_pictureExtensions);
945
946   // music extensions
947   pExts = pRootElement->FirstChildElement("musicextensions");
948   if (pExts)
949     GetCustomExtensions(pExts, m_musicExtensions);
950
951   // video extensions
952   pExts = pRootElement->FirstChildElement("videoextensions");
953   if (pExts)
954     GetCustomExtensions(pExts, m_videoExtensions);
955
956   // stub extensions
957   pExts = pRootElement->FirstChildElement("discstubextensions");
958   if (pExts)
959     GetCustomExtensions(pExts, m_discStubExtensions);
960
961   m_vecTokens.clear();
962   CLangInfo::LoadTokens(pRootElement->FirstChild("sorttokens"),m_vecTokens);
963
964   // TODO: Should cache path be given in terms of our predefined paths??
965   //       Are we even going to have predefined paths??
966   CStdString tmp;
967   if (XMLUtils::GetPath(pRootElement, "cachepath", tmp))
968     m_cachePath = tmp;
969   URIUtils::AddSlashAtEnd(m_cachePath);
970
971   g_LangCodeExpander.LoadUserCodes(pRootElement->FirstChildElement("languagecodes"));
972
973   // trailer matching regexps
974   TiXmlElement* pTrailerMatching = pRootElement->FirstChildElement("trailermatching");
975   if (pTrailerMatching)
976     GetCustomRegexps(pTrailerMatching, m_trailerMatchRegExps);
977
978   //everything thats a trailer is not a movie
979   m_moviesExcludeFromScanRegExps.insert(m_moviesExcludeFromScanRegExps.end(),
980                                         m_trailerMatchRegExps.begin(),
981                                         m_trailerMatchRegExps.end());
982
983   // video stacking regexps
984   TiXmlElement* pVideoStacking = pRootElement->FirstChildElement("moviestacking");
985   if (pVideoStacking)
986     GetCustomRegexps(pVideoStacking, m_videoStackRegExps);
987
988   // folder stacking regexps
989   TiXmlElement* pFolderStacking = pRootElement->FirstChildElement("folderstacking");
990   if (pFolderStacking)
991     GetCustomRegexps(pFolderStacking, m_folderStackRegExps);
992
993   //tv stacking regexps
994   TiXmlElement* pTVStacking = pRootElement->FirstChildElement("tvshowmatching");
995   if (pTVStacking)
996     GetCustomTVRegexps(pTVStacking, m_tvshowEnumRegExps);
997
998   //tv multipart enumeration regexp
999   XMLUtils::GetString(pRootElement, "tvmultipartmatching", m_tvshowMultiPartEnumRegExp);
1000
1001   // path substitutions
1002   TiXmlElement* pPathSubstitution = pRootElement->FirstChildElement("pathsubstitution");
1003   if (pPathSubstitution)
1004   {
1005     m_pathSubstitutions.clear();
1006     CLog::Log(LOGDEBUG,"Configuring path substitutions");
1007     TiXmlNode* pSubstitute = pPathSubstitution->FirstChildElement("substitute");
1008     while (pSubstitute)
1009     {
1010       CStdString strFrom, strTo;
1011       TiXmlNode* pFrom = pSubstitute->FirstChild("from");
1012       if (pFrom)
1013         strFrom = CSpecialProtocol::TranslatePath(pFrom->FirstChild()->Value()).c_str();
1014       TiXmlNode* pTo = pSubstitute->FirstChild("to");
1015       if (pTo)
1016         strTo = pTo->FirstChild()->Value();
1017
1018       if (!strFrom.empty() && !strTo.empty())
1019       {
1020         CLog::Log(LOGDEBUG,"  Registering substition pair:");
1021         CLog::Log(LOGDEBUG,"    From: [%s]", strFrom.c_str());
1022         CLog::Log(LOGDEBUG,"    To:   [%s]", strTo.c_str());
1023         m_pathSubstitutions.push_back(make_pair(strFrom,strTo));
1024       }
1025       else
1026       {
1027         // error message about missing tag
1028         if (strFrom.empty())
1029           CLog::Log(LOGERROR,"  Missing <from> tag");
1030         else
1031           CLog::Log(LOGERROR,"  Missing <to> tag");
1032       }
1033
1034       // get next one
1035       pSubstitute = pSubstitute->NextSiblingElement("substitute");
1036     }
1037   }
1038
1039   XMLUtils::GetInt(pRootElement, "remotedelay", m_remoteDelay, 1, 20);
1040   XMLUtils::GetFloat(pRootElement, "controllerdeadzone", m_controllerDeadzone, 0.0f, 1.0f);
1041   XMLUtils::GetUInt(pRootElement, "fanartres", m_fanartRes, 0, 1080);
1042   XMLUtils::GetUInt(pRootElement, "imageres", m_imageRes, 0, 1080);
1043   XMLUtils::GetBoolean(pRootElement, "useddsfanart", m_useDDSFanart);
1044
1045   XMLUtils::GetBoolean(pRootElement, "playlistasfolders", m_playlistAsFolders);
1046   XMLUtils::GetBoolean(pRootElement, "detectasudf", m_detectAsUdf);
1047
1048   // music thumbs
1049   TiXmlElement* pThumbs = pRootElement->FirstChildElement("musicthumbs");
1050   if (pThumbs)
1051     GetCustomExtensions(pThumbs,m_musicThumbs);
1052
1053   // movie fanarts
1054   TiXmlElement* pFanart = pRootElement->FirstChildElement("fanart");
1055   if (pFanart)
1056     GetCustomExtensions(pFanart,m_fanartImages);
1057
1058   // music filename->tag filters
1059   TiXmlElement* filters = pRootElement->FirstChildElement("musicfilenamefilters");
1060   if (filters)
1061   {
1062     TiXmlNode* filter = filters->FirstChild("filter");
1063     while (filter)
1064     {
1065       if (filter->FirstChild())
1066         m_musicTagsFromFileFilters.push_back(filter->FirstChild()->ValueStr());
1067       filter = filter->NextSibling("filter");
1068     }
1069   }
1070
1071   TiXmlElement* pHostEntries = pRootElement->FirstChildElement("hosts");
1072   if (pHostEntries)
1073   {
1074     TiXmlElement* element = pHostEntries->FirstChildElement("entry");
1075     while(element)
1076     {
1077       CStdString name  = element->Attribute("name");
1078       CStdString value;
1079       if(element->GetText())
1080         value = element->GetText();
1081
1082       if(name.length() > 0 && value.length() > 0)
1083         CDNSNameCache::Add(name, value);
1084       element = element->NextSiblingElement("entry");
1085     }
1086   }
1087
1088   XMLUtils::GetString(pRootElement, "cputempcommand", m_cpuTempCmd);
1089   XMLUtils::GetString(pRootElement, "gputempcommand", m_gpuTempCmd);
1090
1091   XMLUtils::GetBoolean(pRootElement, "alwaysontop", m_alwaysOnTop);
1092
1093   TiXmlElement *pPVR = pRootElement->FirstChildElement("pvr");
1094   if (pPVR)
1095   {
1096     XMLUtils::GetInt(pPVR, "timecorrection", m_iPVRTimeCorrection, 0, 1440);
1097     XMLUtils::GetInt(pPVR, "infotoggleinterval", m_iPVRInfoToggleInterval, 0, 30000);
1098     XMLUtils::GetBoolean(pPVR, "showepginfoonselect", m_bPVRShowEpgInfoOnEpgItemSelect);
1099     XMLUtils::GetInt(pPVR, "minvideocachelevel", m_iPVRMinVideoCacheLevel, 0, 100);
1100     XMLUtils::GetInt(pPVR, "minaudiocachelevel", m_iPVRMinAudioCacheLevel, 0, 100);
1101     XMLUtils::GetBoolean(pPVR, "cacheindvdplayer", m_bPVRCacheInDvdPlayer);
1102     XMLUtils::GetBoolean(pPVR, "channeliconsautoscan", m_bPVRChannelIconsAutoScan);
1103     XMLUtils::GetBoolean(pPVR, "autoscaniconsuserset", m_bPVRAutoScanIconsUserSet);
1104     XMLUtils::GetInt(pPVR, "numericchannelswitchtimeout", m_iPVRNumericChannelSwitchTimeout, 50, 60000);
1105   }
1106
1107   XMLUtils::GetBoolean(pRootElement, "measurerefreshrate", m_measureRefreshrate);
1108
1109   TiXmlElement* pDatabase = pRootElement->FirstChildElement("videodatabase");
1110   if (pDatabase)
1111   {
1112     CLog::Log(LOGWARNING, "VIDEO database configuration is experimental.");
1113     XMLUtils::GetString(pDatabase, "type", m_databaseVideo.type);
1114     XMLUtils::GetString(pDatabase, "host", m_databaseVideo.host);
1115     XMLUtils::GetString(pDatabase, "port", m_databaseVideo.port);
1116     XMLUtils::GetString(pDatabase, "user", m_databaseVideo.user);
1117     XMLUtils::GetString(pDatabase, "pass", m_databaseVideo.pass);
1118     XMLUtils::GetString(pDatabase, "name", m_databaseVideo.name);
1119     XMLUtils::GetString(pDatabase, "key", m_databaseVideo.key);
1120     XMLUtils::GetString(pDatabase, "cert", m_databaseVideo.cert);
1121     XMLUtils::GetString(pDatabase, "ca", m_databaseVideo.ca);
1122     XMLUtils::GetString(pDatabase, "capath", m_databaseVideo.capath);
1123     XMLUtils::GetString(pDatabase, "ciphers", m_databaseVideo.ciphers);
1124   }
1125
1126   pDatabase = pRootElement->FirstChildElement("musicdatabase");
1127   if (pDatabase)
1128   {
1129     XMLUtils::GetString(pDatabase, "type", m_databaseMusic.type);
1130     XMLUtils::GetString(pDatabase, "host", m_databaseMusic.host);
1131     XMLUtils::GetString(pDatabase, "port", m_databaseMusic.port);
1132     XMLUtils::GetString(pDatabase, "user", m_databaseMusic.user);
1133     XMLUtils::GetString(pDatabase, "pass", m_databaseMusic.pass);
1134     XMLUtils::GetString(pDatabase, "name", m_databaseMusic.name);
1135     XMLUtils::GetString(pDatabase, "key", m_databaseMusic.key);
1136     XMLUtils::GetString(pDatabase, "cert", m_databaseMusic.cert);
1137     XMLUtils::GetString(pDatabase, "ca", m_databaseMusic.ca);
1138     XMLUtils::GetString(pDatabase, "capath", m_databaseMusic.capath);
1139     XMLUtils::GetString(pDatabase, "ciphers", m_databaseMusic.ciphers);
1140   }
1141
1142   pDatabase = pRootElement->FirstChildElement("tvdatabase");
1143   if (pDatabase)
1144   {
1145     XMLUtils::GetString(pDatabase, "type", m_databaseTV.type);
1146     XMLUtils::GetString(pDatabase, "host", m_databaseTV.host);
1147     XMLUtils::GetString(pDatabase, "port", m_databaseTV.port);
1148     XMLUtils::GetString(pDatabase, "user", m_databaseTV.user);
1149     XMLUtils::GetString(pDatabase, "pass", m_databaseTV.pass);
1150     XMLUtils::GetString(pDatabase, "name", m_databaseTV.name);
1151     XMLUtils::GetString(pDatabase, "key", m_databaseTV.key);
1152     XMLUtils::GetString(pDatabase, "cert", m_databaseTV.cert);
1153     XMLUtils::GetString(pDatabase, "ca", m_databaseTV.ca);
1154     XMLUtils::GetString(pDatabase, "capath", m_databaseTV.capath);
1155     XMLUtils::GetString(pDatabase, "ciphers", m_databaseTV.ciphers);
1156   }
1157
1158   pDatabase = pRootElement->FirstChildElement("epgdatabase");
1159   if (pDatabase)
1160   {
1161     XMLUtils::GetString(pDatabase, "type", m_databaseEpg.type);
1162     XMLUtils::GetString(pDatabase, "host", m_databaseEpg.host);
1163     XMLUtils::GetString(pDatabase, "port", m_databaseEpg.port);
1164     XMLUtils::GetString(pDatabase, "user", m_databaseEpg.user);
1165     XMLUtils::GetString(pDatabase, "pass", m_databaseEpg.pass);
1166     XMLUtils::GetString(pDatabase, "name", m_databaseEpg.name);
1167     XMLUtils::GetString(pDatabase, "key", m_databaseEpg.key);
1168     XMLUtils::GetString(pDatabase, "cert", m_databaseEpg.cert);
1169     XMLUtils::GetString(pDatabase, "ca", m_databaseEpg.ca);
1170     XMLUtils::GetString(pDatabase, "capath", m_databaseEpg.capath);
1171     XMLUtils::GetString(pDatabase, "ciphers", m_databaseEpg.ciphers);
1172   }
1173
1174   pElement = pRootElement->FirstChildElement("enablemultimediakeys");
1175   if (pElement)
1176   {
1177     XMLUtils::GetBoolean(pRootElement, "enablemultimediakeys", m_enableMultimediaKeys);
1178   }
1179   
1180   pElement = pRootElement->FirstChildElement("gui");
1181   if (pElement)
1182   {
1183     XMLUtils::GetBoolean(pElement, "visualizedirtyregions", m_guiVisualizeDirtyRegions);
1184     XMLUtils::GetInt(pElement, "algorithmdirtyregions",     m_guiAlgorithmDirtyRegions);
1185     XMLUtils::GetInt(pElement, "nofliptimeout",             m_guiDirtyRegionNoFlipTimeout);
1186   }
1187
1188   // load in the settings overrides
1189   CSettings::Get().Load(pRootElement, true);  // true to hide the settings we read in
1190 }
1191
1192 void CAdvancedSettings::Clear()
1193 {
1194   m_videoCleanStringRegExps.clear();
1195   m_moviesExcludeFromScanRegExps.clear();
1196   m_tvshowExcludeFromScanRegExps.clear();
1197   m_videoExcludeFromListingRegExps.clear();
1198   m_videoStackRegExps.clear();
1199   m_folderStackRegExps.clear();
1200   m_audioExcludeFromScanRegExps.clear();
1201   m_audioExcludeFromListingRegExps.clear();
1202   m_pictureExcludeFromListingRegExps.clear();
1203
1204   m_pictureExtensions.clear();
1205   m_musicExtensions.clear();
1206   m_videoExtensions.clear();
1207   m_discStubExtensions.clear();
1208
1209   m_logFolder.clear();
1210   m_userAgent.clear();
1211 }
1212
1213 void CAdvancedSettings::GetCustomTVRegexps(TiXmlElement *pRootElement, SETTINGS_TVSHOWLIST& settings)
1214 {
1215   TiXmlElement *pElement = pRootElement;
1216   while (pElement)
1217   {
1218     int iAction = 0; // overwrite
1219     // for backward compatibility
1220     const char* szAppend = pElement->Attribute("append");
1221     if ((szAppend && stricmp(szAppend, "yes") == 0))
1222       iAction = 1;
1223     // action takes precedence if both attributes exist
1224     const char* szAction = pElement->Attribute("action");
1225     if (szAction)
1226     {
1227       iAction = 0; // overwrite
1228       if (stricmp(szAction, "append") == 0)
1229         iAction = 1; // append
1230       else if (stricmp(szAction, "prepend") == 0)
1231         iAction = 2; // prepend
1232     }
1233     if (iAction == 0)
1234       settings.clear();
1235     TiXmlNode* pRegExp = pElement->FirstChild("regexp");
1236     int i = 0;
1237     while (pRegExp)
1238     {
1239       if (pRegExp->FirstChild())
1240       {
1241         bool bByDate = false;
1242         int iDefaultSeason = 1;
1243         if (pRegExp->ToElement())
1244         {
1245           CStdString byDate = pRegExp->ToElement()->Attribute("bydate");
1246           if(byDate && stricmp(byDate, "true") == 0)
1247           {
1248             bByDate = true;
1249           }
1250           CStdString defaultSeason = pRegExp->ToElement()->Attribute("defaultseason");
1251           if(!defaultSeason.empty())
1252           {
1253             iDefaultSeason = atoi(defaultSeason.c_str());
1254           }
1255         }
1256         CStdString regExp = pRegExp->FirstChild()->Value();
1257         if (iAction == 2)
1258           settings.insert(settings.begin() + i++, 1, TVShowRegexp(bByDate,regExp,iDefaultSeason));
1259         else
1260           settings.push_back(TVShowRegexp(bByDate,regExp,iDefaultSeason));
1261       }
1262       pRegExp = pRegExp->NextSibling("regexp");
1263     }
1264
1265     pElement = pElement->NextSiblingElement(pRootElement->Value());
1266   }
1267 }
1268
1269 void CAdvancedSettings::GetCustomRegexps(TiXmlElement *pRootElement, CStdStringArray& settings)
1270 {
1271   TiXmlElement *pElement = pRootElement;
1272   while (pElement)
1273   {
1274     int iAction = 0; // overwrite
1275     // for backward compatibility
1276     const char* szAppend = pElement->Attribute("append");
1277     if ((szAppend && stricmp(szAppend, "yes") == 0))
1278       iAction = 1;
1279     // action takes precedence if both attributes exist
1280     const char* szAction = pElement->Attribute("action");
1281     if (szAction)
1282     {
1283       iAction = 0; // overwrite
1284       if (stricmp(szAction, "append") == 0)
1285         iAction = 1; // append
1286       else if (stricmp(szAction, "prepend") == 0)
1287         iAction = 2; // prepend
1288     }
1289     if (iAction == 0)
1290       settings.clear();
1291     TiXmlNode* pRegExp = pElement->FirstChild("regexp");
1292     int i = 0;
1293     while (pRegExp)
1294     {
1295       if (pRegExp->FirstChild())
1296       {
1297         CStdString regExp = pRegExp->FirstChild()->Value();
1298         if (iAction == 2)
1299           settings.insert(settings.begin() + i++, 1, regExp);
1300         else
1301           settings.push_back(regExp);
1302       }
1303       pRegExp = pRegExp->NextSibling("regexp");
1304     }
1305
1306     pElement = pElement->NextSiblingElement(pRootElement->Value());
1307   }
1308 }
1309
1310 void CAdvancedSettings::GetCustomExtensions(TiXmlElement *pRootElement, CStdString& extensions)
1311 {
1312   CStdString extraExtensions;
1313   if (XMLUtils::GetString(pRootElement, "add", extraExtensions) && !extraExtensions.empty())
1314     extensions += "|" + extraExtensions;
1315   if (XMLUtils::GetString(pRootElement, "remove", extraExtensions) && !extraExtensions.empty())
1316   {
1317     CStdStringArray exts;
1318     StringUtils::SplitString(extraExtensions,"|",exts);
1319     for (unsigned int i=0;i<exts.size();++i)
1320     {
1321       int iPos = extensions.Find(exts[i]);
1322       if (iPos == -1)
1323         continue;
1324       extensions.erase(iPos,exts[i].size()+1);
1325     }
1326   }
1327 }
1328
1329 void CAdvancedSettings::AddSettingsFile(const CStdString &filename)
1330 {
1331   m_settingsFiles.push_back(filename);
1332 }
1333
1334 float CAdvancedSettings::GetDisplayLatency(float refreshrate)
1335 {
1336   float delay = m_videoDefaultLatency / 1000.0f;
1337   for (int i = 0; i < (int) m_videoRefreshLatency.size(); i++)
1338   {
1339     RefreshVideoLatency& videolatency = m_videoRefreshLatency[i];
1340     if (refreshrate >= videolatency.refreshmin && refreshrate <= videolatency.refreshmax)
1341       delay = videolatency.delay / 1000.0f;
1342   }
1343
1344   return delay; // in seconds
1345 }
1346
1347 void CAdvancedSettings::SetDebugMode(bool debug)
1348 {
1349   if (debug)
1350   {
1351     int level = std::max(m_logLevelHint, LOG_LEVEL_DEBUG_FREEMEM);
1352     m_logLevel = level;
1353     CLog::SetLogLevel(level);
1354     CLog::Log(LOGNOTICE, "Enabled debug logging due to GUI setting. Level %d.", level);
1355   }
1356   else
1357   {
1358     int level = std::min(m_logLevelHint, LOG_LEVEL_DEBUG/*LOG_LEVEL_NORMAL*/);
1359     CLog::Log(LOGNOTICE, "Disabled debug logging due to GUI setting. Level %d.", level);
1360     m_logLevel = level;
1361     CLog::SetLogLevel(level);
1362   }
1363 }
1364
1365 void CAdvancedSettings::SetExtraLogsFromAddon(ADDON::IAddon* addon)
1366 {
1367   m_extraLogLevels = 0;
1368   for (int i=LOGMASKBIT;i<31;++i)
1369   {
1370     CStdString str = StringUtils::Format("bit%i", i-LOGMASKBIT+1);
1371     if (addon->GetSetting(str) == "true")
1372       m_extraLogLevels |= (1 << i);
1373   }
1374   CLog::SetExtraLogLevels(m_extraLogLevels);
1375 }