diff options
author | Kai Sommerfeld <3226626+ksooo@users.noreply.github.com> | 2023-12-07 19:44:51 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-07 19:44:51 +0100 |
commit | 448b7a4e3d33aa5e2648d673d176d09c9c4326aa (patch) | |
tree | a49cae43c1aa8356098e36c7a532a901e3081999 | |
parent | 49ba27934d228aa7c963dc38b8a143dc8cbd1f23 (diff) | |
parent | c8b8c2f3cbf4758fdc254c5b0802e9e2a920109c (diff) |
Merge pull request #24180 from ksooo/video-fix-version-select
[video] Video Versions: Refactor play/select logic
28 files changed, 666 insertions, 283 deletions
diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po index 05e898b52d..296c4039e1 100644 --- a/addons/resource.language.en_gb/resources/strings.po +++ b/addons/resource.language.en_gb/resources/strings.po @@ -23868,22 +23868,22 @@ 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 +#. Select default video version setting #: system/settings/settings.xml msgctxt "#40200" -msgid "Play default video version" +msgid "Select default video version" msgstr "" -#. Help for play default video version setting +#. Help for select default video version setting #: system/settings/settings.xml msgctxt "#40201" -msgid "Select player action for video with multiple versions.[CR][Enabled] Automatically play the default video version without prompting.[CR][Disabled] Always display a dialogue to select the preferred video version." +msgid "Defines how to handle selection of videos with multiple versions.[CR][Enabled] Automatically select the default video version without prompting.[CR][Disabled] Display a dialogue to select a version of the video." msgstr "" #. Ignore different video versions settting @@ -23919,9 +23919,17 @@ msgstr "" #. Help for show video versions as folder settting #: system/settings/settings.xml msgctxt "#40207" -msgid "When enabled, video with multiple versions will be shown as folder in library, this folder can then be opened to display the individual video versions. When disabled, a video version dialog will be opened for the video." +msgid "When enabled, a video with multiple versions will be shown as a folder in the video library. This folder can then be opened to display the individual video versions. When disabled, the configured select action will be applied." msgstr "" +#. Choose video version context menu item label +#: xbmc/video/ContextMenus.h +msgctxt "#40208" +msgid "Choose version" +msgstr "" + +#empty strings from id 40209 to 40399 + # Video versions #. Name of a video version, like "Director's Cut" 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/system/settings/settings.xml b/system/settings/settings.xml index 826f1ea708..6330fafad4 100755 --- a/system/settings/settings.xml +++ b/system/settings/settings.xml @@ -21,11 +21,6 @@ <hidevalue>false</hidevalue> </control> </setting> - <setting id="videoplayer.playdefaultversion" type="boolean" label="40200" help="40201"> - <level>0</level> - <default>false</default> - <control type="toggle" /> - </setting> <setting id="videoplayer.seeksteps" type="list[integer]" label="13556" help="37042"> <level>1</level> <default>-600,-300,-180,-60,-30,-10,10,30,60,180,300,600</default> @@ -1030,6 +1025,11 @@ </constraints> <control type="list" format="string" /> </setting> + <setting id="myvideos.selectdefaultversion" type="boolean" label="40200" help="40201"> + <level>0</level> + <default>false</default> + <control type="toggle" /> + </setting> <setting id="myvideos.playaction" type="integer" label="22076" help="36204"> <level>0</level> <default>1</default> <!-- PLAY_ACTION_PLAY_OR_RESUME --> diff --git a/xbmc/ContextMenuManager.cpp b/xbmc/ContextMenuManager.cpp index 607e960366..7aed939162 100644 --- a/xbmc/ContextMenuManager.cpp +++ b/xbmc/ContextMenuManager.cpp @@ -62,6 +62,7 @@ void CContextMenuManager::Init() std::unique_lock<CCriticalSection> lock(m_criticalSection); m_items = { std::make_shared<CONTEXTMENU::CVideoBrowse>(), + std::make_shared<CONTEXTMENU::CVideoChooseVersion>(), std::make_shared<CONTEXTMENU::CVideoResume>(), std::make_shared<CONTEXTMENU::CVideoPlay>(), std::make_shared<CONTEXTMENU::CVideoPlayUsing>(), diff --git a/xbmc/favourites/GUIWindowFavourites.cpp b/xbmc/favourites/GUIWindowFavourites.cpp index 762697af3e..25989b364a 100644 --- a/xbmc/favourites/GUIWindowFavourites.cpp +++ b/xbmc/favourites/GUIWindowFavourites.cpp @@ -50,43 +50,46 @@ namespace class CVideoSelectActionProcessor : public VIDEO::GUILIB::CVideoSelectActionProcessorBase { public: - explicit CVideoSelectActionProcessor(CFileItem& item) : CVideoSelectActionProcessorBase(item) {} + explicit CVideoSelectActionProcessor(const std::shared_ptr<CFileItem>& item) + : CVideoSelectActionProcessorBase(item) + { + } protected: bool OnPlayPartSelected(unsigned int part) override { // part numbers are 1-based FAVOURITES_UTILS::ExecuteAction( - {"PlayMedia", m_item, StringUtils::Format("playoffset={}", part - 1)}); + {"PlayMedia", *m_item, StringUtils::Format("playoffset={}", part - 1)}); return true; } bool OnResumeSelected() override { - FAVOURITES_UTILS::ExecuteAction({"PlayMedia", m_item, "resume"}); + FAVOURITES_UTILS::ExecuteAction({"PlayMedia", *m_item, "resume"}); return true; } bool OnPlaySelected() override { - FAVOURITES_UTILS::ExecuteAction({"PlayMedia", m_item, "noresume"}); + FAVOURITES_UTILS::ExecuteAction({"PlayMedia", *m_item, "noresume"}); return true; } bool OnQueueSelected() override { - FAVOURITES_UTILS::ExecuteAction({"QueueMedia", m_item, ""}); + FAVOURITES_UTILS::ExecuteAction({"QueueMedia", *m_item, ""}); return true; } bool OnInfoSelected() override { - return UTILS::GUILIB::CGUIContentUtils::ShowInfoForItem(m_item); + return UTILS::GUILIB::CGUIContentUtils::ShowInfoForItem(*m_item); } bool OnMoreSelected() override { - CONTEXTMENU::ShowFor(std::make_shared<CFileItem>(m_item), CContextMenuManager::MAIN); + CONTEXTMENU::ShowFor(m_item, CContextMenuManager::MAIN); return true; } }; @@ -94,18 +97,21 @@ protected: class CVideoPlayActionProcessor : public VIDEO::GUILIB::CVideoPlayActionProcessorBase { public: - explicit CVideoPlayActionProcessor(CFileItem& item) : CVideoPlayActionProcessorBase(item) {} + explicit CVideoPlayActionProcessor(const ::std::shared_ptr<CFileItem>& item) + : CVideoPlayActionProcessorBase(item) + { + } protected: bool OnResumeSelected() override { - FAVOURITES_UTILS::ExecuteAction({"PlayMedia", m_item, "resume"}); + FAVOURITES_UTILS::ExecuteAction({"PlayMedia", *m_item, "resume"}); return true; } bool OnPlaySelected() override { - FAVOURITES_UTILS::ExecuteAction({"PlayMedia", m_item, "noresume"}); + FAVOURITES_UTILS::ExecuteAction({"PlayMedia", *m_item, "noresume"}); return true; } }; @@ -132,7 +138,7 @@ bool CGUIWindowFavourites::OnSelect(int itemIdx) // video select action setting is for files only, except exec func is playmedia... if (targetItem.HasVideoInfoTag() && (!targetItem.m_bIsFolder || isPlayMedia)) { - CVideoSelectActionProcessor proc{targetItem}; + CVideoSelectActionProcessor proc{std::make_shared<CFileItem>(targetItem)}; if (proc.Process()) return true; } @@ -154,24 +160,24 @@ bool CGUIWindowFavourites::OnAction(const CAction& action) if (!target) return false; - CFileItem item{*target}; + const auto item{std::make_shared<CFileItem>(*target)}; // video play action setting is for files and folders... - if (item.HasVideoInfoTag() || (item.m_bIsFolder && VIDEO_UTILS::IsItemPlayable(item))) + if (item->HasVideoInfoTag() || (item->m_bIsFolder && VIDEO_UTILS::IsItemPlayable(*item))) { CVideoPlayActionProcessor proc{item}; if (proc.Process()) return true; } - if (CPlayerUtils::IsItemPlayable(item)) + if (CPlayerUtils::IsItemPlayable(*item)) { - CFavouritesURL target{item, {}}; + CFavouritesURL target{*item, {}}; if (target.GetAction() != CFavouritesURL::Action::PLAY_MEDIA) { // build a playmedia execute string for given target target = CFavouritesURL{CFavouritesURL::Action::PLAY_MEDIA, - {StringUtils::Paramify(item.GetPath())}}; + {StringUtils::Paramify(item->GetPath())}}; } return FAVOURITES_UTILS::ExecuteAction(target); } 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 b581cf6e2a..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" @@ -475,7 +474,7 @@ bool ExecuteAction(const CExecString& execute) class CVideoSelectActionProcessor : public VIDEO::GUILIB::CVideoSelectActionProcessorBase { public: - CVideoSelectActionProcessor(CDirectoryProvider& provider, CFileItem& item) + CVideoSelectActionProcessor(CDirectoryProvider& provider, const std::shared_ptr<CFileItem>& item) : CVideoSelectActionProcessorBase(item), m_provider(provider) { } @@ -484,49 +483,37 @@ protected: bool OnPlayPartSelected(unsigned int part) override { // part numbers are 1-based - ExecuteAction({"PlayMedia", m_item, StringUtils::Format("playoffset={}", part - 1)}); + ExecuteAction({"PlayMedia", *m_item, StringUtils::Format("playoffset={}", part - 1)}); return true; } bool OnResumeSelected() override { - ExecuteAction({"PlayMedia", m_item, "resume"}); + ExecuteAction({"PlayMedia", *m_item, "resume"}); return true; } bool OnPlaySelected() override { - //! @todo get rid of special handling for movie versions - if (m_item.GetVideoInfoTag()->m_type == MediaTypeMovie) - { - auto videoItem = std::make_shared<CFileItem>(m_item); - CGUIDialogVideoVersion::PlayVideoVersion( - videoItem, - [](const std::shared_ptr<CFileItem>& item) { - ExecuteAction({"PlayMedia", *item.get(), "noresume"}); - }); - } - else - ExecuteAction({"PlayMedia", m_item, "noresume"}); - + ExecuteAction({"PlayMedia", *m_item, "noresume"}); return true; } bool OnQueueSelected() override { - ExecuteAction({"QueueMedia", m_item, ""}); + ExecuteAction({"QueueMedia", *m_item, ""}); return true; } bool OnInfoSelected() override { - m_provider.OnInfo(std::make_shared<CFileItem>(m_item)); + m_provider.OnInfo(m_item); return true; } bool OnMoreSelected() override { - m_provider.OnContextMenu(std::make_shared<CFileItem>(m_item)); + m_provider.OnContextMenu(m_item); return true; } @@ -537,30 +524,21 @@ private: class CVideoPlayActionProcessor : public VIDEO::GUILIB::CVideoPlayActionProcessorBase { public: - explicit CVideoPlayActionProcessor(CFileItem& item) : CVideoPlayActionProcessorBase(item) {} + explicit CVideoPlayActionProcessor(const std::shared_ptr<CFileItem>& item) + : CVideoPlayActionProcessorBase(item) + { + } protected: bool OnResumeSelected() override { - ExecuteAction({"PlayMedia", m_item, "resume"}); + ExecuteAction({"PlayMedia", *m_item, "resume"}); return true; } bool OnPlaySelected() override { - //! @todo get rid of special handling for movie versions - if (m_item.GetVideoInfoTag()->m_type == MediaTypeMovie) - { - auto videoItem = std::make_shared<CFileItem>(m_item); - CGUIDialogVideoVersion::PlayVideoVersion( - videoItem, - [](const std::shared_ptr<CFileItem>& item) { - ExecuteAction({"PlayMedia", *item.get(), "noresume"}); - }); - } - else - ExecuteAction({"PlayMedia", m_item, "noresume"}); - + ExecuteAction({"PlayMedia", *m_item, "noresume"}); return true; } }; @@ -585,7 +563,7 @@ bool CDirectoryProvider::OnClick(const CGUIListItemPtr& item) // video select action setting is for files only, except exec func is playmedia... if (targetItem.HasVideoInfoTag() && (!targetItem.m_bIsFolder || isPlayMedia)) { - CVideoSelectActionProcessor proc{*this, targetItem}; + CVideoSelectActionProcessor proc{*this, std::make_shared<CFileItem>(targetItem)}; if (proc.Process()) return true; } @@ -616,7 +594,7 @@ bool CDirectoryProvider::OnPlay(const CGUIListItemPtr& item) if (targetItem.HasVideoInfoTag() || (targetItem.m_bIsFolder && VIDEO_UTILS::IsItemPlayable(targetItem))) { - CVideoPlayActionProcessor proc{targetItem}; + CVideoPlayActionProcessor proc{std::make_shared<CFileItem>(targetItem)}; if (proc.Process()) return true; } diff --git a/xbmc/pvr/dialogs/GUIDialogPVRGuideInfo.cpp b/xbmc/pvr/dialogs/GUIDialogPVRGuideInfo.cpp index 9b8ed4fa4a..c3c20264e0 100644 --- a/xbmc/pvr/dialogs/GUIDialogPVRGuideInfo.cpp +++ b/xbmc/pvr/dialogs/GUIDialogPVRGuideInfo.cpp @@ -140,8 +140,7 @@ bool CGUIDialogPVRGuideInfo::OnClickButtonPlay(const CGUIMessage& message) const auto recording{CPVRItem(m_progItem).GetRecording()}; if (recording) { - CFileItem item{recording}; - CGUIPVRRecordingsPlayActionProcessor proc{item}; + CGUIPVRRecordingsPlayActionProcessor proc{std::make_shared<CFileItem>(recording)}; proc.Process(); if (proc.UserCancelled()) Open(); diff --git a/xbmc/pvr/dialogs/GUIDialogPVRRecordingInfo.cpp b/xbmc/pvr/dialogs/GUIDialogPVRRecordingInfo.cpp index a9458f54b3..f6af16e05c 100644 --- a/xbmc/pvr/dialogs/GUIDialogPVRRecordingInfo.cpp +++ b/xbmc/pvr/dialogs/GUIDialogPVRRecordingInfo.cpp @@ -60,7 +60,7 @@ bool CGUIDialogPVRRecordingInfo::OnClickButtonPlay(const CGUIMessage& message) if (m_recordItem) { - CGUIPVRRecordingsPlayActionProcessor proc{*m_recordItem}; + CGUIPVRRecordingsPlayActionProcessor proc{m_recordItem}; proc.Process(); if (proc.UserCancelled()) Open(); diff --git a/xbmc/pvr/guilib/PVRGUIRecordingsPlayActionProcessor.h b/xbmc/pvr/guilib/PVRGUIRecordingsPlayActionProcessor.h index 14225bc3b6..80df2dfc96 100644 --- a/xbmc/pvr/guilib/PVRGUIRecordingsPlayActionProcessor.h +++ b/xbmc/pvr/guilib/PVRGUIRecordingsPlayActionProcessor.h @@ -19,7 +19,7 @@ namespace PVR class CGUIPVRRecordingsPlayActionProcessor : public VIDEO::GUILIB::CVideoPlayActionProcessorBase { public: - explicit CGUIPVRRecordingsPlayActionProcessor(CFileItem& item) + explicit CGUIPVRRecordingsPlayActionProcessor(const std::shared_ptr<CFileItem>& item) : CVideoPlayActionProcessorBase(item) { } @@ -27,7 +27,7 @@ public: protected: bool OnResumeSelected() override { - m_item.SetStartOffset(STARTOFFSET_RESUME); + m_item->SetStartOffset(STARTOFFSET_RESUME); Play(); return true; } @@ -42,7 +42,7 @@ private: void Play() { CServiceBroker::GetPVRManager().Get<PVR::GUI::Playback>().PlayRecording( - m_item, false /* no resume check */); + *m_item, false /* no resume check */); } }; } // namespace PVR diff --git a/xbmc/pvr/windows/GUIWindowPVRRecordings.cpp b/xbmc/pvr/windows/GUIWindowPVRRecordings.cpp index d939d741b5..a1164e640f 100644 --- a/xbmc/pvr/windows/GUIWindowPVRRecordings.cpp +++ b/xbmc/pvr/windows/GUIWindowPVRRecordings.cpp @@ -227,7 +227,9 @@ namespace class CVideoSelectActionProcessor : public VIDEO::GUILIB::CVideoSelectActionProcessorBase { public: - CVideoSelectActionProcessor(CGUIWindowPVRRecordingsBase& window, CFileItem& item, int itemIndex) + CVideoSelectActionProcessor(CGUIWindowPVRRecordingsBase& window, + const std::shared_ptr<CFileItem>& item, + int itemIndex) : CVideoSelectActionProcessorBase(item), m_window(window), m_itemIndex(itemIndex) { } @@ -242,27 +244,26 @@ protected: bool OnResumeSelected() override { CServiceBroker::GetPVRManager().Get<PVR::GUI::Playback>().ResumePlayRecording( - m_item, true /* fall back to play if no resume possible */); + *m_item, true /* fall back to play if no resume possible */); return true; } bool OnPlaySelected() override { CServiceBroker::GetPVRManager().Get<PVR::GUI::Playback>().PlayRecording( - m_item, false /* no resume check */); + *m_item, false /* no resume check */); return true; } bool OnQueueSelected() override { - VIDEO_UTILS::QueueItem(std::make_shared<CFileItem>(m_item), - VIDEO_UTILS::QueuePosition::POSITION_END); + VIDEO_UTILS::QueueItem(m_item, VIDEO_UTILS::QueuePosition::POSITION_END); return true; } bool OnInfoSelected() override { - CServiceBroker::GetPVRManager().Get<PVR::GUI::Recordings>().ShowRecordingInfo(m_item); + CServiceBroker::GetPVRManager().Get<PVR::GUI::Recordings>().ShowRecordingInfo(*m_item); return true; } @@ -280,37 +281,40 @@ private: class CVideoPlayActionProcessor : public CVideoPlayActionProcessorBase { public: - explicit CVideoPlayActionProcessor(CFileItem& item) : CVideoPlayActionProcessorBase(item) {} + explicit CVideoPlayActionProcessor(const std::shared_ptr<CFileItem>& item) + : CVideoPlayActionProcessorBase(item) + { + } protected: bool OnResumeSelected() override { - if (m_item.m_bIsFolder) + if (m_item->m_bIsFolder) { - m_item.SetStartOffset(STARTOFFSET_RESUME); + m_item->SetStartOffset(STARTOFFSET_RESUME); CServiceBroker::GetPVRManager().Get<PVR::GUI::Playback>().PlayRecordingFolder( - m_item, false /* no resume check */); + *m_item, false /* no resume check */); } else { CServiceBroker::GetPVRManager().Get<PVR::GUI::Playback>().ResumePlayRecording( - m_item, true /* fall back to play if no resume possible */); + *m_item, true /* fall back to play if no resume possible */); } return true; } bool OnPlaySelected() override { - if (m_item.m_bIsFolder) + if (m_item->m_bIsFolder) { - m_item.SetStartOffset(0); + m_item->SetStartOffset(0); CServiceBroker::GetPVRManager().Get<PVR::GUI::Playback>().PlayRecordingFolder( - m_item, false /* no resume check */); + *m_item, false /* no resume check */); } else { CServiceBroker::GetPVRManager().Get<PVR::GUI::Playback>().PlayRecording( - m_item, false /* no resume check */); + *m_item, false /* no resume check */); } return true; } @@ -346,7 +350,7 @@ bool CGUIWindowPVRRecordingsBase::OnMessage(CGUIMessage& message) if (!item->IsParentFolder() && message.GetParam1() == ACTION_PLAYER_PLAY) { - CVideoPlayActionProcessor proc{*item}; + CVideoPlayActionProcessor proc{item}; bReturn = proc.Process(); } else if (item->m_bIsFolder) @@ -356,7 +360,7 @@ bool CGUIWindowPVRRecordingsBase::OnMessage(CGUIMessage& message) } else { - CVideoSelectActionProcessor proc(*this, *item, iItem); + CVideoSelectActionProcessor proc(*this, item, iItem); bReturn = proc.Process(); } break; diff --git a/xbmc/settings/Settings.h b/xbmc/settings/Settings.h index 3ba4b08cde..8a62a03b4d 100644 --- a/xbmc/settings/Settings.h +++ b/xbmc/settings/Settings.h @@ -101,7 +101,6 @@ public: static constexpr auto SETTING_VIDEOLIBRARY_IGNOREVIDEOEXTRAS = "videolibrary.ignorevideoextras"; static constexpr auto SETTING_VIDEOLIBRARY_SHOWVIDEOVERSIONSASFOLDER = "videolibrary.showvideoversionsasfolder"; - static constexpr auto SETTING_VIDEOPLAYER_PLAYDEFAULTVERSION = "videoplayer.playdefaultversion"; static constexpr auto SETTING_LOCALE_AUDIOLANGUAGE = "locale.audiolanguage"; static constexpr auto SETTING_VIDEOPLAYER_PREFERDEFAULTFLAG = "videoplayer.preferdefaultflag"; static constexpr auto SETTING_VIDEOPLAYER_AUTOPLAYNEXTITEM = "videoplayer.autoplaynextitem"; @@ -137,6 +136,7 @@ public: static constexpr auto SETTING_VIDEOPLAYER_SUPPORTMVC = "videoplayer.supportmvc"; static constexpr auto SETTING_VIDEOPLAYER_CONVERTDOVI = "videoplayer.convertdovi"; static constexpr auto SETTING_MYVIDEOS_SELECTACTION = "myvideos.selectaction"; + static constexpr auto SETTING_MYVIDEOS_SELECTDEFAULTVERSION = "myvideos.selectdefaultversion"; static constexpr auto SETTING_MYVIDEOS_PLAYACTION = "myvideos.playaction"; static constexpr auto SETTING_MYVIDEOS_USETAGS = "myvideos.usetags"; static constexpr auto SETTING_MYVIDEOS_EXTRACTFLAGS = "myvideos.extractflags"; diff --git a/xbmc/video/ContextMenus.cpp b/xbmc/video/ContextMenus.cpp index 9a179d5020..4128284579 100644 --- a/xbmc/video/ContextMenus.cpp +++ b/xbmc/video/ContextMenus.cpp @@ -9,6 +9,7 @@ #include "ContextMenus.h" #include "Autorun.h" +#include "ContextMenuManager.h" #include "FileItem.h" #include "GUIUserMessages.h" #include "ServiceBroker.h" @@ -17,11 +18,14 @@ #include "guilib/GUIComponent.h" #include "guilib/GUIWindowManager.h" #include "guilib/LocalizeStrings.h" +#include "utils/ExecString.h" +#include "utils/StringUtils.h" #include "utils/URIUtils.h" #include "video/VideoInfoTag.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 <utility> @@ -159,6 +163,84 @@ bool CVideoBrowse::Execute(const std::shared_ptr<CFileItem>& item) const return true; } +namespace +{ +bool ExecuteAction(const CExecString& execute) +{ + const std::string execStr{execute.GetExecString()}; + if (!execStr.empty()) + { + CGUIMessage message(GUI_MSG_EXECUTE, 0, 0); + message.SetStringParam(execStr); + CServiceBroker::GetGUI()->GetWindowManager().SendMessage(message); + return true; + } + return false; +} + +class CVideoSelectActionProcessor : public VIDEO::GUILIB::CVideoSelectActionProcessorBase +{ +public: + explicit CVideoSelectActionProcessor(const std::shared_ptr<CFileItem>& item) + : CVideoSelectActionProcessorBase(item) + { + } + +protected: + bool OnPlayPartSelected(unsigned int part) override + { + // part numbers are 1-based + ExecuteAction({"PlayMedia", *m_item, StringUtils::Format("playoffset={}", part - 1)}); + return true; + } + + bool OnResumeSelected() override + { + ExecuteAction({"PlayMedia", *m_item, "resume"}); + return true; + } + + bool OnPlaySelected() override + { + ExecuteAction({"PlayMedia", *m_item, "noresume"}); + return true; + } + + bool OnQueueSelected() override + { + ExecuteAction({"QueueMedia", *m_item, ""}); + return true; + } + + bool OnInfoSelected() override + { + CGUIDialogVideoInfo::ShowFor(*m_item); + return true; + } + + bool OnMoreSelected() override + { + CONTEXTMENU::ShowFor(m_item, CContextMenuManager::MAIN); + return true; + } +}; +} // unnamed namespace + +bool CVideoChooseVersion::IsVisible(const CFileItem& item) const +{ + return item.HasVideoVersions(); +} + +bool CVideoChooseVersion::Execute(const std::shared_ptr<CFileItem>& item) const +{ + // force selection dialog, regardless of any settings like 'Select default video version' + item->SetProperty("force_choose_video_version", true); + CVideoSelectActionProcessor proc{item}; + const bool ret = proc.Process(); + item->ClearProperty("force_choose_video_version"); + return ret; +} + std::string CVideoResume::GetLabel(const CFileItem& item) const { return VIDEO_UTILS::GetResumeString(item.GetItemToPlay()); @@ -175,38 +257,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 +343,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 +371,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 +388,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/ContextMenus.h b/xbmc/video/ContextMenus.h index e220670b02..6728f58d54 100644 --- a/xbmc/video/ContextMenus.h +++ b/xbmc/video/ContextMenus.h @@ -86,6 +86,13 @@ struct CVideoBrowse : CStaticContextMenuAction bool Execute(const std::shared_ptr<CFileItem>& item) const override; }; +struct CVideoChooseVersion : CStaticContextMenuAction +{ + CVideoChooseVersion() : CStaticContextMenuAction(40208) {} // Choose version + bool IsVisible(const CFileItem& item) const override; + bool Execute(const std::shared_ptr<CFileItem>& item) const override; +}; + struct CVideoResume : IContextMenuItem { std::string GetLabel(const CFileItem& item) const override; diff --git a/xbmc/video/dialogs/GUIDialogVideoInfo.cpp b/xbmc/video/dialogs/GUIDialogVideoInfo.cpp index eae46427ab..08e7a1579f 100644 --- a/xbmc/video/dialogs/GUIDialogVideoInfo.cpp +++ b/xbmc/video/dialogs/GUIDialogVideoInfo.cpp @@ -715,12 +715,15 @@ namespace class CVideoPlayActionProcessor : public CVideoPlayActionProcessorBase { public: - explicit CVideoPlayActionProcessor(CFileItem& item) : CVideoPlayActionProcessorBase(item) {} + explicit CVideoPlayActionProcessor(const std::shared_ptr<CFileItem>& item) + : CVideoPlayActionProcessorBase(item) + { + } protected: bool OnResumeSelected() override { - m_item.SetStartOffset(STARTOFFSET_RESUME); + m_item->SetStartOffset(STARTOFFSET_RESUME); Play(); return true; } @@ -734,21 +737,11 @@ protected: private: void Play() { - m_item.SetProperty("playlist_type_hint", PLAYLIST::TYPE_VIDEO); - const ContentUtils::PlayMode mode{m_item.GetProperty("CheckAutoPlayNextItem").asBoolean() + 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}; - - //! @todo get rid of special handling for movie versions - if (m_item.GetStartOffset() != STARTOFFSET_RESUME && - m_item.GetVideoInfoTag()->m_type == MediaTypeMovie) - { - CGUIDialogVideoVersion::PlayVideoVersion(std::make_shared<CFileItem>(m_item), - [mode](const std::shared_ptr<CFileItem>& item) - { VIDEO_UTILS::PlayItem(item, "", mode); }); - } - else - VIDEO_UTILS::PlayItem(std::make_shared<CFileItem>(m_item), "", mode); + VIDEO_UTILS::PlayItem(m_item, "", mode); } }; } // unnamed namespace @@ -797,7 +790,7 @@ void CGUIDialogVideoInfo::Play(bool resume) if (resume) { - CVideoPlayActionProcessor proc{*m_movieItem}; + CVideoPlayActionProcessor proc{m_movieItem}; proc.Process(PLAY_ACTION_RESUME); } else @@ -805,13 +798,13 @@ void CGUIDialogVideoInfo::Play(bool resume) if (GetControl(CONTROL_BTN_RESUME)) { // if dialog has a resume button, play button has always the purpose to start from beginning - CVideoPlayActionProcessor proc{*m_movieItem}; + CVideoPlayActionProcessor proc{m_movieItem}; proc.Process(PLAY_ACTION_PLAY_FROM_BEGINNING); } else { // play button acts according to default play action setting - CVideoPlayActionProcessor proc{*m_movieItem}; + CVideoPlayActionProcessor proc{m_movieItem}; proc.Process(); if (proc.UserCancelled()) { diff --git a/xbmc/video/dialogs/GUIDialogVideoVersion.cpp b/xbmc/video/dialogs/GUIDialogVideoVersion.cpp index ea85194864..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(); @@ -121,15 +119,15 @@ bool CGUIDialogVideoVersion::OnMessage(CGUIMessage& message) } else { - CONTROL_ENABLE_ON_CONDITION(CONTROL_BUTTON_REMOVE, !m_playMode); - CONTROL_ENABLE_ON_CONDITION(CONTROL_BUTTON_RENAME, !m_playMode); - CONTROL_ENABLE_ON_CONDITION(CONTROL_BUTTON_SET_DEFAULT, !m_playMode); + CONTROL_ENABLE_ON_CONDITION(CONTROL_BUTTON_REMOVE, m_mode == Mode::MANAGE); + CONTROL_ENABLE_ON_CONDITION(CONTROL_BUTTON_RENAME, m_mode == Mode::MANAGE); + CONTROL_ENABLE_ON_CONDITION(CONTROL_BUTTON_SET_DEFAULT, m_mode == Mode::MANAGE); } - if (!m_playMode) + if (m_mode == Mode::MANAGE) SET_CONTROL_FOCUS(CONTROL_BUTTON_PLAY, 0); else - Play(); + CloseAll(); } } else if (control == CONTROL_LIST_EXTRAS_VERSION) @@ -148,13 +146,13 @@ bool CGUIDialogVideoVersion::OnMessage(CGUIMessage& message) CONTROL_DISABLE(CONTROL_BUTTON_SET_DEFAULT); - CONTROL_ENABLE_ON_CONDITION(CONTROL_BUTTON_REMOVE, !m_playMode); - CONTROL_ENABLE_ON_CONDITION(CONTROL_BUTTON_RENAME, !m_playMode); + CONTROL_ENABLE_ON_CONDITION(CONTROL_BUTTON_REMOVE, m_mode == Mode::MANAGE); + CONTROL_ENABLE_ON_CONDITION(CONTROL_BUTTON_RENAME, m_mode == Mode::MANAGE); - if (!m_playMode) + 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_playMode ? "manage" : "play"); + SET_CONTROL_LABEL(CONTROL_LABEL_MODE, m_mode == Mode::MANAGE ? "manage" : "choose"); // set window title std::string title = m_videoItem->GetVideoInfoTag()->GetTitle(); @@ -205,8 +209,9 @@ void CGUIDialogVideoVersion::OnInitWindow() if (year != 0) title = StringUtils::Format("{} ({})", title, year); - SET_CONTROL_LABEL(CONTROL_LABEL_TITLE, - StringUtils::Format(g_localizeStrings.Get(!m_playMode ? 40022 : 40023), title)); + SET_CONTROL_LABEL( + CONTROL_LABEL_TITLE, + StringUtils::Format(g_localizeStrings.Get(m_mode == Mode::MANAGE ? 40022 : 40023), title)); // bind primary and extras version lists CGUIMessage msg1(GUI_MSG_LABEL_BIND, GetID(), CONTROL_LIST_PRIMARY_VERSION, 0, 0, @@ -221,11 +226,11 @@ void CGUIDialogVideoVersion::OnInitWindow() CONTROL_DISABLE(CONTROL_BUTTON_REMOVE); CONTROL_DISABLE(CONTROL_BUTTON_SET_DEFAULT); - CONTROL_ENABLE_ON_CONDITION(CONTROL_BUTTON_ADD_VERSION, !m_playMode); - CONTROL_ENABLE_ON_CONDITION(CONTROL_BUTTON_ADD_EXTRAS, !m_playMode); - CONTROL_ENABLE_ON_CONDITION(CONTROL_BUTTON_CHOOSE_ART, !m_playMode); - CONTROL_ENABLE_ON_CONDITION(CONTROL_BUTTON_RENAME, !m_playMode); - CONTROL_ENABLE_ON_CONDITION(CONTROL_BUTTON_PLAY, !m_playMode); + CONTROL_ENABLE_ON_CONDITION(CONTROL_BUTTON_ADD_VERSION, m_mode == Mode::MANAGE); + CONTROL_ENABLE_ON_CONDITION(CONTROL_BUTTON_ADD_EXTRAS, m_mode == Mode::MANAGE); + CONTROL_ENABLE_ON_CONDITION(CONTROL_BUTTON_CHOOSE_ART, m_mode == Mode::MANAGE); + CONTROL_ENABLE_ON_CONDITION(CONTROL_BUTTON_RENAME, m_mode == Mode::MANAGE); + CONTROL_ENABLE_ON_CONDITION(CONTROL_BUTTON_PLAY, m_mode == Mode::MANAGE); CGUIDialog::OnInitWindow(); } @@ -274,7 +279,7 @@ void CGUIDialogVideoVersion::RefreshVideoVersionList() m_database.GetDefaultVideoVersion(itemType, dbId, *m_selectedVideoVersion.get()); } -void CGUIDialogVideoVersion::SetVideoItem(const std::shared_ptr<CFileItem>& item, bool playMode) +void CGUIDialogVideoVersion::SetVideoItem(const std::shared_ptr<CFileItem>& item) { if (item == nullptr || !item->HasVideoInfoTag() || item->GetVideoInfoTag()->m_type != MediaTypeMovie) @@ -284,7 +289,6 @@ void CGUIDialogVideoVersion::SetVideoItem(const std::shared_ptr<CFileItem>& item } m_videoItem = item; - m_playMode = playMode; ClearVideoVersionList(); @@ -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,77 +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, false); - dialog->SetPlayCallback(PlayVideoItem); + dialog->SetVideoItem(item); + dialog->SetMode(Mode::MANAGE); 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, true); - dialog->SetPlayCallback(PlayVideoItem); + dialog->SetVideoItem(item); + 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) @@ -695,7 +711,8 @@ int CGUIDialogVideoVersion::ManageVideoVersionContextMenu(const std::shared_ptr< videoItem)) return -1; - dialog->SetVideoItem(std::make_shared<CFileItem>(videoItem), false); + dialog->SetVideoItem(std::make_shared<CFileItem>(videoItem)); + dialog->SetMode(Mode::MANAGE); dialog->SetSelectedVideoVersion(version); switch (static_cast<CONTEXT_BUTTON>(button)) diff --git a/xbmc/video/dialogs/GUIDialogVideoVersion.h b/xbmc/video/dialogs/GUIDialogVideoVersion.h index bb2c72eff9..b408f3c782 100644 --- a/xbmc/video/dialogs/GUIDialogVideoVersion.h +++ b/xbmc/video/dialogs/GUIDialogVideoVersion.h @@ -25,23 +25,33 @@ public: CGUIDialogVideoVersion(int id); ~CGUIDialogVideoVersion(void) override; bool OnMessage(CGUIMessage& message) override; - void SetVideoItem(const std::shared_ptr<CFileItem>& item, bool playMode); + bool OnBack(int actionID) override; + + enum class Mode + { + MANAGE, + CHOOSE, + }; + void SetMode(Mode mode) { m_mode = mode; } + void SetVideoItem(const std::shared_ptr<CFileItem>& item); + static std::tuple<int, std::string> NewVideoVersion(); static bool ConvertVideoVersion(const std::shared_ptr<CFileItem>& item); 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; @@ -50,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(); @@ -59,15 +68,14 @@ private: void SetDefault(); void Remove(); void ChooseArt(); - - VideoVersionPlayCallback m_playCallback; + void CloseAll(); std::shared_ptr<CFileItem> m_videoItem; - bool m_playMode{false}; - + 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..04f3132cbb --- /dev/null +++ b/xbmc/video/guilib/VideoActionProcessorHelper.cpp @@ -0,0 +1,161 @@ +/* + * 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()) + { + if (!m_item->GetProperty("force_choose_video_version").asBoolean(false)) + { + // 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_MYVIDEOS_SELECTDEFAULTVERSION)) + { + 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("force_choose_video_version").asBoolean(false) || + !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 6e0e75fdae..7d508dca82 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,26 @@ 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) + { + 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: { @@ -62,7 +80,7 @@ PlayAction CVideoPlayActionProcessorBase::ChoosePlayOrResume() { PlayAction action = PLAY_ACTION_PLAY_FROM_BEGINNING; - const std::string resumeString = VIDEO_UTILS::GetResumeString(m_item); + const std::string resumeString = VIDEO_UTILS::GetResumeString(*m_item); if (!resumeString.empty()) { CContextButtons choices; diff --git a/xbmc/video/guilib/VideoPlayActionProcessor.h b/xbmc/video/guilib/VideoPlayActionProcessor.h index ea57549178..25753bc6d0 100644 --- a/xbmc/video/guilib/VideoPlayActionProcessor.h +++ b/xbmc/video/guilib/VideoPlayActionProcessor.h @@ -10,6 +10,8 @@ #include "video/guilib/VideoPlayAction.h" +#include <memory> + class CFileItem; namespace VIDEO @@ -19,7 +21,12 @@ namespace GUILIB class CVideoPlayActionProcessorBase { public: - explicit CVideoPlayActionProcessorBase(CFileItem& item) : m_item(item) {} + 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(); @@ -33,12 +40,15 @@ protected: virtual bool OnResumeSelected() = 0; virtual bool OnPlaySelected() = 0; - CFileItem& m_item; + std::shared_ptr<CFileItem> m_item; bool m_userCancelled{false}; 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 1a8d274a4f..15fd6e5e4d 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,18 @@ bool CVideoSelectActionProcessorBase::Process() bool CVideoSelectActionProcessorBase::Process(SelectAction selectAction) { + CVideoActionProcessorHelper procHelper{m_item, m_videoVersion}; + + if (!m_versionChecked) + { + 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: @@ -50,7 +64,7 @@ bool CVideoSelectActionProcessorBase::Process(SelectAction selectAction) case SELECT_ACTION_PLAY_OR_RESUME: { - const SelectAction action = ChoosePlayOrResume(m_item); + const SelectAction action = ChoosePlayOrResume(*m_item); if (action < 0) return true; // User cancelled the select menu. We're done. @@ -90,7 +104,7 @@ bool CVideoSelectActionProcessorBase::Process(SelectAction selectAction) unsigned int CVideoSelectActionProcessorBase::ChooseStackItemPartNumber() const { CFileItemList parts; - XFILE::CDirectory::GetDirectory(m_item.GetDynPath(), parts, "", XFILE::DIR_FLAG_DEFAULTS); + XFILE::CDirectory::GetDirectory(m_item->GetDynPath(), parts, "", XFILE::DIR_FLAG_DEFAULTS); for (int i = 0; i < parts.Size(); ++i) parts[i]->SetLabel(StringUtils::Format(g_localizeStrings.Get(23051), i + 1)); // Part # @@ -132,7 +146,7 @@ SelectAction CVideoSelectActionProcessorBase::ChooseVideoItemSelectAction() cons { CContextButtons choices; - const std::string resumeString = VIDEO_UTILS::GetResumeString(m_item); + const std::string resumeString = VIDEO_UTILS::GetResumeString(*m_item); if (!resumeString.empty()) { choices.Add(SELECT_ACTION_RESUME, resumeString); diff --git a/xbmc/video/guilib/VideoSelectActionProcessor.h b/xbmc/video/guilib/VideoSelectActionProcessor.h index c896a386da..a154921166 100644 --- a/xbmc/video/guilib/VideoSelectActionProcessor.h +++ b/xbmc/video/guilib/VideoSelectActionProcessor.h @@ -10,6 +10,8 @@ #include "video/guilib/VideoSelectAction.h" +#include <memory> + class CFileItem; namespace VIDEO @@ -19,7 +21,12 @@ namespace GUILIB class CVideoSelectActionProcessorBase { public: - explicit CVideoSelectActionProcessorBase(CFileItem& item) : m_item(item) {} + 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(); @@ -37,12 +44,15 @@ protected: virtual bool OnInfoSelected() = 0; virtual bool OnMoreSelected() = 0; - CFileItem& m_item; + std::shared_ptr<CFileItem> m_item; 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 9bb90f0ea2..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" @@ -543,7 +542,7 @@ class CVideoSelectActionProcessor : public CVideoSelectActionProcessorBase { public: CVideoSelectActionProcessor(CGUIWindowVideoBase& window, - CFileItem& item, + const std::shared_ptr<CFileItem>& item, int itemIndex, const std::string& player) : CVideoSelectActionProcessorBase(item), @@ -553,7 +552,7 @@ public: { // Reset the current start offset. The actual resume // option is set by the processor, based on the action passed. - m_item.SetStartOffset(0); + m_item->SetStartOffset(0); } protected: @@ -564,8 +563,8 @@ protected: bool OnResumeSelected() override { - m_item.SetStartOffset(STARTOFFSET_RESUME); - if (m_item.m_bIsFolder) + m_item->SetStartOffset(STARTOFFSET_RESUME); + if (m_item->m_bIsFolder) { // resume playback of the folder m_window.PlayItem(m_itemIndex, m_player); @@ -577,7 +576,7 @@ protected: bool OnPlaySelected() override { - if (m_item.m_bIsFolder) + if (m_item->m_bIsFolder) { // play the folder m_window.PlayItem(m_itemIndex, m_player); @@ -614,7 +613,7 @@ bool CGUIWindowVideoBase::OnFileAction(int iItem, SelectAction action, const std if (!item) return false; - CVideoSelectActionProcessor proc(*this, *item, iItem, player); + CVideoSelectActionProcessor proc(*this, item, iItem, player); return proc.Process(action); } @@ -741,7 +740,7 @@ class CVideoPlayActionProcessor : public CVideoPlayActionProcessorBase { public: CVideoPlayActionProcessor(CGUIWindowVideoBase& window, - CFileItem& item, + const std::shared_ptr<CFileItem>& item, int itemIndex, const std::string& player) : CVideoPlayActionProcessorBase(item), @@ -754,13 +753,13 @@ public: protected: bool OnResumeSelected() override { - m_item.SetStartOffset(STARTOFFSET_RESUME); + m_item->SetStartOffset(STARTOFFSET_RESUME); return m_window.OnFileAction(m_itemIndex, SELECT_ACTION_RESUME, m_player); } bool OnPlaySelected() override { - m_item.SetStartOffset(0); + m_item->SetStartOffset(0); return m_window.OnFileAction(m_itemIndex, SELECT_ACTION_PLAY, m_player); } @@ -776,7 +775,7 @@ bool CGUIWindowVideoBase::OnPlayOrResumeItem(int iItem, const std::string& playe if (iItem < 0 || iItem >= m_vecItems->Size()) return false; - CVideoPlayActionProcessor proc{*this, *m_vecItems->Get(iItem), iItem, player}; + CVideoPlayActionProcessor proc{*this, m_vecItems->Get(iItem), iItem, player}; return proc.Process(); } @@ -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>(); |