bool CAdvancedSettings::Load() { // NOTE: This routine should NOT set the default of any of these parameters // it should instead use the versions of GetString/Integer/Float that // don't take defaults in. Defaults are set in the constructor above CStdString advancedSettingsXML; advancedSettingsXML = g_settings.GetUserDataItem("advancedsettings.xml"); TiXmlDocument advancedXML; if (!CFile::Exists(advancedSettingsXML)) { // tell the user it doesn't exist CLog::Log(LOGNOTICE, "No advancedsettings.xml to load (%s)", advancedSettingsXML.c_str()); return false; } if (!advancedXML.LoadFile(advancedSettingsXML)) { CLog::Log(LOGERROR, "Error loading %s, Line %d\n%s", advancedSettingsXML.c_str(), advancedXML.ErrorRow(), advancedXML.ErrorDesc()); return false; } TiXmlElement *pRootElement = advancedXML.RootElement(); if (!pRootElement || strcmpi(pRootElement->Value(),"advancedsettings") != 0) { CLog::Log(LOGERROR, "Error loading %s, no <advancedsettings> node", advancedSettingsXML.c_str()); return false; } // succeeded - tell the user it worked CLog::Log(LOGNOTICE, "Loaded advancedsettings.xml from %s", advancedSettingsXML.c_str()); // Dump contents of AS.xml to debug log TiXmlPrinter printer; printer.SetLineBreak("\n"); printer.SetIndent(" "); advancedXML.Accept(&printer); CLog::Log(LOGNOTICE, "Contents of %s are...\n%s", advancedSettingsXML.c_str(), printer.CStr()); TiXmlElement *pElement = pRootElement->FirstChildElement("audio"); if (pElement) { XMLUtils::GetFloat(pElement, "ac3downmixgain", m_ac3Gain, -96.0f, 96.0f); XMLUtils::GetInt(pElement, "headroom", m_audioHeadRoom, 0, 12); XMLUtils::GetFloat(pElement, "karaokesyncdelay", m_karaokeSyncDelay, -3.0f, 3.0f); // 101 on purpose - can be used to never automark as watched XMLUtils::GetFloat(pElement, "playcountminimumpercent", m_audioPlayCountMinimumPercent, 0.0f, 101.0f); XMLUtils::GetBoolean(pElement, "usetimeseeking", m_musicUseTimeSeeking); XMLUtils::GetInt(pElement, "timeseekforward", m_musicTimeSeekForward, 0, 6000); XMLUtils::GetInt(pElement, "timeseekbackward", m_musicTimeSeekBackward, -6000, 0); XMLUtils::GetInt(pElement, "timeseekforwardbig", m_musicTimeSeekForwardBig, 0, 6000); XMLUtils::GetInt(pElement, "timeseekbackwardbig", m_musicTimeSeekBackwardBig, -6000, 0); XMLUtils::GetInt(pElement, "percentseekforward", m_musicPercentSeekForward, 0, 100); XMLUtils::GetInt(pElement, "percentseekbackward", m_musicPercentSeekBackward, -100, 0); XMLUtils::GetInt(pElement, "percentseekforwardbig", m_musicPercentSeekForwardBig, 0, 100); XMLUtils::GetInt(pElement, "percentseekbackwardbig", m_musicPercentSeekBackwardBig, -100, 0); XMLUtils::GetInt(pElement, "resample", m_musicResample, 0, 48000); TiXmlElement* pAudioExcludes = pElement->FirstChildElement("excludefromlisting"); if (pAudioExcludes) GetCustomRegexps(pAudioExcludes, m_audioExcludeFromListingRegExps); pAudioExcludes = pElement->FirstChildElement("excludefromscan"); if (pAudioExcludes) GetCustomRegexps(pAudioExcludes, m_audioExcludeFromScanRegExps); XMLUtils::GetBoolean(pElement, "applydrc", m_audioApplyDrc); XMLUtils::GetBoolean(pElement, "dvdplayerignoredtsinwav", m_dvdplayerIgnoreDTSinWAV); } pElement = pRootElement->FirstChildElement("video"); if (pElement) { XMLUtils::GetFloat(pElement, "subsdelayrange", m_videoSubsDelayRange, 10, 600); XMLUtils::GetFloat(pElement, "audiodelayrange", m_videoAudioDelayRange, 10, 600); XMLUtils::GetInt(pElement, "blackbarcolour", m_videoBlackBarColour, 0, 255); XMLUtils::GetBoolean(pElement, "fullscreenonmoviestart", m_fullScreenOnMovieStart); // 101 on purpose - can be used to never automark as watched XMLUtils::GetFloat(pElement, "playcountminimumpercent", m_videoPlayCountMinimumPercent, 0.0f, 101.0f); XMLUtils::GetInt(pElement, "ignoresecondsatstart", m_videoIgnoreSecondsAtStart, 0, 900); XMLUtils::GetFloat(pElement, "ignorepercentatend", m_videoIgnorePercentAtEnd, 0, 100.0f); XMLUtils::GetInt(pElement, "smallstepbackseconds", m_videoSmallStepBackSeconds, 1, INT_MAX); XMLUtils::GetInt(pElement, "smallstepbacktries", m_videoSmallStepBackTries, 1, 10); XMLUtils::GetInt(pElement, "smallstepbackdelay", m_videoSmallStepBackDelay, 100, 5000); //MS XMLUtils::GetBoolean(pElement, "usetimeseeking", m_videoUseTimeSeeking); XMLUtils::GetInt(pElement, "timeseekforward", m_videoTimeSeekForward, 0, 6000); XMLUtils::GetInt(pElement, "timeseekbackward", m_videoTimeSeekBackward, -6000, 0); XMLUtils::GetInt(pElement, "timeseekforwardbig", m_videoTimeSeekForwardBig, 0, 6000); XMLUtils::GetInt(pElement, "timeseekbackwardbig", m_videoTimeSeekBackwardBig, -6000, 0); XMLUtils::GetInt(pElement, "percentseekforward", m_videoPercentSeekForward, 0, 100); XMLUtils::GetInt(pElement, "percentseekbackward", m_videoPercentSeekBackward, -100, 0); XMLUtils::GetInt(pElement, "percentseekforwardbig", m_videoPercentSeekForwardBig, 0, 100); XMLUtils::GetInt(pElement, "percentseekbackwardbig", m_videoPercentSeekBackwardBig, -100, 0); TiXmlElement* pVideoExcludes = pElement->FirstChildElement("excludefromlisting"); if (pVideoExcludes) GetCustomRegexps(pVideoExcludes, m_videoExcludeFromListingRegExps); pVideoExcludes = pElement->FirstChildElement("excludefromscan"); if (pVideoExcludes) GetCustomRegexps(pVideoExcludes, m_moviesExcludeFromScanRegExps); pVideoExcludes = pElement->FirstChildElement("excludetvshowsfromscan"); if (pVideoExcludes) GetCustomRegexps(pVideoExcludes, m_tvshowExcludeFromScanRegExps); pVideoExcludes = pElement->FirstChildElement("cleanstrings"); if (pVideoExcludes) GetCustomRegexps(pVideoExcludes, m_videoCleanStringRegExps); XMLUtils::GetString(pElement,"cleandatetime", m_videoCleanDateTimeRegExp); XMLUtils::GetString(pElement,"ppffmpegdeinterlacing",m_videoPPFFmpegDeint); XMLUtils::GetString(pElement,"ppffmpegpostprocessing",m_videoPPFFmpegPostProc); } pElement = pRootElement->FirstChildElement("musiclibrary"); if (pElement) { XMLUtils::GetBoolean(pElement, "hideallitems", m_bMusicLibraryHideAllItems); XMLUtils::GetInt(pElement, "recentlyaddeditems", m_iMusicLibraryRecentlyAddedItems, 1, INT_MAX); XMLUtils::GetBoolean(pElement, "prioritiseapetags", m_prioritiseAPEv2tags); XMLUtils::GetBoolean(pElement, "allitemsonbottom", m_bMusicLibraryAllItemsOnBottom); XMLUtils::GetBoolean(pElement, "albumssortbyartistthenyear", m_bMusicLibraryAlbumsSortByArtistThenYear); XMLUtils::GetString(pElement, "albumformat", m_strMusicLibraryAlbumFormat); XMLUtils::GetString(pElement, "albumformatright", m_strMusicLibraryAlbumFormatRight); XMLUtils::GetString(pElement, "itemseparator", m_musicItemSeparator); } pElement = pRootElement->FirstChildElement("videolibrary"); if (pElement) { XMLUtils::GetBoolean(pElement, "hideallitems", m_bVideoLibraryHideAllItems); XMLUtils::GetBoolean(pElement, "allitemsonbottom", m_bVideoLibraryAllItemsOnBottom); XMLUtils::GetInt(pElement, "recentlyaddeditems", m_iVideoLibraryRecentlyAddedItems, 1, INT_MAX); XMLUtils::GetBoolean(pElement, "hiderecentlyaddeditems", m_bVideoLibraryHideRecentlyAddedItems); XMLUtils::GetBoolean(pElement, "hideemptyseries", m_bVideoLibraryHideEmptySeries); XMLUtils::GetBoolean(pElement, "cleanonupdate", m_bVideoLibraryCleanOnUpdate); XMLUtils::GetString(pElement, "itemseparator", m_videoItemSeparator); XMLUtils::GetBoolean(pElement, "exportautothumbs", m_bVideoLibraryExportAutoThumbs); XMLUtils::GetBoolean(pElement, "importwatchedstate", m_bVideoLibraryImportWatchedState); TiXmlElement* pMyMovies = pElement->FirstChildElement("mymovies"); if (pMyMovies) XMLUtils::GetBoolean(pMyMovies, "categoriestogenres", m_bVideoLibraryMyMoviesCategoriesToGenres); } pElement = pRootElement->FirstChildElement("videoscanner"); if (pElement) { XMLUtils::GetBoolean(pElement, "ignoreerrors", m_bVideoScannerIgnoreErrors); } pElement = pRootElement->FirstChildElement("slideshow"); if (pElement) { XMLUtils::GetFloat(pElement, "panamount", m_slideshowPanAmount, 0.0f, 20.0f); XMLUtils::GetFloat(pElement, "zoomamount", m_slideshowZoomAmount, 0.0f, 20.0f); XMLUtils::GetFloat(pElement, "blackbarcompensation", m_slideshowBlackBarCompensation, 0.0f, 50.0f); } pElement = pRootElement->FirstChildElement("lcd"); if (pElement) { XMLUtils::GetInt(pElement, "rows", m_lcdRows, 1, 4); XMLUtils::GetInt(pElement, "columns", m_lcdColumns, 1, 40); XMLUtils::GetInt(pElement, "address1", m_lcdAddress1, 0, 0x100); XMLUtils::GetInt(pElement, "address2", m_lcdAddress2, 0, 0x100); XMLUtils::GetInt(pElement, "address3", m_lcdAddress3, 0, 0x100); XMLUtils::GetInt(pElement, "address4", m_lcdAddress4, 0, 0x100); } pElement = pRootElement->FirstChildElement("network"); if (pElement) { XMLUtils::GetInt(pElement, "autodetectpingtime", m_autoDetectPingTime, 1, 240); XMLUtils::GetInt(pElement, "curlclienttimeout", m_curlconnecttimeout, 1, 1000); XMLUtils::GetInt(pElement, "curllowspeedtime", m_curllowspeedtime, 1, 1000); XMLUtils::GetInt(pElement, "curlretries", m_curlretries, 0, 10); XMLUtils::GetUInt(pElement, "cachemembuffersize", m_cacheMemBufferSize); } pElement = pRootElement->FirstChildElement("samba"); if (pElement) { XMLUtils::GetString(pElement, "doscodepage", m_sambadoscodepage); XMLUtils::GetInt(pElement, "clienttimeout", m_sambaclienttimeout, 5, 100); XMLUtils::GetBoolean(pElement, "statfiles", m_sambastatfiles); } pElement = pRootElement->FirstChildElement("httpdirectory"); if (pElement) XMLUtils::GetBoolean(pElement, "statfilesize", m_bHTTPDirectoryStatFilesize); pElement = pRootElement->FirstChildElement("ftp"); if (pElement) { XMLUtils::GetBoolean(pElement, "remotethumbs", m_bFTPThumbs); } pElement = pRootElement->FirstChildElement("loglevel"); if (pElement) { // read the loglevel setting, so set the setting advanced to hide it in GUI // as altering it will do nothing - we don't write to advancedsettings.xml XMLUtils::GetInt(pRootElement, "loglevel", m_logLevelHint, LOG_LEVEL_NONE, LOG_LEVEL_MAX); CSettingBool *setting = (CSettingBool *)g_guiSettings.GetSetting("debug.showloginfo"); if (setting) { const char* hide; if (!((hide = pElement->Attribute("hide")) && strnicmp("false", hide, 4) == 0)) setting->SetAdvanced(); } g_advancedSettings.m_logLevel = std::max(g_advancedSettings.m_logLevel, g_advancedSettings.m_logLevelHint); CLog::SetLogLevel(g_advancedSettings.m_logLevel); } pElement = pRootElement->FirstChildElement("python"); if (pElement) { XMLUtils::GetBoolean(pElement, "verbose", m_bPythonVerbose); } XMLUtils::GetString(pRootElement, "cddbaddress", m_cddbAddress); XMLUtils::GetBoolean(pRootElement, "usepcdvdrom", m_usePCDVDROM); XMLUtils::GetBoolean(pRootElement, "nodvdrom", m_noDVDROM); XMLUtils::GetBoolean(pRootElement, "enableintro", m_enableintro); XMLUtils::GetBoolean(pRootElement, "fasterscanning", m_fastscanning); XMLUtils::GetBoolean(pRootElement, "slowscrolling", m_slowscrolling); XMLUtils::GetBoolean(pRootElement, "splash", m_splashImage); XMLUtils::GetBoolean(pRootElement, "disablemodchipdetection", m_DisableModChipDetection); XMLUtils::GetBoolean(pRootElement, "powersave", m_bPowerSave); XMLUtils::GetInt(pRootElement, "songinfoduration", m_songInfoDuration, 0, INT_MAX); XMLUtils::GetInt(pRootElement, "busydialogdelay", m_busyDialogDelay, 0, 5000); XMLUtils::GetInt(pRootElement, "playlistretries", m_playlistRetries, -1, 5000); XMLUtils::GetInt(pRootElement, "playlisttimeout", m_playlistTimeout, 0, 5000); XMLUtils::GetBoolean(pRootElement,"virtualshares", m_bVirtualShares); XMLUtils::GetBoolean(pRootElement,"navigatevirtualkeyboard", m_bNavVKeyboard); //Tuxbox pElement = pRootElement->FirstChildElement("tuxbox"); if (pElement) { XMLUtils::GetInt(pElement, "streamtsport", m_iTuxBoxStreamtsPort, 0, 65535); XMLUtils::GetBoolean(pElement, "audiochannelselection", m_bTuxBoxAudioChannelSelection); XMLUtils::GetBoolean(pElement, "submenuselection", m_bTuxBoxSubMenuSelection); XMLUtils::GetBoolean(pElement, "pictureicon", m_bTuxBoxPictureIcon); XMLUtils::GetBoolean(pElement, "sendallaudiopids", m_bTuxBoxSendAllAPids); XMLUtils::GetInt(pElement, "epgrequesttime", m_iTuxBoxEpgRequestTime, 0, 3600); XMLUtils::GetInt(pElement, "defaultsubmenu", m_iTuxBoxDefaultSubMenu, 1, 4); XMLUtils::GetInt(pElement, "defaultrootmenu", m_iTuxBoxDefaultRootMenu, 0, 4); XMLUtils::GetInt(pElement, "zapwaittime", m_iTuxBoxZapWaitTime, 0, 120); XMLUtils::GetBoolean(pElement, "zapstream", m_bTuxBoxZapstream); XMLUtils::GetInt(pElement, "zapstreamport", m_iTuxBoxZapstreamPort, 0, 65535); } // Myth TV pElement = pRootElement->FirstChildElement("myth"); if (pElement) { XMLUtils::GetInt(pElement, "movielength", m_iMythMovieLength); } // EDL commercial break handling pElement = pRootElement->FirstChildElement("edl"); if (pElement) { XMLUtils::GetBoolean(pElement, "mergeshortcommbreaks", m_bEdlMergeShortCommBreaks); XMLUtils::GetInt(pElement, "maxcommbreaklength", m_iEdlMaxCommBreakLength, 0, 10 * 60); // Between 0 and 10 minutes XMLUtils::GetInt(pElement, "mincommbreaklength", m_iEdlMinCommBreakLength, 0, 5 * 60); // Between 0 and 5 minutes XMLUtils::GetInt(pElement, "maxcommbreakgap", m_iEdlMaxCommBreakGap, 0, 5 * 60); // Between 0 and 5 minutes. XMLUtils::GetInt(pElement, "maxstartgap", m_iEdlMaxStartGap, 0, 10 * 60); // Between 0 and 10 minutes XMLUtils::GetInt(pElement, "commbreakautowait", m_iEdlCommBreakAutowait, 0, 10); // Between 0 and 10 seconds XMLUtils::GetInt(pElement, "commbreakautowind", m_iEdlCommBreakAutowind, 0, 10); // Between 0 and 10 seconds } // picture exclude regexps TiXmlElement* pPictureExcludes = pRootElement->FirstChildElement("pictureexcludes"); if (pPictureExcludes) GetCustomRegexps(pPictureExcludes, m_pictureExcludeFromListingRegExps); // picture extensions CStdString extraExtensions; TiXmlElement* pExts = pRootElement->FirstChildElement("pictureextensions"); if (pExts) GetCustomExtensions(pExts,g_settings.m_pictureExtensions); // music extensions pExts = pRootElement->FirstChildElement("musicextensions"); if (pExts) GetCustomExtensions(pExts,g_settings.m_musicExtensions); // video extensions pExts = pRootElement->FirstChildElement("videoextensions"); if (pExts) GetCustomExtensions(pExts,g_settings.m_videoExtensions); m_vecTokens.clear(); CLangInfo::LoadTokens(pRootElement->FirstChild("sorttokens"),m_vecTokens); XMLUtils::GetBoolean(pRootElement, "displayremotecodes", m_displayRemoteCodes); // TODO: Should cache path be given in terms of our predefined paths?? // Are we even going to have predefined paths?? CSettings::GetPath(pRootElement, "cachepath", m_cachePath); URIUtils::AddSlashAtEnd(m_cachePath); XMLUtils::GetBoolean(pRootElement, "ftpshowcache", m_FTPShowCache); g_LangCodeExpander.LoadUserCodes(pRootElement->FirstChildElement("languagecodes")); // trailer matching regexps TiXmlElement* pTrailerMatching = pRootElement->FirstChildElement("trailermatching"); if (pTrailerMatching) GetCustomRegexps(pTrailerMatching, m_trailerMatchRegExps); //everything thats a trailer is not a movie m_moviesExcludeFromScanRegExps.insert(m_moviesExcludeFromScanRegExps.end(), m_trailerMatchRegExps.begin(), m_trailerMatchRegExps.end()); // stacking regexps TiXmlElement* pVideoStacking = pRootElement->FirstChildElement("moviestacking"); if (pVideoStacking) GetCustomRegexps(pVideoStacking, m_videoStackRegExps); //tv stacking regexps TiXmlElement* pTVStacking = pRootElement->FirstChildElement("tvshowmatching"); if (pTVStacking) GetCustomTVRegexps(pTVStacking, m_tvshowStackRegExps); // path substitutions TiXmlElement* pPathSubstitution = pRootElement->FirstChildElement("pathsubstitution"); if (pPathSubstitution) { m_pathSubstitutions.clear(); CLog::Log(LOGDEBUG,"Configuring path substitutions"); TiXmlNode* pSubstitute = pPathSubstitution->FirstChildElement("substitute"); while (pSubstitute) { CStdString strFrom, strTo; TiXmlNode* pFrom = pSubstitute->FirstChild("from"); if (pFrom) strFrom = pFrom->FirstChild()->Value(); TiXmlNode* pTo = pSubstitute->FirstChild("to"); if (pTo) strTo = pTo->FirstChild()->Value(); if (!strFrom.IsEmpty() && !strTo.IsEmpty()) { CLog::Log(LOGDEBUG," Registering substition pair:"); CLog::Log(LOGDEBUG," From: [%s]", strFrom.c_str()); CLog::Log(LOGDEBUG," To: [%s]", strTo.c_str()); // keep literal commas since we use comma as a seperator strFrom.Replace(",",",,"); strTo.Replace(",",",,"); m_pathSubstitutions.push_back(strFrom + " , " + strTo); } else { // error message about missing tag if (strFrom.IsEmpty()) CLog::Log(LOGERROR," Missing <from> tag"); else CLog::Log(LOGERROR," Missing <to> tag"); } // get next one pSubstitute = pSubstitute->NextSiblingElement("substitute"); } } XMLUtils::GetInt(pRootElement, "remoterepeat", m_remoteRepeat, 1, INT_MAX); XMLUtils::GetFloat(pRootElement, "controllerdeadzone", m_controllerDeadzone, 0.0f, 1.0f); XMLUtils::GetInt(pRootElement, "thumbsize", m_thumbSize, 0, 1024); XMLUtils::GetInt(pRootElement, "fanartheight", m_fanartHeight, 0, 1080); //dds support XMLUtils::GetBoolean(pRootElement, "useddsfanart", m_useddsfanart); XMLUtils::GetBoolean(pRootElement, "playlistasfolders", m_playlistAsFolders); XMLUtils::GetBoolean(pRootElement, "detectasudf", m_detectAsUdf); // music thumbs CStdString extraThumbs; TiXmlElement* pThumbs = pRootElement->FirstChildElement("musicthumbs"); if (pThumbs) { // remove before add so that the defaults can be restored after user defined ones // (ie, the list can be:cover.jpg|cover.png|folder.jpg) CSettings::GetString(pThumbs, "remove", extraThumbs, ""); if (extraThumbs != "") { CStdStringArray thumbs; StringUtils::SplitString(extraThumbs, "|", thumbs); for (unsigned int i = 0; i < thumbs.size(); ++i) { int iPos = m_musicThumbs.Find(thumbs[i]); if (iPos == -1) continue; m_musicThumbs.erase(iPos, thumbs[i].size() + 1); } } CSettings::GetString(pThumbs, "add", extraThumbs,""); if (extraThumbs != "") { if (!m_musicThumbs.IsEmpty()) m_musicThumbs += "|"; m_musicThumbs += extraThumbs; } } // dvd thumbs pThumbs = pRootElement->FirstChildElement("dvdthumbs"); if (pThumbs) { // remove before add so that the defaults can be restored after user defined ones // (ie, the list can be:cover.jpg|cover.png|folder.jpg) CSettings::GetString(pThumbs, "remove", extraThumbs, ""); if (extraThumbs != "") { CStdStringArray thumbs; StringUtils::SplitString(extraThumbs, "|", thumbs); for (unsigned int i = 0; i < thumbs.size(); ++i) { int iPos = m_dvdThumbs.Find(thumbs[i]); if (iPos == -1) continue; m_dvdThumbs.erase(iPos, thumbs[i].size() + 1); } } CSettings::GetString(pThumbs, "add", extraThumbs,""); if (extraThumbs != "") { if (!m_dvdThumbs.IsEmpty()) m_dvdThumbs += "|"; m_dvdThumbs += extraThumbs; } } // movie fanarts TiXmlElement* pFanart = pRootElement->FirstChildElement("fanart"); if (pFanart) GetCustomExtensions(pFanart,m_fanartImages); // music filename->tag filters TiXmlElement* filters = pRootElement->FirstChildElement("musicfilenamefilters"); if (filters) { TiXmlNode* filter = filters->FirstChild("filter"); while (filter) { if (filter->FirstChild()) m_musicTagsFromFileFilters.push_back(filter->FirstChild()->ValueStr()); filter = filter->NextSibling("filter"); } } TiXmlElement* pHostEntries = pRootElement->FirstChildElement("hosts"); if (pHostEntries) { TiXmlElement* element = pHostEntries->FirstChildElement("entry"); while(element) { CStdString name = element->Attribute("name"); CStdString value; if(element->GetText()) value = element->GetText(); if(name.length() > 0 && value.length() > 0) CDNSNameCache::Add(name, value); element = element->NextSiblingElement("entry"); } } XMLUtils::GetInt(pRootElement, "bginfoloadermaxthreads", m_bgInfoLoaderMaxThreads); m_bgInfoLoaderMaxThreads = std::max(3, m_bgInfoLoaderMaxThreads); // load in the GUISettings overrides: g_guiSettings.LoadXML(pRootElement, true); // true to hide the settings we read in return true; }