aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKai Sommerfeld <3226626+ksooo@users.noreply.github.com>2023-12-07 19:44:51 +0100
committerGitHub <noreply@github.com>2023-12-07 19:44:51 +0100
commit448b7a4e3d33aa5e2648d673d176d09c9c4326aa (patch)
treea49cae43c1aa8356098e36c7a532a901e3081999
parent49ba27934d228aa7c963dc38b8a143dc8cbd1f23 (diff)
parentc8b8c2f3cbf4758fdc254c5b0802e9e2a920109c (diff)
Merge pull request #24180 from ksooo/video-fix-version-select
[video] Video Versions: Refactor play/select logic
-rw-r--r--addons/resource.language.en_gb/resources/strings.po22
-rw-r--r--addons/skin.estuary/xml/DialogVideoVersion.xml4
-rw-r--r--addons/skin.estuary/xml/Includes_DialogVideoVersion.xml6
-rwxr-xr-xsystem/settings/settings.xml10
-rw-r--r--xbmc/ContextMenuManager.cpp1
-rw-r--r--xbmc/favourites/GUIWindowFavourites.cpp38
-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.cpp52
-rw-r--r--xbmc/pvr/dialogs/GUIDialogPVRGuideInfo.cpp3
-rw-r--r--xbmc/pvr/dialogs/GUIDialogPVRRecordingInfo.cpp2
-rw-r--r--xbmc/pvr/guilib/PVRGUIRecordingsPlayActionProcessor.h6
-rw-r--r--xbmc/pvr/windows/GUIWindowPVRRecordings.cpp38
-rw-r--r--xbmc/settings/Settings.h2
-rw-r--r--xbmc/video/ContextMenus.cpp179
-rw-r--r--xbmc/video/ContextMenus.h7
-rw-r--r--xbmc/video/dialogs/GUIDialogVideoInfo.cpp29
-rw-r--r--xbmc/video/dialogs/GUIDialogVideoVersion.cpp193
-rw-r--r--xbmc/video/dialogs/GUIDialogVideoVersion.h34
-rw-r--r--xbmc/video/guilib/CMakeLists.txt6
-rw-r--r--xbmc/video/guilib/VideoActionProcessorHelper.cpp161
-rw-r--r--xbmc/video/guilib/VideoActionProcessorHelper.h44
-rw-r--r--xbmc/video/guilib/VideoPlayActionProcessor.cpp24
-rw-r--r--xbmc/video/guilib/VideoPlayActionProcessor.h14
-rw-r--r--xbmc/video/guilib/VideoSelectActionProcessor.cpp20
-rw-r--r--xbmc/video/guilib/VideoSelectActionProcessor.h14
-rw-r--r--xbmc/video/windows/GUIWindowVideoBase.cpp32
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>();