[Windows] Fix driver version detection of AMD RDNA+ GPU on Windows 10
[xbmc.git] / xbmc / view / GUIViewState.cpp
blobcebf9319bebae0c94feb196279652b30274e08a9
1 /*
2 * Copyright (C) 2005-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 "view/GUIViewState.h"
11 #include "AutoSwitch.h"
12 #include "FileItem.h"
13 #include "FileItemList.h"
14 #include "GUIPassword.h"
15 #include "PlayListPlayer.h"
16 #include "ServiceBroker.h"
17 #include "URL.h"
18 #include "ViewDatabase.h"
19 #include "addons/Addon.h"
20 #include "addons/AddonManager.h"
21 #include "addons/PluginSource.h"
22 #include "addons/addoninfo/AddonType.h"
23 #include "addons/gui/GUIViewStateAddonBrowser.h"
24 #include "dialogs/GUIDialogSelect.h"
25 #include "events/windows/GUIViewStateEventLog.h"
26 #include "favourites/GUIViewStateFavourites.h"
27 #include "games/windows/GUIViewStateWindowGames.h"
28 #include "guilib/GUIComponent.h"
29 #include "guilib/GUIWindowManager.h"
30 #include "guilib/LocalizeStrings.h"
31 #include "guilib/TextureManager.h"
32 #include "music/GUIViewStateMusic.h"
33 #include "pictures/GUIViewStatePictures.h"
34 #include "profiles/ProfileManager.h"
35 #include "programs/GUIViewStatePrograms.h"
36 #include "pvr/windows/GUIViewStatePVR.h"
37 #include "settings/MediaSourceSettings.h"
38 #include "settings/Settings.h"
39 #include "settings/SettingsComponent.h"
40 #include "settings/lib/Setting.h"
41 #include "utils/URIUtils.h"
42 #include "video/GUIViewStateVideo.h"
43 #include "video/VideoUtils.h"
44 #include "view/ViewState.h"
46 #define PROPERTY_SORT_ORDER "sort.order"
47 #define PROPERTY_SORT_ASCENDING "sort.ascending"
49 using namespace KODI;
50 using namespace ADDON;
51 using namespace PVR;
53 std::string CGUIViewState::m_strPlaylistDirectory;
54 VECSOURCES CGUIViewState::m_sources;
56 CGUIViewState* CGUIViewState::GetViewState(int windowId, const CFileItemList& items)
58 // don't expect derived classes to clear the sources
59 m_sources.clear();
61 if (windowId == 0)
62 return GetViewState(CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow(),items);
64 const CURL url=items.GetURL();
66 if (items.IsAddonsPath())
67 return new CGUIViewStateAddonBrowser(items);
69 if (items.HasSortDetails())
70 return new CGUIViewStateFromItems(items);
72 if (url.IsProtocol("musicdb"))
73 return new CGUIViewStateMusicDatabase(items);
75 if (url.IsProtocol("musicsearch"))
76 return new CGUIViewStateMusicSearch(items);
78 if (items.IsSmartPlayList() || url.IsProtocol("upnp") ||
79 items.IsLibraryFolder())
81 if (items.GetContent() == "songs" ||
82 items.GetContent() == "albums" ||
83 items.GetContent() == "mixed")
84 return new CGUIViewStateMusicSmartPlaylist(items);
85 else if (items.GetContent() == "musicvideos")
86 return new CGUIViewStateVideoMusicVideos(items);
87 else if (items.GetContent() == "tvshows")
88 return new CGUIViewStateVideoTVShows(items);
89 else if (items.GetContent() == "episodes")
90 return new CGUIViewStateVideoEpisodes(items);
91 else if (items.GetContent() == "movies")
92 return new CGUIViewStateVideoMovies(items);
95 if (url.IsProtocol("library"))
96 return new CGUIViewStateLibrary(items);
98 if (items.IsPlayList())
100 // Playlists (like .strm) can be music or video type
101 if (windowId == WINDOW_VIDEO_NAV)
102 return new CGUIViewStateVideoPlaylist(items);
103 else
104 return new CGUIViewStateMusicPlaylist(items);
107 if (items.GetPath() == "special://musicplaylists/")
108 return new CGUIViewStateWindowMusicNav(items);
110 if (url.IsProtocol("androidapp"))
111 return new CGUIViewStateWindowPrograms(items);
113 if (url.IsProtocol("activities"))
114 return new CGUIViewStateEventLog(items);
116 if (windowId == WINDOW_MUSIC_NAV)
117 return new CGUIViewStateWindowMusicNav(items);
119 if (windowId == WINDOW_MUSIC_PLAYLIST)
120 return new CGUIViewStateWindowMusicPlaylist(items);
122 if (windowId == WINDOW_MUSIC_PLAYLIST_EDITOR)
123 return new CGUIViewStateWindowMusicNav(items);
125 if (windowId == WINDOW_VIDEO_NAV)
126 return new CGUIViewStateWindowVideoNav(items);
128 if (windowId == WINDOW_VIDEO_PLAYLIST)
129 return new CGUIViewStateWindowVideoPlaylist(items);
131 if (windowId == WINDOW_TV_CHANNELS)
132 return new CGUIViewStateWindowPVRChannels(windowId, items);
134 if (windowId == WINDOW_TV_RECORDINGS)
135 return new CGUIViewStateWindowPVRRecordings(windowId, items);
137 if (windowId == WINDOW_TV_GUIDE)
138 return new CGUIViewStateWindowPVRGuide(windowId, items);
140 if (windowId == WINDOW_TV_TIMERS)
141 return new CGUIViewStateWindowPVRTimers(windowId, items);
143 if (windowId == WINDOW_TV_TIMER_RULES)
144 return new CGUIViewStateWindowPVRTimers(windowId, items);
146 if (windowId == WINDOW_TV_SEARCH)
147 return new CGUIViewStateWindowPVRSearch(windowId, items);
149 if (windowId == WINDOW_RADIO_CHANNELS)
150 return new CGUIViewStateWindowPVRChannels(windowId, items);
152 if (windowId == WINDOW_RADIO_RECORDINGS)
153 return new CGUIViewStateWindowPVRRecordings(windowId, items);
155 if (windowId == WINDOW_RADIO_GUIDE)
156 return new CGUIViewStateWindowPVRGuide(windowId, items);
158 if (windowId == WINDOW_RADIO_TIMERS)
159 return new CGUIViewStateWindowPVRTimers(windowId, items);
161 if (windowId == WINDOW_RADIO_TIMER_RULES)
162 return new CGUIViewStateWindowPVRTimers(windowId, items);
164 if (windowId == WINDOW_RADIO_SEARCH)
165 return new CGUIViewStateWindowPVRSearch(windowId, items);
167 if (windowId == WINDOW_PICTURES)
168 return new CGUIViewStateWindowPictures(items);
170 if (windowId == WINDOW_PROGRAMS)
171 return new CGUIViewStateWindowPrograms(items);
173 if (windowId == WINDOW_GAMES)
174 return new GAME::CGUIViewStateWindowGames(items);
176 if (windowId == WINDOW_ADDON_BROWSER)
177 return new CGUIViewStateAddonBrowser(items);
179 if (windowId == WINDOW_EVENT_LOG)
180 return new CGUIViewStateEventLog(items);
182 if (windowId == WINDOW_FAVOURITES)
183 return new CGUIViewStateFavourites(items);
185 // Use as fallback/default
186 return new CGUIViewStateGeneral(items);
189 CGUIViewState::CGUIViewState(const CFileItemList& items) : m_items(items)
191 m_currentViewAsControl = 0;
192 m_currentSortMethod = 0;
193 m_playlist = PLAYLIST::Id::TYPE_NONE;
196 CGUIViewState::~CGUIViewState() = default;
198 SortOrder CGUIViewState::SetNextSortOrder()
200 if (GetSortOrder() == SortOrderAscending)
201 SetSortOrder(SortOrderDescending);
202 else
203 SetSortOrder(SortOrderAscending);
205 SaveViewState();
207 return GetSortOrder();
210 SortOrder CGUIViewState::GetSortOrder() const
212 if (m_currentSortMethod >= 0 && m_currentSortMethod < (int)m_sortMethods.size())
213 return m_sortMethods[m_currentSortMethod].m_sortDescription.sortOrder;
215 return SortOrderAscending;
218 int CGUIViewState::GetSortOrderLabel() const
220 if (m_currentSortMethod >= 0 && m_currentSortMethod < (int)m_sortMethods.size())
221 if (m_sortMethods[m_currentSortMethod].m_sortDescription.sortOrder == SortOrderDescending)
222 return 585;
224 return 584; // default sort order label 'Ascending'
227 int CGUIViewState::GetViewAsControl() const
229 return m_currentViewAsControl;
232 void CGUIViewState::SetViewAsControl(int viewAsControl)
234 if (viewAsControl == DEFAULT_VIEW_AUTO)
235 m_currentViewAsControl = CAutoSwitch::GetView(m_items);
236 else
237 m_currentViewAsControl = viewAsControl;
240 void CGUIViewState::SaveViewAsControl(int viewAsControl)
242 SetViewAsControl(viewAsControl);
243 SaveViewState();
246 SortDescription CGUIViewState::GetSortMethod() const
248 SortDescription sorting;
249 if (m_currentSortMethod >= 0 && m_currentSortMethod < (int)m_sortMethods.size())
250 sorting = m_sortMethods[m_currentSortMethod].m_sortDescription;
252 return sorting;
255 bool CGUIViewState::HasMultipleSortMethods() const
257 return m_sortMethods.size() > 1;
260 int CGUIViewState::GetSortMethodLabel() const
262 if (m_currentSortMethod >= 0 && m_currentSortMethod < (int)m_sortMethods.size())
263 return m_sortMethods[m_currentSortMethod].m_buttonLabel;
265 return 551; // default sort method label 'Name'
268 void CGUIViewState::GetSortMethodLabelMasks(LABEL_MASKS& masks) const
270 if (m_currentSortMethod >= 0 && m_currentSortMethod < (int)m_sortMethods.size())
272 masks = m_sortMethods[m_currentSortMethod].m_labelMasks;
273 return;
276 masks.m_strLabelFile.clear();
277 masks.m_strLabel2File.clear();
278 masks.m_strLabelFolder.clear();
279 masks.m_strLabel2Folder.clear();
282 std::vector<SortDescription> CGUIViewState::GetSortDescriptions() const
284 std::vector<SortDescription> descriptions;
285 descriptions.reserve(m_sortMethods.size());
286 for (const auto& desc : m_sortMethods)
288 descriptions.emplace_back(desc.m_sortDescription);
290 return descriptions;
293 void CGUIViewState::AddSortMethod(SortBy sortBy, int buttonLabel, const LABEL_MASKS &labelMasks, SortAttribute sortAttributes /* = SortAttributeNone */, SortOrder sortOrder /* = SortOrderNone */)
295 AddSortMethod(sortBy, sortAttributes, buttonLabel, labelMasks, sortOrder);
298 void CGUIViewState::AddSortMethod(SortBy sortBy, SortAttribute sortAttributes, int buttonLabel, const LABEL_MASKS &labelMasks, SortOrder sortOrder /* = SortOrderNone */)
300 for (size_t i = 0; i < m_sortMethods.size(); ++i)
301 if (m_sortMethods[i].m_sortDescription.sortBy == sortBy)
302 return;
304 // handle unspecified sort order
305 if (sortBy != SortByNone && sortOrder == SortOrderNone)
307 // the following sort methods are sorted in descending order by default
308 if (sortBy == SortByDate || sortBy == SortBySize || sortBy == SortByPlaycount ||
309 sortBy == SortByRating || sortBy == SortByProgramCount ||
310 sortBy == SortByBitrate || sortBy == SortByListeners ||
311 sortBy == SortByUserRating || sortBy == SortByLastPlayed)
312 sortOrder = SortOrderDescending;
313 else
314 sortOrder = SortOrderAscending;
317 GUIViewSortDetails sort;
318 sort.m_sortDescription.sortBy = sortBy;
319 sort.m_sortDescription.sortOrder = sortOrder;
320 sort.m_sortDescription.sortAttributes = sortAttributes;
321 sort.m_buttonLabel = buttonLabel;
322 sort.m_labelMasks = labelMasks;
323 m_sortMethods.push_back(sort);
326 void CGUIViewState::AddSortMethod(SortDescription sortDescription, int buttonLabel, const LABEL_MASKS &labelMasks)
328 AddSortMethod(sortDescription.sortBy, sortDescription.sortAttributes, buttonLabel, labelMasks, sortDescription.sortOrder);
331 void CGUIViewState::SetCurrentSortMethod(int method)
333 SortBy sortBy = (SortBy)method;
334 if (sortBy < SortByNone || sortBy > SortByLastUsed)
335 return; // invalid
337 SetSortMethod(sortBy);
338 SaveViewState();
341 void CGUIViewState::SetSortMethod(SortBy sortBy, SortOrder sortOrder /* = SortOrderNone */)
343 for (int i = 0; i < (int)m_sortMethods.size(); ++i)
345 if (m_sortMethods[i].m_sortDescription.sortBy == sortBy)
347 m_currentSortMethod = i;
348 break;
352 if (sortOrder != SortOrderNone)
353 SetSortOrder(sortOrder);
356 void CGUIViewState::SetSortMethod(SortDescription sortDescription)
358 return SetSortMethod(sortDescription.sortBy, sortDescription.sortOrder);
361 bool CGUIViewState::ChooseSortMethod()
364 CGUIDialogSelect *dialog = CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogSelect>(WINDOW_DIALOG_SELECT);
365 if (!dialog)
366 return false;
367 dialog->Reset();
368 dialog->SetHeading(CVariant{ 39010 }); // Label "Sort by"
369 for (auto &sortMethod : m_sortMethods)
370 dialog->Add(g_localizeStrings.Get(sortMethod.m_buttonLabel));
371 dialog->SetSelected(m_currentSortMethod);
372 dialog->Open();
373 int newSelected = dialog->GetSelectedItem();
374 // check if selection has changed
375 if (!dialog->IsConfirmed() || newSelected < 0 || newSelected == m_currentSortMethod)
376 return false;
378 m_currentSortMethod = newSelected;
379 SaveViewState();
380 return true;
383 SortDescription CGUIViewState::SetNextSortMethod(int direction /* = 1 */)
385 m_currentSortMethod += direction;
387 if (m_currentSortMethod >= (int)m_sortMethods.size())
388 m_currentSortMethod = 0;
389 if (m_currentSortMethod < 0)
390 m_currentSortMethod = m_sortMethods.size() ? (int)m_sortMethods.size() - 1 : 0;
392 SaveViewState();
394 return GetSortMethod();
397 bool CGUIViewState::HideExtensions()
399 return !CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_FILELISTS_SHOWEXTENSIONS);
402 bool CGUIViewState::HideParentDirItems()
404 return !CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_FILELISTS_SHOWPARENTDIRITEMS);
407 bool CGUIViewState::DisableAddSourceButtons()
409 const std::shared_ptr<CProfileManager> profileManager = CServiceBroker::GetSettingsComponent()->GetProfileManager();
411 if (profileManager->GetCurrentProfile().canWriteSources() || g_passwordManager.bMasterUser)
412 return !CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_FILELISTS_SHOWADDSOURCEBUTTONS);
414 return true;
417 PLAYLIST::Id CGUIViewState::GetPlaylist() const
419 return m_playlist;
422 const std::string& CGUIViewState::GetPlaylistDirectory()
424 return m_strPlaylistDirectory;
427 void CGUIViewState::SetPlaylistDirectory(const std::string& strDirectory)
429 m_strPlaylistDirectory = strDirectory;
430 URIUtils::RemoveSlashAtEnd(m_strPlaylistDirectory);
433 bool CGUIViewState::IsCurrentPlaylistDirectory(const std::string& strDirectory)
435 if (CServiceBroker::GetPlaylistPlayer().GetCurrentPlaylist()!=GetPlaylist())
436 return false;
438 std::string strDir = strDirectory;
439 URIUtils::RemoveSlashAtEnd(strDir);
441 return m_strPlaylistDirectory == strDir;
444 bool CGUIViewState::AutoPlayNextItem()
446 return false;
449 std::string CGUIViewState::GetLockType()
451 return "";
454 std::string CGUIViewState::GetExtensions()
456 return "";
459 VECSOURCES& CGUIViewState::GetSources()
461 return m_sources;
464 void CGUIViewState::AddLiveTVSources()
466 VECSOURCES *sources = CMediaSourceSettings::GetInstance().GetSources("video");
467 for (IVECSOURCES it = sources->begin(); it != sources->end(); ++it)
469 if (URIUtils::IsLiveTV((*it).strPath))
471 CMediaSource source;
472 source.strPath = (*it).strPath;
473 source.strName = (*it).strName;
474 source.vecPaths = (*it).vecPaths;
475 source.m_strThumbnailImage = "";
476 source.FromNameAndPaths("video", source.strName, source.vecPaths);
477 m_sources.push_back(source);
482 void CGUIViewState::SetSortOrder(SortOrder sortOrder)
484 if (sortOrder == SortOrderNone)
485 return;
487 if (m_currentSortMethod < 0 || m_currentSortMethod >= (int)m_sortMethods.size())
488 return;
490 m_sortMethods[m_currentSortMethod].m_sortDescription.sortOrder = sortOrder;
493 bool CGUIViewState::AutoPlayNextVideoItem() const
495 if (GetPlaylist() != PLAYLIST::Id::TYPE_VIDEO)
496 return false;
498 return VIDEO::UTILS::IsAutoPlayNextItem(m_items.GetContent());
501 void CGUIViewState::LoadViewState(const std::string &path, int windowID)
502 { // get our view state from the db
503 CViewDatabase db;
504 if (!db.Open())
505 return;
507 CViewState state;
508 if (db.GetViewState(path, windowID, state, CServiceBroker::GetSettingsComponent()->GetSettings()->GetString(CSettings::SETTING_LOOKANDFEEL_SKIN)) ||
509 db.GetViewState(path, windowID, state, ""))
511 SetViewAsControl(state.m_viewMode);
512 SetSortMethod(state.m_sortDescription);
516 void CGUIViewState::SaveViewToDb(const std::string &path, int windowID, CViewState *viewState)
518 CViewDatabase db;
519 if (!db.Open())
520 return;
522 SortDescription sorting = GetSortMethod();
523 CViewState state(m_currentViewAsControl, sorting.sortBy, sorting.sortOrder, sorting.sortAttributes);
524 if (viewState != NULL)
525 *viewState = state;
527 const std::shared_ptr<CSettings> settings = CServiceBroker::GetSettingsComponent()->GetSettings();
528 db.SetViewState(path, windowID, state, settings->GetString(CSettings::SETTING_LOOKANDFEEL_SKIN));
529 db.Close();
531 if (viewState != NULL)
532 settings->Save();
535 void CGUIViewState::AddPlaylistOrder(const CFileItemList& items, const LABEL_MASKS& label_masks)
537 SortBy sortBy = SortByPlaylistOrder;
538 int sortLabel = 559;
539 SortOrder sortOrder = SortOrderAscending;
540 if (items.HasProperty(PROPERTY_SORT_ORDER))
542 sortBy = (SortBy)items.GetProperty(PROPERTY_SORT_ORDER).asInteger();
543 if (sortBy != SortByNone)
545 sortLabel = SortUtils::GetSortLabel(sortBy);
546 sortOrder = items.GetProperty(PROPERTY_SORT_ASCENDING).asBoolean() ? SortOrderAscending : SortOrderDescending;
550 AddSortMethod(sortBy, sortLabel, label_masks, SortAttributeNone, sortOrder);
551 SetSortMethod(sortBy, sortOrder);
554 CGUIViewStateGeneral::CGUIViewStateGeneral(const CFileItemList& items) : CGUIViewState(items)
556 AddSortMethod(SortByLabel, 551, LABEL_MASKS("%F", "%I", "%L", "")); // Filename, size | Foldername, empty
557 SetSortMethod(SortByLabel);
559 SetViewAsControl(DEFAULT_VIEW_LIST);
562 CGUIViewStateFromItems::CGUIViewStateFromItems(const CFileItemList &items) : CGUIViewState(items)
564 const std::vector<GUIViewSortDetails> &details = items.GetSortDetails();
565 for (unsigned int i = 0; i < details.size(); i++)
567 const GUIViewSortDetails& sort = details[i];
568 AddSortMethod(sort.m_sortDescription, sort.m_buttonLabel, sort.m_labelMasks);
570 //! @todo Should default sort/view mode be specified?
571 m_currentSortMethod = 0;
573 SetViewAsControl(DEFAULT_VIEW_LIST);
575 if (items.IsPlugin())
577 CURL url(items.GetPath());
578 AddonPtr addon;
579 if (CServiceBroker::GetAddonMgr().GetAddon(url.GetHostName(), addon, AddonType::PLUGIN,
580 OnlyEnabled::CHOICE_YES))
582 const auto plugin = std::static_pointer_cast<CPluginSource>(addon);
583 if (plugin->Provides(CPluginSource::AUDIO))
584 m_playlist = PLAYLIST::Id::TYPE_MUSIC;
585 if (plugin->Provides(CPluginSource::VIDEO))
586 m_playlist = PLAYLIST::Id::TYPE_VIDEO;
590 LoadViewState(items.GetPath(), CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow());
593 bool CGUIViewStateFromItems::AutoPlayNextItem()
595 return AutoPlayNextVideoItem();
598 void CGUIViewStateFromItems::SaveViewState()
600 SaveViewToDb(m_items.GetPath(), CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow());
603 CGUIViewStateLibrary::CGUIViewStateLibrary(const CFileItemList &items) : CGUIViewState(items)
605 AddSortMethod(SortByNone, 551, LABEL_MASKS("%F", "%I", "%L", "")); // Filename, Size | Foldername, empty
606 SetSortMethod(SortByNone);
608 SetViewAsControl(DEFAULT_VIEW_LIST);
610 LoadViewState(items.GetPath(), CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow());
613 void CGUIViewStateLibrary::SaveViewState()
615 SaveViewToDb(m_items.GetPath(), CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow());