1 /*
2  *  Copyright (C) 2016-2018 Team Kodi
3  *  This file is part of Kodi - https://kodi.tv
4  *
5  *  SPDX-License-Identifier: GPL-2.0-or-later
6  *  See LICENSES/README.md for more information.
7  */
8 
9 #pragma once
10 
11 #include "pvr/PVRChannelNumberInputHandler.h"
12 #include "pvr/guilib/PVRGUIChannelNavigator.h"
13 #include "pvr/settings/PVRSettings.h"
14 #include "threads/CriticalSection.h"
15 
16 #include <memory>
17 #include <string>
18 #include <vector>
19 
20 class CFileItem;
21 
22 class CGUIWindow;
23 
24 namespace PVR
25 {
26   enum PlaybackType
27   {
28     PlaybackTypeAny = 0,
29     PlaybackTypeTV,
30     PlaybackTypeRadio
31   };
32 
33   enum class ParentalCheckResult
34   {
35     CANCELED,
36     FAILED,
37     SUCCESS
38   };
39 
40   class CPVRRecording;
41   class CPVRStreamProperties;
42   class CPVRTimerInfoTag;
43 
44   class CPVRChannelSwitchingInputHandler : public CPVRChannelNumberInputHandler
45   {
46   public:
47     // CPVRChannelNumberInputHandler implementation
48     void GetChannelNumbers(std::vector<std::string>& channelNumbers) override;
49     void AppendChannelNumberCharacter(char cCharacter) override;
50     void OnInputDone() override;
51 
52   private:
53     /*!
54      * @brief Switch to the channel with the given number.
55      * @param channelNumber the channel number
56      */
57     void SwitchToChannel(const CPVRChannelNumber& channelNumber);
58 
59     /*!
60      * @brief Switch to the previously played channel.
61      */
62     void SwitchToPreviousChannel();
63   };
64 
65   class CPVRGUIActions
66   {
67   public:
68     CPVRGUIActions();
69     virtual ~CPVRGUIActions() = default;
70 
71     /*!
72      * @brief Open a dialog with epg information for a given item.
73      * @param item containing epg data to show. item must be an epg tag, a channel or a timer.
74      * @return true on success, false otherwise.
75      */
76     bool ShowEPGInfo(const std::shared_ptr<CFileItem>& item) const;
77 
78     /*!
79      * @brief Open a dialog with the epg list for a given item.
80      * @param item containing channel info. item must be an epg tag, a channel or a timer.
81      * @return true on success, false otherwise.
82      */
83     bool ShowChannelEPG(const std::shared_ptr<CFileItem>& item) const;
84 
85     /*!
86      * @brief Open a window containing a list of epg tags 'similar' to a given item.
87      * @param item containing epg data for matching. item must be an epg tag, a channel or a recording.
88      * @return true on success, false otherwise.
89      */
90     bool FindSimilar(const std::shared_ptr<CFileItem>& item) const;
91 
92     /*!
93      * @brief Open the timer settings dialog to create a new tv or radio timer.
94      * @param bRadio indicates whether a radio or tv timer shall be created.
95      * @return true on success, false otherwise.
96      */
97     bool AddTimer(bool bRadio) const;
98 
99     /*!
100      * @brief Create a new timer, either interactive or non-interactive.
101      * @param item containing epg data to create a timer for. item must be an epg tag or a channel.
102      * @param bShowTimerSettings is used to control whether a settings dialog will be opened prior creating the timer.
103      * @return true, if the timer was created successfully, false otherwise.
104      */
105     bool AddTimer(const std::shared_ptr<CFileItem>& item, bool bShowTimerSettings) const;
106 
107     /*!
108      * @brief Add a timer to the client. Doesn't add the timer to the container. The backend will do this.
109      * @return True if it was sent correctly, false if not.
110      */
111     bool AddTimer(const std::shared_ptr<CPVRTimerInfoTag>& item) const;
112 
113     /*!
114      * @brief Create a new timer rule, either interactive or non-interactive.
115      * @param item containing epg data to create a timer rule for. item must be an epg tag or a channel.
116      * @param bShowTimerSettings is used to control whether a settings dialog will be opened prior creating the timer rule.
117      * @param bFallbackToOneShotTimer if no timer rule can be created, try to create a one-shot timer instead.
118      * @return true, if the timer rule was created successfully, false otherwise.
119      */
120     bool AddTimerRule(const std::shared_ptr<CFileItem>& item, bool bShowTimerSettings, bool bFallbackToOneShotTimer) const;
121 
122     /*!
123      * @brief Creates or deletes a timer for the given epg tag.
124      * @param item containing an epg tag.
125      * @return true on success, false otherwise.
126      */
127     bool ToggleTimer(const std::shared_ptr<CFileItem>& item) const;
128 
129     /*!
130      * @brief Toggles a given timer's enabled/disabled state.
131      * @param item containing a timer.
132      * @return true on success, false otherwise.
133      */
134     bool ToggleTimerState(const std::shared_ptr<CFileItem>& item) const;
135 
136     /*!
137      * @brief Open the timer settings dialog to edit an existing timer.
138      * @param item containing an epg tag or a timer.
139      * @return true on success, false otherwise.
140      */
141     bool EditTimer(const std::shared_ptr<CFileItem>& item) const;
142 
143     /*!
144      * @brief Open the timer settings dialog to edit an existing timer rule.
145      * @param item containing an epg tag or a timer.
146      * @return true on success, false otherwise.
147      */
148     bool EditTimerRule(const std::shared_ptr<CFileItem>& item) const;
149 
150     /*!
151      * @brief Get the timer rule for a given timer
152      * @param item containg an item to query the timer rule for. item must be a timer or an epg tag.
153      * @return The timer rule item, or nullptr if none was found.
154      */
155     std::shared_ptr<CFileItem> GetTimerRule(const std::shared_ptr<CFileItem>& item) const;
156 
157     /*!
158      * @brief Delete a timer, always showing a confirmation dialog.
159      * @param item containing a timer to delete. item must be a timer, an epg tag or a channel.
160      * @return true, if the timer was deleted successfully, false otherwise.
161      */
162     bool DeleteTimer(const std::shared_ptr<CFileItem>& item) const;
163 
164     /*!
165      * @brief Delete a timer rule, always showing a confirmation dialog.
166      * @param item containing a timer rule to delete. item must be a timer, an epg tag or a channel.
167      * @return true, if the timer rule was deleted successfully, false otherwise.
168      */
169     bool DeleteTimerRule(const std::shared_ptr<CFileItem>& item) const;
170 
171     /*!
172      * @brief Open a dialog with information for a given recording.
173      * @param item containing a recording.
174      * @return true on success, false otherwise.
175      */
176     bool ShowRecordingInfo(const std::shared_ptr<CFileItem>& item) const;
177 
178     /*!
179      * @brief Toggle recording on the currently playing channel, if any.
180      * @return True if the recording was started or stopped successfully, false otherwise.
181      */
182     bool ToggleRecordingOnPlayingChannel();
183 
184     /*!
185      * @brief Start or stop recording on a given channel.
186      * @param channel the channel to start/stop recording.
187      * @param bOnOff True to start recording, false to stop.
188      * @return True if the recording was started or stopped successfully, false otherwise.
189      */
190     bool SetRecordingOnChannel(const std::shared_ptr<CPVRChannel>& channel, bool bOnOff);
191 
192     /*!
193      * @brief Stop a currently active recording, always showing a confirmation dialog.
194      * @param item containing a recording to stop. item must be a timer, an epg tag or a channel.
195      * @return true, if the recording was stopped successfully, false otherwise.
196      */
197     bool StopRecording(const std::shared_ptr<CFileItem>& item) const;
198 
199     /*!
200      * @brief Open the recording settings dialog to edit a recording.
201      * @param item containing the recording to edit.
202      * @return true on success, false otherwise.
203      */
204     bool EditRecording(const std::shared_ptr<CFileItem>& item) const;
205 
206     /*!
207      * @brief Check if any recording settings can be edited.
208      * @param item containing the recording to edit.
209      * @return true on success, false otherwise.
210      */
211     bool CanEditRecording(const CFileItem& item) const;
212 
213     /*!
214      * @brief Delete a recording, always showing a confirmation dialog.
215      * @param item containing a recording to delete.
216      * @return true, if the recording was deleted successfully, false otherwise.
217      */
218     bool DeleteRecording(const std::shared_ptr<CFileItem>& item) const;
219 
220     /*!
221      * @brief Delete all watched recordings contained in the given folder, always showing a confirmation dialog.
222      * @param item containing a recording folder containing the items to delete.
223      * @return true, if the recordings were deleted successfully, false otherwise.
224      */
225     bool DeleteWatchedRecordings(const std::shared_ptr<CFileItem>& item) const;
226 
227     /*!
228      * @brief Delete all recordings from trash, always showing a confirmation dialog.
229      * @return true, if the recordings were permanently deleted successfully, false otherwise.
230      */
231     bool DeleteAllRecordingsFromTrash() const;
232 
233     /*!
234      * @brief Undelete a recording.
235      * @param item containing a recording to undelete.
236      * @return true, if the recording was undeleted successfully, false otherwise.
237      */
238     bool UndeleteRecording(const std::shared_ptr<CFileItem>& item) const;
239 
240     /*!
241      * @brief Get a localized resume play label, if the given item can be resumed.
242      * @param item containing a recording or an epg tag.
243      * @return the localized resume play label that can be used for instance as context menu item label or an empty string if resume is not possible.
244      */
245     std::string GetResumeLabel(const CFileItem& item) const;
246 
247     /*!
248      * @brief Resume a previously not completely played recording.
249      * @param item containing a recording or an epg tag.
250      * @param bFallbackToPlay controls whether playback of the recording should be started at the beginning ig no resume data are available.
251      * @return true on success, false otherwise.
252      */
253     bool ResumePlayRecording(const std::shared_ptr<CFileItem>& item, bool bFallbackToPlay) const;
254 
255     /*!
256      * @brief Play recording.
257      * @param item containing a recording or an epg tag.
258      * @param bCheckResume controls resume check.
259      * @return true on success, false otherwise.
260      */
261     bool PlayRecording(const std::shared_ptr<CFileItem>& item, bool bCheckResume) const;
262 
263     /*!
264      * @brief Play EPG tag.
265      * @param item containing an epg tag.
266      * @return true on success, false otherwise.
267      */
268     bool PlayEpgTag(const std::shared_ptr<CFileItem>& item) const;
269 
270     /*!
271      * @brief Switch channel.
272      * @param item containing a channel or an epg tag.
273      * @param bCheckResume controls resume check in case a recording for the current epg event is present.
274      * @return true on success, false otherwise.
275      */
276     bool SwitchToChannel(const std::shared_ptr<CFileItem>& item, bool bCheckResume) const;
277 
278     /*!
279      * @brief Playback the given file item.
280      * @param item containing a channel or a recording.
281      * @return True if the item could be played, false otherwise.
282      */
283     bool PlayMedia(const std::shared_ptr<CFileItem>& item) const;
284 
285     /*!
286      * @brief Start playback of the last played channel, and if there is none, play first channel in the current channelgroup.
287      * @param type The type of playback to be started (any, radio, tv). See PlaybackType enum
288      * @return True if playback was started, false otherwise.
289      */
290     bool SwitchToChannel(PlaybackType type) const;
291 
292     /*!
293      * @brief Plays the last played channel or the first channel of TV or Radio on startup.
294      * @return True if playback was started, false otherwise.
295      */
296     bool PlayChannelOnStartup() const;
297 
298     /*!
299      * @brief Hide a channel, always showing a confirmation dialog.
300      * @param item containing a channel or an epg tag.
301      * @return true on success, false otherwise.
302      */
303     bool HideChannel(const std::shared_ptr<CFileItem>& item) const;
304 
305     /*!
306      * @brief Open a selection dialog and start a channel scan on the selected client.
307      * @return true on success, false otherwise.
308      */
309     bool StartChannelScan();
310 
311     /*!
312      * @brief Start a channel scan on the specified client or open a dialog to select a client
313      * @param clientId the id of client to scan or PVR_INVALID_CLIENT_ID if a dialog will be opened
314      * @return true on success, false otherwise.
315      */
316     bool StartChannelScan(int clientId);
317 
318     /*!
319      * @return True when a channel scan is currently running, false otherwise.
320      */
IsRunningChannelScan()321     bool IsRunningChannelScan() const { return m_bChannelScanRunning; }
322 
323     /*!
324      * @brief Select and invoke client-specific settings actions
325      * @return true on success, false otherwise.
326      */
327     bool ProcessSettingsMenuHooks();
328 
329     /*!
330      * @brief Reset the TV database to it's initial state and delete all the data.
331      * @param bResetEPGOnly True to only reset the EPG database, false to reset both PVR and EPG database.
332      * @return true on success, false otherwise.
333      */
334     bool ResetPVRDatabase(bool bResetEPGOnly);
335 
336     /*!
337      * @brief Check if channel is parental locked. Ask for PIN if necessary.
338      * @param channel The channel to do the check for.
339      * @return the result of the check (success, failed, or canceled by user).
340      */
341     ParentalCheckResult CheckParentalLock(const std::shared_ptr<CPVRChannel>& channel) const;
342 
343     /*!
344      * @brief Open Numeric dialog to check for parental PIN.
345      * @return the result of the check (success, failed, or canceled by user).
346      */
347     ParentalCheckResult CheckParentalPIN() const;
348 
349     /*!
350      * @brief Check whether the system Kodi is running on can be powered down
351      *        (shutdown/reboot/suspend/hibernate) without stopping any active
352      *        recordings and/or without preventing the start of recordings
353      *        scheduled for now + pvrpowermanagement.backendidletime.
354      * @param bAskUser True to informs user in case of potential
355      *        data loss. User can decide to allow powerdown anyway. False to
356      *        not to ask user and to not confirm power down.
357      * @return True if system can be safely powered down, false otherwise.
358      */
359     bool CanSystemPowerdown(bool bAskUser = true) const;
360 
361     /*!
362      * @brief Create a new reminder timer, non-interactive.
363      * @param item containing epg data to create a reminder timer for. item must be an epg tag.
364      * @return true, if the timer was created successfully, false otherwise.
365      */
366     bool AddReminder(const std::shared_ptr<CFileItem>& item) const;
367 
368     /*!
369      * @brief Announce due reminders, if any.
370      */
371     void AnnounceReminders() const;
372 
373     /*!
374      * @brief Get the currently selected item path; used across several windows/dialogs to share item selection.
375      * @param bRadio True to query the selected path for PVR radio, false for Live TV.
376      * @return the path.
377      */
378     std::string GetSelectedItemPath(bool bRadio) const;
379 
380     /*!
381      * @brief Set the currently selected item path; used across several windows/dialogs to share item selection.
382      * @param bRadio True to set the selected path for PVR radio, false for Live TV.
383      * @param path The new path to set.
384      */
385     void SetSelectedItemPath(bool bRadio, const std::string& path);
386 
387     /*!
388      * @brief Seek to the start of the next epg event in timeshift buffer, relative to the currently playing event.
389      *        If there is no next event, seek to the end of the currently playing event (to the 'live' position).
390      */
391     void SeekForward();
392 
393     /*!
394      * @brief Seek to the start of the previous epg event in timeshift buffer, relative to the currently playing event
395      *        or if there is no previous event or if playback time is greater than given threshold, seek to the start
396      *        of the playing event.
397      * @param iThreshold the value in seconds to trigger seek to start of current event instead of start of previous event.
398      */
399     void SeekBackward(unsigned int iThreshold);
400 
401     /*!
402      * @brief Get the currently active channel number input handler.
403      * @return the handler.
404      */
405     CPVRChannelNumberInputHandler& GetChannelNumberInputHandler();
406 
407     /*!
408      * @brief Get the channel navigator.
409      * @return the navigator.
410      */
411     CPVRGUIChannelNavigator& GetChannelNavigator();
412 
413     /*!
414      * @brief Inform GUI actions that playback of an item just started.
415      * @param item The item that started to play.
416      */
417     void OnPlaybackStarted(const std::shared_ptr<CFileItem>& item);
418 
419     /*!
420      * @brief Inform GUI actions that playback of an item was stopped due to user interaction.
421      * @param item The item that stopped to play.
422      */
423     void OnPlaybackStopped(const std::shared_ptr<CFileItem>& item);
424 
425   private:
426     CPVRGUIActions(const CPVRGUIActions&) = delete;
427     CPVRGUIActions const& operator=(CPVRGUIActions const&) = delete;
428 
429     /*!
430      * @brief Open the timer settings dialog.
431      * @param timer containing the timer the settings shall be displayed for.
432      * @return true, if the dialog was ended successfully, false otherwise.
433      */
434     bool ShowTimerSettings(const std::shared_ptr<CPVRTimerInfoTag>& timer) const;
435 
436     /*!
437      * @brief Add a timer or timer rule, either interactive or non-interactive.
438      * @param item containing epg data to create a timer or timer rule for. item must be an epg tag or a channel.
439      * @param bCreateteRule denotes whether to create a one-shot timer or a timer rule.
440      * @param bShowTimerSettings is used to control whether a settings dialog will be opened prior creating the timer or timer rule.
441      * @param bFallbackToOneShotTimer if bCreateteRule is true and no timer rule can be created, try to create a one-shot timer instead.
442      * @return true, if the timer or timer rule was created successfully, false otherwise.
443      */
444     bool AddTimer(const std::shared_ptr<CFileItem>& item, bool bCreateRule, bool bShowTimerSettings, bool bFallbackToOneShotTimer) const;
445 
446     /*!
447      * @brief Delete a timer or timer rule, always showing a confirmation dialog.
448      * @param item containing a timer or timer rule to delete. item must be a timer, an epg tag or a channel.
449      * @param bIsRecording denotes whether the timer is currently recording (controls correct confirmation dialog).
450      * @param bDeleteRule denotes to delete a timer rule. For convenience, one can pass a timer created by a rule.
451      * @return true, if the timer or timer rule was deleted successfully, false otherwise.
452     */
453     bool DeleteTimer(const std::shared_ptr<CFileItem>& item, bool bIsRecording, bool bDeleteRule) const;
454 
455     /*!
456      * @brief Delete a timer or timer rule, showing a confirmation dialog in case a timer currently recording shall be deleted.
457      * @param timer containing a timer or timer rule to delete.
458      * @param bIsRecording denotes whether the timer is currently recording (controls correct confirmation dialog).
459      * @param bDeleteRule denotes to delete a timer rule. For convenience, one can pass a timer created by a rule.
460      * @return true, if the timer or timer rule was deleted successfully, false otherwise.
461      */
462     bool DeleteTimer(const std::shared_ptr<CPVRTimerInfoTag>& timer, bool bIsRecording, bool bDeleteRule) const;
463 
464     /*!
465      * @brief Open a dialog to confirm timer delete.
466      * @param timer the timer to delete.
467      * @param bDeleteRule in: ignored
468      *                    out, for one shot timer scheduled by a timer rule: true to also delete the timer
469      *                         rule that has scheduled this timer, false to only delete the one shot timer.
470      *                    out, for one shot timer not scheduled by a timer rule: ignored
471      * @return true, to proceed with delete, false otherwise.
472      */
473     bool ConfirmDeleteTimer(const std::shared_ptr<CPVRTimerInfoTag>& timer, bool& bDeleteRule) const;
474 
475     /*!
476      * @brief Open a dialog to confirm stop recording.
477      * @param timer the recording to stop (actually the timer to delete).
478      * @return true, to proceed with delete, false otherwise.
479      */
480     bool ConfirmStopRecording(const std::shared_ptr<CPVRTimerInfoTag>& timer) const;
481 
482     /*!
483      * @brief Open a dialog to confirm to delete a recording.
484      * @param item the recording to delete.
485      * @return true, to proceed with delete, false otherwise.
486      */
487     bool ConfirmDeleteRecording(const std::shared_ptr<CFileItem>& item) const;
488 
489     /*!
490      * @brief Open a dialog to confirm delete all watched recordings contained in the given folder.
491      * @param item containing a recording folder containing the items to delete.
492      * @return true, to proceed with delete, false otherwise.
493      */
494     bool ConfirmDeleteWatchedRecordings(const std::shared_ptr<CFileItem>& item) const;
495 
496     /*!
497      * @brief Open a dialog to confirm to permanently remove all deleted recordings.
498      * @return true, to proceed with delete, false otherwise.
499      */
500     bool ConfirmDeleteAllRecordingsFromTrash() const;
501 
502     /*!
503      * @brief Open the recording settings dialog.
504      * @param recording containing the recording the settings shall be displayed for.
505      * @return true, if the dialog was ended successfully, false otherwise.
506      */
507     bool ShowRecordingSettings(const std::shared_ptr<CPVRRecording>& recording) const;
508 
509     /*!
510      * @brief Check whether resume play is possible for a given item, display "resume from ..."/"play from start" context menu in case.
511      * @param item containing a recording or an epg tag.
512      * @return true, to play/resume the item, false otherwise.
513      */
514     bool CheckResumeRecording(const std::shared_ptr<CFileItem>& item) const;
515 
516     /*!
517      * @brief Check "play minimized" settings value and switch to fullscreen if not set.
518      * @param bFullscreen switch to fullscreen or set windowed playback.
519      */
520     void CheckAndSwitchToFullscreen(bool bFullscreen) const;
521 
522     /*!
523      * @brief Start playback of the given item.
524      * @param bFullscreen start playback fullscreen or not.
525      * @param epgProps propeties to be used instead of calling to the client if supplied.
526      * @param item containing a channel or a recording.
527      */
528     void StartPlayback(CFileItem* item,
529                        bool bFullscreen,
530                        CPVRStreamProperties* epgProps = nullptr) const;
531 
532     bool AllLocalBackendsIdle(std::shared_ptr<CPVRTimerInfoTag>& causingEvent) const;
533     bool EventOccursOnLocalBackend(const std::shared_ptr<CFileItem>& item) const;
534     bool IsNextEventWithinBackendIdleTime() const;
535 
536     /*!
537      * @brief Announce and process a reminder timer.
538      * @param timer The reminder timer.
539      */
540     void AnnounceReminder(const std::shared_ptr<CPVRTimerInfoTag>& timer) const;
541 
542     mutable CCriticalSection m_critSection;
543     CPVRChannelSwitchingInputHandler m_channelNumberInputHandler;
544     bool m_bChannelScanRunning = false;
545     CPVRSettings m_settings;
546     CPVRGUIChannelNavigator m_channelNavigator;
547     std::string m_selectedItemPathTV;
548     std::string m_selectedItemPathRadio;
549     mutable bool m_bReminderAnnouncementRunning = false;
550   };
551 
552 } // namespace PVR
553