aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorksooo <3226626+ksooo@users.noreply.github.com>2023-11-29 08:58:33 +0100
committerksooo <3226626+ksooo@users.noreply.github.com>2023-12-07 19:07:45 +0100
commit565fe8a525d26be43ea082221f7a4472dbcf862a (patch)
treef0f55e07f4d90dd34b28734576d36afafbe323bf
parentfbda2709c5a84870e2be2805a433253805410099 (diff)
[video] Move play/select action handling for video versions to CVideo(Play|Select)ActionProcessor implementation, to gain consistent functionality across Kodi and to get rid of special handling for video versions playback scattered across the code base.
-rw-r--r--addons/resource.language.en_gb/resources/strings.po4
-rw-r--r--addons/skin.estuary/xml/DialogVideoVersion.xml4
-rw-r--r--addons/skin.estuary/xml/Includes_DialogVideoVersion.xml6
-rw-r--r--xbmc/guilib/GUIWindowManager.cpp4
-rw-r--r--xbmc/guilib/WindowIDs.h2
-rw-r--r--xbmc/input/WindowTranslator.cpp2
-rw-r--r--xbmc/listproviders/DirectoryProvider.cpp27
-rw-r--r--xbmc/video/ContextMenus.cpp97
-rw-r--r--xbmc/video/dialogs/GUIDialogVideoInfo.cpp12
-rw-r--r--xbmc/video/dialogs/GUIDialogVideoVersion.cpp154
-rw-r--r--xbmc/video/dialogs/GUIDialogVideoVersion.h24
-rw-r--r--xbmc/video/guilib/CMakeLists.txt6
-rw-r--r--xbmc/video/guilib/VideoActionProcessorHelper.cpp157
-rw-r--r--xbmc/video/guilib/VideoActionProcessorHelper.h44
-rw-r--r--xbmc/video/guilib/VideoPlayActionProcessor.cpp23
-rw-r--r--xbmc/video/guilib/VideoPlayActionProcessor.h8
-rw-r--r--xbmc/video/guilib/VideoSelectActionProcessor.cpp15
-rw-r--r--xbmc/video/guilib/VideoSelectActionProcessor.h8
-rw-r--r--xbmc/video/windows/GUIWindowVideoBase.cpp12
19 files changed, 432 insertions, 177 deletions
diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po
index 05e898b52d..bb3f6157e7 100644
--- a/addons/resource.language.en_gb/resources/strings.po
+++ b/addons/resource.language.en_gb/resources/strings.po
@@ -23868,10 +23868,10 @@ msgctxt "#40022"
msgid "Manage {0:s}"
msgstr ""
-#. Play video version dialog title
+#. Choose video version dialog title
#: xbmc/video/dialogs/GUIDialogVideoVersion.cpp
msgctxt "#40023"
-msgid "Play {0:s}"
+msgid "Choose {0:s}"
msgstr ""
#. Play default video version setting
diff --git a/addons/skin.estuary/xml/DialogVideoVersion.xml b/addons/skin.estuary/xml/DialogVideoVersion.xml
index 2c50812913..9a109ca028 100644
--- a/addons/skin.estuary/xml/DialogVideoVersion.xml
+++ b/addons/skin.estuary/xml/DialogVideoVersion.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<window>
<defaultcontrol always="true">200</defaultcontrol>
- <onload condition="Window.IsActive(videoversionplay)">Control.SetFocus(50)</onload>
+ <onload condition="Window.IsActive(videoversionselect)">Control.SetFocus(50)</onload>
<include>Animation_DialogPopupOpenClose</include>
<controls>
<include condition="Window.IsActive(videoversion)">DialogVideoVersionLayout</include>
- <include condition="Window.IsActive(videoversionplay)">DialogVideoVersionPlayLayout</include>
+ <include condition="Window.IsActive(videoversionselect)">DialogVideoVersionSelectLayout</include>
</controls>
</window>
diff --git a/addons/skin.estuary/xml/Includes_DialogVideoVersion.xml b/addons/skin.estuary/xml/Includes_DialogVideoVersion.xml
index d6180c8f1b..4f7163c048 100644
--- a/addons/skin.estuary/xml/Includes_DialogVideoVersion.xml
+++ b/addons/skin.estuary/xml/Includes_DialogVideoVersion.xml
@@ -57,7 +57,7 @@
</control>
</control>
</include>
- <include name="DialogVideoVersionPlayLayout">
+ <include name="DialogVideoVersionSelectLayout">
<control type="group">
<centertop>50%</centertop>
<centerleft>50%</centerleft>
@@ -85,13 +85,13 @@
<param name="id" value="201" />
<param name="label" value="$LOCALIZE[40000]" />
<param name="usealttexture" value="Control.IsVisible(50)" />
- <param name="visible">Window.IsActive(videoversion)| Window.IsActive(videoversionplay) + Integer.IsGreater(Container(50).NumItems,0)</param>
+ <param name="visible">Window.IsActive(videoversion)| Window.IsActive(videoversionselect) + Integer.IsGreater(Container(50).NumItems,0)</param>
</include>
<include content="DialogToggleButton">
<param name="id" value="202" />
<param name="label" value="$LOCALIZE[31615]" />
<param name="usealttexture" value="Control.IsVisible(51)" />
- <param name="visible">Window.IsActive(videoversion) | Window.IsActive(videoversionplay) + Integer.IsGreater(Container(51).NumItems,0)</param>
+ <param name="visible">Window.IsActive(videoversion) | Window.IsActive(videoversionselect) + Integer.IsGreater(Container(51).NumItems,0)</param>
</include>
</control>
<control type="image">
diff --git a/xbmc/guilib/GUIWindowManager.cpp b/xbmc/guilib/GUIWindowManager.cpp
index 555857849d..3104ce1be8 100644
--- a/xbmc/guilib/GUIWindowManager.cpp
+++ b/xbmc/guilib/GUIWindowManager.cpp
@@ -293,7 +293,7 @@ void CGUIWindowManager::CreateWindows()
Add(new CGUIDialogOK);
Add(new CGUIDialogVideoInfo);
Add(new CGUIDialogVideoVersion(WINDOW_DIALOG_VIDEO_VERSION));
- Add(new CGUIDialogVideoVersion(WINDOW_DIALOG_VIDEO_VERSION_PLAY));
+ Add(new CGUIDialogVideoVersion(WINDOW_DIALOG_VIDEO_VERSION_SELECT));
Add(new CGUIDialogTextViewer);
Add(new CGUIWindowFullScreen);
Add(new CGUIWindowVisualisation);
@@ -335,7 +335,7 @@ bool CGUIWindowManager::DestroyWindows()
DestroyWindow(WINDOW_DIALOG_MUSIC_INFO);
DestroyWindow(WINDOW_DIALOG_VIDEO_INFO);
DestroyWindow(WINDOW_DIALOG_VIDEO_VERSION);
- DestroyWindow(WINDOW_DIALOG_VIDEO_VERSION_PLAY);
+ DestroyWindow(WINDOW_DIALOG_VIDEO_VERSION_SELECT);
DestroyWindow(WINDOW_VIDEO_PLAYLIST);
DestroyWindow(WINDOW_VIDEO_NAV);
DestroyWindow(WINDOW_FILES);
diff --git a/xbmc/guilib/WindowIDs.h b/xbmc/guilib/WindowIDs.h
index 8b54b358d7..3f70bd8fc3 100644
--- a/xbmc/guilib/WindowIDs.h
+++ b/xbmc/guilib/WindowIDs.h
@@ -169,7 +169,7 @@
#define WINDOW_VISUALISATION 12006
#define WINDOW_SLIDESHOW 12007
#define WINDOW_DIALOG_COLOR_PICKER 12008
-#define WINDOW_DIALOG_VIDEO_VERSION_PLAY 12009
+#define WINDOW_DIALOG_VIDEO_VERSION_SELECT 12009
#define WINDOW_WEATHER 12600
#define WINDOW_SCREENSAVER 12900
#define WINDOW_DIALOG_VIDEO_OSD 12901
diff --git a/xbmc/input/WindowTranslator.cpp b/xbmc/input/WindowTranslator.cpp
index cfcba73003..c1bbd68da7 100644
--- a/xbmc/input/WindowTranslator.cpp
+++ b/xbmc/input/WindowTranslator.cpp
@@ -120,7 +120,7 @@ const CWindowTranslator::WindowMapByName CWindowTranslator::WindowMappingByName
{"okdialog", WINDOW_DIALOG_OK},
{"movieinformation", WINDOW_DIALOG_VIDEO_INFO},
{"videoversion", WINDOW_DIALOG_VIDEO_VERSION},
- {"videoversionplay", WINDOW_DIALOG_VIDEO_VERSION_PLAY},
+ {"videoversionselect", WINDOW_DIALOG_VIDEO_VERSION_SELECT},
{"textviewer", WINDOW_DIALOG_TEXT_VIEWER},
{"fullscreenvideo", WINDOW_FULLSCREEN_VIDEO},
{"dialogcolorpicker", WINDOW_DIALOG_COLOR_PICKER},
diff --git a/xbmc/listproviders/DirectoryProvider.cpp b/xbmc/listproviders/DirectoryProvider.cpp
index a7ba3592d2..f1f4228f5d 100644
--- a/xbmc/listproviders/DirectoryProvider.cpp
+++ b/xbmc/listproviders/DirectoryProvider.cpp
@@ -37,7 +37,6 @@
#include "video/VideoInfoTag.h"
#include "video/VideoThumbLoader.h"
#include "video/VideoUtils.h"
-#include "video/dialogs/GUIDialogVideoVersion.h"
#include "video/guilib/VideoPlayActionProcessor.h"
#include "video/guilib/VideoSelectActionProcessor.h"
@@ -496,18 +495,7 @@ protected:
bool OnPlaySelected() override
{
- //! @todo get rid of special handling for movie versions
- if (m_item->GetVideoInfoTag()->m_type == MediaTypeMovie)
- {
- CGUIDialogVideoVersion::PlayVideoVersion(
- m_item,
- [](const std::shared_ptr<CFileItem>& item) {
- ExecuteAction({"PlayMedia", *item.get(), "noresume"});
- });
- }
- else
- ExecuteAction({"PlayMedia", *m_item, "noresume"});
-
+ ExecuteAction({"PlayMedia", *m_item, "noresume"});
return true;
}
@@ -550,18 +538,7 @@ protected:
bool OnPlaySelected() override
{
- //! @todo get rid of special handling for movie versions
- if (m_item->GetVideoInfoTag()->m_type == MediaTypeMovie)
- {
- CGUIDialogVideoVersion::PlayVideoVersion(
- m_item,
- [](const std::shared_ptr<CFileItem>& item) {
- ExecuteAction({"PlayMedia", *item.get(), "noresume"});
- });
- }
- else
- ExecuteAction({"PlayMedia", *m_item, "noresume"});
-
+ ExecuteAction({"PlayMedia", *m_item, "noresume"});
return true;
}
};
diff --git a/xbmc/video/ContextMenus.cpp b/xbmc/video/ContextMenus.cpp
index 9a179d5020..ec7a1bbd3f 100644
--- a/xbmc/video/ContextMenus.cpp
+++ b/xbmc/video/ContextMenus.cpp
@@ -21,7 +21,7 @@
#include "video/VideoInfoTag.h"
#include "video/VideoUtils.h"
#include "video/dialogs/GUIDialogVideoInfo.h"
-#include "video/dialogs/GUIDialogVideoVersion.h"
+#include "video/guilib/VideoPlayActionProcessor.h"
#include <utility>
@@ -175,38 +175,69 @@ bool CVideoResume::IsVisible(const CFileItem& itemIn) const
namespace
{
-void SetPathAndPlay(CFileItem& item, const std::string& player)
+class CVideoPlayActionProcessor : public VIDEO::GUILIB::CVideoPlayActionProcessorBase
{
- if (!item.m_bIsFolder && item.IsVideoDb())
+public:
+ explicit CVideoPlayActionProcessor(const std::shared_ptr<CFileItem>& item,
+ const std::string& player)
+ : CVideoPlayActionProcessorBase(item), m_player(player)
{
- item.SetProperty("original_listitem_url", item.GetPath());
- item.SetPath(item.GetVideoInfoTag()->m_strFileNameAndPath);
}
- item.SetProperty("check_resume", false);
- if (item.IsLiveTV()) // pvr tv or pvr radio?
+protected:
+ bool OnResumeSelected() override
{
- g_application.PlayMedia(item, "", PLAYLIST::TYPE_VIDEO);
+ m_item->SetStartOffset(STARTOFFSET_RESUME);
+ Play();
+ return true;
}
- else
+
+ bool OnPlaySelected() override
{
- item.SetProperty("playlist_type_hint", PLAYLIST::TYPE_VIDEO);
+ Play();
+ return true;
+ }
+
+private:
+ void Play()
+ {
+ m_item->SetProperty("playlist_type_hint", PLAYLIST::TYPE_VIDEO);
+ const ContentUtils::PlayMode mode{m_item->GetProperty("CheckAutoPlayNextItem").asBoolean()
+ ? ContentUtils::PlayMode::CHECK_AUTO_PLAY_NEXT_ITEM
+ : ContentUtils::PlayMode::PLAY_ONLY_THIS};
+ VIDEO_UTILS::PlayItem(m_item, m_player, mode);
+ }
+
+ const std::string m_player;
+};
- const ContentUtils::PlayMode mode = item.GetProperty("CheckAutoPlayNextItem").asBoolean()
- ? ContentUtils::PlayMode::CHECK_AUTO_PLAY_NEXT_ITEM
- : ContentUtils::PlayMode::PLAY_ONLY_THIS;
+void SetPathAndPlay(const std::shared_ptr<CFileItem>& item, const std::string& player, bool resume)
+{
+ item->SetProperty("check_resume", false);
- //! @todo get rid of special handling for movie versions
- if (item.GetStartOffset() != STARTOFFSET_RESUME &&
- item.GetVideoInfoTag()->m_type == MediaTypeMovie)
+ if (item->IsLiveTV()) // pvr tv or pvr radio?
+ {
+ g_application.PlayMedia(*item, "", PLAYLIST::TYPE_VIDEO);
+ }
+ else
+ {
+ if (!item->m_bIsFolder && item->IsVideoDb())
{
- auto videoItem = std::make_shared<CFileItem>(item);
- CGUIDialogVideoVersion::PlayVideoVersion(
- videoItem, [player, mode](const std::shared_ptr<CFileItem>& item)
- { VIDEO_UTILS::PlayItem(item, player, mode); });
+ item->SetProperty("original_listitem_url", item->GetPath());
+ item->SetPath(item->GetVideoInfoTag()->m_strFileNameAndPath);
}
+
+ // play the given/default video version, if multiple versions are available
+ item->SetProperty("prohibit_choose_video_version", true);
+
+ CVideoPlayActionProcessor proc{item, player};
+ if (resume && (item->GetStartOffset() == STARTOFFSET_RESUME ||
+ VIDEO_UTILS::GetItemResumeInformation(*item).isResumable))
+ proc.Process(VIDEO::GUILIB::PLAY_ACTION_RESUME);
else
- VIDEO_UTILS::PlayItem(std::make_shared<CFileItem>(item), player, mode);
+ proc.Process(VIDEO::GUILIB::PLAY_ACTION_PLAY_FROM_BEGINNING);
+
+ item->ClearProperty("prohibit_choose_video_version");
}
}
@@ -230,14 +261,14 @@ std::vector<std::string> GetPlayers(const CPlayerCoreFactory& playerCoreFactory,
bool CVideoResume::Execute(const std::shared_ptr<CFileItem>& itemIn) const
{
- CFileItem item(itemIn->GetItemToPlay());
+ const auto item{std::make_shared<CFileItem>(itemIn->GetItemToPlay())};
#ifdef HAS_OPTICAL_DRIVE
- if (item.IsDVD() || item.IsCDDA())
- return MEDIA_DETECT::CAutorun::PlayDisc(item.GetPath(), true, false);
+ if (item->IsDVD() || item->IsCDDA())
+ return MEDIA_DETECT::CAutorun::PlayDisc(item->GetPath(), true, false);
#endif
- item.SetStartOffset(STARTOFFSET_RESUME);
- SetPathAndPlay(item, "");
+ item->SetStartOffset(STARTOFFSET_RESUME);
+ SetPathAndPlay(item, "", true);
return true;
};
@@ -258,12 +289,12 @@ bool CVideoPlay::IsVisible(const CFileItem& item) const
bool CVideoPlay::Execute(const std::shared_ptr<CFileItem>& itemIn) const
{
- CFileItem item(itemIn->GetItemToPlay());
+ const auto item{std::make_shared<CFileItem>(itemIn->GetItemToPlay())};
#ifdef HAS_OPTICAL_DRIVE
- if (item.IsDVD() || item.IsCDDA())
- return MEDIA_DETECT::CAutorun::PlayDisc(item.GetPath(), true, true);
+ if (item->IsDVD() || item->IsCDDA())
+ return MEDIA_DETECT::CAutorun::PlayDisc(item->GetPath(), true, true);
#endif
- SetPathAndPlay(item, "");
+ SetPathAndPlay(item, "", false);
return true;
};
@@ -275,14 +306,14 @@ bool CVideoPlayUsing::IsVisible(const CFileItem& item) const
bool CVideoPlayUsing::Execute(const std::shared_ptr<CFileItem>& itemIn) const
{
- CFileItem item{itemIn->GetItemToPlay()};
+ const auto item{std::make_shared<CFileItem>(itemIn->GetItemToPlay())};
const CPlayerCoreFactory& playerCoreFactory{CServiceBroker::GetPlayerCoreFactory()};
- const std::vector<std::string> players{GetPlayers(playerCoreFactory, item)};
+ const std::vector<std::string> players{GetPlayers(playerCoreFactory, *item)};
const std::string player{playerCoreFactory.SelectPlayerDialog(players)};
if (!player.empty())
{
- SetPathAndPlay(item, player);
+ SetPathAndPlay(item, player, false);
return true;
}
return false;
diff --git a/xbmc/video/dialogs/GUIDialogVideoInfo.cpp b/xbmc/video/dialogs/GUIDialogVideoInfo.cpp
index e1e781b9b7..08e7a1579f 100644
--- a/xbmc/video/dialogs/GUIDialogVideoInfo.cpp
+++ b/xbmc/video/dialogs/GUIDialogVideoInfo.cpp
@@ -741,17 +741,7 @@ private:
const ContentUtils::PlayMode mode{m_item->GetProperty("CheckAutoPlayNextItem").asBoolean()
? ContentUtils::PlayMode::CHECK_AUTO_PLAY_NEXT_ITEM
: ContentUtils::PlayMode::PLAY_ONLY_THIS};
-
- //! @todo get rid of special handling for movie versions
- if (m_item->GetStartOffset() != STARTOFFSET_RESUME &&
- m_item->GetVideoInfoTag()->m_type == MediaTypeMovie)
- {
- CGUIDialogVideoVersion::PlayVideoVersion(m_item,
- [mode](const std::shared_ptr<CFileItem>& item)
- { VIDEO_UTILS::PlayItem(item, "", mode); });
- }
- else
- VIDEO_UTILS::PlayItem(m_item, "", mode);
+ VIDEO_UTILS::PlayItem(m_item, "", mode);
}
};
} // unnamed namespace
diff --git a/xbmc/video/dialogs/GUIDialogVideoVersion.cpp b/xbmc/video/dialogs/GUIDialogVideoVersion.cpp
index 94e1c45eeb..a8f380ab59 100644
--- a/xbmc/video/dialogs/GUIDialogVideoVersion.cpp
+++ b/xbmc/video/dialogs/GUIDialogVideoVersion.cpp
@@ -11,16 +11,13 @@
#include "FileItem.h"
#include "GUIUserMessages.h"
#include "ServiceBroker.h"
-#include "Util.h"
-#include "application/Application.h"
+#include "URL.h"
#include "cores/VideoPlayer/DVDFileInfo.h"
#include "dialogs/GUIDialogContextMenu.h"
#include "dialogs/GUIDialogFileBrowser.h"
#include "dialogs/GUIDialogOK.h"
#include "dialogs/GUIDialogSelect.h"
#include "dialogs/GUIDialogYesNo.h"
-#include "filesystem/Directory.h"
-#include "filesystem/VideoDatabaseDirectory.h"
#include "guilib/GUIComponent.h"
#include "guilib/GUIImage.h"
#include "guilib/GUIKeyboardFactory.h"
@@ -28,29 +25,24 @@
#include "guilib/GUIWindowManager.h"
#include "guilib/LocalizeStrings.h"
#include "input/Key.h"
-#include "profiles/ProfileManager.h"
-#include "settings/AdvancedSettings.h"
+#include "playlists/PlayListTypes.h"
#include "settings/MediaSourceSettings.h"
-#include "settings/SettingUtils.h"
#include "settings/Settings.h"
#include "settings/SettingsComponent.h"
-#include "settings/lib/Setting.h"
#include "storage/MediaManager.h"
-#include "utils/ExecString.h"
#include "utils/FileExtensionProvider.h"
#include "utils/SortUtils.h"
#include "utils/StringUtils.h"
#include "utils/URIUtils.h"
#include "utils/Variant.h"
#include "utils/log.h"
-#include "video/VideoDbUrl.h"
#include "video/VideoInfoTag.h"
-#include "video/VideoItemArtworkHandler.h"
#include "video/VideoThumbLoader.h"
+#include "video/VideoUtils.h"
#include "video/dialogs/GUIDialogVideoInfo.h"
+#include "video/guilib/VideoPlayActionProcessor.h"
#include <algorithm>
-#include <iterator>
#include <string>
static constexpr unsigned int CONTROL_LABEL_MODE = 1;
@@ -90,6 +82,12 @@ bool CGUIDialogVideoVersion::OnMessage(CGUIMessage& message)
{
switch (message.GetMessage())
{
+ case GUI_MSG_WINDOW_INIT:
+ {
+ m_cancelled = false;
+ break;
+ }
+
case GUI_MSG_WINDOW_DEINIT:
{
ClearVideoVersionList();
@@ -129,7 +127,7 @@ bool CGUIDialogVideoVersion::OnMessage(CGUIMessage& message)
if (m_mode == Mode::MANAGE)
SET_CONTROL_FOCUS(CONTROL_BUTTON_PLAY, 0);
else
- Play();
+ CloseAll();
}
}
else if (control == CONTROL_LIST_EXTRAS_VERSION)
@@ -154,7 +152,7 @@ bool CGUIDialogVideoVersion::OnMessage(CGUIMessage& message)
if (m_mode == Mode::MANAGE)
SET_CONTROL_FOCUS(CONTROL_BUTTON_PLAY, 0);
else
- Play();
+ CloseAll();
}
}
else if (control == CONTROL_BUTTON_PLAY)
@@ -193,10 +191,16 @@ bool CGUIDialogVideoVersion::OnMessage(CGUIMessage& message)
return CGUIDialog::OnMessage(message);
}
+bool CGUIDialogVideoVersion::OnBack(int actionID)
+{
+ m_cancelled = true;
+ return CGUIDialog::OnBack(actionID);
+}
+
void CGUIDialogVideoVersion::OnInitWindow()
{
// set working mode
- SET_CONTROL_LABEL(CONTROL_LABEL_MODE, m_mode == Mode::MANAGE ? "manage" : "play");
+ SET_CONTROL_LABEL(CONTROL_LABEL_MODE, m_mode == Mode::MANAGE ? "manage" : "choose");
// set window title
std::string title = m_videoItem->GetVideoInfoTag()->GetTitle();
@@ -312,7 +316,7 @@ void CGUIDialogVideoVersion::SetVideoItem(const std::shared_ptr<CFileItem>& item
loader.LoadItem(item.get());
}
-void CGUIDialogVideoVersion::Play()
+void CGUIDialogVideoVersion::CloseAll()
{
// close our dialog
Close(true);
@@ -323,15 +327,51 @@ void CGUIDialogVideoVersion::Play()
WINDOW_DIALOG_VIDEO_INFO);
if (dialog)
dialog->Close(true);
+}
- // set the selected video version as default temporarily
- SetDefaultVideoVersion(*m_selectedVideoVersion.get());
+namespace
+{
+class CVideoPlayActionProcessor : public VIDEO::GUILIB::CVideoPlayActionProcessorBase
+{
+public:
+ explicit CVideoPlayActionProcessor(const std::shared_ptr<CFileItem>& item,
+ const std::shared_ptr<CFileItem>& videoVersion)
+ : CVideoPlayActionProcessorBase(item, videoVersion)
+ {
+ }
+
+protected:
+ bool OnResumeSelected() override
+ {
+ m_item->SetStartOffset(STARTOFFSET_RESUME);
+ Play();
+ return true;
+ }
+
+ bool OnPlaySelected() override
+ {
+ Play();
+ return true;
+ }
+
+private:
+ void Play()
+ {
+ m_item->SetProperty("playlist_type_hint", PLAYLIST::TYPE_VIDEO);
+ const ContentUtils::PlayMode mode{m_item->GetProperty("CheckAutoPlayNextItem").asBoolean()
+ ? ContentUtils::PlayMode::CHECK_AUTO_PLAY_NEXT_ITEM
+ : ContentUtils::PlayMode::PLAY_ONLY_THIS};
+ VIDEO_UTILS::PlayItem(m_item, "", mode);
+ }
+};
+} // unnamed namespace
- // play the video item
- m_playCallback(m_videoItem);
+void CGUIDialogVideoVersion::Play()
+{
+ CloseAll();
- // restore the default video version
- SetDefaultVideoVersion(*m_defaultVideoVersion.get());
+ CVideoPlayActionProcessor proc{m_videoItem, m_selectedVideoVersion};
+ proc.Process();
}
void CGUIDialogVideoVersion::Remove()
@@ -599,79 +639,53 @@ void CGUIDialogVideoVersion::SetSelectedVideoVersion(const std::shared_ptr<CFile
m_selectedVideoVersion = std::make_unique<CFileItem>(*version);
}
-void CGUIDialogVideoVersion::SetPlayCallback(VideoVersionPlayCallback callback)
-{
- m_playCallback = callback;
-}
-
-void CGUIDialogVideoVersion::PlayVideoItem(const std::shared_ptr<CFileItem>& item)
-{
- CGUIMessage msg(GUI_MSG_EXECUTE, 0, 0);
- msg.SetStringParam(CExecString("PlayMedia", *item.get(), "noresume").GetExecString());
- CServiceBroker::GetGUI()->GetWindowManager().SendMessage(msg);
-}
-
void CGUIDialogVideoVersion::ManageVideoVersion(const std::shared_ptr<CFileItem>& item)
{
CGUIDialogVideoVersion* dialog =
CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogVideoVersion>(
WINDOW_DIALOG_VIDEO_VERSION);
if (!dialog)
+ {
+ CLog::LogF(LOGERROR, "Unable to get WINDOW_DIALOG_VIDEO_VERSION instance!");
return;
+ }
dialog->SetVideoItem(item);
dialog->SetMode(Mode::MANAGE);
- dialog->SetPlayCallback(PlayVideoItem);
dialog->Open();
}
-void CGUIDialogVideoVersion::PlayVideoVersion(const std::shared_ptr<CFileItem>& item,
- VideoVersionPlayCallback callback)
+CGUIDialogVideoVersion::VersionSelectResult CGUIDialogVideoVersion::ChooseVideoVersion(
+ const std::shared_ptr<CFileItem>& item)
{
- // play the specified video version
- if (item->GetVideoInfoTag()->m_idVideoVersion > 0)
- {
- callback(item);
- return;
- }
-
- // play the default video version
- if (CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(
- CSettings::SETTING_VIDEOPLAYER_PLAYDEFAULTVERSION))
+ if (!item->HasVideoInfoTag())
{
- auto temp = item;
-
- // play a temporary copy of the item if it is video version folder
- if (item->GetVideoInfoTag()->m_idVideoVersion == VIDEO_VERSION_ID_ALL &&
- CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(
- CSettings::SETTING_VIDEOLIBRARY_SHOWVIDEOVERSIONSASFOLDER))
- {
- temp = std::make_shared<CFileItem>(*item);
- temp->m_bIsFolder = false;
- }
-
- callback(temp);
- return;
+ CLog::LogF(LOGWARNING, "Item is not a video. path={}", item->GetPath());
+ return {true, {}};
}
- // play the video item directly
- if (!item->GetVideoInfoTag()->m_hasVideoVersions)
+ if (!item->HasVideoVersions())
{
- callback(item);
- return;
+ CLog::LogF(LOGWARNING, "Item has no video versions. path={}", item->GetPath());
+ return {true, {}};
}
- // prompt to play selected video version
- CGUIDialogVideoVersion* dialog =
+ // prompt to select a video version
+ CGUIDialogVideoVersion* dialog{
CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogVideoVersion>(
- WINDOW_DIALOG_VIDEO_VERSION_PLAY);
+ WINDOW_DIALOG_VIDEO_VERSION_SELECT)};
if (!dialog)
- return;
+ {
+ CLog::LogF(LOGERROR, "Unable to get WINDOW_DIALOG_VIDEO_VERSION_SELECT instance!");
+ return {true, {}};
+ }
dialog->SetVideoItem(item);
- dialog->SetMode(Mode::PLAY);
- dialog->SetPlayCallback(PlayVideoItem);
+ dialog->SetMode(Mode::CHOOSE);
dialog->Open();
+
+ // get the selected video version from dialog if not cancelled
+ return {dialog->m_cancelled, dialog->m_selectedVideoVersion};
}
int CGUIDialogVideoVersion::ManageVideoVersionContextMenu(const std::shared_ptr<CFileItem>& version)
diff --git a/xbmc/video/dialogs/GUIDialogVideoVersion.h b/xbmc/video/dialogs/GUIDialogVideoVersion.h
index ba547edd83..b408f3c782 100644
--- a/xbmc/video/dialogs/GUIDialogVideoVersion.h
+++ b/xbmc/video/dialogs/GUIDialogVideoVersion.h
@@ -25,11 +25,12 @@ public:
CGUIDialogVideoVersion(int id);
~CGUIDialogVideoVersion(void) override;
bool OnMessage(CGUIMessage& message) override;
+ bool OnBack(int actionID) override;
enum class Mode
{
MANAGE,
- PLAY,
+ CHOOSE,
};
void SetMode(Mode mode) { m_mode = mode; }
void SetVideoItem(const std::shared_ptr<CFileItem>& item);
@@ -39,17 +40,18 @@ public:
static bool ProcessVideoVersion(VideoDbContentType itemType, int dbId);
static int SelectVideoVersion(const std::shared_ptr<CFileItem>& item);
static void ManageVideoVersion(const std::shared_ptr<CFileItem>& item);
- static void PlayVideoItem(const std::shared_ptr<CFileItem>& item);
static std::string GenerateExtrasVideoVersion(const std::string& extrasRoot,
const std::string& extrasPath);
static std::string GenerateExtrasVideoVersion(const std::string& extrasPath);
-
- using VideoVersionPlayCallback = std::function<void(const std::shared_ptr<CFileItem>& item)>;
- static void PlayVideoVersion(const std::shared_ptr<CFileItem>& item,
- VideoVersionPlayCallback play);
-
static int ManageVideoVersionContextMenu(const std::shared_ptr<CFileItem>& version);
+ struct VersionSelectResult
+ {
+ bool cancelled{false};
+ std::shared_ptr<CFileItem> selected;
+ };
+ static VersionSelectResult ChooseVideoVersion(const std::shared_ptr<CFileItem>& item);
+
protected:
void OnInitWindow() override;
@@ -58,7 +60,6 @@ private:
void SetSelectedVideoVersion(const std::shared_ptr<CFileItem>& version);
void ClearVideoVersionList();
void RefreshVideoVersionList();
- void SetPlayCallback(VideoVersionPlayCallback callback);
void AddVideoVersion(bool primary);
void Play();
void AddVersion();
@@ -67,15 +68,14 @@ private:
void SetDefault();
void Remove();
void ChooseArt();
-
- VideoVersionPlayCallback m_playCallback;
+ void CloseAll();
std::shared_ptr<CFileItem> m_videoItem;
Mode m_mode{Mode::MANAGE};
-
+ bool m_cancelled{false};
CVideoDatabase m_database;
std::unique_ptr<CFileItemList> m_primaryVideoVersionList;
std::unique_ptr<CFileItemList> m_extrasVideoVersionList;
std::unique_ptr<CFileItem> m_defaultVideoVersion;
- std::unique_ptr<CFileItem> m_selectedVideoVersion;
+ std::shared_ptr<CFileItem> m_selectedVideoVersion;
};
diff --git a/xbmc/video/guilib/CMakeLists.txt b/xbmc/video/guilib/CMakeLists.txt
index b0a93d5234..c5226897c4 100644
--- a/xbmc/video/guilib/CMakeLists.txt
+++ b/xbmc/video/guilib/CMakeLists.txt
@@ -1,9 +1,11 @@
set(SOURCES VideoPlayActionProcessor.cpp
- VideoSelectActionProcessor.cpp)
+ VideoSelectActionProcessor.cpp
+ VideoActionProcessorHelper.cpp)
set(HEADERS VideoPlayAction.h
VideoPlayActionProcessor.h
VideoSelectAction.h
- VideoSelectActionProcessor.h)
+ VideoSelectActionProcessor.h
+ VideoActionProcessorHelper.h)
core_add_library(video_guilib)
diff --git a/xbmc/video/guilib/VideoActionProcessorHelper.cpp b/xbmc/video/guilib/VideoActionProcessorHelper.cpp
new file mode 100644
index 0000000000..10f7d3f936
--- /dev/null
+++ b/xbmc/video/guilib/VideoActionProcessorHelper.cpp
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2023 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#include "VideoActionProcessorHelper.h"
+
+#include "FileItem.h"
+#include "GUIUserMessages.h"
+#include "ServiceBroker.h"
+#include "guilib/GUIComponent.h"
+#include "guilib/GUIWindowManager.h"
+#include "settings/Settings.h"
+#include "settings/SettingsComponent.h"
+#include "settings/lib/Setting.h"
+#include "utils/log.h"
+#include "video/VideoDatabase.h"
+#include "video/dialogs/GUIDialogVideoVersion.h"
+
+using namespace VIDEO::GUILIB;
+
+CVideoActionProcessorHelper::~CVideoActionProcessorHelper()
+{
+ RestoreDefaultVideoVersion();
+}
+
+void CVideoActionProcessorHelper::SetDefaultVideoVersion()
+{
+ RestoreDefaultVideoVersion();
+
+ //! @todo this hack must go away! Playback currently only works if we persist the
+ //! movie version to play in the video database temporarily, until playback was started.
+ CVideoDatabase db;
+ if (!db.Open())
+ {
+ CLog::LogF(LOGERROR, "Unable to open video database!");
+ return;
+ }
+
+ const VideoDbContentType itemType{m_item->GetVideoContentType()};
+ const int dbId{m_item->GetVideoInfoTag()->m_iDbId};
+
+ CFileItem defaultVideoVersion;
+ db.GetDefaultVideoVersion(itemType, dbId, defaultVideoVersion);
+ m_defaultVideoVersionFileId = defaultVideoVersion.GetVideoInfoTag()->m_iDbId;
+ m_defaultVideoVersionDynPath = defaultVideoVersion.GetDynPath();
+
+ db.SetDefaultVideoVersion(itemType, dbId, m_videoVersion->GetVideoInfoTag()->m_iDbId);
+
+ m_item->SetDynPath(m_videoVersion->GetDynPath());
+ db.GetDetailsByTypeAndId(*m_item, itemType, dbId);
+
+ // notify all windows to update the file item
+ CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_UPDATE_ITEM, GUI_MSG_FLAG_FORCE_UPDATE, m_item);
+ CServiceBroker::GetGUI()->GetWindowManager().SendMessage(msg);
+}
+
+void CVideoActionProcessorHelper::RestoreDefaultVideoVersion()
+{
+ //! @todo this hack must go away!
+ if (m_restoreFolderFlag)
+ {
+ m_restoreFolderFlag = false;
+ m_item->m_bIsFolder = true;
+ }
+
+ if (m_defaultVideoVersionFileId == -1)
+ return;
+
+ //! @todo this hack must go away! Playback currently only works if we persist the
+ //! movie version to play in the video database temporarily, until playback was started.
+ CVideoDatabase db;
+ if (!db.Open())
+ {
+ CLog::LogF(LOGERROR, "Unable to open video database!");
+ return;
+ }
+
+ const VideoDbContentType itemType{m_item->GetVideoContentType()};
+ const int dbId{m_item->GetVideoInfoTag()->m_iDbId};
+
+ db.SetDefaultVideoVersion(itemType, dbId, m_defaultVideoVersionFileId);
+
+ m_item->SetDynPath(m_defaultVideoVersionDynPath);
+ db.GetDetailsByTypeAndId(*m_item, itemType, dbId);
+
+ m_defaultVideoVersionFileId = -1;
+ m_defaultVideoVersionDynPath.clear();
+
+ // notify all windows to update the file item
+ CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_UPDATE_ITEM, GUI_MSG_FLAG_FORCE_UPDATE, m_item);
+ CServiceBroker::GetGUI()->GetWindowManager().SendMessage(msg);
+}
+
+std::shared_ptr<CFileItem> CVideoActionProcessorHelper::ChooseVideoVersion()
+{
+ if (!m_videoVersion && m_item->HasVideoVersions())
+ {
+ // select the specified video version
+ if (m_item->GetVideoInfoTag()->m_idVideoVersion > 0)
+ m_videoVersion = m_item;
+
+ const auto settings{CServiceBroker::GetSettingsComponent()->GetSettings()};
+
+ if (!m_videoVersion)
+ {
+ //! @todo get rid of this hack to patch away item's folder flag if it is video version
+ //! folder
+ if (m_item->GetVideoInfoTag()->m_idVideoVersion == VIDEO_VERSION_ID_ALL &&
+ settings->GetBool(CSettings::SETTING_VIDEOLIBRARY_SHOWVIDEOVERSIONSASFOLDER))
+ {
+ m_item->m_bIsFolder = false;
+ m_restoreFolderFlag = true;
+ }
+ }
+
+ if (!m_videoVersion)
+ {
+ // select the default video version
+ if (settings->GetBool(CSettings::SETTING_VIDEOPLAYER_PLAYDEFAULTVERSION))
+ {
+ CVideoDatabase db;
+ if (!db.Open())
+ {
+ CLog::LogF(LOGERROR, "Unable to open video database!");
+ }
+ else
+ {
+ CFileItem defaultVersion;
+ db.GetDefaultVideoVersion(m_item->GetVideoContentType(),
+ m_item->GetVideoInfoTag()->m_iDbId, defaultVersion);
+ if (!defaultVersion.HasVideoInfoTag() || defaultVersion.GetVideoInfoTag()->IsEmpty())
+ CLog::LogF(LOGERROR, "Unable to get default video version from video database!");
+ else
+ m_videoVersion = std::make_shared<const CFileItem>(defaultVersion);
+ }
+ }
+ }
+
+ if (!m_videoVersion && !m_item->GetProperty("prohibit_choose_video_version").asBoolean(false))
+ {
+ const auto result{CGUIDialogVideoVersion::ChooseVideoVersion(m_item)};
+ if (result.cancelled)
+ return {};
+ else
+ m_videoVersion = result.selected;
+ }
+ }
+
+ if (m_videoVersion)
+ SetDefaultVideoVersion();
+
+ return m_item;
+}
diff --git a/xbmc/video/guilib/VideoActionProcessorHelper.h b/xbmc/video/guilib/VideoActionProcessorHelper.h
new file mode 100644
index 0000000000..0238d70953
--- /dev/null
+++ b/xbmc/video/guilib/VideoActionProcessorHelper.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#pragma once
+
+#include <memory>
+#include <string>
+
+class CFileItem;
+
+namespace VIDEO
+{
+namespace GUILIB
+{
+class CVideoActionProcessorHelper
+{
+public:
+ CVideoActionProcessorHelper(const std::shared_ptr<CFileItem>& item,
+ const std::shared_ptr<const CFileItem>& videoVersion)
+ : m_item{item}, m_videoVersion{videoVersion}
+ {
+ }
+ virtual ~CVideoActionProcessorHelper();
+
+ std::shared_ptr<CFileItem> ChooseVideoVersion();
+
+private:
+ CVideoActionProcessorHelper() = delete;
+ void SetDefaultVideoVersion();
+ void RestoreDefaultVideoVersion();
+
+ std::shared_ptr<CFileItem> m_item;
+ std::shared_ptr<const CFileItem> m_videoVersion;
+ int m_defaultVideoVersionFileId{-1};
+ std::string m_defaultVideoVersionDynPath;
+ bool m_restoreFolderFlag{false};
+};
+} // namespace GUILIB
+} // namespace VIDEO
diff --git a/xbmc/video/guilib/VideoPlayActionProcessor.cpp b/xbmc/video/guilib/VideoPlayActionProcessor.cpp
index 0c01f2caa4..123bdb1985 100644
--- a/xbmc/video/guilib/VideoPlayActionProcessor.cpp
+++ b/xbmc/video/guilib/VideoPlayActionProcessor.cpp
@@ -8,12 +8,15 @@
#include "VideoPlayActionProcessor.h"
+#include "FileItem.h"
#include "ServiceBroker.h"
#include "dialogs/GUIDialogContextMenu.h"
#include "guilib/LocalizeStrings.h"
#include "settings/Settings.h"
#include "settings/SettingsComponent.h"
+#include "utils/Variant.h"
#include "video/VideoUtils.h"
+#include "video/guilib/VideoActionProcessorHelper.h"
using namespace VIDEO::GUILIB;
@@ -28,11 +31,27 @@ bool CVideoPlayActionProcessorBase::Process()
return Process(GetDefaultPlayAction());
}
-bool CVideoPlayActionProcessorBase::Process(PlayAction PlayAction)
+bool CVideoPlayActionProcessorBase::Process(PlayAction playAction)
{
m_userCancelled = false;
- switch (PlayAction)
+ CVideoActionProcessorHelper procHelper{m_item, m_videoVersion};
+
+ if (!m_versionChecked &&
+ (playAction == PLAY_ACTION_PLAY_FROM_BEGINNING || playAction == PLAY_ACTION_PLAY_OR_RESUME))
+ {
+ m_versionChecked = true;
+ const auto videoVersion{procHelper.ChooseVideoVersion()};
+ if (videoVersion)
+ m_item = videoVersion;
+ else
+ {
+ m_userCancelled = true;
+ return true; // User cancelled the select menu. We're done.
+ }
+ }
+
+ switch (playAction)
{
case PLAY_ACTION_PLAY_OR_RESUME:
{
diff --git a/xbmc/video/guilib/VideoPlayActionProcessor.h b/xbmc/video/guilib/VideoPlayActionProcessor.h
index d3f447b98b..25753bc6d0 100644
--- a/xbmc/video/guilib/VideoPlayActionProcessor.h
+++ b/xbmc/video/guilib/VideoPlayActionProcessor.h
@@ -22,6 +22,11 @@ class CVideoPlayActionProcessorBase
{
public:
explicit CVideoPlayActionProcessorBase(const std::shared_ptr<CFileItem>& item) : m_item(item) {}
+ CVideoPlayActionProcessorBase(const std::shared_ptr<CFileItem>& item,
+ const std::shared_ptr<const CFileItem>& videoVersion)
+ : m_item{item}, m_videoVersion{videoVersion}
+ {
+ }
virtual ~CVideoPlayActionProcessorBase() = default;
static PlayAction GetDefaultPlayAction();
@@ -41,6 +46,9 @@ protected:
private:
CVideoPlayActionProcessorBase() = delete;
PlayAction ChoosePlayOrResume();
+
+ bool m_versionChecked{false};
+ const std::shared_ptr<const CFileItem> m_videoVersion;
};
} // namespace GUILIB
} // namespace VIDEO
diff --git a/xbmc/video/guilib/VideoSelectActionProcessor.cpp b/xbmc/video/guilib/VideoSelectActionProcessor.cpp
index dfb6e2eabe..6ff489c580 100644
--- a/xbmc/video/guilib/VideoSelectActionProcessor.cpp
+++ b/xbmc/video/guilib/VideoSelectActionProcessor.cpp
@@ -19,8 +19,10 @@
#include "settings/Settings.h"
#include "settings/SettingsComponent.h"
#include "utils/StringUtils.h"
+#include "utils/Variant.h"
#include "video/VideoInfoTag.h"
#include "video/VideoUtils.h"
+#include "video/guilib/VideoActionProcessorHelper.h"
using namespace VIDEO::GUILIB;
@@ -37,6 +39,19 @@ bool CVideoSelectActionProcessorBase::Process()
bool CVideoSelectActionProcessorBase::Process(SelectAction selectAction)
{
+ CVideoActionProcessorHelper procHelper{m_item, m_videoVersion};
+
+ if (!m_versionChecked &&
+ (selectAction == SELECT_ACTION_PLAY || selectAction == SELECT_ACTION_PLAY_OR_RESUME))
+ {
+ m_versionChecked = true;
+ const auto videoVersion{procHelper.ChooseVideoVersion()};
+ if (videoVersion)
+ m_item = videoVersion;
+ else
+ return true; // User cancelled the select menu. We're done.
+ }
+
switch (selectAction)
{
case SELECT_ACTION_CHOOSE:
diff --git a/xbmc/video/guilib/VideoSelectActionProcessor.h b/xbmc/video/guilib/VideoSelectActionProcessor.h
index 52d01b0846..a154921166 100644
--- a/xbmc/video/guilib/VideoSelectActionProcessor.h
+++ b/xbmc/video/guilib/VideoSelectActionProcessor.h
@@ -22,6 +22,11 @@ class CVideoSelectActionProcessorBase
{
public:
explicit CVideoSelectActionProcessorBase(const std::shared_ptr<CFileItem>& item) : m_item(item) {}
+ CVideoSelectActionProcessorBase(const std::shared_ptr<CFileItem>& item,
+ const std::shared_ptr<const CFileItem>& videoVersion)
+ : m_item{item}, m_videoVersion{videoVersion}
+ {
+ }
virtual ~CVideoSelectActionProcessorBase() = default;
static SelectAction GetDefaultSelectAction();
@@ -45,6 +50,9 @@ private:
CVideoSelectActionProcessorBase() = delete;
SelectAction ChooseVideoItemSelectAction() const;
unsigned int ChooseStackItemPartNumber() const;
+
+ bool m_versionChecked{false};
+ const std::shared_ptr<const CFileItem> m_videoVersion;
};
} // namespace GUILIB
} // namespace VIDEO
diff --git a/xbmc/video/windows/GUIWindowVideoBase.cpp b/xbmc/video/windows/GUIWindowVideoBase.cpp
index 3aef9de39f..7e7ee38705 100644
--- a/xbmc/video/windows/GUIWindowVideoBase.cpp
+++ b/xbmc/video/windows/GUIWindowVideoBase.cpp
@@ -57,7 +57,6 @@
#include "video/VideoLibraryQueue.h"
#include "video/VideoUtils.h"
#include "video/dialogs/GUIDialogVideoInfo.h"
-#include "video/dialogs/GUIDialogVideoVersion.h"
#include "video/guilib/VideoPlayActionProcessor.h"
#include "video/guilib/VideoSelectActionProcessor.h"
#include "view/GUIViewState.h"
@@ -978,16 +977,7 @@ bool CGUIWindowVideoBase::OnPlayMedia(int iItem, const std::string &player)
if (m_thumbLoader.IsLoading())
m_thumbLoader.StopAsync();
- //! @todo get rid of special handling for movie versions
- if (itemCopy->GetVideoInfoTag()->m_type == MediaTypeMovie ||
- itemCopy->GetVideoInfoTag()->m_type == MediaTypeVideoVersion)
- {
- CGUIDialogVideoVersion::PlayVideoVersion(
- itemCopy, [player](const std::shared_ptr<CFileItem>& item)
- { CServiceBroker::GetPlaylistPlayer().Play(item, player); });
- }
- else
- CServiceBroker::GetPlaylistPlayer().Play(itemCopy, player);
+ CServiceBroker::GetPlaylistPlayer().Play(itemCopy, player);
const auto& components = CServiceBroker::GetAppComponents();
const auto appPlayer = components.GetComponent<CApplicationPlayer>();