[videodb] Remove nested transaction when saving state after stopping PVR playback
[xbmc.git] / xbmc / view / ViewStateSettings.cpp
blobd8833934ae602935ae0665a8c67f867d75be8e2d
1 /*
2 * Copyright (C) 2013-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include "ViewStateSettings.h"
11 #include "utils/SortUtils.h"
12 #include "utils/XBMCTinyXML.h"
13 #include "utils/XMLUtils.h"
14 #include "utils/log.h"
16 #include <cstring>
17 #include <mutex>
18 #include <utility>
20 #define XML_VIEWSTATESETTINGS "viewstates"
21 #define XML_VIEWMODE "viewmode"
22 #define XML_SORTMETHOD "sortmethod"
23 #define XML_SORTORDER "sortorder"
24 #define XML_SORTATTRIBUTES "sortattributes"
25 #define XML_GENERAL "general"
26 #define XML_SETTINGLEVEL "settinglevel"
27 #define XML_EVENTLOG "eventlog"
28 #define XML_EVENTLOG_LEVEL "level"
29 #define XML_EVENTLOG_LEVEL_HIGHER "showhigherlevels"
31 CViewStateSettings::CViewStateSettings()
33 AddViewState("musicnavartists");
34 AddViewState("musicnavalbums");
35 AddViewState("musicnavsongs", DEFAULT_VIEW_LIST, SortByTrackNumber);
36 AddViewState("musiclastfm");
37 AddViewState("videonavactors");
38 AddViewState("videonavyears");
39 AddViewState("videonavgenres");
40 AddViewState("videonavtitles");
41 AddViewState("videonavepisodes", DEFAULT_VIEW_AUTO, SortByEpisodeNumber);
42 AddViewState("videonavtvshows");
43 AddViewState("videonavseasons");
44 AddViewState("videonavmusicvideos");
46 AddViewState("programs", DEFAULT_VIEW_AUTO);
47 AddViewState("pictures", DEFAULT_VIEW_AUTO);
48 AddViewState("videofiles", DEFAULT_VIEW_AUTO);
49 AddViewState("musicfiles", DEFAULT_VIEW_AUTO);
50 AddViewState("games", DEFAULT_VIEW_AUTO);
52 Clear();
55 CViewStateSettings::~CViewStateSettings()
57 for (std::map<std::string, CViewState*>::const_iterator viewState = m_viewStates.begin(); viewState != m_viewStates.end(); ++viewState)
58 delete viewState->second;
59 m_viewStates.clear();
62 CViewStateSettings& CViewStateSettings::GetInstance()
64 static CViewStateSettings sViewStateSettings;
65 return sViewStateSettings;
68 bool CViewStateSettings::Load(const TiXmlNode *settings)
70 if (settings == NULL)
71 return false;
73 std::unique_lock<CCriticalSection> lock(m_critical);
74 const TiXmlNode *pElement = settings->FirstChildElement(XML_VIEWSTATESETTINGS);
75 if (pElement == NULL)
77 CLog::Log(LOGWARNING, "CViewStateSettings: no <viewstates> tag found");
78 return false;
81 for (std::map<std::string, CViewState*>::iterator viewState = m_viewStates.begin(); viewState != m_viewStates.end(); ++viewState)
83 const TiXmlNode* pViewState = pElement->FirstChildElement(viewState->first);
84 if (pViewState == NULL)
85 continue;
87 XMLUtils::GetInt(pViewState, XML_VIEWMODE, viewState->second->m_viewMode, DEFAULT_VIEW_LIST, DEFAULT_VIEW_MAX);
89 // keep backwards compatibility to the old sorting methods
90 if (pViewState->FirstChild(XML_SORTATTRIBUTES) == NULL)
92 int sortMethod;
93 if (XMLUtils::GetInt(pViewState, XML_SORTMETHOD, sortMethod, SORT_METHOD_NONE, SORT_METHOD_MAX))
94 viewState->second->m_sortDescription = SortUtils::TranslateOldSortMethod((SORT_METHOD)sortMethod);
96 else
98 int sortMethod;
99 if (XMLUtils::GetInt(pViewState, XML_SORTMETHOD, sortMethod, SortByNone, SortByLastUsed))
100 viewState->second->m_sortDescription.sortBy = (SortBy)sortMethod;
101 if (XMLUtils::GetInt(pViewState, XML_SORTATTRIBUTES, sortMethod, SortAttributeNone, SortAttributeIgnoreFolders))
102 viewState->second->m_sortDescription.sortAttributes = (SortAttribute)sortMethod;
105 int sortOrder;
106 if (XMLUtils::GetInt(pViewState, XML_SORTORDER, sortOrder, SortOrderNone, SortOrderDescending))
107 viewState->second->m_sortDescription.sortOrder = (SortOrder)sortOrder;
110 pElement = settings->FirstChild(XML_GENERAL);
111 if (pElement != NULL)
113 int settingLevel;
114 if (XMLUtils::GetInt(pElement, XML_SETTINGLEVEL, settingLevel, static_cast<int>(SettingLevel::Basic), static_cast<int>(SettingLevel::Expert)))
115 m_settingLevel = (SettingLevel)settingLevel;
116 else
117 m_settingLevel = SettingLevel::Standard;
119 const TiXmlNode* pEventLogNode = pElement->FirstChild(XML_EVENTLOG);
120 if (pEventLogNode != NULL)
122 int eventLevel;
123 if (XMLUtils::GetInt(pEventLogNode, XML_EVENTLOG_LEVEL, eventLevel, static_cast<int>(EventLevel::Basic), static_cast<int>(EventLevel::Error)))
124 m_eventLevel = (EventLevel)eventLevel;
125 else
126 m_eventLevel = EventLevel::Basic;
128 if (!XMLUtils::GetBoolean(pEventLogNode, XML_EVENTLOG_LEVEL_HIGHER, m_eventShowHigherLevels))
129 m_eventShowHigherLevels = true;
133 return true;
136 bool CViewStateSettings::Save(TiXmlNode *settings) const
138 if (settings == NULL)
139 return false;
141 std::unique_lock<CCriticalSection> lock(m_critical);
142 // add the <viewstates> tag
143 TiXmlElement xmlViewStateElement(XML_VIEWSTATESETTINGS);
144 TiXmlNode *pViewStateNode = settings->InsertEndChild(xmlViewStateElement);
145 if (pViewStateNode == NULL)
147 CLog::Log(LOGWARNING, "CViewStateSettings: could not create <viewstates> tag");
148 return false;
151 for (std::map<std::string, CViewState*>::const_iterator viewState = m_viewStates.begin(); viewState != m_viewStates.end(); ++viewState)
153 TiXmlElement newElement(viewState->first);
154 TiXmlNode *pNewNode = pViewStateNode->InsertEndChild(newElement);
155 if (pNewNode == NULL)
156 continue;
158 XMLUtils::SetInt(pNewNode, XML_VIEWMODE, viewState->second->m_viewMode);
159 XMLUtils::SetInt(pNewNode, XML_SORTMETHOD, (int)viewState->second->m_sortDescription.sortBy);
160 XMLUtils::SetInt(pNewNode, XML_SORTORDER, (int)viewState->second->m_sortDescription.sortOrder);
161 XMLUtils::SetInt(pNewNode, XML_SORTATTRIBUTES, (int)viewState->second->m_sortDescription.sortAttributes);
164 TiXmlNode *generalNode = settings->FirstChild(XML_GENERAL);
165 if (generalNode == NULL)
167 TiXmlElement generalElement(XML_GENERAL);
168 generalNode = settings->InsertEndChild(generalElement);
169 if (generalNode == NULL)
170 return false;
173 XMLUtils::SetInt(generalNode, XML_SETTINGLEVEL, (int)m_settingLevel);
175 TiXmlNode *eventLogNode = generalNode->FirstChild(XML_EVENTLOG);
176 if (eventLogNode == NULL)
178 TiXmlElement eventLogElement(XML_EVENTLOG);
179 eventLogNode = generalNode->InsertEndChild(eventLogElement);
180 if (eventLogNode == NULL)
181 return false;
184 XMLUtils::SetInt(eventLogNode, XML_EVENTLOG_LEVEL, (int)m_eventLevel);
185 XMLUtils::SetBoolean(eventLogNode, XML_EVENTLOG_LEVEL_HIGHER, (int)m_eventShowHigherLevels);
187 return true;
190 void CViewStateSettings::Clear()
192 m_settingLevel = SettingLevel::Standard;
195 const CViewState* CViewStateSettings::Get(const std::string &viewState) const
197 std::unique_lock<CCriticalSection> lock(m_critical);
198 std::map<std::string, CViewState*>::const_iterator view = m_viewStates.find(viewState);
199 if (view != m_viewStates.end())
200 return view->second;
202 return NULL;
205 CViewState* CViewStateSettings::Get(const std::string &viewState)
207 std::unique_lock<CCriticalSection> lock(m_critical);
208 std::map<std::string, CViewState*>::iterator view = m_viewStates.find(viewState);
209 if (view != m_viewStates.end())
210 return view->second;
212 return NULL;
215 void CViewStateSettings::SetSettingLevel(SettingLevel settingLevel)
217 if (settingLevel < SettingLevel::Basic)
218 m_settingLevel = SettingLevel::Basic;
219 if (settingLevel > SettingLevel::Expert)
220 m_settingLevel = SettingLevel::Expert;
221 else
222 m_settingLevel = settingLevel;
225 void CViewStateSettings::CycleSettingLevel()
227 m_settingLevel = GetNextSettingLevel();
230 SettingLevel CViewStateSettings::GetNextSettingLevel() const
232 SettingLevel level = (SettingLevel)((int)m_settingLevel + 1);
233 if (level > SettingLevel::Expert)
234 level = SettingLevel::Basic;
235 return level;
238 void CViewStateSettings::SetEventLevel(EventLevel eventLevel)
240 if (eventLevel < EventLevel::Basic)
241 m_eventLevel = EventLevel::Basic;
242 if (eventLevel > EventLevel::Error)
243 m_eventLevel = EventLevel::Error;
244 else
245 m_eventLevel = eventLevel;
248 void CViewStateSettings::CycleEventLevel()
250 m_eventLevel = GetNextEventLevel();
253 EventLevel CViewStateSettings::GetNextEventLevel() const
255 EventLevel level = (EventLevel)((int)m_eventLevel + 1);
256 if (level > EventLevel::Error)
257 level = EventLevel::Basic;
258 return level;
261 void CViewStateSettings::AddViewState(const std::string& strTagName, int defaultView /* = DEFAULT_VIEW_LIST */, SortBy defaultSort /* = SortByLabel */)
263 if (strTagName.empty() || m_viewStates.find(strTagName) != m_viewStates.end())
264 return;
266 CViewState *viewState = new CViewState(defaultView, defaultSort, SortOrderAscending);
267 if (viewState == NULL)
268 return;
270 m_viewStates.insert(make_pair(strTagName, viewState));