1 /*
2  *  Copyright (C) 2005-2018 Team Kodi
3  *  This file is part of Kodi - https://kodi.tv
4  *
5  *  SPDX-License-Identifier: GPL-2.0-or-later
6  *  See LICENSES/README.md for more information.
7  */
8 
9 #include "view/GUIViewState.h"
10 
11 #include "AutoSwitch.h"
12 #include "FileItem.h"
13 #include "GUIPassword.h"
14 #include "PlayListPlayer.h"
15 #include "ServiceBroker.h"
16 #include "URL.h"
17 #include "ViewDatabase.h"
18 #include "addons/Addon.h"
19 #include "addons/AddonManager.h"
20 #include "addons/PluginSource.h"
21 #include "addons/gui/GUIViewStateAddonBrowser.h"
22 #include "dialogs/GUIDialogSelect.h"
23 #include "events/windows/GUIViewStateEventLog.h"
24 #include "filesystem/AddonsDirectory.h"
25 #include "games/windows/GUIViewStateWindowGames.h"
26 #include "guilib/GUIComponent.h"
27 #include "guilib/GUIWindowManager.h"
28 #include "guilib/LocalizeStrings.h"
29 #include "guilib/TextureManager.h"
30 #include "music/GUIViewStateMusic.h"
31 #include "pictures/GUIViewStatePictures.h"
32 #include "profiles/ProfileManager.h"
33 #include "programs/GUIViewStatePrograms.h"
34 #include "pvr/windows/GUIViewStatePVR.h"
35 #include "settings/AdvancedSettings.h"
36 #include "settings/MediaSourceSettings.h"
37 #include "settings/SettingUtils.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 "view/ViewState.h"
44 
45 #define PROPERTY_SORT_ORDER         "sort.order"
46 #define PROPERTY_SORT_ASCENDING     "sort.ascending"
47 
48 using namespace KODI;
49 using namespace ADDON;
50 using namespace PVR;
51 
52 std::string CGUIViewState::m_strPlaylistDirectory;
53 VECSOURCES CGUIViewState::m_sources;
54 
55 static const int SETTING_AUTOPLAYNEXT_MUSICVIDEOS = 0;
56 static const int SETTING_AUTOPLAYNEXT_TVSHOWS = 1;
57 static const int SETTING_AUTOPLAYNEXT_EPISODES = 2;
58 static const int SETTING_AUTOPLAYNEXT_MOVIES = 3;
59 static const int SETTING_AUTOPLAYNEXT_UNCATEGORIZED = 4;
60 
GetViewState(int windowId,const CFileItemList & items)61 CGUIViewState* CGUIViewState::GetViewState(int windowId, const CFileItemList& items)
62 {
63   // don't expect derived classes to clear the sources
64   m_sources.clear();
65 
66   if (windowId == 0)
67     return GetViewState(CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow(),items);
68 
69   const CURL url=items.GetURL();
70 
71   if (items.IsAddonsPath())
72     return new CGUIViewStateAddonBrowser(items);
73 
74   if (items.HasSortDetails())
75     return new CGUIViewStateFromItems(items);
76 
77   if (url.IsProtocol("musicdb"))
78     return new CGUIViewStateMusicDatabase(items);
79 
80   if (url.IsProtocol("musicsearch"))
81     return new CGUIViewStateMusicSearch(items);
82 
83   if (items.IsSmartPlayList() || url.IsProtocol("upnp") ||
84       items.IsLibraryFolder())
85   {
86     if (items.GetContent() == "songs" ||
87         items.GetContent() == "albums" ||
88         items.GetContent() == "mixed")
89       return new CGUIViewStateMusicSmartPlaylist(items);
90     else if (items.GetContent() == "musicvideos")
91       return new CGUIViewStateVideoMusicVideos(items);
92     else if (items.GetContent() == "tvshows")
93       return new CGUIViewStateVideoTVShows(items);
94     else if (items.GetContent() == "episodes")
95       return new CGUIViewStateVideoEpisodes(items);
96     else if (items.GetContent() == "movies")
97       return new CGUIViewStateVideoMovies(items);
98   }
99 
100   if (url.IsProtocol("library"))
101     return new CGUIViewStateLibrary(items);
102 
103   if (items.IsPlayList())
104     return new CGUIViewStateMusicPlaylist(items);
105 
106   if (items.GetPath() == "special://musicplaylists/")
107     return new CGUIViewStateWindowMusicNav(items);
108 
109   if (url.IsProtocol("androidapp"))
110     return new CGUIViewStateWindowPrograms(items);
111 
112   if (url.IsProtocol("activities"))
113     return new CGUIViewStateEventLog(items);
114 
115   if (windowId == WINDOW_MUSIC_NAV)
116     return new CGUIViewStateWindowMusicNav(items);
117 
118   if (windowId == WINDOW_MUSIC_PLAYLIST)
119     return new CGUIViewStateWindowMusicPlaylist(items);
120 
121   if (windowId == WINDOW_MUSIC_PLAYLIST_EDITOR)
122     return new CGUIViewStateWindowMusicNav(items);
123 
124   if (windowId == WINDOW_VIDEO_NAV)
125     return new CGUIViewStateWindowVideoNav(items);
126 
127   if (windowId == WINDOW_VIDEO_PLAYLIST)
128     return new CGUIViewStateWindowVideoPlaylist(items);
129 
130   if (windowId == WINDOW_TV_CHANNELS)
131     return new CGUIViewStateWindowPVRChannels(windowId, items);
132 
133   if (windowId == WINDOW_TV_RECORDINGS)
134     return new CGUIViewStateWindowPVRRecordings(windowId, items);
135 
136   if (windowId == WINDOW_TV_GUIDE)
137     return new CGUIViewStateWindowPVRGuide(windowId, items);
138 
139   if (windowId == WINDOW_TV_TIMERS)
140     return new CGUIViewStateWindowPVRTimers(windowId, items);
141 
142   if (windowId == WINDOW_TV_TIMER_RULES)
143     return new CGUIViewStateWindowPVRTimers(windowId, items);
144 
145   if (windowId == WINDOW_TV_SEARCH)
146     return new CGUIViewStateWindowPVRSearch(windowId, items);
147 
148   if (windowId == WINDOW_RADIO_CHANNELS)
149       return new CGUIViewStateWindowPVRChannels(windowId, items);
150 
151   if (windowId == WINDOW_RADIO_RECORDINGS)
152     return new CGUIViewStateWindowPVRRecordings(windowId, items);
153 
154   if (windowId == WINDOW_RADIO_GUIDE)
155     return new CGUIViewStateWindowPVRGuide(windowId, items);
156 
157   if (windowId == WINDOW_RADIO_TIMERS)
158     return new CGUIViewStateWindowPVRTimers(windowId, items);
159 
160   if (windowId == WINDOW_RADIO_TIMER_RULES)
161     return new CGUIViewStateWindowPVRTimers(windowId, items);
162 
163   if (windowId == WINDOW_RADIO_SEARCH)
164     return new CGUIViewStateWindowPVRSearch(windowId, items);
165 
166   if (windowId == WINDOW_PICTURES)
167     return new CGUIViewStateWindowPictures(items);
168 
169   if (windowId == WINDOW_PROGRAMS)
170     return new CGUIViewStateWindowPrograms(items);
171 
172   if (windowId == WINDOW_GAMES)
173     return new GAME::CGUIViewStateWindowGames(items);
174 
175   if (windowId == WINDOW_ADDON_BROWSER)
176     return new CGUIViewStateAddonBrowser(items);
177 
178   if (windowId == WINDOW_EVENT_LOG)
179     return new CGUIViewStateEventLog(items);
180 
181   //  Use as fallback/default
182   return new CGUIViewStateGeneral(items);
183 }
184 
CGUIViewState(const CFileItemList & items)185 CGUIViewState::CGUIViewState(const CFileItemList& items) : m_items(items)
186 {
187   m_currentViewAsControl = 0;
188   m_currentSortMethod = 0;
189   m_playlist = PLAYLIST_NONE;
190 }
191 
192 CGUIViewState::~CGUIViewState() = default;
193 
SetNextSortOrder()194 SortOrder CGUIViewState::SetNextSortOrder()
195 {
196   if (GetSortOrder() == SortOrderAscending)
197     SetSortOrder(SortOrderDescending);
198   else
199     SetSortOrder(SortOrderAscending);
200 
201   SaveViewState();
202 
203   return GetSortOrder();
204 }
205 
GetSortOrder() const206 SortOrder CGUIViewState::GetSortOrder() const
207 {
208   if (m_currentSortMethod >= 0 && m_currentSortMethod < (int)m_sortMethods.size())
209     return m_sortMethods[m_currentSortMethod].m_sortDescription.sortOrder;
210 
211   return SortOrderAscending;
212 }
213 
GetSortOrderLabel() const214 int CGUIViewState::GetSortOrderLabel() const
215 {
216   if (m_currentSortMethod >= 0 && m_currentSortMethod < (int)m_sortMethods.size())
217     if (m_sortMethods[m_currentSortMethod].m_sortDescription.sortOrder == SortOrderDescending)
218       return 585;
219 
220   return 584; // default sort order label 'Ascending'
221 }
222 
GetViewAsControl() const223 int CGUIViewState::GetViewAsControl() const
224 {
225   return m_currentViewAsControl;
226 }
227 
SetViewAsControl(int viewAsControl)228 void CGUIViewState::SetViewAsControl(int viewAsControl)
229 {
230   if (viewAsControl == DEFAULT_VIEW_AUTO)
231     m_currentViewAsControl = CAutoSwitch::GetView(m_items);
232   else
233     m_currentViewAsControl = viewAsControl;
234 }
235 
SaveViewAsControl(int viewAsControl)236 void CGUIViewState::SaveViewAsControl(int viewAsControl)
237 {
238   SetViewAsControl(viewAsControl);
239   SaveViewState();
240 }
241 
GetSortMethod() const242 SortDescription CGUIViewState::GetSortMethod() const
243 {
244   SortDescription sorting;
245   if (m_currentSortMethod >= 0 && m_currentSortMethod < (int)m_sortMethods.size())
246     sorting = m_sortMethods[m_currentSortMethod].m_sortDescription;
247 
248   return sorting;
249 }
250 
HasMultipleSortMethods() const251 bool CGUIViewState::HasMultipleSortMethods() const
252 {
253   return m_sortMethods.size() > 1;
254 }
255 
GetSortMethodLabel() const256 int CGUIViewState::GetSortMethodLabel() const
257 {
258   if (m_currentSortMethod >= 0 && m_currentSortMethod < (int)m_sortMethods.size())
259     return m_sortMethods[m_currentSortMethod].m_buttonLabel;
260 
261   return 551; // default sort method label 'Name'
262 }
263 
GetSortMethodLabelMasks(LABEL_MASKS & masks) const264 void CGUIViewState::GetSortMethodLabelMasks(LABEL_MASKS& masks) const
265 {
266   if (m_currentSortMethod >= 0 && m_currentSortMethod < (int)m_sortMethods.size())
267   {
268     masks = m_sortMethods[m_currentSortMethod].m_labelMasks;
269     return;
270   }
271 
272   masks.m_strLabelFile.clear();
273   masks.m_strLabel2File.clear();
274   masks.m_strLabelFolder.clear();
275   masks.m_strLabel2Folder.clear();
276 }
277 
AddSortMethod(SortBy sortBy,int buttonLabel,const LABEL_MASKS & labelMasks,SortAttribute sortAttributes,SortOrder sortOrder)278 void CGUIViewState::AddSortMethod(SortBy sortBy, int buttonLabel, const LABEL_MASKS &labelMasks, SortAttribute sortAttributes /* = SortAttributeNone */, SortOrder sortOrder /* = SortOrderNone */)
279 {
280   AddSortMethod(sortBy, sortAttributes, buttonLabel, labelMasks, sortOrder);
281 }
282 
AddSortMethod(SortBy sortBy,SortAttribute sortAttributes,int buttonLabel,const LABEL_MASKS & labelMasks,SortOrder sortOrder)283 void CGUIViewState::AddSortMethod(SortBy sortBy, SortAttribute sortAttributes, int buttonLabel, const LABEL_MASKS &labelMasks, SortOrder sortOrder /* = SortOrderNone */)
284 {
285   for (size_t i = 0; i < m_sortMethods.size(); ++i)
286     if (m_sortMethods[i].m_sortDescription.sortBy == sortBy)
287       return;
288 
289   // handle unspecified sort order
290   if (sortBy != SortByNone && sortOrder == SortOrderNone)
291   {
292     // the following sort methods are sorted in descending order by default
293     if (sortBy == SortByDate || sortBy == SortBySize || sortBy == SortByPlaycount ||
294         sortBy == SortByRating || sortBy == SortByProgramCount ||
295         sortBy == SortByBitrate || sortBy == SortByListeners ||
296         sortBy == SortByUserRating || sortBy == SortByLastPlayed)
297       sortOrder = SortOrderDescending;
298     else
299       sortOrder = SortOrderAscending;
300   }
301 
302   GUIViewSortDetails sort;
303   sort.m_sortDescription.sortBy = sortBy;
304   sort.m_sortDescription.sortOrder = sortOrder;
305   sort.m_sortDescription.sortAttributes = sortAttributes;
306   sort.m_buttonLabel = buttonLabel;
307   sort.m_labelMasks = labelMasks;
308   m_sortMethods.push_back(sort);
309 }
310 
AddSortMethod(SortDescription sortDescription,int buttonLabel,const LABEL_MASKS & labelMasks)311 void CGUIViewState::AddSortMethod(SortDescription sortDescription, int buttonLabel, const LABEL_MASKS &labelMasks)
312 {
313   AddSortMethod(sortDescription.sortBy, sortDescription.sortAttributes, buttonLabel, labelMasks, sortDescription.sortOrder);
314 }
315 
SetCurrentSortMethod(int method)316 void CGUIViewState::SetCurrentSortMethod(int method)
317 {
318   SortBy sortBy = (SortBy)method;
319   if (sortBy < SortByNone || sortBy > SortByLastUsed)
320     return; // invalid
321 
322   SetSortMethod(sortBy);
323   SaveViewState();
324 }
325 
SetSortMethod(SortBy sortBy,SortOrder sortOrder)326 void CGUIViewState::SetSortMethod(SortBy sortBy, SortOrder sortOrder /* = SortOrderNone */)
327 {
328   for (int i = 0; i < (int)m_sortMethods.size(); ++i)
329   {
330     if (m_sortMethods[i].m_sortDescription.sortBy == sortBy)
331     {
332       m_currentSortMethod = i;
333       break;
334     }
335   }
336 
337   if (sortOrder != SortOrderNone)
338     SetSortOrder(sortOrder);
339 }
340 
SetSortMethod(SortDescription sortDescription)341 void CGUIViewState::SetSortMethod(SortDescription sortDescription)
342 {
343   return SetSortMethod(sortDescription.sortBy, sortDescription.sortOrder);
344 }
345 
ChooseSortMethod()346 bool CGUIViewState::ChooseSortMethod()
347 {
348 
349   CGUIDialogSelect *dialog = CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogSelect>(WINDOW_DIALOG_SELECT);
350   if (!dialog)
351     return false;
352   dialog->Reset();
353   dialog->SetHeading(CVariant{ 39010 }); // Label "Sort by"
354   for (auto &sortMethod : m_sortMethods)
355     dialog->Add(g_localizeStrings.Get(sortMethod.m_buttonLabel));
356   dialog->SetSelected(m_currentSortMethod);
357   dialog->Open();
358   int newSelected = dialog->GetSelectedItem();
359   // check if selection has changed
360   if (!dialog->IsConfirmed() || newSelected < 0 || newSelected == m_currentSortMethod)
361     return false;
362 
363   m_currentSortMethod = newSelected;
364   SaveViewState();
365   return true;
366 }
367 
SetNextSortMethod(int direction)368 SortDescription CGUIViewState::SetNextSortMethod(int direction /* = 1 */)
369 {
370   m_currentSortMethod += direction;
371 
372   if (m_currentSortMethod >= (int)m_sortMethods.size())
373     m_currentSortMethod = 0;
374   if (m_currentSortMethod < 0)
375     m_currentSortMethod = m_sortMethods.size() ? (int)m_sortMethods.size() - 1 : 0;
376 
377   SaveViewState();
378 
379   return GetSortMethod();
380 }
381 
HideExtensions()382 bool CGUIViewState::HideExtensions()
383 {
384   return !CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_FILELISTS_SHOWEXTENSIONS);
385 }
386 
HideParentDirItems()387 bool CGUIViewState::HideParentDirItems()
388 {
389   return !CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_FILELISTS_SHOWPARENTDIRITEMS);
390 }
391 
DisableAddSourceButtons()392 bool CGUIViewState::DisableAddSourceButtons()
393 {
394   const std::shared_ptr<CProfileManager> profileManager = CServiceBroker::GetSettingsComponent()->GetProfileManager();
395 
396   if (profileManager->GetCurrentProfile().canWriteSources() || g_passwordManager.bMasterUser)
397     return !CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_FILELISTS_SHOWADDSOURCEBUTTONS);
398 
399   return true;
400 }
401 
GetPlaylist() const402 int CGUIViewState::GetPlaylist() const
403 {
404   return m_playlist;
405 }
406 
GetPlaylistDirectory()407 const std::string& CGUIViewState::GetPlaylistDirectory()
408 {
409   return m_strPlaylistDirectory;
410 }
411 
SetPlaylistDirectory(const std::string & strDirectory)412 void CGUIViewState::SetPlaylistDirectory(const std::string& strDirectory)
413 {
414   m_strPlaylistDirectory = strDirectory;
415   URIUtils::RemoveSlashAtEnd(m_strPlaylistDirectory);
416 }
417 
IsCurrentPlaylistDirectory(const std::string & strDirectory)418 bool CGUIViewState::IsCurrentPlaylistDirectory(const std::string& strDirectory)
419 {
420   if (CServiceBroker::GetPlaylistPlayer().GetCurrentPlaylist()!=GetPlaylist())
421     return false;
422 
423   std::string strDir = strDirectory;
424   URIUtils::RemoveSlashAtEnd(strDir);
425 
426   return m_strPlaylistDirectory == strDir;
427 }
428 
AutoPlayNextItem()429 bool CGUIViewState::AutoPlayNextItem()
430 {
431   return false;
432 }
433 
GetLockType()434 std::string CGUIViewState::GetLockType()
435 {
436   return "";
437 }
438 
GetExtensions()439 std::string CGUIViewState::GetExtensions()
440 {
441   return "";
442 }
443 
GetSources()444 VECSOURCES& CGUIViewState::GetSources()
445 {
446   return m_sources;
447 }
448 
AddAddonsSource(const std::string & content,const std::string & label,const std::string & thumb)449 void CGUIViewState::AddAddonsSource(const std::string &content, const std::string &label, const std::string &thumb)
450 {
451   if (!CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_bVirtualShares)
452     return;
453 
454   CFileItemList items;
455   if (XFILE::CAddonsDirectory::GetScriptsAndPlugins(content, items))
456   { // add the plugin source
457     CMediaSource source;
458     source.strPath = "addons://sources/" + content + "/";
459     source.strName = label;
460     if (!thumb.empty() && CServiceBroker::GetGUI()->GetTextureManager().HasTexture(thumb))
461       source.m_strThumbnailImage = thumb;
462     source.m_iDriveType = CMediaSource::SOURCE_TYPE_LOCAL;
463     source.m_ignore = true;
464     m_sources.push_back(source);
465   }
466 }
467 
AddLiveTVSources()468 void CGUIViewState::AddLiveTVSources()
469 {
470   VECSOURCES *sources = CMediaSourceSettings::GetInstance().GetSources("video");
471   for (IVECSOURCES it = sources->begin(); it != sources->end(); it++)
472   {
473     if (URIUtils::IsLiveTV((*it).strPath))
474     {
475       CMediaSource source;
476       source.strPath = (*it).strPath;
477       source.strName = (*it).strName;
478       source.vecPaths = (*it).vecPaths;
479       source.m_strThumbnailImage = "";
480       source.FromNameAndPaths("video", source.strName, source.vecPaths);
481       m_sources.push_back(source);
482     }
483   }
484 }
485 
SetSortOrder(SortOrder sortOrder)486 void CGUIViewState::SetSortOrder(SortOrder sortOrder)
487 {
488   if (sortOrder == SortOrderNone)
489     return;
490 
491   if (m_currentSortMethod < 0 || m_currentSortMethod >= (int)m_sortMethods.size())
492     return;
493 
494   m_sortMethods[m_currentSortMethod].m_sortDescription.sortOrder = sortOrder;
495 }
496 
AutoPlayNextVideoItem() const497 bool CGUIViewState::AutoPlayNextVideoItem() const
498 {
499   if (GetPlaylist() != PLAYLIST_VIDEO)
500     return false;
501 
502   int settingValue(-1);
503   if (m_items.GetContent() == "musicvideos")
504     settingValue = SETTING_AUTOPLAYNEXT_MUSICVIDEOS;
505   else if (m_items.GetContent() == "tvshows")
506     settingValue = SETTING_AUTOPLAYNEXT_TVSHOWS;
507   else if (m_items.GetContent() == "episodes")
508     settingValue = SETTING_AUTOPLAYNEXT_EPISODES;
509   else if (m_items.GetContent() == "movies")
510     settingValue = SETTING_AUTOPLAYNEXT_MOVIES;
511   else
512     settingValue = SETTING_AUTOPLAYNEXT_UNCATEGORIZED;
513 
514   const auto setting = std::dynamic_pointer_cast<CSettingList>(
515       CServiceBroker::GetSettingsComponent()->GetSettings()->GetSetting(
516           CSettings::SETTING_VIDEOPLAYER_AUTOPLAYNEXTITEM));
517 
518   return settingValue >= 0 && setting != nullptr &&
519          CSettingUtils::FindIntInList(setting, settingValue);
520 }
521 
LoadViewState(const std::string & path,int windowID)522 void CGUIViewState::LoadViewState(const std::string &path, int windowID)
523 { // get our view state from the db
524   CViewDatabase db;
525   if (!db.Open())
526     return;
527 
528   CViewState state;
529   if (db.GetViewState(path, windowID, state, CServiceBroker::GetSettingsComponent()->GetSettings()->GetString(CSettings::SETTING_LOOKANDFEEL_SKIN)) ||
530       db.GetViewState(path, windowID, state, ""))
531   {
532     SetViewAsControl(state.m_viewMode);
533     SetSortMethod(state.m_sortDescription);
534   }
535 }
536 
SaveViewToDb(const std::string & path,int windowID,CViewState * viewState)537 void CGUIViewState::SaveViewToDb(const std::string &path, int windowID, CViewState *viewState)
538 {
539   CViewDatabase db;
540   if (!db.Open())
541     return;
542 
543   SortDescription sorting = GetSortMethod();
544   CViewState state(m_currentViewAsControl, sorting.sortBy, sorting.sortOrder, sorting.sortAttributes);
545   if (viewState != NULL)
546     *viewState = state;
547 
548   const std::shared_ptr<CSettings> settings = CServiceBroker::GetSettingsComponent()->GetSettings();
549   db.SetViewState(path, windowID, state, settings->GetString(CSettings::SETTING_LOOKANDFEEL_SKIN));
550   db.Close();
551 
552   if (viewState != NULL)
553     settings->Save();
554 }
555 
AddPlaylistOrder(const CFileItemList & items,const LABEL_MASKS & label_masks)556 void CGUIViewState::AddPlaylistOrder(const CFileItemList& items, const LABEL_MASKS& label_masks)
557 {
558   SortBy sortBy = SortByPlaylistOrder;
559   int sortLabel = 559;
560   SortOrder sortOrder = SortOrderAscending;
561   if (items.HasProperty(PROPERTY_SORT_ORDER))
562   {
563     sortBy = (SortBy)items.GetProperty(PROPERTY_SORT_ORDER).asInteger();
564     if (sortBy != SortByNone)
565     {
566       sortLabel = SortUtils::GetSortLabel(sortBy);
567       sortOrder = items.GetProperty(PROPERTY_SORT_ASCENDING).asBoolean() ? SortOrderAscending : SortOrderDescending;
568     }
569   }
570 
571   AddSortMethod(sortBy, sortLabel, label_masks, SortAttributeNone, sortOrder);
572   SetSortMethod(sortBy, sortOrder);
573 }
574 
CGUIViewStateGeneral(const CFileItemList & items)575 CGUIViewStateGeneral::CGUIViewStateGeneral(const CFileItemList& items) : CGUIViewState(items)
576 {
577   AddSortMethod(SortByLabel, 551, LABEL_MASKS("%F", "%I", "%L", ""));  // Filename, size | Foldername, empty
578   SetSortMethod(SortByLabel);
579 
580   SetViewAsControl(DEFAULT_VIEW_LIST);
581 }
582 
CGUIViewStateFromItems(const CFileItemList & items)583 CGUIViewStateFromItems::CGUIViewStateFromItems(const CFileItemList &items) : CGUIViewState(items)
584 {
585   const std::vector<GUIViewSortDetails> &details = items.GetSortDetails();
586   for (unsigned int i = 0; i < details.size(); i++)
587   {
588     const GUIViewSortDetails sort = details[i];
589     AddSortMethod(sort.m_sortDescription, sort.m_buttonLabel, sort.m_labelMasks);
590   }
591   //! @todo Should default sort/view mode be specified?
592   m_currentSortMethod = 0;
593 
594   SetViewAsControl(DEFAULT_VIEW_LIST);
595 
596   if (items.IsPlugin())
597   {
598     CURL url(items.GetPath());
599     AddonPtr addon;
600     if (CServiceBroker::GetAddonMgr().GetAddon(url.GetHostName(), addon, ADDON_PLUGIN,
601                                                OnlyEnabled::YES))
602     {
603       PluginPtr plugin = std::static_pointer_cast<CPluginSource>(addon);
604       if (plugin->Provides(CPluginSource::AUDIO))
605         m_playlist = PLAYLIST_MUSIC;
606       if (plugin->Provides(CPluginSource::VIDEO))
607         m_playlist = PLAYLIST_VIDEO;
608     }
609   }
610 
611   LoadViewState(items.GetPath(), CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow());
612 }
613 
AutoPlayNextItem()614 bool CGUIViewStateFromItems::AutoPlayNextItem()
615 {
616   return AutoPlayNextVideoItem();
617 }
618 
SaveViewState()619 void CGUIViewStateFromItems::SaveViewState()
620 {
621   SaveViewToDb(m_items.GetPath(), CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow());
622 }
623 
CGUIViewStateLibrary(const CFileItemList & items)624 CGUIViewStateLibrary::CGUIViewStateLibrary(const CFileItemList &items) : CGUIViewState(items)
625 {
626   AddSortMethod(SortByNone, 551, LABEL_MASKS("%F", "%I", "%L", ""));  // Filename, Size | Foldername, empty
627   SetSortMethod(SortByNone);
628 
629   SetViewAsControl(DEFAULT_VIEW_LIST);
630 
631   LoadViewState(items.GetPath(), CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow());
632 }
633 
SaveViewState()634 void CGUIViewStateLibrary::SaveViewState()
635 {
636   SaveViewToDb(m_items.GetPath(), CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow());
637 }
638