2 * Copyright (C) 2023 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.
9 #include "VideoVersionHelper.h"
12 #include "FileItemList.h"
13 #include "ServiceBroker.h"
15 #include "dialogs/GUIDialogSelect.h"
16 #include "guilib/GUIComponent.h"
17 #include "guilib/GUIWindowManager.h"
18 #include "guilib/LocalizeStrings.h"
19 #include "settings/Settings.h"
20 #include "settings/SettingsComponent.h"
21 #include "settings/lib/Setting.h"
22 #include "utils/StringUtils.h"
23 #include "utils/log.h"
24 #include "video/VideoDatabase.h"
25 #include "video/VideoFileItemClassify.h"
26 #include "video/VideoManagerTypes.h"
27 #include "video/VideoThumbLoader.h"
29 namespace KODI::VIDEO::GUILIB
37 explicit CVideoChooser(const std::shared_ptr
<const CFileItem
>& item
) : m_item(item
) {}
38 virtual ~CVideoChooser() = default;
40 void EnableTypeSwitch(bool enable
) { m_enableTypeSwitch
= enable
; }
41 void SetInitialAssetType(VideoAssetType type
) { m_initialAssetType
= type
; }
43 std::shared_ptr
<const CFileItem
> ChooseVideo();
46 CVideoChooser() = delete;
47 std::shared_ptr
<const CFileItem
> ChooseVideoVersion();
48 std::shared_ptr
<const CFileItem
> ChooseVideoExtra();
49 std::shared_ptr
<const CFileItem
> ChooseVideo(CGUIDialogSelect
& dialog
,
52 CFileItemList
& itemsToDisplay
,
53 const CFileItemList
& itemsToSwitchTo
);
55 const std::shared_ptr
<const CFileItem
> m_item
;
56 bool m_enableTypeSwitch
{false};
57 VideoAssetType m_initialAssetType
{VideoAssetType::UNKNOWN
};
58 bool m_switchType
{false};
59 CFileItemList m_videoVersions
;
60 CFileItemList m_videoExtras
;
63 std::shared_ptr
<const CFileItem
> CVideoChooser::ChooseVideo()
66 m_videoVersions
.Clear();
67 m_videoExtras
.Clear();
69 std::shared_ptr
<const CFileItem
> result
;
70 if (m_enableTypeSwitch
&& !m_item
->HasVideoVersions() && !m_item
->HasVideoExtras())
73 if (!m_enableTypeSwitch
&& m_initialAssetType
== VideoAssetType::VERSION
&&
74 !m_item
->HasVideoVersions())
77 if (!m_enableTypeSwitch
&& m_initialAssetType
== VideoAssetType::EXTRA
&&
78 !m_item
->HasVideoExtras())
84 CLog::LogF(LOGERROR
, "Unable to open video database!");
88 if (m_initialAssetType
== VideoAssetType::VERSION
|| m_enableTypeSwitch
)
90 db
.GetAssetsForVideo(m_item
->GetVideoContentType(), m_item
->GetVideoInfoTag()->m_iDbId
,
91 VideoAssetType::VERSION
, m_videoVersions
);
93 // find default version item in list and select it
94 for (const auto& item
: m_videoVersions
)
96 item
->Select(item
->GetVideoInfoTag()->IsDefaultVideoVersion());
100 if (m_initialAssetType
== VideoAssetType::EXTRA
|| m_enableTypeSwitch
)
101 db
.GetAssetsForVideo(m_item
->GetVideoContentType(), m_item
->GetVideoInfoTag()->m_iDbId
,
102 VideoAssetType::EXTRA
, m_videoExtras
);
104 VideoAssetType itemType
{m_initialAssetType
};
107 if (itemType
== VideoAssetType::VERSION
)
109 result
= ChooseVideoVersion();
110 itemType
= VideoAssetType::EXTRA
;
114 result
= ChooseVideoExtra();
115 itemType
= VideoAssetType::VERSION
;
121 // switch type button pressed. Re-open, this time with the "other" type to select.
126 std::shared_ptr
<const CFileItem
> CVideoChooser::ChooseVideoVersion()
128 CGUIDialogSelect
* dialog
{CServiceBroker::GetGUI()->GetWindowManager().GetWindow
<CGUIDialogSelect
>(
129 WINDOW_DIALOG_SELECT_VIDEO_VERSION
)};
132 CLog::LogF(LOGERROR
, "Unable to get WINDOW_DIALOG_SELECT_VIDEO_VERSION dialog instance!");
136 return ChooseVideo(*dialog
, 40208 /* Choose version */, 40211 /* Extras */, m_videoVersions
,
140 std::shared_ptr
<const CFileItem
> CVideoChooser::ChooseVideoExtra()
142 CGUIDialogSelect
* dialog
{CServiceBroker::GetGUI()->GetWindowManager().GetWindow
<CGUIDialogSelect
>(
143 WINDOW_DIALOG_SELECT_VIDEO_EXTRA
)};
146 CLog::LogF(LOGERROR
, "Unable to get WINDOW_DIALOG_SELECT_VIDEO_EXTRA dialog instance!");
150 return ChooseVideo(*dialog
, 40214 /* Choose extra */, 40210 /* Versions */, m_videoExtras
,
154 std::shared_ptr
<const CFileItem
> CVideoChooser::ChooseVideo(CGUIDialogSelect
& dialog
,
157 CFileItemList
& itemsToDisplay
,
158 const CFileItemList
& itemsToSwitchTo
)
160 CVideoThumbLoader thumbLoader
;
161 thumbLoader
.Load(itemsToDisplay
);
162 for (auto& item
: itemsToDisplay
)
163 item
->SetLabel2(item
->GetVideoInfoTag()->m_strFileNameAndPath
);
167 const std::string heading
{
168 StringUtils::Format(g_localizeStrings
.Get(headingId
), m_item
->GetVideoInfoTag()->GetTitle())};
169 dialog
.SetHeading(heading
);
171 dialog
.EnableButton(m_enableTypeSwitch
&& !itemsToSwitchTo
.IsEmpty(), buttonId
);
172 dialog
.SetUseDetails(true);
173 dialog
.SetMultiSelection(false);
174 dialog
.SetItems(itemsToDisplay
);
178 if (thumbLoader
.IsLoading())
179 thumbLoader
.StopThread();
181 m_switchType
= dialog
.IsButtonPressed();
182 if (dialog
.IsConfirmed())
183 return dialog
.GetSelectedFileItem();
187 } // unnamed namespace
189 std::shared_ptr
<CFileItem
> CVideoVersionHelper::ChooseVideoFromAssets(
190 const std::shared_ptr
<CFileItem
>& item
)
192 std::shared_ptr
<const CFileItem
> video
;
194 VideoAssetType assetType
{static_cast<int>(
195 item
->GetProperty("video_asset_type").asInteger(static_cast<int>(VideoAssetType::UNKNOWN
)))};
196 bool allAssetTypes
{false};
197 bool hasMultipleChoices
{false};
201 case VideoAssetType::UNKNOWN
:
202 // asset type not provided means all types are allowed and the user can switch between types
203 allAssetTypes
= true;
204 if (item
->HasVideoVersions() || item
->HasVideoExtras())
205 hasMultipleChoices
= true;
208 case VideoAssetType::VERSION
:
209 if (item
->HasVideoVersions())
210 hasMultipleChoices
= true;
213 case VideoAssetType::EXTRA
:
214 if (item
->HasVideoExtras())
215 hasMultipleChoices
= true;
219 CLog::LogF(LOGERROR
, "unknown asset type ({})", static_cast<int>(assetType
));
223 if (hasMultipleChoices
)
225 if (!item
->GetProperty("needs_resolved_video_asset").asBoolean(false))
227 // auto select the default video version
228 const auto settings
{CServiceBroker::GetSettingsComponent()->GetSettings()};
229 if (settings
->GetBool(CSettings::SETTING_MYVIDEOS_SELECTDEFAULTVERSION
))
231 if (item
->GetVideoInfoTag()->IsDefaultVideoVersion())
233 video
= std::make_shared
<const CFileItem
>(*item
);
240 CLog::LogF(LOGERROR
, "Unable to open video database!");
244 CFileItem defaultVersion
;
245 if (!db
.GetDefaultVersionForVideo(item
->GetVideoContentType(),
246 item
->GetVideoInfoTag()->m_iDbId
, defaultVersion
))
247 CLog::LogF(LOGERROR
, "Unable to get default version from video database!");
249 video
= std::make_shared
<const CFileItem
>(defaultVersion
);
255 if (!video
&& (item
->GetProperty("needs_resolved_video_asset").asBoolean(false) ||
256 !item
->GetProperty("has_resolved_video_asset").asBoolean(false)))
258 CVideoChooser chooser
{item
};
262 chooser
.EnableTypeSwitch(true);
263 chooser
.SetInitialAssetType(VideoAssetType::VERSION
);
267 chooser
.EnableTypeSwitch(false);
268 chooser
.SetInitialAssetType(assetType
);
271 const auto result
{chooser
.ChooseVideo()};
280 return std::make_shared
<CFileItem
>(*video
);
285 } // namespace KODI::VIDEO::GUILIB