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
10 #include "GUIDialogSimpleMenu.h"
11
12 #include "GUIDialogSelect.h"
13 #include "ServiceBroker.h"
14 #include "URL.h"
15 #include "dialogs/GUIDialogBusy.h"
16 #include "filesystem/Directory.h"
17 #include "filesystem/File.h"
18 #include "guilib/GUIComponent.h"
19 #include "guilib/GUIWindowManager.h"
20 #include "settings/DiscSettings.h"
21 #include "settings/Settings.h"
22 #include "settings/SettingsComponent.h"
23 #include "threads/IRunnable.h"
24 #include "utils/URIUtils.h"
25 #include "utils/Variant.h"
26 #include "utils/log.h"
27 #include "video/VideoInfoTag.h"
28
29 namespace
30 {
31 class CGetDirectoryItems : public IRunnable
32 {
33 public:
CGetDirectoryItems(const std::string & path,CFileItemList & items,const XFILE::CDirectory::CHints & hints)34 CGetDirectoryItems(const std::string &path, CFileItemList &items, const XFILE::CDirectory::CHints &hints)
35 : m_path(path), m_items(items), m_hints(hints)
36 {
37 }
Run()38 void Run() override
39 {
40 m_result = XFILE::CDirectory::GetDirectory(m_path, m_items, m_hints);
41 }
42 bool m_result;
43 protected:
44 std::string m_path;
45 CFileItemList &m_items;
46 XFILE::CDirectory::CHints m_hints;
47 };
48 }
49
50
ShowPlaySelection(CFileItem & item)51 bool CGUIDialogSimpleMenu::ShowPlaySelection(CFileItem& item)
52 {
53 if (CServiceBroker::GetSettingsComponent()->GetSettings()->GetInt(CSettings::SETTING_DISC_PLAYBACK) != BD_PLAYBACK_SIMPLE_MENU)
54 return true;
55
56 std::string path;
57 if (item.IsVideoDb())
58 path = item.GetVideoInfoTag()->m_strFileNameAndPath;
59 else
60 path = item.GetPath();
61
62 if (item.IsBDFile())
63 {
64 std::string root = URIUtils::GetParentPath(item.GetDynPath());
65 URIUtils::RemoveSlashAtEnd(root);
66 if (URIUtils::GetFileName(root) == "BDMV")
67 {
68 CURL url("bluray://");
69 url.SetHostName(URIUtils::GetParentPath(root));
70 url.SetFileName("root");
71 return ShowPlaySelection(item, url.Get());
72 }
73 }
74
75 if (item.IsDiscImage())
76 {
77 CURL url2("udf://");
78 url2.SetHostName(item.GetDynPath());
79 url2.SetFileName("BDMV/index.bdmv");
80 if (XFILE::CFile::Exists(url2.Get()))
81 {
82 url2.SetFileName("");
83
84 CURL url("bluray://");
85 url.SetHostName(url2.Get());
86 url.SetFileName("root");
87 return ShowPlaySelection(item, url.Get());
88 }
89 }
90 return true;
91 }
92
ShowPlaySelection(CFileItem & item,const std::string & directory)93 bool CGUIDialogSimpleMenu::ShowPlaySelection(CFileItem& item, const std::string& directory)
94 {
95
96 CFileItemList items;
97
98 if (!GetDirectoryItems(directory, items, XFILE::CDirectory::CHints()))
99 {
100 CLog::Log(LOGERROR, "CGUIWindowVideoBase::ShowPlaySelection - Failed to get play directory for %s", directory.c_str());
101 return true;
102 }
103
104 if (items.IsEmpty())
105 {
106 CLog::Log(LOGERROR, "CGUIWindowVideoBase::ShowPlaySelection - Failed to get any items %s", directory.c_str());
107 return true;
108 }
109
110 CGUIDialogSelect* dialog = CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogSelect>(WINDOW_DIALOG_SELECT);
111 while (true)
112 {
113 dialog->Reset();
114 dialog->SetHeading(CVariant{25006}); // Select playback item
115 dialog->SetItems(items);
116 dialog->SetUseDetails(true);
117 dialog->Open();
118
119 CFileItemPtr item_new = dialog->GetSelectedFileItem();
120 if (!item_new || dialog->GetSelectedItem() < 0)
121 {
122 CLog::Log(LOGDEBUG, "CGUIWindowVideoBase::ShowPlaySelection - User aborted %s", directory.c_str());
123 break;
124 }
125
126 if (item_new->m_bIsFolder == false)
127 {
128 std::string original_path = item.GetDynPath();
129 item.Reset();
130 item = *item_new;
131 item.SetProperty("original_listitem_url", original_path);
132 return true;
133 }
134
135 items.Clear();
136 if (!GetDirectoryItems(item_new->GetDynPath(), items, XFILE::CDirectory::CHints()) || items.IsEmpty())
137 {
138 CLog::Log(LOGERROR, "CGUIWindowVideoBase::ShowPlaySelection - Failed to get any items %s", item_new->GetPath().c_str());
139 break;
140 }
141 }
142
143 return false;
144 }
145
GetDirectoryItems(const std::string & path,CFileItemList & items,const XFILE::CDirectory::CHints & hints)146 bool CGUIDialogSimpleMenu::GetDirectoryItems(const std::string &path, CFileItemList &items,
147 const XFILE::CDirectory::CHints &hints)
148 {
149 CGetDirectoryItems getItems(path, items, hints);
150 if (!CGUIDialogBusy::Wait(&getItems, 100, true))
151 {
152 return false;
153 }
154 return getItems.m_result;
155 }
156