Skip to content

Commit 0730dac

Browse files
authored
Merge pull request xbmc#23848 from ksooo/fix-and-refactor-video-select-actions
[listproviders][video][PVR][utils][builtins] Fix and Refactor Video Select Actions
2 parents ba7adbd + 96ad203 commit 0730dac

24 files changed

+703
-381
lines changed

addons/resource.language.en_gb/resources/strings.po

+19-7
Original file line numberDiff line numberDiff line change
@@ -955,9 +955,8 @@ msgstr ""
955955
#: xbmc/dialogs/GUIDialogPlayEject.cpp
956956
#: xbmc/games/windows/GUIWindowGames.cpp
957957
#: xbmc/music/ContextMenus.h
958-
#: xbmc/music/MusicUtils.cpp
959958
#: xbmc/video/ContextMenus.cpp
960-
#: xbmc/video/windows/GUIWindowVideoBase.cpp
959+
#: xbmc/video/guilib/VideoSelectActionProcessor.cpp
961960
#: system/settings/settings.xml
962961
msgctxt "#208"
963962
msgid "Play"
@@ -5723,10 +5722,9 @@ msgstr ""
57235722
#: addons/skin.estuary/xml/SkinSettings.xml
57245723
#: addons/skin.estuary/xml/Variables.xml
57255724
#: xbmc/Autorun.cpp
5726-
#: xbmc/pvr/PVRContextMenus.cpp
5727-
#: xbmc/pvr/PVRGUIActions.cpp
5725+
#: xbmc/pvr/PVRGUIActionsPlayback.cpp
57285726
#: xbmc/video/ContextMenus.cpp
5729-
#: xbmc/video/windows/GUIWindowVideoBase.cpp
5727+
#: xbmc/video/guilib/VideoSelectActionProcessor.cpp
57305728
msgctxt "#12021"
57315729
msgid "Play from beginning"
57325730
msgstr ""
@@ -6928,11 +6926,13 @@ msgctxt "#13346"
69286926
msgid "Movie information"
69296927
msgstr ""
69306928

6929+
#. Label for 'queue item' (adds an item to a playlist), used at several places
69316930
#: addons/skin.estuary/xml/SkinSettings.xml
69326931
#: addons/skin.estuary/xml/Variables.xml
69336932
#: system/settings/settings.xml
69346933
#: xbmc/music/ContextMenus.h
6935-
#: xbmc/video/ContextMenus.cpp
6934+
#: xbmc/video/ContextMenus.h
6935+
#: xbmc/video/guilib/VideoSelectActionProcessor.cpp
69366936
msgctxt "#13347"
69376937
msgid "Queue item"
69386938
msgstr ""
@@ -13303,6 +13303,9 @@ msgctxt "#20323"
1330313303
msgid "Movie plot"
1330413304
msgstr ""
1330513305

13306+
#. Label for context menu entry to start playback of a part of a video stack
13307+
#: xbmc/video/guilib/VideoSelectActionProcessor.cpp
13308+
#: xbmc/video/windows/GUIWindowVideoBase.cpp
1330613309
msgctxt "#20324"
1330713310
msgid "Play part..."
1330813311
msgstr ""
@@ -15318,11 +15321,17 @@ msgctxt "#22080"
1531815321
msgid "Choose"
1531915322
msgstr ""
1532015323

15324+
#. Label for video select action 'show info'
15325+
#: xbmc/video/guilib/VideoSelectActionProcessor.cpp
1532115326
#: system/settings/settings.xml
1532215327
msgctxt "#22081"
1532315328
msgid "Show information"
1532415329
msgstr ""
1532515330

15331+
#. Label to denote that there is something 'more'
15332+
#: xbmc/listproviders/DirectoryProvider.cpp
15333+
#: xbmc/video/guilib/VideoSelectActionProcessor.cpp
15334+
#: system/settings/settings.xml
1532615335
msgctxt "#22082"
1532715336
msgid "More..."
1532815337
msgstr ""
@@ -15342,6 +15351,9 @@ msgctxt "#23050"
1534215351
msgid "Activate teletext"
1534315352
msgstr ""
1534415353

