summaryrefslogtreecommitdiffstats
path: root/xbmc/pvr/windows/GUIWindowPVRChannels.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'xbmc/pvr/windows/GUIWindowPVRChannels.cpp')
-rw-r--r--xbmc/pvr/windows/GUIWindowPVRChannels.cpp414
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());
+}