2 * Copyright (C) 2013 Team XBMC
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)
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.
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/>.
23 #include "SkinSettings.h"
24 #include "GUIInfoManager.h"
25 #include "settings/Settings.h"
26 #include "threads/SingleLock.h"
27 #include "utils/log.h"
28 #include "utils/StringUtils.h"
29 #include "utils/XBMCTinyXML.h"
31 #define XML_SKINSETTINGS "skinsettings"
32 #define XML_SETTING "setting"
33 #define XML_ATTR_TYPE "type"
34 #define XML_ATTR_NAME "name"
38 CSkinSettings::CSkinSettings()
43 CSkinSettings::~CSkinSettings()
46 CSkinSettings& CSkinSettings::Get()
48 static CSkinSettings sSkinSettings;
52 int CSkinSettings::TranslateString(const string &setting)
54 std::string settingName = StringUtils::Format("%s.%s", GetCurrentSkin().c_str(), setting.c_str());
56 CSingleLock lock(m_critical);
57 // run through and see if we have this setting
58 for (map<int, CSkinString>::const_iterator it = m_strings.begin(); it != m_strings.end(); ++it)
60 if (StringUtils::EqualsNoCase(settingName, it->second.name))
64 // didn't find it - insert it
65 CSkinString skinString;
66 skinString.name = settingName;
68 int number = m_bools.size() + m_strings.size();
69 m_strings.insert(pair<int, CSkinString>(number, skinString));
73 const string& CSkinSettings::GetString(int setting) const
75 CSingleLock lock(m_critical);
76 map<int, CSkinString>::const_iterator it = m_strings.find(setting);
77 if (it != m_strings.end())
78 return it->second.value;
80 return StringUtils::EmptyString;
83 void CSkinSettings::SetString(int setting, const string &label)
85 CSingleLock lock(m_critical);
86 map<int, CSkinString>::iterator it = m_strings.find(setting);
87 if (it != m_strings.end())
89 it->second.value = label;
94 CLog::Log(LOGFATAL, "%s: unknown setting (%d) requested", __FUNCTION__, setting);
97 int CSkinSettings::TranslateBool(const string &setting)
99 string settingName = StringUtils::Format("%s.%s", GetCurrentSkin().c_str(), setting.c_str());
101 CSingleLock lock(m_critical);
102 // run through and see if we have this setting
103 for (map<int, CSkinBool>::const_iterator it = m_bools.begin(); it != m_bools.end(); ++it)
105 if (StringUtils::EqualsNoCase(settingName, it->second.name))
109 // didn't find it - insert it
111 skinBool.name = settingName;
112 skinBool.value = false;
114 int number = m_bools.size() + m_strings.size();
115 m_bools.insert(pair<int, CSkinBool>(number, skinBool));
119 bool CSkinSettings::GetBool(int setting) const
121 CSingleLock lock(m_critical);
122 map<int, CSkinBool>::const_iterator it = m_bools.find(setting);
123 if (it != m_bools.end())
124 return it->second.value;
126 // default is to return false
130 void CSkinSettings::SetBool(int setting, bool set)
132 CSingleLock lock(m_critical);
133 map<int, CSkinBool>::iterator it = m_bools.find(setting);
134 if (it != m_bools.end())
136 it->second.value = set;
141 CLog::Log(LOGFATAL,"%s: unknown setting (%d) requested", __FUNCTION__, setting);
144 void CSkinSettings::Reset(const string &setting)
146 string settingName = StringUtils::Format("%s.%s", GetCurrentSkin().c_str(), setting.c_str());
148 CSingleLock lock(m_critical);
149 // run through and see if we have this setting as a string
150 for (map<int, CSkinString>::iterator it = m_strings.begin(); it != m_strings.end(); ++it)
152 if (StringUtils::EqualsNoCase(settingName, it->second.name))
154 it->second.value.clear();
159 // and now check for the skin bool
160 for (map<int, CSkinBool>::iterator it = m_bools.begin(); it != m_bools.end(); ++it)
162 if (StringUtils::EqualsNoCase(settingName, it->second.name))
164 it->second.value = false;
170 void CSkinSettings::Reset()
172 string currentSkin = GetCurrentSkin() + ".";
174 CSingleLock lock(m_critical);
175 // clear all the settings and strings from this skin.
176 for (map<int, CSkinBool>::iterator it = m_bools.begin(); it != m_bools.end(); ++it)
178 if (StringUtils::StartsWithNoCase(it->second.name, currentSkin))
179 it->second.value = false;
182 for (map<int, CSkinString>::iterator it = m_strings.begin(); it != m_strings.end(); ++it)
184 if (StringUtils::StartsWithNoCase(it->second.name, currentSkin))
185 it->second.value.clear();
188 g_infoManager.ResetCache();
191 bool CSkinSettings::Load(const TiXmlNode *settings)
193 if (settings == NULL)
196 const TiXmlElement *pElement = settings->FirstChildElement(XML_SKINSETTINGS);
197 if (pElement == NULL)
199 CLog::Log(LOGWARNING, "CSkinSettings: no <skinsettings> tag found");
203 CSingleLock lock(m_critical);
208 const TiXmlElement *pChild = pElement->FirstChildElement(XML_SETTING);
211 CStdString settingName = pChild->Attribute(XML_ATTR_NAME);
212 if (pChild->Attribute("type") && StringUtils::EqualsNoCase(pChild->Attribute(XML_ATTR_TYPE), "string"))
215 string.name = settingName;
216 string.value = pChild->FirstChild() ? pChild->FirstChild()->Value() : "";
217 m_strings.insert(pair<int, CSkinString>(number++, string));
222 setting.name = settingName;
223 setting.value = pChild->FirstChild() ? StringUtils::EqualsNoCase(pChild->FirstChild()->Value(), "true") : false;
224 m_bools.insert(pair<int, CSkinBool>(number++, setting));
226 pChild = pChild->NextSiblingElement(XML_SETTING);
232 bool CSkinSettings::Save(TiXmlNode *settings) const
234 if (settings == NULL)
237 CSingleLock lock(m_critical);
238 // add the <skinsettings> tag
239 TiXmlElement xmlSettingsElement(XML_SKINSETTINGS);
240 TiXmlNode *pSettingsNode = settings->InsertEndChild(xmlSettingsElement);
241 if (pSettingsNode == NULL)
243 CLog::Log(LOGWARNING, "CSkinSettings: could not create <skinsettings> tag");
247 for (map<int, CSkinBool>::const_iterator it = m_bools.begin(); it != m_bools.end(); ++it)
249 // Add a <setting type="bool" name="name">true/false</setting>
250 TiXmlElement xmlSetting(XML_SETTING);
251 xmlSetting.SetAttribute(XML_ATTR_TYPE, "bool");
252 xmlSetting.SetAttribute(XML_ATTR_NAME, (*it).second.name.c_str());
253 TiXmlText xmlBool((*it).second.value ? "true" : "false");
254 xmlSetting.InsertEndChild(xmlBool);
255 pSettingsNode->InsertEndChild(xmlSetting);
257 for (map<int, CSkinString>::const_iterator it = m_strings.begin(); it != m_strings.end(); ++it)
259 // Add a <setting type="string" name="name">string</setting>
260 TiXmlElement xmlSetting(XML_SETTING);
261 xmlSetting.SetAttribute(XML_ATTR_TYPE, "string");
262 xmlSetting.SetAttribute(XML_ATTR_NAME, (*it).second.name.c_str());
263 TiXmlText xmlLabel((*it).second.value);
264 xmlSetting.InsertEndChild(xmlLabel);
265 pSettingsNode->InsertEndChild(xmlSetting);
271 void CSkinSettings::Clear()
273 CSingleLock lock(m_critical);
278 std::string CSkinSettings::GetCurrentSkin() const
280 return CSettings::Get().GetString("lookandfeel.skin");