15354+
#. Label for disc stack part and number
15355+
#: xbmc/video/guilib/VideoSelectActionProcessor.cpp
15356+
#: xbmc/video/VideoUtils.cpp
1534515357
msgctxt "#23051"
1534615358
msgid "Part {0:d}"
1534715359
msgstr ""
@@ -19475,7 +19487,7 @@ msgstr ""
1947519487
#. Description of setting with label #22079 "Default select action"
1947619488
#: system/settings/settings.xml
1947719489
msgctxt "#36177"
19478-
msgid "Toggle between [Choose], [Play] (default), [Resume] and [Show information].[CR][Choose] Will select an item, e.g. open a directory in files mode.[CR][Resume] Will automatically resume videos from the last position that you were viewing them, even after restarting the system."
19490+
msgid "Toggle between [Choose], [Play] (default), [Resume], [Show information] and [Queue item].[CR][Choose] will open a context menu to select an item, e.g. show information.[CR][Play] will automatically play videos from the beginning or if a resume point is present ask whether to play from beginning or to resume.[CR][Resume] Will automatically resume videos from the last position that you were viewing them.[CR][Show information] will open the video's information dialog.[CR][Queue item] will append the video to the video playlist."
1947919491
msgstr ""
1948019492

1948119493
#. Description of setting with label #20433 "Extract thumbnails and video information"

cmake/treedata/common/video.txt

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
xbmc/video video
22
xbmc/video/dialogs video/dialogs
3+
xbmc/video/guilib video/guilib
34
xbmc/video/jobs video/jobs
45
xbmc/video/tags video/tags
56
xbmc/video/windows video/windows

xbmc/FileItem.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -886,9 +886,9 @@ bool CFileItem::IsVideo() const
886886
if (HasPictureInfoTag())
887887
return false;
888888

889-
// only tv recordings are videos...
890-
if (IsPVRRecording())
891-
return !GetPVRRecordingInfoTag()->IsRadio();
889+
// TV recordings are videos...
890+
if (!m_bIsFolder && URIUtils::IsPVRTVRecordingFileOrFolder(GetPath()))
891+
return true;
892892

893893
// ... all other PVR items are not.
894894
if (IsPVR())
@@ -1178,7 +1178,7 @@ bool CFileItem::IsNFO() const
11781178

11791179
bool CFileItem::IsDiscImage() const
11801180
{
1181-
return URIUtils::HasExtension(GetDynPath(), ".img|.iso|.nrg|.udf");
1181+
return URIUtils::IsDiscImage(GetDynPath());
11821182
}
11831183

11841184
bool CFileItem::IsOpticalMediaFile() const
@@ -3741,14 +3741,14 @@ bool CFileItem::LoadDetails()
37413741
return true;
37423742
}
37433743

3744-
if (m_bIsFolder && URIUtils::IsPVRRecordingFileOrFolder(GetPath()))
3744+
if (URIUtils::IsPVRRecordingFileOrFolder(GetPath()))
37453745
{
37463746
if (HasProperty("watchedepisodes") || HasProperty("watched"))
37473747
return true;
37483748

37493749
const std::string parentPath = URIUtils::GetParentPath(GetPath());
37503750

3751-
//! @todo optimize, find a way to set the details of the directory without loading its content.
3751+
//! @todo optimize, find a way to set the details of the item without loading parent directory.
37523752
CFileItemList items;
37533753
if (CDirectory::GetDirectory(parentPath, items, "", XFILE::DIR_FLAG_DEFAULTS))
37543754
{

xbmc/application/ApplicationStackHelper.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ bool CApplicationStackHelper::InitializeStack(const CFileItem & item)
7575
SetRegisteredStack(GetStackPartFileItem(i), stack);
7676
SetRegisteredStackPartNumber(GetStackPartFileItem(i), i);
7777
}
78-
m_currentStackIsDiscImageStack = CFileItem(CStackDirectory::GetFirstStackedFile(item.GetPath()), false).IsDiscImage();
78+
m_currentStackIsDiscImageStack = URIUtils::IsDiscImageStack(item.GetDynPath());
7979

8080
return true;
8181
}

xbmc/dialogs/GUIDialogContextMenu.h

