Remove LiveTV menu.
[vuplus_xbmc] / xbmc / settings / SkinSettings.cpp
1 /*
2  *      Copyright (C) 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 <string.h>
22
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"
30
31 #define XML_SKINSETTINGS  "skinsettings"
32 #define XML_SETTING       "setting"
33 #define XML_ATTR_TYPE     "type"
34 #define XML_ATTR_NAME     "name"
35
36 using namespace std;
37
38 CSkinSettings::CSkinSettings()
39 {
40   Clear();
41 }
42
43 CSkinSettings::~CSkinSettings()
44 { }
45
46 CSkinSettings& CSkinSettings::Get()
47 {
48   static CSkinSettings sSkinSettings;
49   return sSkinSettings;
50 }
51
52 int CSkinSettings::TranslateString(const string &setting)
53 {
54   std::string settingName = StringUtils::Format("%s.%s", GetCurrentSkin().c_str(), setting.c_str());
55
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)
59   {
60     if (StringUtils::EqualsNoCase(settingName, it->second.name))
61       return it->first;
62   }
63
64   // didn't find it - insert it
65   CSkinString skinString;
66   skinString.name = settingName;
67
68   int number = m_bools.size() + m_strings.size();
69   m_strings.insert(pair<int, CSkinString>(number, skinString));
70   return number;
71 }
72
73 const string& CSkinSettings::GetString(int setting) const
74 {
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;
79
80   return StringUtils::EmptyString;
81 }
82
83 void CSkinSettings::SetString(int setting, const string &label)
84 {
85   CSingleLock lock(m_critical);
86   map<int, CSkinString>::iterator it = m_strings.find(setting);
87   if (it != m_strings.end())
88   {
89     it->second.value = label;
90     return;
91   }
92
93   assert(false);
94   CLog::Log(LOGFATAL, "%s: unknown setting (%d) requested", __FUNCTION__, setting);
95 }
96
97 int CSkinSettings::TranslateBool(const string &setting)
98 {
99   string settingName = StringUtils::Format("%s.%s", GetCurrentSkin().c_str(), setting.c_str());
100
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)
104   {
105     if (StringUtils::EqualsNoCase(settingName, it->second.name))
106       return it->first;
107   }
108
109   // didn't find it - insert it
110   CSkinBool skinBool;
111   skinBool.name = settingName;
112   skinBool.value = false;
113
114   int number = m_bools.size() + m_strings.size();
115   m_bools.insert(pair<int, CSkinBool>(number, skinBool));
116   return number;
117 }
118
119 bool CSkinSettings::GetBool(int setting) const
120 {
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;
125
126   // default is to return false
127   return false;
128 }
129
130 void CSkinSettings::SetBool(int setting, bool set)
131 {
132   CSingleLock lock(m_critical);
133   map<int, CSkinBool>::iterator it = m_bools.find(setting);
134   if (it != m_bools.end())
135   {
136     it->second.value = set;
137     return;
138   }
139
140   assert(false);
141   CLog::Log(LOGFATAL,"%s: unknown setting (%d) requested", __FUNCTION__, setting);
142 }
143
144 void CSkinSettings::Reset(const string &setting)
145 {
146   string settingName = StringUtils::Format("%s.%s", GetCurrentSkin().c_str(), setting.c_str());
147
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)
151   {
152     if (StringUtils::EqualsNoCase(settingName, it->second.name))
153     {
154       it->second.value.clear();
155       return;
156     }
157   }
158
159   // and now check for the skin bool
160   for (map<int, CSkinBool>::iterator it = m_bools.begin(); it != m_bools.end(); ++it)
161   {
162     if (StringUtils::EqualsNoCase(settingName, it->second.name))
163     {
164       it->second.value = false;
165       return;
166     }
167   }
168 }
169
170 void CSkinSettings::Reset()
171 {
172   string currentSkin = GetCurrentSkin() + ".";
173
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)
177   {
178     if (StringUtils::StartsWithNoCase(it->second.name, currentSkin))
179       it->second.value = false;
180   }
181
182   for (map<int, CSkinString>::iterator it = m_strings.begin(); it != m_strings.end(); ++it)
183   {
184     if (StringUtils::StartsWithNoCase(it->second.name, currentSkin))
185       it->second.value.clear();
186   }
187
188   g_infoManager.ResetCache();
189 }
190
191 bool CSkinSettings::Load(const TiXmlNode *settings)
192 {
193   if (settings == NULL)
194     return false;
195
196   const TiXmlElement *pElement = settings->FirstChildElement(XML_SKINSETTINGS);
197   if (pElement == NULL)
198   {
199     CLog::Log(LOGWARNING, "CSkinSettings: no <skinsettings> tag found");
200     return false;
201   }
202
203   CSingleLock lock(m_critical);
204   m_strings.clear();
205   m_bools.clear();
206
207   int number = 0;
208   const TiXmlElement *pChild = pElement->FirstChildElement(XML_SETTING);
209   while (pChild)
210   {
211     CStdString settingName = pChild->Attribute(XML_ATTR_NAME);
212     if (pChild->Attribute("type") && StringUtils::EqualsNoCase(pChild->Attribute(XML_ATTR_TYPE), "string"))
213     { // string setting
214       CSkinString string;
215       string.name = settingName;
216       string.value = pChild->FirstChild() ? pChild->FirstChild()->Value() : "";
217       m_strings.insert(pair<int, CSkinString>(number++, string));
218     }
219     else
220     { // bool setting
221       CSkinBool setting;
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));
225     }
226     pChild = pChild->NextSiblingElement(XML_SETTING);
227   }
228
229   return true;
230 }
231
232 bool CSkinSettings::Save(TiXmlNode *settings) const
233 {
234   if (settings == NULL)
235     return false;
236
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)
242   {
243     CLog::Log(LOGWARNING, "CSkinSettings: could not create <skinsettings> tag");
244     return false;
245   }
246
247   for (map<int, CSkinBool>::const_iterator it = m_bools.begin(); it != m_bools.end(); ++it)
248   {
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);
256   }
257   for (map<int, CSkinString>::const_iterator it = m_strings.begin(); it != m_strings.end(); ++it)
258   {
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);
266   }
267
268   return true;
269 }
270
271 void CSkinSettings::Clear()
272 {
273   CSingleLock lock(m_critical);
274   m_strings.clear();
275   m_bools.clear();
276 }
277
278 std::string CSkinSettings::GetCurrentSkin() const
279 {
280   return CSettings::Get().GetString("lookandfeel.skin");
281 }