diff options
Diffstat (limited to '')
-rw-r--r-- | xbmc/pvr/PVRContextMenus.cpp | 780 |
1 files changed, 780 insertions, 0 deletions
diff --git a/xbmc/pvr/PVRContextMenus.cpp b/xbmc/pvr/PVRContextMenus.cpp new file mode 100644 index 0000000..724872d --- /dev/null +++ b/xbmc/pvr/PVRContextMenus.cpp @@ -0,0 +1,780 @@ +/* + * Copyright (C) 2016-2018 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 "PVRContextMenus.h" + +#include "ContextMenuItem.h" +#include "FileItem.h" +#include "ServiceBroker.h" +#include "guilib/LocalizeStrings.h" +#include "pvr/PVRManager.h" +#include "pvr/addons/PVRClient.h" +#include "pvr/addons/PVRClientMenuHooks.h" +#include "pvr/addons/PVRClients.h" +#include "pvr/channels/PVRChannel.h" +#include "pvr/channels/PVRChannelGroupsContainer.h" +#include "pvr/epg/EpgInfoTag.h" +#include "pvr/guilib/PVRGUIActionsEPG.h" +#include "pvr/guilib/PVRGUIActionsPlayback.h" +#include "pvr/guilib/PVRGUIActionsRecordings.h" +#include "pvr/guilib/PVRGUIActionsTimers.h" +#include "pvr/recordings/PVRRecording.h" +#include "pvr/recordings/PVRRecordings.h" +#include "pvr/recordings/PVRRecordingsPath.h" +#include "pvr/timers/PVRTimerInfoTag.h" +#include "pvr/timers/PVRTimers.h" +#include "pvr/timers/PVRTimersPath.h" +#include "utils/URIUtils.h" + +#include <memory> +#include <string> + +namespace PVR +{ +namespace CONTEXTMENUITEM +{ +#define DECL_STATICCONTEXTMENUITEM(clazz) \ + class clazz : public CStaticContextMenuAction \ + { \ + public: \ + explicit clazz(uint32_t label) : CStaticContextMenuAction(label) {} \ + bool IsVisible(const CFileItem& item) const override; \ + bool Execute(const CFileItemPtr& item) const override; \ + }; + +#define DECL_CONTEXTMENUITEM(clazz) \ + class clazz : public IContextMenuItem \ + { \ + public: \ + std::string GetLabel(const CFileItem& item) const override; \ + bool IsVisible(const CFileItem& item) const override; \ + bool Execute(const CFileItemPtr& item) const override; \ + }; + +DECL_STATICCONTEXTMENUITEM(PlayEpgTag); +DECL_STATICCONTEXTMENUITEM(PlayRecording); +DECL_CONTEXTMENUITEM(ShowInformation); +DECL_STATICCONTEXTMENUITEM(ShowChannelGuide); +DECL_STATICCONTEXTMENUITEM(FindSimilar); +DECL_STATICCONTEXTMENUITEM(StartRecording); +DECL_STATICCONTEXTMENUITEM(StopRecording); +DECL_STATICCONTEXTMENUITEM(AddTimerRule); +DECL_CONTEXTMENUITEM(EditTimerRule); +DECL_STATICCONTEXTMENUITEM(DeleteTimerRule); +DECL_CONTEXTMENUITEM(EditTimer); +DECL_CONTEXTMENUITEM(DeleteTimer); +DECL_STATICCONTEXTMENUITEM(EditRecording); +DECL_CONTEXTMENUITEM(DeleteRecording); +DECL_STATICCONTEXTMENUITEM(UndeleteRecording); +DECL_STATICCONTEXTMENUITEM(DeleteWatchedRecordings); +DECL_CONTEXTMENUITEM(ToggleTimerState); +DECL_STATICCONTEXTMENUITEM(AddReminder); +DECL_STATICCONTEXTMENUITEM(ExecuteSearch); +DECL_STATICCONTEXTMENUITEM(EditSearch); +DECL_STATICCONTEXTMENUITEM(RenameSearch); +DECL_STATICCONTEXTMENUITEM(DeleteSearch); + +class PVRClientMenuHook : public IContextMenuItem +{ +public: + explicit PVRClientMenuHook(const CPVRClientMenuHook& hook) : m_hook(hook) {} + + std::string GetLabel(const CFileItem& item) const override; + bool IsVisible(const CFileItem& item) const override; + bool Execute(const CFileItemPtr& item) const override; + + const CPVRClientMenuHook& GetHook() const { return m_hook; } + +private: + const CPVRClientMenuHook m_hook; +}; + +std::shared_ptr<CPVRTimerInfoTag> GetTimerInfoTagFromItem(const CFileItem& item) +{ + std::shared_ptr<CPVRTimerInfoTag> timer; + + const std::shared_ptr<CPVREpgInfoTag> epg(item.GetEPGInfoTag()); + if (epg) + timer = CServiceBroker::GetPVRManager().Timers()->GetTimerForEpgTag(epg); + + if (!timer) + timer = item.GetPVRTimerInfoTag(); + + return timer; +} + +/////////////////////////////////////////////////////////////////////////////// +// Play epg tag + +bool PlayEpgTag::IsVisible(const CFileItem& item) const +{ + const std::shared_ptr<CPVREpgInfoTag> epg(item.GetEPGInfoTag()); + if (epg) + return epg->IsPlayable(); + + return false; +} + +bool PlayEpgTag::Execute(const CFileItemPtr& item) const +{ + return CServiceBroker::GetPVRManager().Get<PVR::GUI::Playback>().PlayEpgTag(*item); +} + +/////////////////////////////////////////////////////////////////////////////// +// Play recording + +bool PlayRecording::IsVisible(const CFileItem& item) const +{ + const std::shared_ptr<CPVRRecording> recording = + CServiceBroker::GetPVRManager().Recordings()->GetRecordingForEpgTag(item.GetEPGInfoTag()); + if (recording) + return !recording->IsDeleted(); + + return false; +} + +bool PlayRecording::Execute(const CFileItemPtr& item) const +{ + return CServiceBroker::GetPVRManager().Get<PVR::GUI::Playback>().PlayRecording( + *item, true /* bCheckResume */); +} + +/////////////////////////////////////////////////////////////////////////////// +// Show information (epg, recording) + +std::string ShowInformation::GetLabel(const CFileItem& item) const +{ + if (item.GetPVRRecordingInfoTag()) + return g_localizeStrings.Get(19053); /* Recording Information */ + + return g_localizeStrings.Get(19047); /* Programme information */ +} + +bool ShowInformation::IsVisible(const CFileItem& item) const +{ + const std::shared_ptr<CPVRChannel> channel(item.GetPVRChannelInfoTag()); + if (channel) + return channel->GetEPGNow().get() != nullptr; + + if (item.HasEPGInfoTag()) + return !item.GetEPGInfoTag()->IsGapTag(); + + const std::shared_ptr<CPVRTimerInfoTag> timer(item.GetPVRTimerInfoTag()); + if (timer && !URIUtils::PathEquals(item.GetPath(), CPVRTimersPath::PATH_ADDTIMER)) + return timer->GetEpgInfoTag().get() != nullptr; + + if (item.GetPVRRecordingInfoTag()) + return true; + + return false; +} + +bool ShowInformation::Execute(const CFileItemPtr& item) const +{ + if (item->GetPVRRecordingInfoTag()) + return CServiceBroker::GetPVRManager().Get<PVR::GUI::Recordings>().ShowRecordingInfo(*item); + + return CServiceBroker::GetPVRManager().Get<PVR::GUI::EPG>().ShowEPGInfo(*item); +} + +/////////////////////////////////////////////////////////////////////////////// +// Show channel guide + +bool ShowChannelGuide::IsVisible(const CFileItem& item) const +{ + const std::shared_ptr<CPVRChannel> channel(item.GetPVRChannelInfoTag()); + if (channel) + return channel->GetEPGNow().get() != nullptr; + + return false; +} + +bool ShowChannelGuide::Execute(const CFileItemPtr& item) const +{ + return CServiceBroker::GetPVRManager().Get<PVR::GUI::EPG>().ShowChannelEPG(*item); +} + +/////////////////////////////////////////////////////////////////////////////// +// Find similar + +bool FindSimilar::IsVisible(const CFileItem& item) const +{ + const std::shared_ptr<CPVRChannel> channel(item.GetPVRChannelInfoTag()); + if (channel) + return channel->GetEPGNow().get() != nullptr; + + if (item.HasEPGInfoTag()) + return !item.GetEPGInfoTag()->IsGapTag(); + + const std::shared_ptr<CPVRTimerInfoTag> timer(item.GetPVRTimerInfoTag()); + if (timer && !URIUtils::PathEquals(item.GetPath(), CPVRTimersPath::PATH_ADDTIMER)) + return timer->GetEpgInfoTag().get() != nullptr; + + const std::shared_ptr<CPVRRecording> recording(item.GetPVRRecordingInfoTag()); + if (recording) + return !recording->IsDeleted(); + + return false; +} + +bool FindSimilar::Execute(const CFileItemPtr& item) const +{ + return CServiceBroker::GetPVRManager().Get<PVR::GUI::EPG>().FindSimilar(*item); +} + +/////////////////////////////////////////////////////////////////////////////// +// Start recording + +bool StartRecording::IsVisible(const CFileItem& item) const +{ + const std::shared_ptr<CPVRClient> client = CServiceBroker::GetPVRManager().GetClient(item); + + std::shared_ptr<CPVRChannel> channel = item.GetPVRChannelInfoTag(); + if (channel) + return client && client->GetClientCapabilities().SupportsTimers() && + !CServiceBroker::GetPVRManager().Timers()->IsRecordingOnChannel(*channel); + + const std::shared_ptr<CPVREpgInfoTag> epg = item.GetEPGInfoTag(); + if (epg && epg->IsRecordable()) + { + if (epg->IsGapTag()) + { + channel = CServiceBroker::GetPVRManager().ChannelGroups()->GetChannelForEpgTag(epg); + if (channel) + { + return client && client->GetClientCapabilities().SupportsTimers() && + !CServiceBroker::GetPVRManager().Timers()->IsRecordingOnChannel(*channel); + } + } + else + { + return client && client->GetClientCapabilities().SupportsTimers() && + !CServiceBroker::GetPVRManager().Timers()->GetTimerForEpgTag(epg); + } + } + return false; +} + +bool StartRecording::Execute(const CFileItemPtr& item) const +{ + const std::shared_ptr<CPVREpgInfoTag> epgTag = item->GetEPGInfoTag(); + if (!epgTag || epgTag->IsActive()) + { + // instant recording + std::shared_ptr<CPVRChannel> channel; + if (epgTag) + channel = CServiceBroker::GetPVRManager().ChannelGroups()->GetChannelForEpgTag(epgTag); + + if (!channel) + channel = item->GetPVRChannelInfoTag(); + + if (channel) + return CServiceBroker::GetPVRManager().Get<PVR::GUI::Timers>().SetRecordingOnChannel(channel, + true); + } + + return CServiceBroker::GetPVRManager().Get<PVR::GUI::Timers>().AddTimer(*item, false); +} + +/////////////////////////////////////////////////////////////////////////////// +// Stop recording + +bool StopRecording::IsVisible(const CFileItem& item) const +{ + const std::shared_ptr<CPVRRecording> recording(item.GetPVRRecordingInfoTag()); + if (recording && recording->IsInProgress()) + return true; + + std::shared_ptr<CPVRChannel> channel = item.GetPVRChannelInfoTag(); + if (channel) + return CServiceBroker::GetPVRManager().Timers()->IsRecordingOnChannel(*channel); + + const std::shared_ptr<CPVRTimerInfoTag> timer(GetTimerInfoTagFromItem(item)); + if (timer && !URIUtils::PathEquals(item.GetPath(), CPVRTimersPath::PATH_ADDTIMER)) + return timer->IsRecording(); + + const std::shared_ptr<CPVREpgInfoTag> epg = item.GetEPGInfoTag(); + if (epg && epg->IsGapTag()) + { + channel = CServiceBroker::GetPVRManager().ChannelGroups()->GetChannelForEpgTag(epg); + if (channel) + return CServiceBroker::GetPVRManager().Timers()->IsRecordingOnChannel(*channel); + } + + return false; +} + +bool StopRecording::Execute(const CFileItemPtr& item) const +{ + const std::shared_ptr<CPVREpgInfoTag> epgTag = item->GetEPGInfoTag(); + if (epgTag && epgTag->IsGapTag()) + { + // instance recording + const std::shared_ptr<CPVRChannel> channel = + CServiceBroker::GetPVRManager().ChannelGroups()->GetChannelForEpgTag(epgTag); + if (channel) + return CServiceBroker::GetPVRManager().Get<PVR::GUI::Timers>().SetRecordingOnChannel(channel, + false); + } + + return CServiceBroker::GetPVRManager().Get<PVR::GUI::Timers>().StopRecording(*item); +} + +/////////////////////////////////////////////////////////////////////////////// +// Edit recording + +bool EditRecording::IsVisible(const CFileItem& item) const +{ + const std::shared_ptr<CPVRRecording> recording(item.GetPVRRecordingInfoTag()); + if (recording && !recording->IsDeleted() && !recording->IsInProgress()) + { + return CServiceBroker::GetPVRManager().Get<PVR::GUI::Recordings>().CanEditRecording(item); + } + return false; +} + +bool EditRecording::Execute(const CFileItemPtr& item) const +{ + return CServiceBroker::GetPVRManager().Get<PVR::GUI::Recordings>().EditRecording(*item); +} + +/////////////////////////////////////////////////////////////////////////////// +// Delete recording + +std::string DeleteRecording::GetLabel(const CFileItem& item) const +{ + const std::shared_ptr<CPVRRecording> recording(item.GetPVRRecordingInfoTag()); + if (recording && recording->IsDeleted()) + return g_localizeStrings.Get(19291); /* Delete permanently */ + + return g_localizeStrings.Get(117); /* Delete */ +} + +bool DeleteRecording::IsVisible(const CFileItem& item) const +{ + const std::shared_ptr<CPVRClient> client = CServiceBroker::GetPVRManager().GetClient(item); + if (client && !client->GetClientCapabilities().SupportsRecordingsDelete()) + return false; + + const std::shared_ptr<CPVRRecording> recording(item.GetPVRRecordingInfoTag()); + if (recording && !recording->IsInProgress()) + return true; + + // recordings folder? + if (item.m_bIsFolder && + CServiceBroker::GetPVRManager().Clients()->AnyClientSupportingRecordingsDelete()) + { + const CPVRRecordingsPath path(item.GetPath()); + return path.IsValid() && !path.IsRecordingsRoot(); + } + + return false; +} + +bool DeleteRecording::Execute(const CFileItemPtr& item) const +{ + return CServiceBroker::GetPVRManager().Get<PVR::GUI::Recordings>().DeleteRecording(*item); +} + +/////////////////////////////////////////////////////////////////////////////// +// Undelete recording + +bool UndeleteRecording::IsVisible(const CFileItem& item) const +{ + const std::shared_ptr<CPVRRecording> recording(item.GetPVRRecordingInfoTag()); + if (recording && recording->IsDeleted()) + return true; + + return false; +} + +bool UndeleteRecording::Execute(const CFileItemPtr& item) const +{ + return CServiceBroker::GetPVRManager().Get<PVR::GUI::Recordings>().UndeleteRecording(*item); +} + +/////////////////////////////////////////////////////////////////////////////// +// Delete watched recordings + +bool DeleteWatchedRecordings::IsVisible(const CFileItem& item) const +{ + // recordings folder? + if (item.m_bIsFolder && !item.IsParentFolder()) + return CPVRRecordingsPath(item.GetPath()).IsValid(); + + return false; +} + +bool DeleteWatchedRecordings::Execute(const std::shared_ptr<CFileItem>& item) const +{ + return CServiceBroker::GetPVRManager().Get<PVR::GUI::Recordings>().DeleteWatchedRecordings(*item); +} + +/////////////////////////////////////////////////////////////////////////////// +// Add reminder + +bool AddReminder::IsVisible(const CFileItem& item) const +{ + const std::shared_ptr<CPVREpgInfoTag> epg = item.GetEPGInfoTag(); + if (epg && !CServiceBroker::GetPVRManager().Timers()->GetTimerForEpgTag(epg) && + epg->StartAsLocalTime() > CDateTime::GetCurrentDateTime()) + return true; + + return false; +} + +bool AddReminder::Execute(const std::shared_ptr<CFileItem>& item) const +{ + return CServiceBroker::GetPVRManager().Get<PVR::GUI::Timers>().AddReminder(*item); +} + +/////////////////////////////////////////////////////////////////////////////// +// Activate / deactivate timer or timer rule + +std::string ToggleTimerState::GetLabel(const CFileItem& item) const +{ + const std::shared_ptr<CPVRTimerInfoTag> timer(item.GetPVRTimerInfoTag()); + if (timer && !timer->IsDisabled()) + return g_localizeStrings.Get(844); /* Deactivate */ + + return g_localizeStrings.Get(843); /* Activate */ +} + +bool ToggleTimerState::IsVisible(const CFileItem& item) const +{ + const std::shared_ptr<CPVRTimerInfoTag> timer(item.GetPVRTimerInfoTag()); + if (!timer || URIUtils::PathEquals(item.GetPath(), CPVRTimersPath::PATH_ADDTIMER) || + timer->IsBroken()) + return false; + + return timer->GetTimerType()->SupportsEnableDisable(); +} + +bool ToggleTimerState::Execute(const CFileItemPtr& item) const +{ + return CServiceBroker::GetPVRManager().Get<PVR::GUI::Timers>().ToggleTimerState(*item); +} + +/////////////////////////////////////////////////////////////////////////////// +// Add timer rule + +bool AddTimerRule::IsVisible(const CFileItem& item) const +{ + const std::shared_ptr<CPVREpgInfoTag> epg = item.GetEPGInfoTag(); + return (epg && !epg->IsGapTag() && + !CServiceBroker::GetPVRManager().Timers()->GetTimerForEpgTag(epg)); +} + +bool AddTimerRule::Execute(const CFileItemPtr& item) const +{ + return CServiceBroker::GetPVRManager().Get<PVR::GUI::Timers>().AddTimerRule(*item, true, true); +} + +/////////////////////////////////////////////////////////////////////////////// +// Edit timer rule + +std::string EditTimerRule::GetLabel(const CFileItem& item) const +{ + const std::shared_ptr<CPVRTimerInfoTag> timer(GetTimerInfoTagFromItem(item)); + if (timer && !URIUtils::PathEquals(item.GetPath(), CPVRTimersPath::PATH_ADDTIMER)) + { + const std::shared_ptr<CPVRTimerInfoTag> parentTimer( + CServiceBroker::GetPVRManager().Timers()->GetTimerRule(timer)); + if (parentTimer) + { + if (!parentTimer->GetTimerType()->IsReadOnly()) + return g_localizeStrings.Get(19243); /* Edit timer rule */ + } + } + + return g_localizeStrings.Get(19304); /* View timer rule */ +} + +bool EditTimerRule::IsVisible(const CFileItem& item) const +{ + const std::shared_ptr<CPVRTimerInfoTag> timer(GetTimerInfoTagFromItem(item)); + if (timer && !URIUtils::PathEquals(item.GetPath(), CPVRTimersPath::PATH_ADDTIMER)) + return timer->HasParent(); + + return false; +} + +bool EditTimerRule::Execute(const CFileItemPtr& item) const +{ + return CServiceBroker::GetPVRManager().Get<PVR::GUI::Timers>().EditTimerRule(*item); +} + +/////////////////////////////////////////////////////////////////////////////// +// Delete timer rule + +bool DeleteTimerRule::IsVisible(const CFileItem& item) const +{ + const std::shared_ptr<CPVRTimerInfoTag> timer(GetTimerInfoTagFromItem(item)); + if (timer && !URIUtils::PathEquals(item.GetPath(), CPVRTimersPath::PATH_ADDTIMER)) + { + const std::shared_ptr<CPVRTimerInfoTag> parentTimer( + CServiceBroker::GetPVRManager().Timers()->GetTimerRule(timer)); + if (parentTimer) + return parentTimer->GetTimerType()->AllowsDelete(); + } + + return false; +} + +bool DeleteTimerRule::Execute(const CFileItemPtr& item) const +{ + auto& timers = CServiceBroker::GetPVRManager().Get<PVR::GUI::Timers>(); + const std::shared_ptr<CFileItem> parentTimer = timers.GetTimerRule(*item); + if (parentTimer) + return timers.DeleteTimerRule(*parentTimer); + + return false; +} + +/////////////////////////////////////////////////////////////////////////////// +// Edit / View timer + +std::string EditTimer::GetLabel(const CFileItem& item) const +{ + const std::shared_ptr<CPVRTimerInfoTag> timer(GetTimerInfoTagFromItem(item)); + if (timer) + { + const std::shared_ptr<CPVRTimerType> timerType = timer->GetTimerType(); + if (item.GetEPGInfoTag()) + { + if (timerType->IsReminder()) + return g_localizeStrings.Get(timerType->IsReadOnly() ? 829 /* View reminder */ + : 830); /* Edit reminder */ + else + return g_localizeStrings.Get(timerType->IsReadOnly() ? 19241 /* View timer */ + : 19242); /* Edit timer */ + } + else + return g_localizeStrings.Get(timerType->IsReadOnly() ? 21483 : 21450); /* View/Edit */ + } + return g_localizeStrings.Get(19241); /* View timer */ +} + +bool EditTimer::IsVisible(const CFileItem& item) const +{ + const std::shared_ptr<CPVRTimerInfoTag> timer(GetTimerInfoTagFromItem(item)); + return timer && (!item.GetEPGInfoTag() || + !URIUtils::PathEquals(item.GetPath(), CPVRTimersPath::PATH_ADDTIMER)); +} + +bool EditTimer::Execute(const CFileItemPtr& item) const +{ + return CServiceBroker::GetPVRManager().Get<PVR::GUI::Timers>().EditTimer(*item); +} + +/////////////////////////////////////////////////////////////////////////////// +// Delete timer + +std::string DeleteTimer::GetLabel(const CFileItem& item) const +{ + if (item.GetPVRTimerInfoTag()) + return g_localizeStrings.Get(117); /* Delete */ + + const std::shared_ptr<CPVREpgInfoTag> epg = item.GetEPGInfoTag(); + if (epg) + { + const std::shared_ptr<CPVRTimerInfoTag> timer = + CServiceBroker::GetPVRManager().Timers()->GetTimerForEpgTag(epg); + if (timer && timer->IsReminder()) + return g_localizeStrings.Get(827); /* Delete reminder */ + } + return g_localizeStrings.Get(19060); /* Delete timer */ +} + +bool DeleteTimer::IsVisible(const CFileItem& item) const +{ + const std::shared_ptr<CPVRTimerInfoTag> timer(GetTimerInfoTagFromItem(item)); + if (timer && + (!item.GetEPGInfoTag() || + !URIUtils::PathEquals(item.GetPath(), CPVRTimersPath::PATH_ADDTIMER)) && + !timer->IsRecording()) + return timer->GetTimerType()->AllowsDelete(); + + return false; +} + +bool DeleteTimer::Execute(const CFileItemPtr& item) const +{ + return CServiceBroker::GetPVRManager().Get<PVR::GUI::Timers>().DeleteTimer(*item); +} + +/////////////////////////////////////////////////////////////////////////////// +// PVR Client menu hook + +std::string PVRClientMenuHook::GetLabel(const CFileItem& item) const +{ + return m_hook.GetLabel(); +} + +bool PVRClientMenuHook::IsVisible(const CFileItem& item) const +{ + const std::shared_ptr<CPVRClient> client = CServiceBroker::GetPVRManager().GetClient(item); + if (!client || m_hook.GetAddonId() != client->ID()) + return false; + + if (m_hook.IsAllHook()) + return !item.m_bIsFolder && + !URIUtils::PathEquals(item.GetPath(), CPVRTimersPath::PATH_ADDTIMER); + else if (m_hook.IsEpgHook()) + return item.IsEPG(); + else if (m_hook.IsChannelHook()) + return item.IsPVRChannel(); + else if (m_hook.IsDeletedRecordingHook()) + return item.IsDeletedPVRRecording(); + else if (m_hook.IsRecordingHook()) + return item.IsUsablePVRRecording(); + else if (m_hook.IsTimerHook()) + return item.IsPVRTimer(); + else + return false; +} + +bool PVRClientMenuHook::Execute(const CFileItemPtr& item) const +{ + const std::shared_ptr<CPVRClient> client = CServiceBroker::GetPVRManager().GetClient(*item); + if (!client) + return false; + + if (item->IsEPG()) + return client->CallEpgTagMenuHook(m_hook, item->GetEPGInfoTag()) == PVR_ERROR_NO_ERROR; + else if (item->IsPVRChannel()) + return client->CallChannelMenuHook(m_hook, item->GetPVRChannelInfoTag()) == PVR_ERROR_NO_ERROR; + else if (item->IsDeletedPVRRecording()) + return client->CallRecordingMenuHook(m_hook, item->GetPVRRecordingInfoTag(), true) == + PVR_ERROR_NO_ERROR; + else if (item->IsUsablePVRRecording()) + return client->CallRecordingMenuHook(m_hook, item->GetPVRRecordingInfoTag(), false) == + PVR_ERROR_NO_ERROR; + else if (item->IsPVRTimer()) + return client->CallTimerMenuHook(m_hook, item->GetPVRTimerInfoTag()) == PVR_ERROR_NO_ERROR; + else + return false; +} + +/////////////////////////////////////////////////////////////////////////////// +// Execute saved search + +bool ExecuteSearch::IsVisible(const CFileItem& item) const +{ + return item.HasEPGSearchFilter(); +} + +bool ExecuteSearch::Execute(const std::shared_ptr<CFileItem>& item) const +{ + return CServiceBroker::GetPVRManager().Get<PVR::GUI::EPG>().ExecuteSavedSearch(*item); +} + +/////////////////////////////////////////////////////////////////////////////// +// Edit saved search + +bool EditSearch::IsVisible(const CFileItem& item) const +{ + return item.HasEPGSearchFilter(); +} + +bool EditSearch::Execute(const std::shared_ptr<CFileItem>& item) const +{ + return CServiceBroker::GetPVRManager().Get<PVR::GUI::EPG>().EditSavedSearch(*item); +} + +/////////////////////////////////////////////////////////////////////////////// +// Rename saved search + +bool RenameSearch::IsVisible(const CFileItem& item) const +{ + return item.HasEPGSearchFilter(); +} + +bool RenameSearch::Execute(const std::shared_ptr<CFileItem>& item) const +{ + return CServiceBroker::GetPVRManager().Get<PVR::GUI::EPG>().RenameSavedSearch(*item); +} + +/////////////////////////////////////////////////////////////////////////////// +// Delete saved search + +bool DeleteSearch::IsVisible(const CFileItem& item) const +{ + return item.HasEPGSearchFilter(); +} + +bool DeleteSearch::Execute(const std::shared_ptr<CFileItem>& item) const +{ + return CServiceBroker::GetPVRManager().Get<PVR::GUI::EPG>().DeleteSavedSearch(*item); +} + +} // namespace CONTEXTMENUITEM + +CPVRContextMenuManager& CPVRContextMenuManager::GetInstance() +{ + static CPVRContextMenuManager instance; + return instance; +} + +CPVRContextMenuManager::CPVRContextMenuManager() + : m_items({ + std::make_shared<CONTEXTMENUITEM::PlayEpgTag>(19190), /* Play programme */ + std::make_shared<CONTEXTMENUITEM::PlayRecording>(19687), /* Play recording */ + std::make_shared<CONTEXTMENUITEM::ShowInformation>(), + std::make_shared<CONTEXTMENUITEM::ShowChannelGuide>(19686), /* Channel guide */ + std::make_shared<CONTEXTMENUITEM::FindSimilar>(19003), /* Find similar */ + std::make_shared<CONTEXTMENUITEM::ToggleTimerState>(), + std::make_shared<CONTEXTMENUITEM::AddTimerRule>(19061), /* Add timer */ + std::make_shared<CONTEXTMENUITEM::EditTimerRule>(), + std::make_shared<CONTEXTMENUITEM::DeleteTimerRule>(19295), /* Delete timer rule */ + std::make_shared<CONTEXTMENUITEM::EditTimer>(), + std::make_shared<CONTEXTMENUITEM::DeleteTimer>(), + std::make_shared<CONTEXTMENUITEM::StartRecording>(264), /* Record */ + std::make_shared<CONTEXTMENUITEM::StopRecording>(19059), /* Stop recording */ + std::make_shared<CONTEXTMENUITEM::EditRecording>(21450), /* Edit */ + std::make_shared<CONTEXTMENUITEM::DeleteRecording>(), + std::make_shared<CONTEXTMENUITEM::UndeleteRecording>(19290), /* Undelete */ + std::make_shared<CONTEXTMENUITEM::DeleteWatchedRecordings>(19327), /* Delete watched */ + std::make_shared<CONTEXTMENUITEM::AddReminder>(826), /* Set reminder */ + std::make_shared<CONTEXTMENUITEM::ExecuteSearch>(137), /* Search */ + std::make_shared<CONTEXTMENUITEM::EditSearch>(21450), /* Edit */ + std::make_shared<CONTEXTMENUITEM::RenameSearch>(118), /* Rename */ + std::make_shared<CONTEXTMENUITEM::DeleteSearch>(117), /* Delete */ + }) +{ +} + +void CPVRContextMenuManager::AddMenuHook(const CPVRClientMenuHook& hook) +{ + if (hook.IsSettingsHook()) + return; // settings hooks are not handled using context menus + + const auto item = std::make_shared<CONTEXTMENUITEM::PVRClientMenuHook>(hook); + m_items.emplace_back(item); + m_events.Publish(PVRContextMenuEvent(PVRContextMenuEventAction::ADD_ITEM, item)); +} + +void CPVRContextMenuManager::RemoveMenuHook(const CPVRClientMenuHook& hook) +{ + if (hook.IsSettingsHook()) + return; // settings hooks are not handled using context menus + + for (auto it = m_items.begin(); it < m_items.end(); ++it) + { + const CONTEXTMENUITEM::PVRClientMenuHook* cmh = + dynamic_cast<const CONTEXTMENUITEM::PVRClientMenuHook*>((*it).get()); + if (cmh && cmh->GetHook() == hook) + { + m_events.Publish(PVRContextMenuEvent(PVRContextMenuEventAction::REMOVE_ITEM, *it)); + m_items.erase(it); + return; + } + } +} + +} // namespace PVR |