-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ enum CONTEXT_BUTTON
5353
CONTEXT_BUTTON_PLAY_WITH,
5454
CONTEXT_BUTTON_PLAY_PARTYMODE,
5555
CONTEXT_BUTTON_PLAY_PART,
56-
CONTEXT_BUTTON_RESUME_ITEM,
5756
CONTEXT_BUTTON_EDIT,
5857
CONTEXT_BUTTON_EDIT_SMART_PLAYLIST,
5958
CONTEXT_BUTTON_INFO,

xbmc/interfaces/builtins/PlayerBuiltins.cpp

+44-24
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
#include "utils/log.h"
3737
#include "video/PlayerController.h"
3838
#include "video/VideoUtils.h"
39-
#include "video/windows/GUIWindowVideoBase.h"
39+
#include "video/guilib/VideoSelectActionProcessor.h"
4040

4141
#include <math.h>
4242

@@ -502,14 +502,33 @@ int PlayOrQueueMedia(const std::vector<std::string>& params, bool forcePlay)
502502
if (!item.m_bIsFolder && item.IsPlugin())
503503
item.SetProperty("IsPlayable", true);
504504

505-
if (askToResume == true)
505+
if (askToResume)
506506
{
507-
if (CGUIWindowVideoBase::ShowResumeMenu(item) == false)
507+
const VIDEO::GUILIB::SelectAction action =
508+
VIDEO::GUILIB::CVideoSelectActionProcessorBase::ChoosePlayOrResume(item);
509+
if (action == VIDEO::GUILIB::SELECT_ACTION_RESUME)
510+
{
511+
item.SetStartOffset(STARTOFFSET_RESUME);
512+
}
513+
else if (action != VIDEO::GUILIB::SELECT_ACTION_PLAY)
514+
{
515+
// The Resume dialog was closed without any choice
508516
return false;
517+
}
509518
item.SetProperty("check_resume", false);
510519
}
511520

