2 * Copyright (C) 2005-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 "PVRGUIActionListener.h"
12 #include "ServiceBroker.h"
13 #include "application/Application.h"
14 #include "application/ApplicationActionListeners.h"
15 #include "application/ApplicationComponents.h"
16 #include "dialogs/GUIDialogNumeric.h"
17 #include "guilib/GUIComponent.h"
18 #include "guilib/GUIWindowManager.h"
19 #include "guilib/WindowIDs.h"
20 #include "input/actions/Action.h"
21 #include "input/actions/ActionIDs.h"
22 #include "messaging/ApplicationMessenger.h"
23 #include "pvr/PVRManager.h"
24 #include "pvr/PVRPlaybackState.h"
25 #include "pvr/addons/PVRClients.h"
26 #include "pvr/channels/PVRChannel.h"
27 #include "pvr/channels/PVRChannelGroup.h"
28 #include "pvr/channels/PVRChannelGroups.h"
29 #include "pvr/channels/PVRChannelGroupsContainer.h"
30 #include "pvr/guilib/PVRGUIActionsChannels.h"
31 #include "pvr/guilib/PVRGUIActionsClients.h"
32 #include "pvr/guilib/PVRGUIActionsDatabase.h"
33 #include "pvr/guilib/PVRGUIActionsPlayback.h"
34 #include "pvr/guilib/PVRGUIActionsTimers.h"
35 #include "settings/Settings.h"
36 #include "settings/SettingsComponent.h"
37 #include "settings/lib/Setting.h"
45 CPVRGUIActionListener::CPVRGUIActionListener()
47 auto& components
= CServiceBroker::GetAppComponents();
48 const auto appListener
= components
.GetComponent
<CApplicationActionListeners
>();
49 appListener
->RegisterActionListener(this);
50 CServiceBroker::GetSettingsComponent()->GetSettings()->RegisterCallback(
52 {CSettings::SETTING_PVRPARENTAL_ENABLED
, CSettings::SETTING_PVRMANAGER_RESETDB
,
53 CSettings::SETTING_EPG_RESETEPG
, CSettings::SETTING_PVRMANAGER_ADDONS
,
54 CSettings::SETTING_PVRMANAGER_CLIENTPRIORITIES
, CSettings::SETTING_PVRMANAGER_CHANNELMANAGER
,
55 CSettings::SETTING_PVRMANAGER_GROUPMANAGER
, CSettings::SETTING_PVRMANAGER_CHANNELSCAN
,
56 CSettings::SETTING_PVRMENU_SEARCHICONS
, CSettings::SETTING_PVRCLIENT_MENUHOOK
,
57 CSettings::SETTING_EPG_PAST_DAYSTODISPLAY
, CSettings::SETTING_EPG_FUTURE_DAYSTODISPLAY
});
60 CPVRGUIActionListener::~CPVRGUIActionListener()
62 CServiceBroker::GetSettingsComponent()->GetSettings()->UnregisterCallback(this);
63 auto& components
= CServiceBroker::GetAppComponents();
64 const auto appListener
= components
.GetComponent
<CApplicationActionListeners
>();
65 appListener
->UnregisterActionListener(this);
68 void CPVRGUIActionListener::Init(CPVRManager
& mgr
)
70 mgr
.Events().Subscribe(this, &CPVRGUIActionListener::OnPVRManagerEvent
);
73 void CPVRGUIActionListener::Deinit(CPVRManager
& mgr
)
75 mgr
.Events().Unsubscribe(this);
78 void CPVRGUIActionListener::OnPVRManagerEvent(const PVREvent
& event
)
80 if (event
== PVREvent::AnnounceReminder
)
82 if (g_application
.IsInitialized())
84 // if GUI is ready, dispatch to GUI thread and handle the action there
85 CServiceBroker::GetAppMessenger()->PostMsg(
86 TMSG_GUI_ACTION
, WINDOW_INVALID
, -1,
87 static_cast<void*>(new CAction(ACTION_PVR_ANNOUNCE_REMINDERS
)));
92 ChannelSwitchMode
CPVRGUIActionListener::GetChannelSwitchMode(int iAction
)
94 if ((iAction
== ACTION_MOVE_UP
|| iAction
== ACTION_MOVE_DOWN
) &&
95 CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(
96 CSettings::SETTING_PVRPLAYBACK_CONFIRMCHANNELSWITCH
))
97 return ChannelSwitchMode::NO_SWITCH
;
99 return ChannelSwitchMode::INSTANT_OR_DELAYED_SWITCH
;
102 bool CPVRGUIActionListener::OnAction(const CAction
& action
)
104 bool bIsJumpSMS
= false;
105 bool bIsPlayingPVR
= CServiceBroker::GetPVRManager().PlaybackState()->IsPlaying() &&
106 g_application
.CurrentFileItem().HasPVRChannelInfoTag();
108 switch (action
.GetID())
110 case ACTION_PVR_PLAY
:
111 case ACTION_PVR_PLAY_TV
:
112 case ACTION_PVR_PLAY_RADIO
:
114 // see if we're already playing a PVR stream and if not or the stream type
115 // doesn't match the demanded type, start playback of according type
116 switch (action
.GetID())
118 case ACTION_PVR_PLAY
:
120 CServiceBroker::GetPVRManager().Get
<PVR::GUI::Playback
>().SwitchToChannel(
123 case ACTION_PVR_PLAY_TV
:
124 if (!bIsPlayingPVR
|| g_application
.CurrentFileItem().GetPVRChannelInfoTag()->IsRadio())
125 CServiceBroker::GetPVRManager().Get
<PVR::GUI::Playback
>().SwitchToChannel(
128 case ACTION_PVR_PLAY_RADIO
:
129 if (!bIsPlayingPVR
|| !g_application
.CurrentFileItem().GetPVRChannelInfoTag()->IsRadio())
130 CServiceBroker::GetPVRManager().Get
<PVR::GUI::Playback
>().SwitchToChannel(
137 case ACTION_JUMP_SMS2
:
138 case ACTION_JUMP_SMS3
:
139 case ACTION_JUMP_SMS4
:
140 case ACTION_JUMP_SMS5
:
141 case ACTION_JUMP_SMS6
:
142 case ACTION_JUMP_SMS7
:
143 case ACTION_JUMP_SMS8
:
144 case ACTION_JUMP_SMS9
:
146 // fallthru is intended
158 case ACTION_CHANNEL_NUMBER_SEP
:
163 if (CServiceBroker::GetGUI()->GetWindowManager().IsWindowActive(WINDOW_FULLSCREEN_VIDEO
) ||
164 CServiceBroker::GetGUI()->GetWindowManager().IsWindowActive(WINDOW_VISUALISATION
))
166 // do not consume action if a python modal is the top most dialog
167 // as a python modal can't return that it consumed the action.
168 if (CServiceBroker::GetGUI()->GetWindowManager().IsPythonWindow(
169 CServiceBroker::GetGUI()->GetWindowManager().GetTopmostModalDialog()))
173 if (action
.GetID() == ACTION_CHANNEL_NUMBER_SEP
)
175 cCharacter
= CPVRChannelNumber::SEPARATOR
;
180 bIsJumpSMS
? action
.GetID() - (ACTION_JUMP_SMS2
- REMOTE_2
) : action
.GetID();
181 cCharacter
= static_cast<char>(iRemote
- REMOTE_0
) + '0';
183 CServiceBroker::GetPVRManager()
184 .Get
<PVR::GUI::Channels
>()
185 .GetChannelNumberInputHandler()
186 .AppendChannelNumberCharacter(cCharacter
);
192 case ACTION_SHOW_INFO
:
197 CServiceBroker::GetPVRManager().Get
<PVR::GUI::Channels
>().GetChannelNavigator().ToggleInfo();
201 case ACTION_SELECT_ITEM
:
206 // If the button that caused this action matches action "Select" ...
207 if (CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(
208 CSettings::SETTING_PVRPLAYBACK_CONFIRMCHANNELSWITCH
) &&
209 CServiceBroker::GetPVRManager()
210 .Get
<PVR::GUI::Channels
>()
211 .GetChannelNavigator()
214 // ... and if "confirm channel switch" setting is active and a channel
215 // preview is currently shown, switch to the currently previewed channel.
216 CServiceBroker::GetPVRManager()
217 .Get
<PVR::GUI::Channels
>()
218 .GetChannelNavigator()
219 .SwitchToCurrentChannel();
222 else if (CServiceBroker::GetPVRManager()
223 .Get
<PVR::GUI::Channels
>()
224 .GetChannelNumberInputHandler()
225 .CheckInputAndExecuteAction())
227 // ... or if the action was processed by direct channel number input, we're done.
233 case ACTION_NEXT_ITEM
:
238 CServiceBroker::GetPVRManager().Get
<PVR::GUI::Playback
>().SeekForward();
242 case ACTION_PREV_ITEM
:
247 CServiceBroker::GetPVRManager().Get
<PVR::GUI::Playback
>().SeekBackward(
248 CApplication::ACTION_PREV_ITEM_THRESHOLD
);
253 case ACTION_CHANNEL_UP
:
258 CServiceBroker::GetPVRManager()
259 .Get
<PVR::GUI::Channels
>()
260 .GetChannelNavigator()
261 .SelectNextChannel(GetChannelSwitchMode(action
.GetID()));
265 case ACTION_MOVE_DOWN
:
266 case ACTION_CHANNEL_DOWN
:
271 CServiceBroker::GetPVRManager()
272 .Get
<PVR::GUI::Channels
>()
273 .GetChannelNavigator()
274 .SelectPreviousChannel(GetChannelSwitchMode(action
.GetID()));
278 case ACTION_CHANNEL_SWITCH
:
283 int iChannelNumber
= static_cast<int>(action
.GetAmount(0));
284 int iSubChannelNumber
= static_cast<int>(action
.GetAmount(1));
286 const std::shared_ptr
<const CPVRPlaybackState
> playbackState
=
287 CServiceBroker::GetPVRManager().PlaybackState();
288 const std::shared_ptr
<const CPVRChannelGroup
> activeGroup
=
289 playbackState
->GetActiveChannelGroup(playbackState
->IsPlayingRadio());
290 const std::shared_ptr
<CPVRChannelGroupMember
> groupMember
=
291 activeGroup
->GetByChannelNumber(CPVRChannelNumber(iChannelNumber
, iSubChannelNumber
));
296 CServiceBroker::GetPVRManager().Get
<PVR::GUI::Playback
>().SwitchToChannel(
297 CFileItem(groupMember
), false);
303 CServiceBroker::GetPVRManager().Get
<PVR::GUI::Timers
>().ToggleRecordingOnPlayingChannel();
307 case ACTION_PVR_ANNOUNCE_REMINDERS
:
309 CServiceBroker::GetPVRManager().Get
<PVR::GUI::Timers
>().AnnounceReminders();
316 void CPVRGUIActionListener::OnSettingChanged(const std::shared_ptr
<const CSetting
>& setting
)
318 if (setting
== nullptr)
321 const std::string
& settingId
= setting
->GetId();
322 if (settingId
== CSettings::SETTING_PVRPARENTAL_ENABLED
)
324 if (std::static_pointer_cast
<const CSettingBool
>(setting
)->GetValue() &&
325 CServiceBroker::GetSettingsComponent()
327 ->GetString(CSettings::SETTING_PVRPARENTAL_PIN
)
330 std::string newPassword
= "";
331 // password set... save it
332 if (CGUIDialogNumeric::ShowAndVerifyNewPassword(newPassword
))
333 CServiceBroker::GetSettingsComponent()->GetSettings()->SetString(
334 CSettings::SETTING_PVRPARENTAL_PIN
, newPassword
);
335 // password not set... disable parental
337 std::static_pointer_cast
<CSettingBool
>(std::const_pointer_cast
<CSetting
>(setting
))
341 else if (settingId
== CSettings::SETTING_EPG_PAST_DAYSTODISPLAY
)
343 CServiceBroker::GetPVRManager().Clients()->SetEPGMaxPastDays(
344 std::static_pointer_cast
<const CSettingInt
>(setting
)->GetValue());
346 else if (settingId
== CSettings::SETTING_EPG_FUTURE_DAYSTODISPLAY
)
348 CServiceBroker::GetPVRManager().Clients()->SetEPGMaxFutureDays(
349 std::static_pointer_cast
<const CSettingInt
>(setting
)->GetValue());
353 void CPVRGUIActionListener::OnSettingAction(const std::shared_ptr
<const CSetting
>& setting
)
355 if (setting
== nullptr)
358 const std::string
& settingId
= setting
->GetId();
359 if (settingId
== CSettings::SETTING_PVRMANAGER_RESETDB
)
361 CServiceBroker::GetPVRManager().Get
<PVR::GUI::Database
>().ResetDatabase(false);
363 else if (settingId
== CSettings::SETTING_EPG_RESETEPG
)
365 CServiceBroker::GetPVRManager().Get
<PVR::GUI::Database
>().ResetDatabase(true);
367 else if (settingId
== CSettings::SETTING_PVRMANAGER_CLIENTPRIORITIES
)
369 if (CServiceBroker::GetPVRManager().IsStarted())
371 CGUIDialog
* dialog
= CServiceBroker::GetGUI()->GetWindowManager().GetDialog(
372 WINDOW_DIALOG_PVR_CLIENT_PRIORITIES
);
376 CServiceBroker::GetPVRManager().ChannelGroups()->UpdateFromClients({});
380 else if (settingId
== CSettings::SETTING_PVRMANAGER_CHANNELMANAGER
)
382 if (CServiceBroker::GetPVRManager().IsStarted())
385 CServiceBroker::GetGUI()->GetWindowManager().GetDialog(WINDOW_DIALOG_PVR_CHANNEL_MANAGER
);
390 else if (settingId
== CSettings::SETTING_PVRMANAGER_GROUPMANAGER
)
392 if (CServiceBroker::GetPVRManager().IsStarted())
395 CServiceBroker::GetGUI()->GetWindowManager().GetDialog(WINDOW_DIALOG_PVR_GROUP_MANAGER
);
400 else if (settingId
== CSettings::SETTING_PVRMANAGER_CHANNELSCAN
)
402 CServiceBroker::GetPVRManager().Get
<PVR::GUI::Channels
>().StartChannelScan();
404 else if (settingId
== CSettings::SETTING_PVRMENU_SEARCHICONS
)
406 CServiceBroker::GetPVRManager().TriggerSearchMissingChannelIcons();
408 else if (settingId
== CSettings::SETTING_PVRCLIENT_MENUHOOK
)
410 CServiceBroker::GetPVRManager().Get
<PVR::GUI::Clients
>().ProcessSettingsMenuHooks();
412 else if (settingId
== CSettings::SETTING_PVRMANAGER_ADDONS
)
414 const std::vector
<std::string
> params
{"addons://default_binary_addons_source/kodi.pvrclient",
416 CServiceBroker::GetGUI()->GetWindowManager().ActivateWindow(WINDOW_ADDON_BROWSER
, params
);