diff options
Diffstat (limited to 'xbmc/pvr/windows/GUIWindowPVRChannels.cpp')
-rw-r--r-- | xbmc/pvr/windows/GUIWindowPVRChannels.cpp | 414 |
1 files changed, 414 insertions, 0 deletions
diff --git a/xbmc/pvr/windows/GUIWindowPVRChannels.cpp b/xbmc/pvr/windows/GUIWindowPVRChannels.cpp new file mode 100644 index 0000000..2b476f7 --- /dev/null +++ b/xbmc/pvr/windows/GUIWindowPVRChannels.cpp @@ -0,0 +1,414 @@ +/* + * Copyright (C) 2012-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 "GUIWindowPVRChannels.h" + +#include "FileItem.h" +#include "GUIInfoManager.h" +#include "ServiceBroker.h" +#include "dialogs/GUIDialogContextMenu.h" +#include "dialogs/GUIDialogKaiToast.h" +#include "dialogs/GUIDialogYesNo.h" +#include "guilib/GUIComponent.h" +#include "guilib/GUIKeyboardFactory.h" +#include "guilib/GUIMessage.h" +#include "guilib/GUIRadioButtonControl.h" +#include "guilib/GUIWindowManager.h" +#include "guilib/LocalizeStrings.h" +#include "input/Key.h" +#include "input/actions/Action.h" +#include "pvr/PVRManager.h" +#include "pvr/channels/PVRChannel.h" +#include "pvr/channels/PVRChannelGroup.h" +#include "pvr/channels/PVRChannelGroupMember.h" +#include "pvr/channels/PVRChannelGroupsContainer.h" +#include "pvr/channels/PVRChannelsPath.h" +#include "pvr/dialogs/GUIDialogPVRChannelManager.h" +#include "pvr/dialogs/GUIDialogPVRGroupManager.h" +#include "pvr/epg/Epg.h" +#include "pvr/epg/EpgContainer.h" +#include "pvr/guilib/PVRGUIActionsChannels.h" +#include "pvr/guilib/PVRGUIActionsEPG.h" +#include "pvr/guilib/PVRGUIActionsPlayback.h" +#include "utils/StringUtils.h" +#include "utils/Variant.h" + +#include <mutex> +#include <string> + +using namespace PVR; + +CGUIWindowPVRChannelsBase::CGUIWindowPVRChannelsBase(bool bRadio, + int id, + const std::string& xmlFile) + : CGUIWindowPVRBase(bRadio, id, xmlFile), m_bShowHiddenChannels(false) +{ + CServiceBroker::GetPVRManager().Get<PVR::GUI::Channels>().RegisterChannelNumberInputHandler(this); +} + +CGUIWindowPVRChannelsBase::~CGUIWindowPVRChannelsBase() +{ + CServiceBroker::GetPVRManager().Get<PVR::GUI::Channels>().DeregisterChannelNumberInputHandler( + this); +} + +std::string CGUIWindowPVRChannelsBase::GetRootPath() const +{ + //! @todo Would it make sense to change GetRootPath() declaration in CGUIMediaWindow + //! to be non-const to get rid of the const_cast's here? + + CGUIWindowPVRChannelsBase* pThis = const_cast<CGUIWindowPVRChannelsBase*>(this); + if (pThis->InitChannelGroup()) + return pThis->GetDirectoryPath(); + + return CGUIWindowPVRBase::GetRootPath(); +} + +void CGUIWindowPVRChannelsBase::GetContextButtons(int itemNumber, CContextButtons& buttons) +{ + // Add parent buttons before the Manage button + CGUIWindowPVRBase::GetContextButtons(itemNumber, buttons); + + buttons.Add(CONTEXT_BUTTON_EDIT, 16106); /* Manage... */ +} + +bool CGUIWindowPVRChannelsBase::OnContextButton(int itemNumber, CONTEXT_BUTTON button) +{ + if (itemNumber < 0 || itemNumber >= m_vecItems->Size()) + return false; + + return OnContextButtonManage(m_vecItems->Get(itemNumber), button) || + CGUIMediaWindow::OnContextButton(itemNumber, button); +} + +bool CGUIWindowPVRChannelsBase::Update(const std::string& strDirectory, + bool updateFilterPath /* = true */) +{ + bool bReturn = CGUIWindowPVRBase::Update(strDirectory); + + if (bReturn) + { + std::unique_lock<CCriticalSection> lock(m_critSection); + /* empty list for hidden channels */ + if (m_vecItems->GetObjectCount() == 0 && m_bShowHiddenChannels) + { + /* show the visible channels instead */ + m_bShowHiddenChannels = false; + lock.unlock(); + Update(GetDirectoryPath()); + } + } + return bReturn; +} + +void CGUIWindowPVRChannelsBase::UpdateButtons() +{ + CGUIRadioButtonControl* btnShowHidden = + static_cast<CGUIRadioButtonControl*>(GetControl(CONTROL_BTNSHOWHIDDEN)); + if (btnShowHidden) + { + btnShowHidden->SetVisible(CServiceBroker::GetPVRManager() + .ChannelGroups() + ->GetGroupAll(m_bRadio) + ->GetNumHiddenChannels() > 0); + btnShowHidden->SetSelected(m_bShowHiddenChannels); + } + + CGUIWindowPVRBase::UpdateButtons(); + SET_CONTROL_LABEL(CONTROL_LABEL_HEADER1, m_bShowHiddenChannels ? g_localizeStrings.Get(19022) + : GetChannelGroup()->GroupName()); +} + +bool CGUIWindowPVRChannelsBase::OnAction(const CAction& action) +{ + switch (action.GetID()) + { + case REMOTE_0: + case REMOTE_1: + case REMOTE_2: + case REMOTE_3: + case REMOTE_4: + case REMOTE_5: + case REMOTE_6: + case REMOTE_7: + case REMOTE_8: + case REMOTE_9: + AppendChannelNumberCharacter(static_cast<char>(action.GetID() - REMOTE_0) + '0'); + return true; + + case ACTION_CHANNEL_NUMBER_SEP: + AppendChannelNumberCharacter(CPVRChannelNumber::SEPARATOR); + return true; + } + + return CGUIWindowPVRBase::OnAction(action); +} + +bool CGUIWindowPVRChannelsBase::OnMessage(CGUIMessage& message) +{ + bool bReturn = false; + switch (message.GetMessage()) + { + case GUI_MSG_WINDOW_INIT: + { + const CPVRChannelsPath path(message.GetStringParam(0)); + if (path.IsValid() && path.IsChannelGroup()) + { + // if a path to a channel group is given we must init + // that group instead of last played/selected group + m_channelGroupPath = message.GetStringParam(0); + } + break; + } + + case GUI_MSG_CLICKED: + if (message.GetSenderId() == m_viewControl.GetCurrentControl()) + { + if (message.GetParam1() == ACTION_SELECT_ITEM || + message.GetParam1() == ACTION_MOUSE_LEFT_CLICK) + { + // If direct channel number input is active, select the entered channel. + if (CServiceBroker::GetPVRManager() + .Get<PVR::GUI::Channels>() + .GetChannelNumberInputHandler() + .CheckInputAndExecuteAction()) + { + bReturn = true; + break; + } + } + + int iItem = m_viewControl.GetSelectedItem(); + if (iItem >= 0 && iItem < m_vecItems->Size()) + { + bReturn = true; + switch (message.GetParam1()) + { + case ACTION_SELECT_ITEM: + case ACTION_MOUSE_LEFT_CLICK: + case ACTION_PLAYER_PLAY: + CServiceBroker::GetPVRManager().Get<PVR::GUI::Playback>().SwitchToChannel( + *(m_vecItems->Get(iItem)), true); + break; + case ACTION_SHOW_INFO: + CServiceBroker::GetPVRManager().Get<PVR::GUI::EPG>().ShowEPGInfo( + *(m_vecItems->Get(iItem))); + break; + case ACTION_DELETE_ITEM: + CServiceBroker::GetPVRManager().Get<PVR::GUI::Channels>().HideChannel( + *(m_vecItems->Get(iItem))); + break; + case ACTION_CONTEXT_MENU: + case ACTION_MOUSE_RIGHT_CLICK: + OnPopupMenu(iItem); + break; + default: + bReturn = false; + break; + } + } + } + else if (message.GetSenderId() == CONTROL_BTNSHOWHIDDEN) + { + CGUIRadioButtonControl* radioButton = + static_cast<CGUIRadioButtonControl*>(GetControl(CONTROL_BTNSHOWHIDDEN)); + if (radioButton) + { + m_bShowHiddenChannels = radioButton->IsSelected(); + Update(GetDirectoryPath()); + } + + bReturn = true; + } + else if (message.GetSenderId() == CONTROL_BTNFILTERCHANNELS) + { + std::string filter = GetProperty("filter").asString(); + CGUIKeyboardFactory::ShowAndGetFilter(filter, false); + OnFilterItems(filter); + UpdateButtons(); + + bReturn = true; + } + break; + + case GUI_MSG_REFRESH_LIST: + { + switch (static_cast<PVREvent>(message.GetParam1())) + { + case PVREvent::ChannelGroup: + case PVREvent::CurrentItem: + case PVREvent::Epg: + case PVREvent::EpgActiveItem: + case PVREvent::EpgContainer: + case PVREvent::RecordingsInvalidated: + case PVREvent::Timers: + SetInvalid(); + break; + + case PVREvent::ChannelGroupInvalidated: + Refresh(true); + break; + + default: + break; + } + break; + } + } + + return bReturn || CGUIWindowPVRBase::OnMessage(message); +} + +bool CGUIWindowPVRChannelsBase::OnContextButtonManage(const CFileItemPtr& item, + CONTEXT_BUTTON button) +{ + bool bReturn = false; + + if (button == CONTEXT_BUTTON_EDIT) + { + // Create context sub menu + CContextButtons buttons; + buttons.Add(CONTEXT_BUTTON_GROUP_MANAGER, 19048); + buttons.Add(CONTEXT_BUTTON_CHANNEL_MANAGER, 19199); + buttons.Add(CONTEXT_BUTTON_UPDATE_EPG, 19251); + + // Get the response + int choice = CGUIDialogContextMenu::ShowAndGetChoice(buttons); + if (choice >= 0) + { + switch (static_cast<CONTEXT_BUTTON>(choice)) + { + case CONTEXT_BUTTON_GROUP_MANAGER: + ShowGroupManager(); + break; + case CONTEXT_BUTTON_CHANNEL_MANAGER: + ShowChannelManager(); + break; + case CONTEXT_BUTTON_UPDATE_EPG: + UpdateEpg(item); + break; + default: + break; + } + + // Refresh the list in case anything was changed + Refresh(true); + } + + bReturn = true; + } + + return bReturn; +} + +void CGUIWindowPVRChannelsBase::UpdateEpg(const CFileItemPtr& item) +{ + const std::shared_ptr<CPVRChannel> channel(item->GetPVRChannelInfoTag()); + + if (!CGUIDialogYesNo::ShowAndGetInput( + CVariant{19251}, // "Update guide information" + CVariant{19252}, // "Schedule guide update for this channel?" + CVariant{""}, CVariant{channel->ChannelName()})) + return; + + const std::shared_ptr<CPVREpg> epg = channel->GetEPG(); + if (epg) + { + epg->ForceUpdate(); + + const std::string strMessage = + StringUtils::Format("{}: '{}'", + g_localizeStrings.Get(19253), // "Guide update scheduled for channel" + channel->ChannelName()); + CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, + g_localizeStrings.Get(19166), // "PVR information" + strMessage); + } + else + { + const std::string strMessage = + StringUtils::Format("{}: '{}'", + g_localizeStrings.Get(19254), // "Guide update failed for channel" + channel->ChannelName()); + CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error, + g_localizeStrings.Get(19166), // "PVR information" + strMessage); + } +} + +void CGUIWindowPVRChannelsBase::ShowChannelManager() +{ + CGUIDialogPVRChannelManager* dialog = + CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogPVRChannelManager>( + WINDOW_DIALOG_PVR_CHANNEL_MANAGER); + if (!dialog) + return; + + dialog->SetRadio(m_bRadio); + + const int iItem = m_viewControl.GetSelectedItem(); + dialog->Open(iItem >= 0 && iItem < m_vecItems->Size() ? m_vecItems->Get(iItem) : nullptr); +} + +void CGUIWindowPVRChannelsBase::ShowGroupManager() +{ + /* Load group manager dialog */ + CGUIDialogPVRGroupManager* pDlgInfo = + CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogPVRGroupManager>( + WINDOW_DIALOG_PVR_GROUP_MANAGER); + if (!pDlgInfo) + return; + + pDlgInfo->SetRadio(m_bRadio); + pDlgInfo->Open(); +} + +void CGUIWindowPVRChannelsBase::OnInputDone() +{ + const CPVRChannelNumber channelNumber = GetChannelNumber(); + if (channelNumber.IsValid()) + { + int itemIndex = 0; + for (const CFileItemPtr& channel : *m_vecItems) + { + if (channel->GetPVRChannelGroupMemberInfoTag()->ChannelNumber() == channelNumber) + { + m_viewControl.SetSelectedItem(itemIndex); + return; + } + ++itemIndex; + } + } +} + +void CGUIWindowPVRChannelsBase::GetChannelNumbers(std::vector<std::string>& channelNumbers) +{ + const std::shared_ptr<CPVRChannelGroup> group = GetChannelGroup(); + if (group) + group->GetChannelNumbers(channelNumbers); +} + +CGUIWindowPVRTVChannels::CGUIWindowPVRTVChannels() + : CGUIWindowPVRChannelsBase(false, WINDOW_TV_CHANNELS, "MyPVRChannels.xml") +{ +} + +std::string CGUIWindowPVRTVChannels::GetDirectoryPath() +{ + return CPVRChannelsPath(false, m_bShowHiddenChannels, GetChannelGroup()->GroupName()); +} + +CGUIWindowPVRRadioChannels::CGUIWindowPVRRadioChannels() + : CGUIWindowPVRChannelsBase(true, WINDOW_RADIO_CHANNELS, "MyPVRChannels.xml") +{ +} + +std::string CGUIWindowPVRRadioChannels::GetDirectoryPath() +{ + return CPVRChannelsPath(true, m_bShowHiddenChannels, GetChannelGroup()->GroupName()); +} |