512-
if (item.m_bIsFolder || item.IsPlayList())
521+
if (item.IsStack())
522+
{
523+
const VIDEO_UTILS::ResumeInformation resumeInfo =
524+
VIDEO_UTILS::GetStackPartResumeInformation(item, playOffset + 1);
525+
526+
if (item.GetStartOffset() == STARTOFFSET_RESUME)
527+
item.SetStartOffset(resumeInfo.startOffset);
528+
529+
item.m_lStartPartNumber = resumeInfo.partNumber;
530+
}
531+
else if (!forcePlay /* queue */ || item.m_bIsFolder || item.IsPlayList())
513532
{
514533
CFileItemList items;
515534
GetItemsForPlayList(std::make_shared<CFileItem>(item), items);
@@ -774,17 +793,17 @@ static int SubtitleShiftDown(const std::vector<std::string>& params)
774793
/// \table_row2_l{
775794
/// <b>`PlayMedia(media[\,isdir][\,1]\,[playoffset=xx])`</b>
776795
/// ,
777-
/// Plays the media. This can be a playlist\, music\, or video file\, directory\,
778-
/// plugin or an Url. The optional parameter "\,isdir" can be used for playing
779-
/// a directory. "\,1" will start the media without switching to fullscreen.
780-
/// If media is a playlist\, you can use playoffset=xx where xx is
781-
/// the position to start playback from.
796+
/// Plays the given media. This can be a playlist\, music\, or video file\, directory\,
797+
/// plugin\, disc image stack\, video file stack or an URL. The optional parameter `,isdir` can
798+
/// be used for playing a directory. `,1` will start the media without switching to fullscreen.
799+
/// If media is a playlist or a disc image stack or a video file stack\, you can use
800+
/// playoffset=xx where xx is the position to start playback from.
782801
/// @param[in] media URL to media to play (optional).
783-
/// @param[in] isdir Set "isdir" if media is a directory (optional).
784-
/// @param[in] windowed Set "1" to start playback without switching to fullscreen (optional).
785-
/// @param[in] resume Set "resume" to force resuming (optional).
786-
/// @param[in] noresume Set "noresume" to force not resuming (optional).
787-
/// @param[in] playeroffset Set "playoffset=<offset>" to start playback from a given position in a playlist (optional).
802+
/// @param[in] isdir Set `isdir` if media is a directory (optional).
803+
/// @param[in] windowed Set `1` to start playback without switching to fullscreen (optional).
804+
/// @param[in] resume Set `resume` to force resuming (optional).
805+
/// @param[in] noresume Set `noresume` to force not resuming (optional).
806+
/// @param[in] playoffset Set `playoffset=<offset>` to start playback from a given position in a playlist or stack (optional).
788807
/// }
789808
/// \table_row2_l{
790809
/// <b>`PlayWith(core)`</b>
@@ -803,17 +822,18 @@ static int SubtitleShiftDown(const std::vector<std::string>& params)
803822
/// <b>`QueueMedia(media[\,isdir][\,1][\,playnext]\,[playoffset=xx])`</b>
804823
/// \anchor Builtin_QueueMedia,
805824
/// Queues the given media. This can be a playlist\, music\, or video file\, directory\,
806-
/// plugin or an Url. The optional parameter "\,isdir" can be used for playing
807-
/// a directory. "\,1" will start the media without switching to fullscreen.
808-
/// If media is a playlist\, you can use playoffset=xx where xx is
809-
/// the position to start playback from.
825+
/// plugin\, disc image stack\, video file stack or an URL. The optional parameter `,isdir` can
826+
/// be used for playing a directory. `,1` will start the media without switching to fullscreen.
827+
/// If media is a playlist or a disc image stack or a video file stack\, you can use
828+
/// playoffset=xx where xx is the position to start playback from.
829+
/// where xx is the position to start playback from.
810830
/// @param[in] media URL of media to queue.
811-
/// @param[in] isdir Set "isdir" if media is a directory (optional).
812-
/// @param[in] 1 Set "1" to start playback without switching to fullscreen (optional).
813-
/// @param[in] resume Set "resume" to force resuming (optional).
814-
/// @param[in] noresume Set "noresume" to force not resuming (optional).
815-
/// @param[in] playeroffset Set "playoffset=<offset>" to start playback from a given position in a playlist (optional).
816-
/// @param[in] playnext Set "playnext" to play the media right after the currently playing item, if player is currently
831+
/// @param[in] isdir Set `isdir` if media is a directory (optional).
832+
/// @param[in] 1 Set `1` to start playback without switching to fullscreen (optional).
833+
/// @param[in] resume Set `resume` to force resuming (optional).
834+
/// @param[in] noresume Set `noresume` to force not resuming (optional).
835+
/// @param[in] playoffset Set `playoffset=<offset>` to start playback from a given position in a playlist or stack (optional).
836+
/// @param[in] playnext Set `playnext` to play the media right after the currently playing item, if player is currently
817837
/// playing. If player is not playing, append media to current playlist (optional).
818838
/// <p><hr>
819839
/// @skinning_v20 **[New builtin]** \link Builtin_QueueMedia `QueueMedia(media[\,isdir][\,1][\,playnext]\,[playoffset=xx])`\endlink

xbmc/listproviders/DirectoryProvider.cpp

+81-11
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,10 @@
3636
#include "utils/Variant.h"
3737
#include "utils/XMLUtils.h"
3838
#include "utils/log.h"
39+
#include "video/VideoInfoTag.h"
3940
#include "video/VideoThumbLoader.h"
4041
#include "video/dialogs/GUIDialogVideoInfo.h"
41-
#include "video/windows/GUIWindowVideoBase.h"
42+
#include "video/guilib/VideoSelectActionProcessor.h"
4243

4344
#include <memory>
4445
#include <mutex>
@@ -465,16 +466,77 @@ bool ExecuteAction(const std::string& execute)
465466
}
466467
return false;
467468
}
468-
} // namespace
469469

