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.
9 #include "GUIDialogPVRChannelsOSD.h"
12 #include "GUIInfoManager.h"
13 #include "ServiceBroker.h"
14 #include "guilib/GUIComponent.h"
15 #include "guilib/GUIMessage.h"
16 #include "input/actions/Action.h"
17 #include "input/actions/ActionIDs.h"
18 #include "messaging/ApplicationMessenger.h"
19 #include "pvr/PVRManager.h"
20 #include "pvr/PVRPlaybackState.h"
21 #include "pvr/channels/PVRChannel.h"
22 #include "pvr/channels/PVRChannelGroupMember.h"
23 #include "pvr/channels/PVRChannelGroups.h"
24 #include "pvr/channels/PVRChannelGroupsContainer.h"
25 #include "pvr/epg/EpgContainer.h"
26 #include "pvr/guilib/PVRGUIActionsChannels.h"
27 #include "pvr/guilib/PVRGUIActionsPlayback.h"
28 #include "settings/Settings.h"
29 #include "settings/SettingsComponent.h"
37 using namespace std::chrono_literals
;
39 #define MAX_INVALIDATION_FREQUENCY 2000ms // limit to one invalidation per X milliseconds
41 CGUIDialogPVRChannelsOSD::CGUIDialogPVRChannelsOSD()
42 : CGUIDialogPVRItemsViewBase(WINDOW_DIALOG_PVR_OSD_CHANNELS
, "DialogPVRChannelsOSD.xml")
44 CServiceBroker::GetPVRManager().Get
<PVR::GUI::Channels
>().RegisterChannelNumberInputHandler(this);
47 CGUIDialogPVRChannelsOSD::~CGUIDialogPVRChannelsOSD()
49 auto& mgr
= CServiceBroker::GetPVRManager();
50 mgr
.Events().Unsubscribe(this);
51 mgr
.Get
<PVR::GUI::Channels
>().DeregisterChannelNumberInputHandler(this);
54 bool CGUIDialogPVRChannelsOSD::OnMessage(CGUIMessage
& message
)
56 if (message
.GetMessage() == GUI_MSG_REFRESH_LIST
)
58 switch (static_cast<PVREvent
>(message
.GetParam1()))
60 case PVREvent::CurrentItem
:
61 m_viewControl
.SetItems(*m_vecItems
);
65 case PVREvent::EpgContainer
:
66 case PVREvent::EpgActiveItem
:
75 return CGUIDialogPVRItemsViewBase::OnMessage(message
);
78 void CGUIDialogPVRChannelsOSD::OnInitWindow()
80 if (!CServiceBroker::GetPVRManager().PlaybackState()->IsPlayingTV() &&
81 !CServiceBroker::GetPVRManager().PlaybackState()->IsPlayingRadio())
89 CGUIDialogPVRItemsViewBase::OnInitWindow();
92 void CGUIDialogPVRChannelsOSD::OnDeinitWindow(int nextWindowID
)
96 CServiceBroker::GetPVRManager().Get
<PVR::GUI::Channels
>().SetSelectedChannelPath(
97 m_group
->IsRadio(), m_viewControl
.GetSelectedItemPath());
99 // next OnInitWindow will set the group which is then selected
103 CGUIDialogPVRItemsViewBase::OnDeinitWindow(nextWindowID
);
106 bool CGUIDialogPVRChannelsOSD::OnAction(const CAction
& action
)
108 switch (action
.GetID())
110 case ACTION_SELECT_ITEM
:
111 case ACTION_MOUSE_LEFT_CLICK
:
113 // If direct channel number input is active, select the entered channel.
114 if (CServiceBroker::GetPVRManager()
115 .Get
<PVR::GUI::Channels
>()
116 .GetChannelNumberInputHandler()
117 .CheckInputAndExecuteAction())
120 if (m_viewControl
.HasControl(GetFocusedControlID()))
123 GotoChannel(m_viewControl
.GetSelectedItem());
128 case ACTION_PREVIOUS_CHANNELGROUP
:
129 case ACTION_NEXT_CHANNELGROUP
:
131 // save control states and currently selected item of group
134 // switch to next or previous group
135 const CPVRChannelGroups
* groups
=
136 CServiceBroker::GetPVRManager().ChannelGroups()->Get(m_group
->IsRadio());
137 const std::shared_ptr
<CPVRChannelGroup
> nextGroup
= action
.GetID() == ACTION_NEXT_CHANNELGROUP
138 ? groups
->GetNextGroup(*m_group
)
139 : groups
->GetPreviousGroup(*m_group
);
140 CServiceBroker::GetPVRManager().PlaybackState()->SetActiveChannelGroup(nextGroup
);
145 // restore control states and previously selected item of group
146 RestoreControlStates();
160 AppendChannelNumberCharacter(static_cast<char>(action
.GetID() - REMOTE_0
) + '0');
163 case ACTION_CHANNEL_NUMBER_SEP
:
165 AppendChannelNumberCharacter(CPVRChannelNumber::SEPARATOR
);
172 return CGUIDialogPVRItemsViewBase::OnAction(action
);
175 void CGUIDialogPVRChannelsOSD::Update()
177 CPVRManager
& pvrMgr
= CServiceBroker::GetPVRManager();
178 pvrMgr
.Events().Subscribe(this, &CGUIDialogPVRChannelsOSD::Notify
);
180 const std::shared_ptr
<const CPVRChannel
> channel
= pvrMgr
.PlaybackState()->GetPlayingChannel();
183 const std::shared_ptr
<CPVRChannelGroup
> group
=
184 pvrMgr
.PlaybackState()->GetActiveChannelGroup(channel
->IsRadio());
187 const std::vector
<std::shared_ptr
<CPVRChannelGroupMember
>> groupMembers
=
188 group
->GetMembers(CPVRChannelGroup::Include::ONLY_VISIBLE
);
189 for (const auto& groupMember
: groupMembers
)
191 m_vecItems
->Add(std::make_shared
<CFileItem
>(groupMember
));
194 m_viewControl
.SetItems(*m_vecItems
);
199 m_viewControl
.SetSelectedItem(
200 pvrMgr
.Get
<PVR::GUI::Channels
>().GetSelectedChannelPath(channel
->IsRadio()));
201 SaveSelectedItemPath(group
->GroupID());
207 void CGUIDialogPVRChannelsOSD::SetInvalid()
209 if (m_refreshTimeout
.IsTimePast())
211 for (const auto& item
: *m_vecItems
)
214 CGUIDialogPVRItemsViewBase::SetInvalid();
215 m_refreshTimeout
.Set(MAX_INVALIDATION_FREQUENCY
);
219 void CGUIDialogPVRChannelsOSD::SaveControlStates()
221 CGUIDialogPVRItemsViewBase::SaveControlStates();
224 SaveSelectedItemPath(m_group
->GroupID());
227 void CGUIDialogPVRChannelsOSD::RestoreControlStates()
229 CGUIDialogPVRItemsViewBase::RestoreControlStates();
233 const std::string path
= GetLastSelectedItemPath(m_group
->GroupID());
235 m_viewControl
.SetSelectedItem(0);
237 m_viewControl
.SetSelectedItem(path
);
241 void CGUIDialogPVRChannelsOSD::GotoChannel(int iItem
)
243 if (iItem
< 0 || iItem
>= m_vecItems
->Size())
246 // Preserve the item before closing self, because this will clear m_vecItems
247 const std::shared_ptr
<CFileItem
> item
= m_vecItems
->Get(iItem
);
249 if (CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(
250 CSettings::SETTING_PVRMENU_CLOSECHANNELOSDONSWITCH
))
253 CServiceBroker::GetPVRManager().Get
<PVR::GUI::Playback
>().SwitchToChannel(
254 *item
, true /* bCheckResume */);
257 void CGUIDialogPVRChannelsOSD::Notify(const PVREvent
& event
)
259 const CGUIMessage
m(GUI_MSG_REFRESH_LIST
, GetID(), 0, static_cast<int>(event
));
260 CServiceBroker::GetAppMessenger()->SendGUIMessage(m
);
263 void CGUIDialogPVRChannelsOSD::SaveSelectedItemPath(int iGroupID
)
265 m_groupSelectedItemPaths
[iGroupID
] = m_viewControl
.GetSelectedItemPath();
268 std::string
CGUIDialogPVRChannelsOSD::GetLastSelectedItemPath(int iGroupID
) const
270 const auto it
= m_groupSelectedItemPaths
.find(iGroupID
);
271 if (it
!= m_groupSelectedItemPaths
.end())
274 return std::string();
277 void CGUIDialogPVRChannelsOSD::GetChannelNumbers(std::vector
<std::string
>& channelNumbers
)
280 m_group
->GetChannelNumbers(channelNumbers
);
283 void CGUIDialogPVRChannelsOSD::OnInputDone()
285 const CPVRChannelNumber channelNumber
= GetChannelNumber();
286 if (channelNumber
.IsValid())
289 for (const CFileItemPtr
& channel
: *m_vecItems
)
291 if (channel
->GetPVRChannelGroupMemberInfoTag()->ChannelNumber() == channelNumber
)
293 m_viewControl
.SetSelectedItem(itemIndex
);