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 "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"
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
);
66 case PVREvent::EpgContainer
:
67 case PVREvent::EpgActiveItem
:
76 return CGUIDialogPVRItemsViewBase::OnMessage(message
);
79 void CGUIDialogPVRChannelsOSD::OnInitWindow()
81 if (!CServiceBroker::GetPVRManager().PlaybackState()->IsPlayingTV() &&
82 !CServiceBroker::GetPVRManager().PlaybackState()->IsPlayingRadio())
90 CGUIDialogPVRItemsViewBase::OnInitWindow();
93 void CGUIDialogPVRChannelsOSD::OnDeinitWindow(int nextWindowID
)
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
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())
121 if (m_viewControl
.HasControl(GetFocusedControlID()))
124 GotoChannel(m_viewControl
.GetSelectedItem());
129 case ACTION_PREVIOUS_CHANNELGROUP
:
130 case ACTION_NEXT_CHANNELGROUP
:
132 // save control states and currently selected item of group
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
);
146 // restore control states and previously selected item of group
147 RestoreControlStates();
161 AppendChannelNumberCharacter(static_cast<char>(action
.GetID() - REMOTE_0
) + '0');
164 case ACTION_CHANNEL_NUMBER_SEP
:
166 AppendChannelNumberCharacter(CPVRChannelNumber::SEPARATOR
);
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();
184 const std::shared_ptr
<CPVRChannelGroup
> group
=
185 pvrMgr
.PlaybackState()->GetActiveChannelGroup(channel
->IsRadio());
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
);
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
)
215 CGUIDialogPVRItemsViewBase::SetInvalid();
216 m_refreshTimeout
.Set(MAX_INVALIDATION_FREQUENCY
);
220 void CGUIDialogPVRChannelsOSD::SaveControlStates()
222 CGUIDialogPVRItemsViewBase::SaveControlStates();
225 SaveSelectedItemPath(m_group
->GroupID());
228 void CGUIDialogPVRChannelsOSD::RestoreControlStates()
230 CGUIDialogPVRItemsViewBase::RestoreControlStates();
234 const std::string path
= GetLastSelectedItemPath(m_group
->GroupID());
236 m_viewControl
.SetSelectedItem(0);
238 m_viewControl
.SetSelectedItem(path
);
242 void CGUIDialogPVRChannelsOSD::GotoChannel(int iItem
)
244 if (iItem
< 0 || iItem
>= m_vecItems
->Size())
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
))
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())
275 return std::string();
278 void CGUIDialogPVRChannelsOSD::GetChannelNumbers(std::vector
<std::string
>& channelNumbers
)
281 m_group
->GetChannelNumbers(channelNumbers
);
284 void CGUIDialogPVRChannelsOSD::OnInputDone()
286 const CPVRChannelNumber channelNumber
= GetChannelNumber();
287 if (channelNumber
.IsValid())
290 for (const CFileItemPtr
& channel
: *m_vecItems
)
292 if (channel
->GetPVRChannelGroupMemberInfoTag()->ChannelNumber() == channelNumber
)
294 m_viewControl
.SetSelectedItem(itemIndex
);