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 "GUIDialogVideoManagerExtras.h"
12 #include "FileItemList.h"
13 #include "GUIUserMessages.h"
14 #include "ServiceBroker.h"
16 #include "cores/VideoPlayer/DVDFileInfo.h"
17 #include "dialogs/GUIDialogFileBrowser.h"
18 #include "dialogs/GUIDialogOK.h"
19 #include "dialogs/GUIDialogYesNo.h"
20 #include "guilib/GUIComponent.h"
21 #include "guilib/GUIWindowManager.h"
22 #include "guilib/LocalizeStrings.h"
23 #include "settings/MediaSourceSettings.h"
24 #include "settings/Settings.h"
25 #include "settings/SettingsComponent.h"
26 #include "storage/MediaManager.h"
27 #include "utils/FileExtensionProvider.h"
28 #include "utils/StringUtils.h"
29 #include "utils/URIUtils.h"
30 #include "utils/log.h"
31 #include "video/VideoManagerTypes.h"
36 static constexpr unsigned int CONTROL_BUTTON_ADD_EXTRAS
= 23;
37 static constexpr unsigned int CONTROL_BUTTON_RENAME_EXTRA
= 28;
39 CGUIDialogVideoManagerExtras::CGUIDialogVideoManagerExtras()
40 : CGUIDialogVideoManager(WINDOW_DIALOG_MANAGE_VIDEO_EXTRAS
)
44 VideoAssetType
CGUIDialogVideoManagerExtras::GetVideoAssetType()
46 return VideoAssetType::EXTRA
;
49 bool CGUIDialogVideoManagerExtras::OnMessage(CGUIMessage
& message
)
51 switch (message
.GetMessage())
55 const int control
{message
.GetSenderId()};
56 if (control
== CONTROL_BUTTON_ADD_EXTRAS
)
60 // refresh data and controls
63 // @todo more detailed status to trigger an library list refresh or item update only when
64 // needed. For example, library movie was converted into an extra.
65 m_hasUpdatedItems
= true;
68 else if (control
== CONTROL_BUTTON_RENAME_EXTRA
)
76 return CGUIDialogVideoManager::OnMessage(message
);
79 void CGUIDialogVideoManagerExtras::UpdateButtons()
81 CGUIDialogVideoManager::UpdateButtons();
84 CONTROL_ENABLE(CONTROL_BUTTON_ADD_EXTRAS
);
86 // Conditional to empty list
87 if (m_videoAssetsList
->IsEmpty())
89 SET_CONTROL_FOCUS(CONTROL_BUTTON_ADD_EXTRAS
, 0);
90 CONTROL_DISABLE(CONTROL_BUTTON_RENAME_EXTRA
);
94 CONTROL_ENABLE(CONTROL_BUTTON_RENAME_EXTRA
);
98 void CGUIDialogVideoManagerExtras::SetVideoAsset(const std::shared_ptr
<CFileItem
>& item
)
100 CGUIDialogVideoManager::SetVideoAsset(item
);
102 if (!m_videoAssetsList
->IsEmpty())
103 SetSelectedVideoAsset(m_videoAssetsList
->Get(0));
106 bool CGUIDialogVideoManagerExtras::AddVideoExtra()
108 // @todo: combine with versions add file logic, structured similarly and sharing most logic.
110 const MediaType mediaType
{m_videoAsset
->GetVideoInfoTag()->m_type
};
112 // prompt to choose a video file
113 std::vector
<CMediaSource
> sources
{*CMediaSourceSettings::GetInstance().GetSources("files")};
115 CServiceBroker::GetMediaManager().GetLocalDrives(sources
);
116 CServiceBroker::GetMediaManager().GetNetworkLocations(sources
);
117 AppendItemFolderToFileBrowserSources(sources
);
120 if (CGUIDialogFileBrowser::ShowAndGetFile(
121 sources
, CServiceBroker::GetFileExtensionProvider().GetVideoExtensions(),
122 g_localizeStrings
.Get(40015), path
))
124 const int dbId
{m_videoAsset
->GetVideoInfoTag()->m_iDbId
};
125 const VideoDbContentType itemType
= m_videoAsset
->GetVideoContentType();
127 const VideoAssetInfo newAsset
{m_database
.GetVideoVersionInfo(path
)};
129 std::string typeNewVideoVersion
{
130 CGUIDialogVideoManagerExtras::GenerateVideoExtra(URIUtils::GetFileName(path
))};
132 if (newAsset
.m_idFile
!= -1 && newAsset
.m_assetTypeId
!= -1)
134 // The video already is an extra of the movie
135 if (newAsset
.m_idMedia
== dbId
&& newAsset
.m_mediaType
== mediaType
&&
136 newAsset
.m_assetType
== VideoAssetType::EXTRA
)
138 unsigned int msgid
{};
140 if (newAsset
.m_assetType
== VideoAssetType::VERSION
)
141 msgid
= 40016; // video is a version of the movie
142 else if (newAsset
.m_assetType
== VideoAssetType::EXTRA
)
143 msgid
= 40026; // video is an extra of the movie
146 CLog::LogF(LOGERROR
, "unexpected asset type {}", static_cast<int>(newAsset
.m_assetType
));
150 CGUIDialogOK::ShowAndGetInput(
152 StringUtils::Format(g_localizeStrings
.Get(msgid
), newAsset
.m_assetTypeName
));
156 // The video is an asset of another movie or different asset type of same movie
158 // The video is a version, ask for confirmation of the asset type change
159 if (newAsset
.m_assetType
== VideoAssetType::VERSION
&&
160 !CGUIDialogYesNo::ShowAndGetInput(CVariant
{40015},
161 StringUtils::Format(g_localizeStrings
.Get(40036))))
166 std::string videoTitle
;
167 if (newAsset
.m_mediaType
== MediaTypeMovie
)
169 videoTitle
= m_database
.GetMovieTitle(newAsset
.m_idMedia
);
174 if (newAsset
.m_idMedia
!= dbId
&& newAsset
.m_mediaType
== mediaType
)
176 unsigned int msgid
{};
178 if (newAsset
.m_assetType
== VideoAssetType::VERSION
)
179 msgid
= 40017; // video is a version of another movie
180 else if (newAsset
.m_assetType
== VideoAssetType::EXTRA
)
181 msgid
= 40027; // video is an extra of another movie
184 CLog::LogF(LOGERROR
, "unexpected asset type {}", static_cast<int>(newAsset
.m_assetType
));
188 if (!CGUIDialogYesNo::ShowAndGetInput(
189 CVariant
{40015}, StringUtils::Format(g_localizeStrings
.Get(msgid
),
190 newAsset
.m_assetTypeName
, videoTitle
)))
196 // Additional constraints for the converion of a movie version
197 if (newAsset
.m_assetType
== VideoAssetType::VERSION
&&
198 m_database
.IsDefaultVideoVersion(newAsset
.m_idFile
))
201 m_database
.GetVideoVersions(itemType
, newAsset
.m_idMedia
, list
, newAsset
.m_assetType
);
205 // cannot add the default version of a movie with multiple versions to another movie
206 CGUIDialogOK::ShowAndGetInput(CVariant
{40015}, CVariant
{40034});
210 const int idNewVideoVersion
{m_database
.AddVideoVersionType(
211 typeNewVideoVersion
, VideoAssetTypeOwner::AUTO
, VideoAssetType::EXTRA
)};
213 if (idNewVideoVersion
== -1)
216 return m_database
.ConvertVideoToVersion(itemType
, newAsset
.m_idMedia
, dbId
,
217 idNewVideoVersion
, VideoAssetType::EXTRA
);
221 CFileItem item
{path
, false};
223 if (CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(
224 CSettings::SETTING_MYVIDEOS_EXTRACTFLAGS
))
226 CDVDFileInfo::GetFileStreamDetails(&item
);
227 CLog::LogF(LOGDEBUG
, "Extracted filestream details from video file {}",
228 CURL::GetRedacted(item
.GetPath()));
231 const int idNewVideoVersion
{m_database
.AddVideoVersionType(
232 typeNewVideoVersion
, VideoAssetTypeOwner::AUTO
, VideoAssetType::EXTRA
)};
234 if (idNewVideoVersion
== -1)
237 m_database
.AddVideoAsset(itemType
, dbId
, idNewVideoVersion
, VideoAssetType::EXTRA
, item
);
244 bool CGUIDialogVideoManagerExtras::ManageVideoExtras(const std::shared_ptr
<CFileItem
>& item
)
246 CGUIDialogVideoManagerExtras
* dialog
{
247 CServiceBroker::GetGUI()->GetWindowManager().GetWindow
<CGUIDialogVideoManagerExtras
>(
248 WINDOW_DIALOG_MANAGE_VIDEO_EXTRAS
)};
251 CLog::LogF(LOGERROR
, "Unable to get WINDOW_DIALOG_MANAGE_VIDEO_EXTRAS instance!");
255 dialog
->SetVideoAsset(item
);
257 return dialog
->HasUpdatedItems();
260 std::string
CGUIDialogVideoManagerExtras::GenerateVideoExtra(const std::string
& extrasRoot
,
261 const std::string
& extrasPath
)
263 // generate a video extra version string from its file path
265 // remove the root path from its path
266 const std::string extrasVersion
{extrasPath
.substr(extrasRoot
.size())};
268 return GenerateVideoExtra(extrasVersion
);
271 std::string
CGUIDialogVideoManagerExtras::GenerateVideoExtra(const std::string
& extrasPath
)
273 // generate a video extra version string from its file path
275 std::string extrasVersion
{extrasPath
};
277 // remove file extension
278 URIUtils::RemoveExtension(extrasVersion
);
281 return StringUtils::Trim(extrasVersion
);