470-
bool CDirectoryProvider::OnClick(const CGUIListItemPtr &item)
470+
class CVideoSelectActionProcessor : public VIDEO::GUILIB::CVideoSelectActionProcessorBase
471471
{
472-
CFileItem fileItem(*std::static_pointer_cast<CFileItem>(item));
472+
public:
473+
CVideoSelectActionProcessor(CDirectoryProvider& provider, CFileItem& item)
474+
: CVideoSelectActionProcessorBase(item), m_provider(provider)
475+
{
476+
}
477+
478+
protected:
479+
bool OnPlayPartSelected(unsigned int part) override
480+
{
481+
// part numbers are 1-based
482+
BuildAndExecAction("PlayMedia", StringUtils::Format("playoffset={}", part - 1));
483+
return true;
484+
}
473485

474-
if (fileItem.HasVideoInfoTag()
475-
&& CServiceBroker::GetSettingsComponent()->GetSettings()->GetInt(CSettings::SETTING_MYVIDEOS_SELECTACTION) == SELECT_ACTION_INFO
476-
&& OnInfo(item))
486+
bool OnResumeSelected() override
487+
{
488+
BuildAndExecAction("PlayMedia", "resume");
489+
return true;
490+
}
491+
492+
bool OnPlaySelected() override
493+
{
494+
BuildAndExecAction("PlayMedia", "noresume");
477495
return true;
496+
}
497+
498+
bool OnQueueSelected() override
499+
{
500+
BuildAndExecAction("QueueMedia", "");
501+
return true;
502+
}
503+
504+
bool OnInfoSelected() override
505+
{
506+
m_provider.OnInfo(std::make_shared<CFileItem>(m_item));
507+
return true;
508+
}
509+
510+
bool OnMoreSelected() override
511+
{
512+
m_provider.OnContextMenu(std::make_shared<CFileItem>(m_item));
513+
return true;
514+
}
515+
516+
private:
517+
void BuildAndExecAction(const std::string& method, const std::string& param)
518+
{
519+
std::vector<std::string> params{StringUtils::Paramify(m_item.GetPath())};
520+
if (!param.empty())
521+
params.emplace_back(param);
522+
523+
const CExecString es{method, params};
524+
ExecuteAction(es.GetExecString());
525+
}
526+
527+
CDirectoryProvider& m_provider;
528+
};
529+
} // namespace
530+
531+
bool CDirectoryProvider::OnClick(const CGUIListItemPtr& item)
532+
{
533+
CFileItem fileItem(*std::static_pointer_cast<CFileItem>(item));
534+
if (fileItem.HasVideoInfoTag())
535+
{
536+
CVideoSelectActionProcessor proc{*this, fileItem};
537+
if (proc.Process())
538+
return true;
539+
}
478540

479541
if (fileItem.HasProperty("node.target_url"))
480542
fileItem.SetPath(fileItem.GetProperty("node.target_url").asString());
@@ -519,10 +581,8 @@ bool CDirectoryProvider::OnPlay(const CGUIListItemPtr& item)
519581
return true;
520582
}
521583

522-
bool CDirectoryProvider::OnInfo(const CGUIListItemPtr& item)
584+
bool CDirectoryProvider::OnInfo(const std::shared_ptr<CFileItem>& fileItem)
523585
{
524-
auto fileItem = std::static_pointer_cast<CFileItem>(item);
525-
526586
if (fileItem->HasAddonInfo())
527587
{
528588
return CGUIDialogAddonInfo::ShowForItem(fileItem);
@@ -551,17 +611,27 @@ bool CDirectoryProvider::OnInfo(const CGUIListItemPtr& item)
551611
return false;
552612
}
553613

554-
bool CDirectoryProvider::OnContextMenu(const CGUIListItemPtr& item)
614+
bool CDirectoryProvider::OnInfo(const CGUIListItemPtr& item)
555615
{
556616
auto fileItem = std::static_pointer_cast<CFileItem>(item);
617+
return OnInfo(fileItem);
618+
}
557619

620+
bool CDirectoryProvider::OnContextMenu(const std::shared_ptr<CFileItem>& fileItem)
621+
{
558622
const std::string target = GetTarget(*fileItem);
559623
if (!target.empty())
560624
fileItem->SetProperty("targetwindow", target);
561625

562626
return CONTEXTMENU::ShowFor(fileItem);
563627
}
564628

629+
bool CDirectoryProvider::OnContextMenu(const CGUIListItemPtr& item)
630+
{
631+
auto fileItem = std::static_pointer_cast<CFileItem>(item);
632+
return OnContextMenu(fileItem);
633+
}
634+
565635
bool CDirectoryProvider::IsUpdating() const
566636
{
567637
std::unique_lock<CCriticalSection> lock(m_section);

0 commit comments

Comments
 (0)