Merge pull request #25614 from garbear/show-version
[xbmc.git] / xbmc / pvr / dialogs / GUIDialogPVRChannelsOSD.cpp
blob36ed331683f7a8881efee5625bc85789c6fed049
1 /*
2 * Copyright (C) 2012-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include "GUIDialogPVRChannelsOSD.h"
11 #include "FileItem.h"
12 #include "FileItemList.h"
13 #include "GUIInfoManager.h"
14 #include "ServiceBroker.h"
15 #include "guilib/GUIComponent.h"
16 #include "guilib/GUIMessage.h"
17 #include "input/actions/Action.h"
18 #include "input/actions/ActionIDs.h"
19 #include "messaging/ApplicationMessenger.h"
20 #include "pvr/PVRManager.h"
21 #include "pvr/PVRPlaybackState.h"
22 #include "pvr/channels/PVRChannel.h"
23 #include "pvr/channels/PVRChannelGroupMember.h"
24 #include "pvr/channels/PVRChannelGroups.h"
25 #include "pvr/channels/PVRChannelGroupsContainer.h"
26 #include "pvr/epg/EpgContainer.h"
27 #include "pvr/guilib/PVRGUIActionsChannels.h"
28 #include "pvr/guilib/PVRGUIActionsPlayback.h"
29 #include "settings/Settings.h"
30 #include "settings/SettingsComponent.h"
32 #include <memory>
33 #include <string>
34 #include <vector>
36 using namespace PVR;
38 using namespace std::chrono_literals;
40 #define MAX_INVALIDATION_FREQUENCY 2000ms // limit to one invalidation per X milliseconds
42 CGUIDialogPVRChannelsOSD::CGUIDialogPVRChannelsOSD()
43 : CGUIDialogPVRItemsViewBase(WINDOW_DIALOG_PVR_OSD_CHANNELS, "DialogPVRChannelsOSD.xml")
45 CServiceBroker::GetPVRManager().Get<PVR::GUI::Channels>().RegisterChannelNumberInputHandler(this);
48 CGUIDialogPVRChannelsOSD::~CGUIDialogPVRChannelsOSD()
50 auto& mgr = CServiceBroker::GetPVRManager();
51 mgr.Events().Unsubscribe(this);
52 mgr.Get<PVR::GUI::Channels>().DeregisterChannelNumberInputHandler(this);
55 bool CGUIDialogPVRChannelsOSD::OnMessage(CGUIMessage& message)
57 if (message.GetMessage() == GUI_MSG_REFRESH_LIST)
59 switch (static_cast<PVREvent>(message.GetParam1()))
61 case PVREvent::CurrentItem:
62 m_viewControl.SetItems(*m_vecItems);
63 return true;
65 case PVREvent::Epg:
66 case PVREvent::EpgContainer:
67 case PVREvent::EpgActiveItem:
68 if (IsActive())
69 SetInvalid();
70 return true;
72 default:
73 break;
76 return CGUIDialogPVRItemsViewBase::OnMessage(message);
79 void CGUIDialogPVRChannelsOSD::OnInitWindow()
81 if (!CServiceBroker::GetPVRManager().PlaybackState()->IsPlayingTV() &&
82 !CServiceBroker::GetPVRManager().PlaybackState()->IsPlayingRadio())
84 Close();
85 return;
88 Init();
89 Update();
90 CGUIDialogPVRItemsViewBase::OnInitWindow();
93 void CGUIDialogPVRChannelsOSD::OnDeinitWindow(int nextWindowID)
95 if (m_group)
97 CServiceBroker::GetPVRManager().Get<PVR::GUI::Channels>().SetSelectedChannelPath(
98 m_group->IsRadio(), m_viewControl.GetSelectedItemPath());
100 // next OnInitWindow will set the group which is then selected
101 m_group.reset();
104 CGUIDialogPVRItemsViewBase::OnDeinitWindow(nextWindowID);
107 bool CGUIDialogPVRChannelsOSD::OnAction(const CAction& action)
109 switch (action.GetID())
111 case ACTION_SELECT_ITEM:
112 case ACTION_MOUSE_LEFT_CLICK:
114 // If direct channel number input is active, select the entered channel.
115 if (CServiceBroker::GetPVRManager()
116 .Get<PVR::GUI::Channels>()
117 .GetChannelNumberInputHandler()
118 .CheckInputAndExecuteAction())
119 return true;
121 if (m_viewControl.HasControl(GetFocusedControlID()))
123 // Switch to channel
124 GotoChannel(m_viewControl.GetSelectedItem());
125 return true;
127 break;
129 case ACTION_PREVIOUS_CHANNELGROUP:
130 case ACTION_NEXT_CHANNELGROUP:
132 // save control states and currently selected item of group
133 SaveControlStates();
135 // switch to next or previous group
136 const std::shared_ptr<const CPVRChannelGroups> groups{
137 CServiceBroker::GetPVRManager().ChannelGroups()->Get(m_group->IsRadio())};
138 const std::shared_ptr<CPVRChannelGroup> nextGroup = action.GetID() == ACTION_NEXT_CHANNELGROUP
139 ? groups->GetNextGroup(*m_group)
140 : groups->GetPreviousGroup(*m_group);
141 CServiceBroker::GetPVRManager().PlaybackState()->SetActiveChannelGroup(nextGroup);
142 m_group = nextGroup;
143 Init();
144 Update();
146 // restore control states and previously selected item of group
147 RestoreControlStates();
148 return true;
150 case REMOTE_0:
151 case REMOTE_1:
152 case REMOTE_2:
153 case REMOTE_3:
154 case REMOTE_4:
155 case REMOTE_5:
156 case REMOTE_6:
157 case REMOTE_7:
158 case REMOTE_8:
159 case REMOTE_9:
161 AppendChannelNumberCharacter(static_cast<char>(action.GetID() - REMOTE_0) + '0');
162 return true;
164 case ACTION_CHANNEL_NUMBER_SEP:
166 AppendChannelNumberCharacter(CPVRChannelNumber::SEPARATOR);
167 return true;
169 default:
170 break;
173 return CGUIDialogPVRItemsViewBase::OnAction(action);
176 void CGUIDialogPVRChannelsOSD::Update()
178 CPVRManager& pvrMgr = CServiceBroker::GetPVRManager();
179 pvrMgr.Events().Subscribe(this, &CGUIDialogPVRChannelsOSD::Notify);
181 const std::shared_ptr<const CPVRChannel> channel = pvrMgr.PlaybackState()->GetPlayingChannel();
182 if (channel)
184 const std::shared_ptr<CPVRChannelGroup> group =
185 pvrMgr.PlaybackState()->GetActiveChannelGroup(channel->IsRadio());
186 if (group)
188 const std::vector<std::shared_ptr<CPVRChannelGroupMember>> groupMembers =
189 group->GetMembers(CPVRChannelGroup::Include::ONLY_VISIBLE);
190 for (const auto& groupMember : groupMembers)
192 m_vecItems->Add(std::make_shared<CFileItem>(groupMember));
195 m_viewControl.SetItems(*m_vecItems);
197 if (!m_group)
199 m_group = group;
200 m_viewControl.SetSelectedItem(
201 pvrMgr.Get<PVR::GUI::Channels>().GetSelectedChannelPath(channel->IsRadio()));
202 SaveSelectedItemPath(group->GroupID());
208 void CGUIDialogPVRChannelsOSD::SetInvalid()
210 if (m_refreshTimeout.IsTimePast())
212 for (const auto& item : *m_vecItems)
213 item->SetInvalid();
215 CGUIDialogPVRItemsViewBase::SetInvalid();
216 m_refreshTimeout.Set(MAX_INVALIDATION_FREQUENCY);
220 void CGUIDialogPVRChannelsOSD::SaveControlStates()
222 CGUIDialogPVRItemsViewBase::SaveControlStates();
224 if (m_group)
225 SaveSelectedItemPath(m_group->GroupID());
228 void CGUIDialogPVRChannelsOSD::RestoreControlStates()
230 CGUIDialogPVRItemsViewBase::RestoreControlStates();
232 if (m_group)
234 const std::string path = GetLastSelectedItemPath(m_group->GroupID());
235 if (path.empty())
236 m_viewControl.SetSelectedItem(0);
237 else
238 m_viewControl.SetSelectedItem(path);
242 void CGUIDialogPVRChannelsOSD::GotoChannel(int iItem)
244 if (iItem < 0 || iItem >= m_vecItems->Size())
245 return;
247 // Preserve the item before closing self, because this will clear m_vecItems
248 const std::shared_ptr<CFileItem> item = m_vecItems->Get(iItem);
250 if (CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(
251 CSettings::SETTING_PVRMENU_CLOSECHANNELOSDONSWITCH))
252 Close();
254 CServiceBroker::GetPVRManager().Get<PVR::GUI::Playback>().SwitchToChannel(
255 *item, true /* bCheckResume */);
258 void CGUIDialogPVRChannelsOSD::Notify(const PVREvent& event)
260 const CGUIMessage m(GUI_MSG_REFRESH_LIST, GetID(), 0, static_cast<int>(event));
261 CServiceBroker::GetAppMessenger()->SendGUIMessage(m);
264 void CGUIDialogPVRChannelsOSD::SaveSelectedItemPath(int iGroupID)
266 m_groupSelectedItemPaths[iGroupID] = m_viewControl.GetSelectedItemPath();
269 std::string CGUIDialogPVRChannelsOSD::GetLastSelectedItemPath(int iGroupID) const
271 const auto it = m_groupSelectedItemPaths.find(iGroupID);
272 if (it != m_groupSelectedItemPaths.end())
273 return it->second;
275 return std::string();
278 void CGUIDialogPVRChannelsOSD::GetChannelNumbers(std::vector<std::string>& channelNumbers)
280 if (m_group)
281 m_group->GetChannelNumbers(channelNumbers);
284 void CGUIDialogPVRChannelsOSD::OnInputDone()
286 const CPVRChannelNumber channelNumber = GetChannelNumber();
287 if (channelNumber.IsValid())
289 int itemIndex = 0;
290 for (const CFileItemPtr& channel : *m_vecItems)
292 if (channel->GetPVRChannelGroupMemberInfoTag()->ChannelNumber() == channelNumber)
294 m_viewControl.SetSelectedItem(itemIndex);
295 return;
297 ++itemIndex;