Merge pull request #26386 from ksooo/guiinfo-fix-listitem-filenamenoextension
[xbmc.git] / xbmc / pvr / guilib / guiinfo / PVRGUIInfo.cpp
blobd20ad906a9f7d43fd054eff13d80b7e872f2119a
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 "PVRGUIInfo.h"
11 #include "FileItem.h"
12 #include "GUIInfoManager.h"
13 #include "ServiceBroker.h"
14 #include "application/Application.h"
15 #include "application/ApplicationComponents.h"
16 #include "application/ApplicationPlayer.h"
17 #include "guilib/GUIComponent.h"
18 #include "guilib/GUIWindowManager.h"
19 #include "guilib/LocalizeStrings.h"
20 #include "guilib/guiinfo/GUIInfo.h"
21 #include "guilib/guiinfo/GUIInfoLabels.h"
22 #include "pvr/PVRItem.h"
23 #include "pvr/PVRManager.h"
24 #include "pvr/PVRPlaybackState.h"
25 #include "pvr/addons/PVRClient.h"
26 #include "pvr/addons/PVRClients.h"
27 #include "pvr/channels/PVRChannel.h"
28 #include "pvr/channels/PVRChannelGroup.h"
29 #include "pvr/channels/PVRChannelGroupMember.h"
30 #include "pvr/channels/PVRChannelGroups.h"
31 #include "pvr/channels/PVRChannelGroupsContainer.h"
32 #include "pvr/channels/PVRRadioRDSInfoTag.h"
33 #include "pvr/epg/EpgContainer.h"
34 #include "pvr/epg/EpgInfoTag.h"
35 #include "pvr/epg/EpgSearchFilter.h"
36 #include "pvr/guilib/PVRGUIActionsChannels.h"
37 #include "pvr/guilib/PVRGUIActionsEPG.h"
38 #include "pvr/providers/PVRProvider.h"
39 #include "pvr/providers/PVRProviders.h"
40 #include "pvr/recordings/PVRRecording.h"
41 #include "pvr/recordings/PVRRecordings.h"
42 #include "pvr/timers/PVRTimerInfoTag.h"
43 #include "pvr/timers/PVRTimers.h"
44 #include "settings/AdvancedSettings.h"
45 #include "settings/Settings.h"
46 #include "settings/SettingsComponent.h"
47 #include "threads/SingleLock.h"
48 #include "threads/SystemClock.h"
49 #include "utils/MathUtils.h"
50 #include "utils/StringUtils.h"
52 #include <cmath>
53 #include <ctime>
54 #include <memory>
55 #include <mutex>
56 #include <string>
57 #include <vector>
59 using namespace PVR;
60 using namespace KODI::GUILIB::GUIINFO;
61 using namespace std::chrono_literals;
63 CPVRGUIInfo::CPVRGUIInfo() : CThread("PVRGUIInfo")
65 ResetProperties();
68 void CPVRGUIInfo::ResetProperties()
70 std::unique_lock<CCriticalSection> lock(m_critSection);
72 m_anyTimersInfo.ResetProperties();
73 m_tvTimersInfo.ResetProperties();
74 m_radioTimersInfo.ResetProperties();
75 m_timesInfo.Reset();
76 m_bHasTVRecordings = false;
77 m_bHasRadioRecordings = false;
78 m_iCurrentActiveClient = 0;
79 m_strPlayingClientName.clear();
80 m_strClientName.clear();
81 m_strInstanceName.clear();
82 m_strBackendName.clear();
83 m_strBackendVersion.clear();
84 m_strBackendHost.clear();
85 m_strBackendTimers.clear();
86 m_strBackendRecordings.clear();
87 m_strBackendDeletedRecordings.clear();
88 m_strBackendProviders.clear();
89 m_strBackendChannelGroups.clear();
90 m_strBackendChannels.clear();
91 m_iBackendDiskTotal = 0;
92 m_iBackendDiskUsed = 0;
93 m_bIsPlayingTV = false;
94 m_bIsPlayingRadio = false;
95 m_bIsPlayingRecording = false;
96 m_bIsPlayingEpgTag = false;
97 m_bIsPlayingEncryptedStream = false;
98 m_bIsRecordingPlayingChannel = false;
99 m_bCanRecordPlayingChannel = false;
100 m_bIsPlayingActiveRecording = false;
101 m_bHasTVChannels = false;
102 m_bHasRadioChannels = false;
104 ClearQualityInfo(m_qualityInfo);
105 ClearDescrambleInfo(m_descrambleInfo);
107 m_updateBackendCacheRequested = false;
108 m_bRegistered = false;
111 void CPVRGUIInfo::ClearQualityInfo(CPVRSignalStatus& qualityInfo)
113 qualityInfo = {g_localizeStrings.Get(13106).c_str(), g_localizeStrings.Get(13106).c_str()};
116 void CPVRGUIInfo::ClearDescrambleInfo(CPVRDescrambleInfo& descrambleInfo)
118 descrambleInfo = {};
121 void CPVRGUIInfo::Start()
123 ResetProperties();
124 Create();
125 SetPriority(ThreadPriority::BELOW_NORMAL);
128 void CPVRGUIInfo::Stop()
130 StopThread();
132 auto& mgr = CServiceBroker::GetPVRManager();
133 auto& channels = mgr.Get<PVR::GUI::Channels>();
134 channels.GetChannelNavigator().Unsubscribe(this);
135 channels.Events().Unsubscribe(this);
136 mgr.Events().Unsubscribe(this);
138 CGUIComponent* gui = CServiceBroker::GetGUI();
139 if (gui)
141 gui->GetInfoManager().UnregisterInfoProvider(this);
142 m_bRegistered = false;
146 void CPVRGUIInfo::Notify(const PVREvent& event)
148 if (event == PVREvent::Timers || event == PVREvent::TimersInvalidated)
149 UpdateTimersCache();
152 void CPVRGUIInfo::Notify(const PVRChannelNumberInputChangedEvent& event)
154 std::unique_lock<CCriticalSection> lock(m_critSection);
155 m_channelNumberInput = event.m_input;
158 void CPVRGUIInfo::Notify(const PVRPreviewAndPlayerShowInfoChangedEvent& event)
160 std::unique_lock<CCriticalSection> lock(m_critSection);
161 m_previewAndPlayerShowInfo = event.m_previewAndPlayerShowInfo;
164 void CPVRGUIInfo::Process()
166 auto toggleIntervalMs = std::chrono::milliseconds(
167 CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_iPVRInfoToggleInterval);
168 XbmcThreads::EndTime<> cacheTimer(toggleIntervalMs);
170 auto& mgr = CServiceBroker::GetPVRManager();
171 mgr.Events().Subscribe(this, &CPVRGUIInfo::Notify);
173 auto& channels = mgr.Get<PVR::GUI::Channels>();
174 channels.Events().Subscribe(this, &CPVRGUIInfo::Notify);
175 channels.GetChannelNavigator().Subscribe(this, &CPVRGUIInfo::Notify);
177 /* updated on request */
178 UpdateTimersCache();
180 /* update the backend cache once initially */
181 m_updateBackendCacheRequested = true;
183 while (!g_application.m_bStop && !m_bStop)
185 if (!m_bRegistered)
187 CGUIComponent* gui = CServiceBroker::GetGUI();
188 if (gui)
190 gui->GetInfoManager().RegisterInfoProvider(this);
191 m_bRegistered = true;
195 if (!m_bStop)
196 UpdateQualityData();
197 std::this_thread::yield();
199 if (!m_bStop)
200 UpdateDescrambleData();
201 std::this_thread::yield();
203 if (!m_bStop)
204 UpdateMisc();
205 std::this_thread::yield();
207 if (!m_bStop)
208 UpdateTimeshiftData();
209 std::this_thread::yield();
211 if (!m_bStop)
212 UpdateTimersToggle();
213 std::this_thread::yield();
215 if (!m_bStop)
216 UpdateNextTimer();
217 std::this_thread::yield();
219 // Update the backend cache every toggleInterval seconds
220 if (!m_bStop && cacheTimer.IsTimePast())
222 UpdateBackendCache();
223 cacheTimer.Set(toggleIntervalMs);
226 if (!m_bStop)
227 CThread::Sleep(500ms);
231 void CPVRGUIInfo::UpdateQualityData()
233 if (!CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(
234 CSettings::SETTING_PVRPLAYBACK_SIGNALQUALITY))
235 return;
237 const std::shared_ptr<const CPVRPlaybackState> playbackState =
238 CServiceBroker::GetPVRManager().PlaybackState();
239 if (!playbackState)
240 return;
242 CPVRSignalStatus qualityInfo;
243 ClearQualityInfo(qualityInfo);
245 const int channelUid = playbackState->GetPlayingChannelUniqueID();
246 if (channelUid > 0)
248 const std::shared_ptr<const CPVRClient> client =
249 CServiceBroker::GetPVRManager().Clients()->GetCreatedClient(
250 playbackState->GetPlayingClientID());
251 if (client)
252 client->SignalQuality(channelUid, qualityInfo);
255 std::unique_lock<CCriticalSection> lock(m_critSection);
256 m_qualityInfo = qualityInfo;
259 void CPVRGUIInfo::UpdateDescrambleData()
261 const std::shared_ptr<const CPVRPlaybackState> playbackState =
262 CServiceBroker::GetPVRManager().PlaybackState();
263 if (!playbackState)
264 return;
266 CPVRDescrambleInfo descrambleInfo;
267 ClearDescrambleInfo(descrambleInfo);
269 const int channelUid = playbackState->GetPlayingChannelUniqueID();
270 if (channelUid > 0)
272 const std::shared_ptr<const CPVRClient> client =
273 CServiceBroker::GetPVRManager().Clients()->GetCreatedClient(
274 playbackState->GetPlayingClientID());
275 if (client)
276 client->GetDescrambleInfo(channelUid, descrambleInfo);
279 std::unique_lock<CCriticalSection> lock(m_critSection);
280 m_descrambleInfo = descrambleInfo;
283 void CPVRGUIInfo::UpdateMisc()
285 const CPVRManager& mgr = CServiceBroker::GetPVRManager();
286 bool bStarted = mgr.IsStarted();
287 const std::shared_ptr<const CPVRPlaybackState> state = mgr.PlaybackState();
289 /* safe to fetch these unlocked, since they're updated from the same thread as this one */
290 const std::string strPlayingClientName = bStarted ? state->GetPlayingClientName() : "";
291 const bool bHasTVRecordings = bStarted && mgr.Recordings()->GetNumTVRecordings() > 0;
292 const bool bHasRadioRecordings = bStarted && mgr.Recordings()->GetNumRadioRecordings() > 0;
293 const bool bIsPlayingTV = bStarted && state->IsPlayingTV();
294 const bool bIsPlayingRadio = bStarted && state->IsPlayingRadio();
295 const bool bIsPlayingRecording = bStarted && state->IsPlayingRecording();
296 const bool bIsPlayingEpgTag = bStarted && state->IsPlayingEpgTag();
297 const bool bIsPlayingEncryptedStream = bStarted && state->IsPlayingEncryptedChannel();
298 const bool bHasTVChannels = bStarted && mgr.ChannelGroups()->GetGroupAllTV()->HasChannels();
299 const bool bHasRadioChannels = bStarted && mgr.ChannelGroups()->GetGroupAllRadio()->HasChannels();
300 const bool bCanRecordPlayingChannel = bStarted && state->CanRecordOnPlayingChannel();
301 const bool bIsRecordingPlayingChannel = bStarted && state->IsRecordingOnPlayingChannel();
302 const bool bIsPlayingActiveRecording = bStarted && state->IsPlayingActiveRecording();
303 const std::string strPlayingTVGroup =
304 (bStarted && bIsPlayingTV) ? state->GetActiveChannelGroup(false)->GroupName() : "";
305 const std::string strPlayingRadioGroup =
306 (bStarted && bIsPlayingRadio) ? state->GetActiveChannelGroup(true)->GroupName() : "";
308 std::unique_lock<CCriticalSection> lock(m_critSection);
309 m_strPlayingClientName = strPlayingClientName;
310 m_bHasTVRecordings = bHasTVRecordings;
311 m_bHasRadioRecordings = bHasRadioRecordings;
312 m_bIsPlayingTV = bIsPlayingTV;
313 m_bIsPlayingRadio = bIsPlayingRadio;
314 m_bIsPlayingRecording = bIsPlayingRecording;
315 m_bIsPlayingEpgTag = bIsPlayingEpgTag;
316 m_bIsPlayingEncryptedStream = bIsPlayingEncryptedStream;
317 m_bHasTVChannels = bHasTVChannels;
318 m_bHasRadioChannels = bHasRadioChannels;
319 m_strPlayingTVGroup = strPlayingTVGroup;
320 m_strPlayingRadioGroup = strPlayingRadioGroup;
321 m_bCanRecordPlayingChannel = bCanRecordPlayingChannel;
322 m_bIsRecordingPlayingChannel = bIsRecordingPlayingChannel;
323 m_bIsPlayingActiveRecording = bIsPlayingActiveRecording;
326 void CPVRGUIInfo::UpdateTimeshiftData()
328 m_timesInfo.Update();
331 bool CPVRGUIInfo::InitCurrentItem(CFileItem* item)
333 CServiceBroker::GetPVRManager().PublishEvent(PVREvent::CurrentItem);
334 return false;
337 bool CPVRGUIInfo::GetLabel(std::string& value,
338 const CFileItem* item,
339 int contextWindow,
340 const CGUIInfo& info,
341 std::string* fallback) const
343 return GetListItemAndPlayerLabel(item, info, value) || GetPVRLabel(item, info, value) ||
344 GetRadioRDSLabel(item, info, value);
347 namespace
349 std::string GetAsLocalizedDateString(const CDateTime& datetime, bool bLongDate)
351 return datetime.IsValid() ? datetime.GetAsLocalizedDate(bLongDate) : "";
354 std::string GetAsLocalizedTimeString(const CDateTime& datetime)
356 return datetime.IsValid() ? datetime.GetAsLocalizedTime("", false) : "";
359 std::string GetAsLocalizedDateTimeString(const CDateTime& datetime)
361 return datetime.IsValid() ? datetime.GetAsLocalizedDateTime(false, false) : "";
364 } // unnamed namespace
366 bool CPVRGUIInfo::GetListItemAndPlayerLabel(const CFileItem* item,
367 const CGUIInfo& info,
368 std::string& strValue) const
370 const std::shared_ptr<const CPVRTimerInfoTag> timer = item->GetPVRTimerInfoTag();
371 if (timer)
373 switch (info.m_info)
375 case LISTITEM_DATE:
376 strValue = timer->Summary();
377 return true;
378 case LISTITEM_STARTDATE:
379 strValue = GetAsLocalizedDateString(timer->StartAsLocalTime(), true);
380 return true;
381 case LISTITEM_STARTTIME:
382 strValue = GetAsLocalizedTimeString(timer->StartAsLocalTime());
383 return true;
384 case LISTITEM_ENDDATE:
385 strValue = GetAsLocalizedDateString(timer->EndAsLocalTime(), true);
386 return true;
387 case LISTITEM_ENDTIME:
388 strValue = GetAsLocalizedTimeString(timer->EndAsLocalTime());
389 return true;
390 case LISTITEM_DURATION:
391 if (timer->GetDuration() > 0)
393 strValue = StringUtils::SecondsToTimeString(timer->GetDuration(),
394 static_cast<TIME_FORMAT>(info.GetData4()));
395 return true;
397 return false;
398 case LISTITEM_TITLE:
399 strValue = timer->Title();
400 return true;
401 case LISTITEM_COMMENT:
402 strValue =
403 timer->GetStatus(CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow() ==
404 WINDOW_RADIO_TIMER_RULES);
405 return true;
406 case LISTITEM_TIMERTYPE:
407 strValue = timer->GetTypeAsString();
408 return true;
409 case LISTITEM_CHANNEL_NAME:
410 strValue = timer->ChannelName();
411 return true;
412 case LISTITEM_CHANNEL_LOGO:
413 strValue = timer->ChannelIcon();
414 return true;
415 case LISTITEM_PVR_CLIENT_NAME:
416 strValue = CServiceBroker::GetPVRManager().GetClient(timer->ClientID())->GetClientName();
417 return true;
418 case LISTITEM_PVR_INSTANCE_NAME:
419 strValue = CServiceBroker::GetPVRManager().GetClient(timer->ClientID())->GetInstanceName();
420 return true;
421 case LISTITEM_EPG_EVENT_TITLE:
422 case LISTITEM_EPG_EVENT_ICON:
423 case LISTITEM_GENRE:
424 case LISTITEM_PLOT:
425 case LISTITEM_PLOT_OUTLINE:
426 case LISTITEM_ORIGINALTITLE:
427 case LISTITEM_YEAR:
428 case LISTITEM_SEASON:
429 case LISTITEM_EPISODE:
430 case LISTITEM_EPISODENAME:
431 case LISTITEM_EPISODEPART:
432 case LISTITEM_DIRECTOR:
433 case LISTITEM_CHANNEL_NUMBER:
434 case LISTITEM_PREMIERED:
435 case LISTITEM_PARENTAL_RATING:
436 case LISTITEM_PARENTAL_RATING_CODE:
437 case LISTITEM_PARENTAL_RATING_ICON:
438 case LISTITEM_PARENTAL_RATING_SOURCE:
439 case LISTITEM_MEDIAPROVIDERS:
440 case LISTITEM_TITLE_EXTRAINFO:
441 break; // obtain value from channel/epg
442 default:
443 return false;
447 const std::shared_ptr<const CPVRRecording> recording(item->GetPVRRecordingInfoTag());
448 if (recording)
450 // Note: CPVRRecoding is derived from CVideoInfoTag. All base class properties will be handled
451 // by CVideoGUIInfoProvider. Only properties introduced by CPVRRecording need to be handled here.
452 switch (info.m_info)
454 case LISTITEM_DATE:
455 strValue = GetAsLocalizedDateTimeString(recording->RecordingTimeAsLocalTime());
456 return true;
457 case LISTITEM_STARTDATE:
458 strValue = GetAsLocalizedDateString(recording->RecordingTimeAsLocalTime(), true);
459 return true;
460 case VIDEOPLAYER_STARTTIME:
461 case LISTITEM_STARTTIME:
462 strValue = GetAsLocalizedTimeString(recording->RecordingTimeAsLocalTime());
463 return true;
464 case LISTITEM_ENDDATE:
465 strValue = GetAsLocalizedDateString(recording->EndTimeAsLocalTime(), true);
466 return true;
467 case VIDEOPLAYER_ENDTIME:
468 case LISTITEM_ENDTIME:
469 strValue = GetAsLocalizedTimeString(recording->EndTimeAsLocalTime());
470 return true;
471 case LISTITEM_EXPIRATION_DATE:
472 if (recording->HasExpirationTime())
474 strValue = GetAsLocalizedDateString(recording->ExpirationTimeAsLocalTime(), false);
475 return true;
477 break;
478 case LISTITEM_EXPIRATION_TIME:
479 if (recording->HasExpirationTime())
481 strValue = GetAsLocalizedTimeString(recording->ExpirationTimeAsLocalTime());
482 return true;
484 break;
485 case VIDEOPLAYER_EPISODENAME:
486 case LISTITEM_EPISODENAME:
487 strValue = recording->EpisodeName();
488 return true;
489 case VIDEOPLAYER_CHANNEL_NAME:
490 case LISTITEM_CHANNEL_NAME:
491 strValue = recording->ChannelName();
492 if (strValue.empty())
494 if (recording->ProviderName().empty())
496 const auto& provider = recording->GetProvider();
497 strValue = provider->GetName();
499 else
501 strValue = recording->ProviderName();
504 return true;
505 case VIDEOPLAYER_CHANNEL_NUMBER:
506 case LISTITEM_CHANNEL_NUMBER:
508 const std::shared_ptr<const CPVRChannelGroupMember> groupMember =
509 CServiceBroker::GetPVRManager().Get<PVR::GUI::Channels>().GetChannelGroupMember(*item);
510 if (groupMember)
512 strValue = groupMember->ChannelNumber().FormattedChannelNumber();
513 return true;
515 break;
517 case VIDEOPLAYER_CHANNEL_LOGO:
518 case LISTITEM_CHANNEL_LOGO:
520 const std::shared_ptr<const CPVRChannelGroupMember> groupMember =
521 CServiceBroker::GetPVRManager().Get<PVR::GUI::Channels>().GetChannelGroupMember(*item);
522 if (groupMember)
524 strValue = groupMember->Channel()->IconPath();
525 return true;
527 break;
529 case LISTITEM_ICON:
530 if (recording->ClientIconPath().empty() && recording->ClientThumbnailPath().empty() &&
531 // Only use a fallback if there is more than a single provider available
532 // Note: an add-on itself is a provider, hence we don't use > 0
533 CServiceBroker::GetPVRManager().Providers()->GetNumProviders() > 1 &&
534 !recording->Channel())
536 auto provider = recording->GetProvider();
537 if (!provider->GetIconPath().empty())
539 strValue = provider->GetIconPath();
540 return true;
543 return false;
544 case VIDEOPLAYER_CHANNEL_GROUP:
546 std::unique_lock<CCriticalSection> lock(m_critSection);
547 strValue = recording->IsRadio() ? m_strPlayingRadioGroup : m_strPlayingTVGroup;
548 return true;
550 case VIDEOPLAYER_PREMIERED:
551 case LISTITEM_PREMIERED:
552 if (recording->FirstAired().IsValid())
554 strValue = recording->FirstAired().GetAsLocalizedDate();
555 return true;
557 else if (recording->HasYear())
559 strValue = std::to_string(recording->GetYear());
560 return true;
562 return false;
563 case LISTITEM_SIZE:
564 if (recording->GetSizeInBytes() > 0)
566 strValue = StringUtils::SizeToString(recording->GetSizeInBytes());
567 return true;
569 return false;
570 case LISTITEM_PVR_CLIENT_NAME:
571 strValue =
572 CServiceBroker::GetPVRManager().GetClient(recording->ClientID())->GetClientName();
573 return true;
574 case LISTITEM_PVR_INSTANCE_NAME:
575 strValue =
576 CServiceBroker::GetPVRManager().GetClient(recording->ClientID())->GetInstanceName();
577 return true;
578 case VIDEOPLAYER_PARENTAL_RATING:
579 case LISTITEM_PARENTAL_RATING:
581 const unsigned int rating{recording->GetParentalRating()};
582 if (rating > 0)
584 strValue = std::to_string(rating);
585 return true;
587 return false;
589 case VIDEOPLAYER_PARENTAL_RATING_CODE:
590 case LISTITEM_PARENTAL_RATING_CODE:
591 strValue = recording->GetParentalRatingCode();
592 return true;
593 case VIDEOPLAYER_PARENTAL_RATING_ICON:
594 case LISTITEM_PARENTAL_RATING_ICON:
595 strValue = recording->GetParentalRatingIcon();
596 return true;
597 case VIDEOPLAYER_PARENTAL_RATING_SOURCE:
598 case LISTITEM_PARENTAL_RATING_SOURCE:
599 strValue = recording->GetParentalRatingSource();
600 return true;
601 case VIDEOPLAYER_EPISODEPART:
602 case LISTITEM_EPISODEPART:
603 if (recording->m_iEpisode > 0 && recording->EpisodePart() > 0)
605 strValue = std::to_string(recording->EpisodePart());
606 return true;
608 return false;
609 case MUSICPLAYER_MEDIAPROVIDERS:
610 case VIDEOPLAYER_MEDIAPROVIDERS:
611 case LISTITEM_MEDIAPROVIDERS:
612 if (recording->HasClientProvider())
614 const std::shared_ptr<const CPVRProvider> provider{recording->GetProvider()};
615 if (provider)
617 strValue = provider->GetName();
618 return true;
621 return false;
622 case LISTITEM_TITLE_EXTRAINFO:
623 case VIDEOPLAYER_TITLE_EXTRAINFO:
625 strValue = recording->TitleExtraInfo();
626 // fixup multiline info strings (which do not fit in any way in our GUI)
627 StringUtils::Replace(strValue, "\n", ", ");
628 return true;
631 return false;
634 const std::shared_ptr<const CPVREpgSearchFilter> filter = item->GetEPGSearchFilter();
635 if (filter)
637 switch (info.m_info)
639 case LISTITEM_DATE:
641 CDateTime lastExecLocal;
642 lastExecLocal.SetFromUTCDateTime(filter->GetLastExecutedDateTime());
643 strValue = GetAsLocalizedDateTimeString(lastExecLocal);
644 if (strValue.empty())
645 strValue = g_localizeStrings.Get(10006); // "N/A"
646 return true;
649 return false;
652 if (item->IsPVRChannelGroup())
654 switch (info.m_info)
656 case LISTITEM_PVR_GROUP_ORIGIN:
658 const std::shared_ptr<CPVRChannelGroup> group{
659 CServiceBroker::GetPVRManager().ChannelGroups()->GetGroupByPath(item->GetPath())};
660 if (group)
662 const CPVRChannelGroup::Origin origin{group->GetOrigin()};
663 switch (origin)
665 case CPVRChannelGroup::Origin::CLIENT:
666 strValue = g_localizeStrings.Get(856); // Client
667 return true;
668 case CPVRChannelGroup::Origin::SYSTEM:
669 strValue = g_localizeStrings.Get(857); // System
670 return true;
671 case CPVRChannelGroup::Origin::USER:
672 strValue = g_localizeStrings.Get(858); // User
673 return true;
676 break;
679 return false;
682 std::shared_ptr<const CPVREpgInfoTag> epgTag;
683 std::shared_ptr<const CPVRChannel> channel;
684 if (item->IsPVRChannel() || item->IsEPG() || item->IsPVRTimer())
686 CPVRItem pvrItem(item);
687 channel = pvrItem.GetChannel();
689 switch (info.m_info)
691 case VIDEOPLAYER_NEXT_TITLE:
692 case VIDEOPLAYER_NEXT_GENRE:
693 case VIDEOPLAYER_NEXT_PLOT:
694 case VIDEOPLAYER_NEXT_PLOT_OUTLINE:
695 case VIDEOPLAYER_NEXT_STARTTIME:
696 case VIDEOPLAYER_NEXT_ENDTIME:
697 case VIDEOPLAYER_NEXT_DURATION:
698 case LISTITEM_NEXT_TITLE:
699 case LISTITEM_NEXT_GENRE:
700 case LISTITEM_NEXT_PLOT:
701 case LISTITEM_NEXT_PLOT_OUTLINE:
702 case LISTITEM_NEXT_STARTDATE:
703 case LISTITEM_NEXT_STARTTIME:
704 case LISTITEM_NEXT_ENDDATE:
705 case LISTITEM_NEXT_ENDTIME:
706 case LISTITEM_NEXT_DURATION:
707 // next playing event
708 epgTag = pvrItem.GetNextEpgInfoTag();
709 break;
710 default:
711 // now playing event
712 epgTag = pvrItem.GetEpgInfoTag();
713 break;
716 switch (info.m_info)
718 // special handling for channels without epg or with radio rds data
719 case PLAYER_TITLE:
720 case LISTITEM_TITLE:
721 case VIDEOPLAYER_NEXT_TITLE:
722 case LISTITEM_NEXT_TITLE:
723 case LISTITEM_EPG_EVENT_TITLE:
724 // Note: in difference to LISTITEM_TITLE, LISTITEM_EPG_EVENT_TITLE returns the title
725 // associated with the epg event of a timer, if any, and not the title of the timer.
726 strValue = CServiceBroker::GetPVRManager().Get<PVR::GUI::EPG>().GetTitleForEpgTag(epgTag);
727 return true;
731 if (epgTag)
733 switch (info.m_info)
735 case VIDEOPLAYER_GENRE:
736 case LISTITEM_GENRE:
737 case VIDEOPLAYER_NEXT_GENRE:
738 case LISTITEM_NEXT_GENRE:
739 strValue = epgTag->GetGenresLabel();
740 return true;
741 case VIDEOPLAYER_PLOT:
742 case LISTITEM_PLOT:
743 case VIDEOPLAYER_NEXT_PLOT:
744 case LISTITEM_NEXT_PLOT:
745 if (!CServiceBroker::GetPVRManager().IsParentalLocked(epgTag))
746 strValue = epgTag->Plot();
747 return true;
748 case VIDEOPLAYER_PLOT_OUTLINE:
749 case LISTITEM_PLOT_OUTLINE:
750 case VIDEOPLAYER_NEXT_PLOT_OUTLINE:
751 case LISTITEM_NEXT_PLOT_OUTLINE:
752 if (!CServiceBroker::GetPVRManager().IsParentalLocked(epgTag))
753 strValue = epgTag->PlotOutline();
754 return true;
755 case LISTITEM_DATE:
756 strValue = GetAsLocalizedDateTimeString(epgTag->StartAsLocalTime());
757 return true;
758 case LISTITEM_STARTDATE:
759 case LISTITEM_NEXT_STARTDATE:
760 strValue = GetAsLocalizedDateString(epgTag->StartAsLocalTime(), true);
761 return true;
762 case VIDEOPLAYER_STARTTIME:
763 case VIDEOPLAYER_NEXT_STARTTIME:
764 case LISTITEM_STARTTIME:
765 case LISTITEM_NEXT_STARTTIME:
766 strValue = GetAsLocalizedTimeString(epgTag->StartAsLocalTime());
767 return true;
768 case LISTITEM_ENDDATE:
769 case LISTITEM_NEXT_ENDDATE:
770 strValue = GetAsLocalizedDateString(epgTag->EndAsLocalTime(), true);
771 return true;
772 case VIDEOPLAYER_ENDTIME:
773 case VIDEOPLAYER_NEXT_ENDTIME:
774 case LISTITEM_ENDTIME:
775 case LISTITEM_NEXT_ENDTIME:
776 strValue = GetAsLocalizedTimeString(epgTag->EndAsLocalTime());
777 return true;
778 // note: for some reason, there is no VIDEOPLAYER_DURATION
779 case LISTITEM_DURATION:
780 case VIDEOPLAYER_NEXT_DURATION:
781 case LISTITEM_NEXT_DURATION:
782 if (epgTag->GetDuration() > 0)
784 strValue = StringUtils::SecondsToTimeString(epgTag->GetDuration(),
785 static_cast<TIME_FORMAT>(info.GetData4()));
786 return true;
788 return false;
789 case VIDEOPLAYER_IMDBNUMBER:
790 case LISTITEM_IMDBNUMBER:
791 strValue = epgTag->IMDBNumber();
792 return true;
793 case VIDEOPLAYER_ORIGINALTITLE:
794 case LISTITEM_ORIGINALTITLE:
795 if (!CServiceBroker::GetPVRManager().IsParentalLocked(epgTag))
796 strValue = epgTag->OriginalTitle();
797 return true;
798 case VIDEOPLAYER_YEAR:
799 case LISTITEM_YEAR:
800 if (epgTag->Year() > 0)
802 strValue = std::to_string(epgTag->Year());
803 return true;
805 return false;
806 case VIDEOPLAYER_SEASON:
807 case LISTITEM_SEASON:
808 if (epgTag->SeriesNumber() >= 0)
810 strValue = std::to_string(epgTag->SeriesNumber());
811 return true;
813 return false;
814 case VIDEOPLAYER_EPISODE:
815 case LISTITEM_EPISODE:
816 if (epgTag->EpisodeNumber() >= 0)
818 strValue = std::to_string(epgTag->EpisodeNumber());
819 return true;
821 return false;
822 case VIDEOPLAYER_EPISODEPART:
823 case LISTITEM_EPISODEPART:
824 if (epgTag->EpisodeNumber() >= 0 && epgTag->EpisodePart() > 0)
825 strValue = std::to_string(epgTag->EpisodePart());
826 return true;
827 case VIDEOPLAYER_EPISODENAME:
828 case LISTITEM_EPISODENAME:
829 if (!CServiceBroker::GetPVRManager().IsParentalLocked(epgTag))
830 strValue = epgTag->EpisodeName();
831 return true;
832 case VIDEOPLAYER_CAST:
833 case LISTITEM_CAST:
834 strValue = epgTag->GetCastLabel();
835 return true;
836 case VIDEOPLAYER_DIRECTOR:
837 case LISTITEM_DIRECTOR:
838 strValue = epgTag->GetDirectorsLabel();
839 return true;
840 case VIDEOPLAYER_WRITER:
841 case LISTITEM_WRITER:
842 strValue = epgTag->GetWritersLabel();
843 return true;
844 case LISTITEM_EPG_EVENT_ICON:
845 strValue = epgTag->IconPath();
846 return true;
847 case VIDEOPLAYER_PARENTAL_RATING:
848 case LISTITEM_PARENTAL_RATING:
850 const unsigned int rating{epgTag->ParentalRating()};
851 if (rating > 0)
853 strValue = std::to_string(rating);
854 return true;
856 return false;
858 case VIDEOPLAYER_PARENTAL_RATING_CODE:
859 case LISTITEM_PARENTAL_RATING_CODE:
860 strValue = epgTag->ParentalRatingCode();
861 return true;
862 case LISTITEM_PVR_CLIENT_NAME:
863 strValue = CServiceBroker::GetPVRManager().GetClient(epgTag->ClientID())->GetClientName();
864 return true;
865 case LISTITEM_PVR_INSTANCE_NAME:
866 strValue = CServiceBroker::GetPVRManager().GetClient(epgTag->ClientID())->GetInstanceName();
867 return true;
868 case VIDEOPLAYER_PARENTAL_RATING_ICON:
869 case LISTITEM_PARENTAL_RATING_ICON:
870 strValue = epgTag->ParentalRatingIcon();
871 return true;
872 case VIDEOPLAYER_PARENTAL_RATING_SOURCE:
873 case LISTITEM_PARENTAL_RATING_SOURCE:
874 strValue = epgTag->ParentalRatingSource();
875 return true;
876 case VIDEOPLAYER_PREMIERED:
877 case LISTITEM_PREMIERED:
878 if (epgTag->FirstAired().IsValid())
880 strValue = epgTag->FirstAired().GetAsLocalizedDate();
881 return true;
883 else if (epgTag->Year() > 0)
885 strValue = std::to_string(epgTag->Year());
886 return true;
888 return false;
889 case VIDEOPLAYER_RATING:
890 case LISTITEM_RATING:
892 int iStarRating = epgTag->StarRating();
893 if (iStarRating > 0)
895 strValue = StringUtils::FormatNumber(iStarRating);
896 return true;
898 return false;
900 case LISTITEM_TITLE_EXTRAINFO:
901 case VIDEOPLAYER_TITLE_EXTRAINFO:
903 strValue = epgTag->TitleExtraInfo();
904 // fixup multiline info strings (which do not fit in any way in our GUI)
905 StringUtils::Replace(strValue, "\n", ", ");
906 return true;
911 if (channel)
913 switch (info.m_info)
915 case MUSICPLAYER_CHANNEL_NAME:
917 const std::shared_ptr<const CPVRRadioRDSInfoTag> rdsTag = channel->GetRadioRDSInfoTag();
918 if (rdsTag)
920 strValue = rdsTag->GetProgStation();
921 if (!strValue.empty())
922 return true;
924 [[fallthrough]];
926 case VIDEOPLAYER_CHANNEL_NAME:
927 case LISTITEM_CHANNEL_NAME:
928 strValue = channel->ChannelName();
929 return true;
930 case MUSICPLAYER_CHANNEL_LOGO:
931 case VIDEOPLAYER_CHANNEL_LOGO:
932 case LISTITEM_CHANNEL_LOGO:
933 strValue = channel->IconPath();
934 return true;
935 case MUSICPLAYER_CHANNEL_NUMBER:
936 case VIDEOPLAYER_CHANNEL_NUMBER:
937 case LISTITEM_CHANNEL_NUMBER:
939 auto groupMember = item->GetPVRChannelGroupMemberInfoTag();
940 if (!groupMember)
941 groupMember =
942 CServiceBroker::GetPVRManager().Get<PVR::GUI::Channels>().GetChannelGroupMember(
943 *item);
944 if (groupMember)
946 strValue = groupMember->ChannelNumber().FormattedChannelNumber();
947 return true;
949 break;
951 case MUSICPLAYER_CHANNEL_GROUP:
952 case VIDEOPLAYER_CHANNEL_GROUP:
954 std::unique_lock<CCriticalSection> lock(m_critSection);
955 strValue = channel->IsRadio() ? m_strPlayingRadioGroup : m_strPlayingTVGroup;
956 return true;
958 case LISTITEM_PVR_CLIENT_NAME:
959 strValue = CServiceBroker::GetPVRManager().GetClient(channel->ClientID())->GetClientName();
960 return true;
961 case LISTITEM_PVR_INSTANCE_NAME:
962 strValue =
963 CServiceBroker::GetPVRManager().GetClient(channel->ClientID())->GetInstanceName();
964 return true;
965 case LISTITEM_DATE_ADDED:
966 if (channel->DateTimeAdded().IsValid())
968 strValue = channel->DateTimeAdded().GetAsLocalizedDate();
969 return true;
971 break;
972 case MUSICPLAYER_MEDIAPROVIDERS:
973 case VIDEOPLAYER_MEDIAPROVIDERS:
974 case LISTITEM_MEDIAPROVIDERS:
975 if (channel->HasClientProvider())
977 const std::shared_ptr<const CPVRProvider> provider{channel->GetProvider()};
978 if (provider)
980 strValue = provider->GetName();
981 return true;
984 break;
988 return false;
991 bool CPVRGUIInfo::GetPVRLabel(const CFileItem* item,
992 const CGUIInfo& info,
993 std::string& strValue) const
995 std::unique_lock<CCriticalSection> lock(m_critSection);
997 switch (info.m_info)
999 case PVR_EPG_EVENT_ICON:
1001 const std::shared_ptr<const CPVREpgInfoTag> epgTag =
1002 (item->IsPVRChannel() || item->IsEPG()) ? CPVRItem(item).GetEpgInfoTag() : nullptr;
1003 if (epgTag)
1005 strValue = epgTag->IconPath();
1007 return true;
1009 case PVR_EPG_EVENT_DURATION:
1011 const std::shared_ptr<const CPVREpgInfoTag> epgTag =
1012 (item->IsPVRChannel() || item->IsEPG()) ? CPVRItem(item).GetEpgInfoTag() : nullptr;
1013 strValue = m_timesInfo.GetEpgEventDuration(epgTag, static_cast<TIME_FORMAT>(info.GetData1()));
1014 return true;
1016 case PVR_EPG_EVENT_ELAPSED_TIME:
1018 const std::shared_ptr<const CPVREpgInfoTag> epgTag =
1019 (item->IsPVRChannel() || item->IsEPG()) ? CPVRItem(item).GetEpgInfoTag() : nullptr;
1020 strValue =
1021 m_timesInfo.GetEpgEventElapsedTime(epgTag, static_cast<TIME_FORMAT>(info.GetData1()));
1022 return true;
1024 case PVR_EPG_EVENT_REMAINING_TIME:
1026 const std::shared_ptr<const CPVREpgInfoTag> epgTag =
1027 (item->IsPVRChannel() || item->IsEPG()) ? CPVRItem(item).GetEpgInfoTag() : nullptr;
1028 strValue =
1029 m_timesInfo.GetEpgEventRemainingTime(epgTag, static_cast<TIME_FORMAT>(info.GetData1()));
1030 return true;
1032 case PVR_EPG_EVENT_FINISH_TIME:
1034 const std::shared_ptr<const CPVREpgInfoTag> epgTag =
1035 (item->IsPVRChannel() || item->IsEPG()) ? CPVRItem(item).GetEpgInfoTag() : nullptr;
1036 strValue =
1037 m_timesInfo.GetEpgEventFinishTime(epgTag, static_cast<TIME_FORMAT>(info.GetData1()));
1038 return true;
1040 case PVR_TIMESHIFT_START_TIME:
1041 strValue = m_timesInfo.GetTimeshiftStartTime(static_cast<TIME_FORMAT>(info.GetData1()));
1042 return true;
1043 case PVR_TIMESHIFT_END_TIME:
1044 strValue = m_timesInfo.GetTimeshiftEndTime(static_cast<TIME_FORMAT>(info.GetData1()));
1045 return true;
1046 case PVR_TIMESHIFT_PLAY_TIME:
1047 strValue = m_timesInfo.GetTimeshiftPlayTime(static_cast<TIME_FORMAT>(info.GetData1()));
1048 return true;
1049 case PVR_TIMESHIFT_OFFSET:
1050 strValue = m_timesInfo.GetTimeshiftOffset(static_cast<TIME_FORMAT>(info.GetData1()));
1051 return true;
1052 case PVR_TIMESHIFT_PROGRESS_DURATION:
1053 strValue =
1054 m_timesInfo.GetTimeshiftProgressDuration(static_cast<TIME_FORMAT>(info.GetData1()));
1055 return true;
1056 case PVR_TIMESHIFT_PROGRESS_START_TIME:
1057 strValue =
1058 m_timesInfo.GetTimeshiftProgressStartTime(static_cast<TIME_FORMAT>(info.GetData1()));
1059 return true;
1060 case PVR_TIMESHIFT_PROGRESS_END_TIME:
1061 strValue = m_timesInfo.GetTimeshiftProgressEndTime(static_cast<TIME_FORMAT>(info.GetData1()));
1062 return true;
1063 case PVR_EPG_EVENT_SEEK_TIME:
1065 const auto& components = CServiceBroker::GetAppComponents();
1066 const auto appPlayer = components.GetComponent<CApplicationPlayer>();
1067 strValue = m_timesInfo.GetEpgEventSeekTime(appPlayer->GetSeekHandler().GetSeekSize(),
1068 static_cast<TIME_FORMAT>(info.GetData1()));
1069 return true;
1071 case PVR_NOW_RECORDING_TITLE:
1072 strValue = m_anyTimersInfo.GetActiveTimerTitle();
1073 return true;
1074 case PVR_NOW_RECORDING_CHANNEL:
1075 strValue = m_anyTimersInfo.GetActiveTimerChannelName();
1076 return true;
1077 case PVR_NOW_RECORDING_CHAN_ICO:
1078 strValue = m_anyTimersInfo.GetActiveTimerChannelIcon();
1079 return true;
1080 case PVR_NOW_RECORDING_DATETIME:
1081 strValue = m_anyTimersInfo.GetActiveTimerDateTime();
1082 return true;
1083 case PVR_NEXT_RECORDING_TITLE:
1084 strValue = m_anyTimersInfo.GetNextTimerTitle();
1085 return true;
1086 case PVR_NEXT_RECORDING_CHANNEL:
1087 strValue = m_anyTimersInfo.GetNextTimerChannelName();
1088 return true;
1089 case PVR_NEXT_RECORDING_CHAN_ICO:
1090 strValue = m_anyTimersInfo.GetNextTimerChannelIcon();
1091 return true;
1092 case PVR_NEXT_RECORDING_DATETIME:
1093 strValue = m_anyTimersInfo.GetNextTimerDateTime();
1094 return true;
1095 case PVR_TV_NOW_RECORDING_TITLE:
1096 strValue = m_tvTimersInfo.GetActiveTimerTitle();
1097 return true;
1098 case PVR_TV_NOW_RECORDING_CHANNEL:
1099 strValue = m_tvTimersInfo.GetActiveTimerChannelName();
1100 return true;
1101 case PVR_TV_NOW_RECORDING_CHAN_ICO:
1102 strValue = m_tvTimersInfo.GetActiveTimerChannelIcon();
1103 return true;
1104 case PVR_TV_NOW_RECORDING_DATETIME:
1105 strValue = m_tvTimersInfo.GetActiveTimerDateTime();
1106 return true;
1107 case PVR_TV_NEXT_RECORDING_TITLE:
1108 strValue = m_tvTimersInfo.GetNextTimerTitle();
1109 return true;
1110 case PVR_TV_NEXT_RECORDING_CHANNEL:
1111 strValue = m_tvTimersInfo.GetNextTimerChannelName();
1112 return true;
1113 case PVR_TV_NEXT_RECORDING_CHAN_ICO:
1114 strValue = m_tvTimersInfo.GetNextTimerChannelIcon();
1115 return true;
1116 case PVR_TV_NEXT_RECORDING_DATETIME:
1117 strValue = m_tvTimersInfo.GetNextTimerDateTime();
1118 return true;
1119 case PVR_RADIO_NOW_RECORDING_TITLE:
1120 strValue = m_radioTimersInfo.GetActiveTimerTitle();
1121 return true;
1122 case PVR_RADIO_NOW_RECORDING_CHANNEL:
1123 strValue = m_radioTimersInfo.GetActiveTimerChannelName();
1124 return true;
1125 case PVR_RADIO_NOW_RECORDING_CHAN_ICO:
1126 strValue = m_radioTimersInfo.GetActiveTimerChannelIcon();
1127 return true;
1128 case PVR_RADIO_NOW_RECORDING_DATETIME:
1129 strValue = m_radioTimersInfo.GetActiveTimerDateTime();
1130 return true;
1131 case PVR_RADIO_NEXT_RECORDING_TITLE:
1132 strValue = m_radioTimersInfo.GetNextTimerTitle();
1133 return true;
1134 case PVR_RADIO_NEXT_RECORDING_CHANNEL:
1135 strValue = m_radioTimersInfo.GetNextTimerChannelName();
1136 return true;
1137 case PVR_RADIO_NEXT_RECORDING_CHAN_ICO:
1138 strValue = m_radioTimersInfo.GetNextTimerChannelIcon();
1139 return true;
1140 case PVR_RADIO_NEXT_RECORDING_DATETIME:
1141 strValue = m_radioTimersInfo.GetNextTimerDateTime();
1142 return true;
1143 case PVR_NEXT_TIMER:
1144 strValue = m_anyTimersInfo.GetNextTimer();
1145 return true;
1146 case PVR_ACTUAL_STREAM_SIG:
1147 CharInfoSignal(strValue);
1148 return true;
1149 case PVR_ACTUAL_STREAM_SNR:
1150 CharInfoSNR(strValue);
1151 return true;
1152 case PVR_ACTUAL_STREAM_BER:
1153 CharInfoBER(strValue);
1154 return true;
1155 case PVR_ACTUAL_STREAM_UNC:
1156 CharInfoUNC(strValue);
1157 return true;
1158 case PVR_ACTUAL_STREAM_CLIENT:
1159 CharInfoPlayingClientName(strValue);
1160 return true;
1161 case PVR_ACTUAL_STREAM_DEVICE:
1162 CharInfoFrontendName(strValue);
1163 return true;
1164 case PVR_ACTUAL_STREAM_STATUS:
1165 CharInfoFrontendStatus(strValue);
1166 return true;
1167 case PVR_ACTUAL_STREAM_CRYPTION:
1168 CharInfoEncryption(strValue);
1169 return true;
1170 case PVR_ACTUAL_STREAM_SERVICE:
1171 CharInfoService(strValue);
1172 return true;
1173 case PVR_ACTUAL_STREAM_MUX:
1174 CharInfoMux(strValue);
1175 return true;
1176 case PVR_ACTUAL_STREAM_PROVIDER:
1177 CharInfoProvider(strValue);
1178 return true;
1179 case PVR_CLIENT_NAME:
1180 CharInfoClientName(strValue);
1181 return true;
1182 case PVR_INSTANCE_NAME:
1183 CharInfoInstanceName(strValue);
1184 return true;
1185 case PVR_BACKEND_NAME:
1186 CharInfoBackendName(strValue);
1187 return true;
1188 case PVR_BACKEND_VERSION:
1189 CharInfoBackendVersion(strValue);
1190 return true;
1191 case PVR_BACKEND_HOST:
1192 CharInfoBackendHost(strValue);
1193 return true;
1194 case PVR_BACKEND_DISKSPACE:
1195 CharInfoBackendDiskspace(strValue);
1196 return true;
1197 case PVR_BACKEND_PROVIDERS:
1198 CharInfoBackendProviders(strValue);
1199 return true;
1200 case PVR_BACKEND_CHANNEL_GROUPS:
1201 CharInfoBackendChannelGroups(strValue);
1202 return true;
1203 case PVR_BACKEND_CHANNELS:
1204 CharInfoBackendChannels(strValue);
1205 return true;
1206 case PVR_BACKEND_TIMERS:
1207 CharInfoBackendTimers(strValue);
1208 return true;
1209 case PVR_BACKEND_RECORDINGS:
1210 CharInfoBackendRecordings(strValue);
1211 return true;
1212 case PVR_BACKEND_DELETED_RECORDINGS:
1213 CharInfoBackendDeletedRecordings(strValue);
1214 return true;
1215 case PVR_BACKEND_NUMBER:
1216 CharInfoBackendNumber(strValue);
1217 return true;
1218 case PVR_TOTAL_DISKSPACE:
1219 CharInfoTotalDiskSpace(strValue);
1220 return true;
1221 case PVR_CHANNEL_NUMBER_INPUT:
1222 strValue = m_channelNumberInput;
1223 return true;
1226 return false;
1229 bool CPVRGUIInfo::GetRadioRDSLabel(const CFileItem* item,
1230 const CGUIInfo& info,
1231 std::string& strValue) const
1233 if (!item->HasPVRChannelInfoTag())
1234 return false;
1236 const std::shared_ptr<const CPVRRadioRDSInfoTag> tag =
1237 item->GetPVRChannelInfoTag()->GetRadioRDSInfoTag();
1238 if (tag)
1240 switch (info.m_info)
1242 case RDS_CHANNEL_COUNTRY:
1243 strValue = tag->GetCountry();
1244 return true;
1245 case RDS_TITLE:
1246 strValue = tag->GetTitle();
1247 return true;
1248 case RDS_ARTIST:
1249 strValue = tag->GetArtist();
1250 return true;
1251 case RDS_BAND:
1252 strValue = tag->GetBand();
1253 return true;
1254 case RDS_COMPOSER:
1255 strValue = tag->GetComposer();
1256 return true;
1257 case RDS_CONDUCTOR:
1258 strValue = tag->GetConductor();
1259 return true;
1260 case RDS_ALBUM:
1261 strValue = tag->GetAlbum();
1262 return true;
1263 case RDS_ALBUM_TRACKNUMBER:
1264 if (tag->GetAlbumTrackNumber() > 0)
1266 strValue = std::to_string(tag->GetAlbumTrackNumber());
1267 return true;
1269 break;
1270 case RDS_GET_RADIO_STYLE:
1271 strValue = tag->GetRadioStyle();
1272 return true;
1273 case RDS_COMMENT:
1274 strValue = tag->GetComment();
1275 return true;
1276 case RDS_INFO_NEWS:
1277 strValue = tag->GetInfoNews();
1278 return true;
1279 case RDS_INFO_NEWS_LOCAL:
1280 strValue = tag->GetInfoNewsLocal();
1281 return true;
1282 case RDS_INFO_STOCK:
1283 strValue = tag->GetInfoStock();
1284 return true;
1285 case RDS_INFO_STOCK_SIZE:
1286 strValue = std::to_string(tag->GetInfoStock().size());
1287 return true;
1288 case RDS_INFO_SPORT:
1289 strValue = tag->GetInfoSport();
1290 return true;
1291 case RDS_INFO_SPORT_SIZE:
1292 strValue = std::to_string(tag->GetInfoSport().size());
1293 return true;
1294 case RDS_INFO_LOTTERY:
1295 strValue = tag->GetInfoLottery();
1296 return true;
1297 case RDS_INFO_LOTTERY_SIZE:
1298 strValue = std::to_string(tag->GetInfoLottery().size());
1299 return true;
1300 case RDS_INFO_WEATHER:
1301 strValue = tag->GetInfoWeather();
1302 return true;
1303 case RDS_INFO_WEATHER_SIZE:
1304 strValue = std::to_string(tag->GetInfoWeather().size());
1305 return true;
1306 case RDS_INFO_HOROSCOPE:
1307 strValue = tag->GetInfoHoroscope();
1308 return true;
1309 case RDS_INFO_HOROSCOPE_SIZE:
1310 strValue = std::to_string(tag->GetInfoHoroscope().size());
1311 return true;
1312 case RDS_INFO_CINEMA:
1313 strValue = tag->GetInfoCinema();
1314 return true;
1315 case RDS_INFO_CINEMA_SIZE:
1316 strValue = std::to_string(tag->GetInfoCinema().size());
1317 return true;
1318 case RDS_INFO_OTHER:
1319 strValue = tag->GetInfoOther();
1320 return true;
1321 case RDS_INFO_OTHER_SIZE:
1322 strValue = std::to_string(tag->GetInfoOther().size());
1323 return true;
1324 case RDS_PROG_HOST:
1325 strValue = tag->GetProgHost();
1326 return true;
1327 case RDS_PROG_EDIT_STAFF:
1328 strValue = tag->GetEditorialStaff();
1329 return true;
1330 case RDS_PROG_HOMEPAGE:
1331 strValue = tag->GetProgWebsite();
1332 return true;
1333 case RDS_PROG_STYLE:
1334 strValue = tag->GetProgStyle();
1335 return true;
1336 case RDS_PHONE_HOTLINE:
1337 strValue = tag->GetPhoneHotline();
1338 return true;
1339 case RDS_PHONE_STUDIO:
1340 strValue = tag->GetPhoneStudio();
1341 return true;
1342 case RDS_SMS_STUDIO:
1343 strValue = tag->GetSMSStudio();
1344 return true;
1345 case RDS_EMAIL_HOTLINE:
1346 strValue = tag->GetEMailHotline();
1347 return true;
1348 case RDS_EMAIL_STUDIO:
1349 strValue = tag->GetEMailStudio();
1350 return true;
1351 case RDS_PROG_STATION:
1352 strValue = tag->GetProgStation();
1353 return true;
1354 case RDS_PROG_NOW:
1355 strValue = tag->GetProgNow();
1356 return true;
1357 case RDS_PROG_NEXT:
1358 strValue = tag->GetProgNext();
1359 return true;
1360 case RDS_AUDIO_LANG:
1361 strValue = tag->GetLanguage();
1362 return true;
1363 case RDS_GET_RADIOTEXT_LINE:
1364 strValue = tag->GetRadioText(info.GetData1());
1365 return true;
1368 return false;
1371 bool CPVRGUIInfo::GetFallbackLabel(std::string& value,
1372 const CFileItem* item,
1373 int contextWindow,
1374 const CGUIInfo& info,
1375 std::string* fallback)
1377 if (item->IsPVRChannel() || item->IsEPG() || item->IsPVRTimer())
1379 switch (info.m_info)
1381 /////////////////////////////////////////////////////////////////////////////////////////////
1382 // VIDEOPLAYER_*, MUSICPLAYER_*
1383 /////////////////////////////////////////////////////////////////////////////////////////////
1384 case VIDEOPLAYER_TITLE:
1385 case MUSICPLAYER_TITLE:
1387 const std::shared_ptr<const CPVREpgInfoTag> tag{CPVRItem(item).GetEpgInfoTag()};
1388 value = CServiceBroker::GetPVRManager().Get<PVR::GUI::EPG>().GetTitleForEpgTag(tag);
1389 return !value.empty();
1391 default:
1392 break;
1395 return false;
1398 bool CPVRGUIInfo::GetInt(int& value,
1399 const CGUIListItem* item,
1400 int contextWindow,
1401 const CGUIInfo& info) const
1403 if (!item->IsFileItem())
1404 return false;
1406 const CFileItem* fitem = static_cast<const CFileItem*>(item);
1407 return GetListItemAndPlayerInt(fitem, info, value) || GetPVRInt(fitem, info, value);
1410 bool CPVRGUIInfo::GetListItemAndPlayerInt(const CFileItem* item,
1411 const CGUIInfo& info,
1412 int& iValue) const
1414 switch (info.m_info)
1416 case LISTITEM_PROGRESS:
1417 if (item->IsPVRChannel() || item->IsEPG())
1419 const std::shared_ptr<const CPVREpgInfoTag> epgTag = CPVRItem(item).GetEpgInfoTag();
1420 if (epgTag)
1421 iValue = static_cast<int>(epgTag->ProgressPercentage());
1423 return true;
1425 return false;
1428 bool CPVRGUIInfo::GetPVRInt(const CFileItem* item, const CGUIInfo& info, int& iValue) const
1430 std::unique_lock<CCriticalSection> lock(m_critSection);
1432 switch (info.m_info)
1434 case PVR_EPG_EVENT_DURATION:
1436 const std::shared_ptr<const CPVREpgInfoTag> epgTag =
1437 (item->IsPVRChannel() || item->IsEPG()) ? CPVRItem(item).GetEpgInfoTag() : nullptr;
1438 iValue = m_timesInfo.GetEpgEventDuration(epgTag);
1439 return true;
1441 case PVR_EPG_EVENT_PROGRESS:
1443 const std::shared_ptr<const CPVREpgInfoTag> epgTag =
1444 (item->IsPVRChannel() || item->IsEPG()) ? CPVRItem(item).GetEpgInfoTag() : nullptr;
1445 iValue = m_timesInfo.GetEpgEventProgress(epgTag);
1446 return true;
1448 case PVR_TIMESHIFT_PROGRESS:
1449 iValue = m_timesInfo.GetTimeshiftProgress();
1450 return true;
1451 case PVR_TIMESHIFT_PROGRESS_DURATION:
1452 iValue = m_timesInfo.GetTimeshiftProgressDuration();
1453 return true;
1454 case PVR_TIMESHIFT_PROGRESS_PLAY_POS:
1455 iValue = m_timesInfo.GetTimeshiftProgressPlayPosition();
1456 return true;
1457 case PVR_TIMESHIFT_PROGRESS_EPG_START:
1458 iValue = m_timesInfo.GetTimeshiftProgressEpgStart();
1459 return true;
1460 case PVR_TIMESHIFT_PROGRESS_EPG_END:
1461 iValue = m_timesInfo.GetTimeshiftProgressEpgEnd();
1462 return true;
1463 case PVR_TIMESHIFT_PROGRESS_BUFFER_START:
1464 iValue = m_timesInfo.GetTimeshiftProgressBufferStart();
1465 return true;
1466 case PVR_TIMESHIFT_PROGRESS_BUFFER_END:
1467 iValue = m_timesInfo.GetTimeshiftProgressBufferEnd();
1468 return true;
1469 case PVR_TIMESHIFT_SEEKBAR:
1470 iValue = GetTimeShiftSeekPercent();
1471 return true;
1472 case PVR_ACTUAL_STREAM_SIG_PROGR:
1473 iValue = MathUtils::round_int(static_cast<double>(m_qualityInfo.Signal()) / 0xFFFF * 100.0);
1474 return true;
1475 case PVR_ACTUAL_STREAM_SNR_PROGR:
1476 iValue = MathUtils::round_int(static_cast<double>(m_qualityInfo.SNR()) / 0xFFFF * 100.0);
1477 return true;
1478 case PVR_BACKEND_DISKSPACE_PROGR:
1479 if (m_iBackendDiskTotal > 0)
1480 iValue = MathUtils::round_int(static_cast<double>(m_iBackendDiskUsed) /
1481 m_iBackendDiskTotal * 100.0);
1482 else
1483 iValue = 0xFF;
1484 return true;
1485 case PVR_CLIENT_COUNT:
1486 iValue = static_cast<int>(CServiceBroker::GetPVRManager().Clients()->EnabledClientAmount());
1487 return true;
1489 return false;
1492 bool CPVRGUIInfo::GetBool(bool& value,
1493 const CGUIListItem* item,
1494 int contextWindow,
1495 const CGUIInfo& info) const
1497 if (!item->IsFileItem())
1498 return false;
1500 const CFileItem* fitem = static_cast<const CFileItem*>(item);
1501 return GetListItemAndPlayerBool(fitem, info, value) || GetPVRBool(fitem, info, value) ||
1502 GetRadioRDSBool(fitem, info, value);
1505 bool CPVRGUIInfo::GetListItemAndPlayerBool(const CFileItem* item,
1506 const CGUIInfo& info,
1507 bool& bValue) const
1509 switch (info.m_info)
1511 case LISTITEM_HASARCHIVE:
1512 if (item->IsPVRChannel())
1514 bValue = item->GetPVRChannelInfoTag()->HasArchive();
1515 return true;
1517 break;
1518 case LISTITEM_ISPLAYABLE:
1519 if (item->IsEPG())
1521 bValue = item->GetEPGInfoTag()->IsPlayable();
1522 return true;
1524 break;
1525 case LISTITEM_ISRECORDING:
1526 if (item->IsPVRChannel())
1528 bValue = CServiceBroker::GetPVRManager().Timers()->IsRecordingOnChannel(
1529 *item->GetPVRChannelInfoTag());
1530 return true;
1532 else if (item->IsEPG() || item->IsPVRTimer())
1534 const std::shared_ptr<const CPVRTimerInfoTag> timer = CPVRItem(item).GetTimerInfoTag();
1535 if (timer)
1536 bValue = timer->IsRecording();
1537 return true;
1539 else if (item->IsPVRRecording())
1541 bValue = item->GetPVRRecordingInfoTag()->IsInProgress();
1542 return true;
1544 break;
1545 case LISTITEM_INPROGRESS:
1546 if (item->IsPVRChannel() || item->IsEPG())
1548 const std::shared_ptr<const CPVREpgInfoTag> epgTag = CPVRItem(item).GetEpgInfoTag();
1549 if (epgTag)
1550 bValue = epgTag->IsActive();
1551 return true;
1553 break;
1554 case LISTITEM_HASTIMER:
1555 if (item->IsPVRChannel() || item->IsEPG() || item->IsPVRTimer())
1557 const std::shared_ptr<const CPVRTimerInfoTag> timer = CPVRItem(item).GetTimerInfoTag();
1558 if (timer)
1559 bValue = true;
1560 return true;
1562 break;
1563 case LISTITEM_HASTIMERSCHEDULE:
1564 if (item->IsPVRChannel() || item->IsEPG() || item->IsPVRTimer())
1566 const std::shared_ptr<const CPVRTimerInfoTag> timer = CPVRItem(item).GetTimerInfoTag();
1567 if (timer)
1568 bValue = timer->HasParent();
1569 return true;
1571 break;
1572 case LISTITEM_HASREMINDER:
1573 if (item->IsPVRChannel() || item->IsEPG() || item->IsPVRTimer())
1575 const std::shared_ptr<const CPVRTimerInfoTag> timer = CPVRItem(item).GetTimerInfoTag();
1576 if (timer)
1577 bValue = timer->IsReminder();
1578 return true;
1580 break;
1581 case LISTITEM_HASREMINDERRULE:
1582 if (item->IsPVRChannel() || item->IsEPG() || item->IsPVRTimer())
1584 const std::shared_ptr<const CPVRTimerInfoTag> timer = CPVRItem(item).GetTimerInfoTag();
1585 if (timer)
1586 bValue = timer->IsReminder() && timer->HasParent();
1587 return true;
1589 break;
1590 case LISTITEM_TIMERISACTIVE:
1591 if (item->IsPVRChannel() || item->IsEPG())
1593 const std::shared_ptr<const CPVRTimerInfoTag> timer = CPVRItem(item).GetTimerInfoTag();
1594 if (timer)
1595 bValue = timer->IsActive();
1596 break;
1598 break;
1599 case LISTITEM_TIMERHASCONFLICT:
1600 if (item->IsPVRChannel() || item->IsEPG())
1602 const std::shared_ptr<const CPVRTimerInfoTag> timer = CPVRItem(item).GetTimerInfoTag();
1603 if (timer)
1604 bValue = timer->HasConflict();
1605 return true;
1607 break;
1608 case LISTITEM_TIMERHASERROR:
1609 if (item->IsPVRChannel() || item->IsEPG())
1611 const std::shared_ptr<const CPVRTimerInfoTag> timer = CPVRItem(item).GetTimerInfoTag();
1612 if (timer)
1613 bValue = (timer->IsBroken() && !timer->HasConflict());
1614 return true;
1616 break;
1617 case LISTITEM_HASRECORDING:
1618 if (item->IsPVRChannel() || item->IsEPG())
1620 const std::shared_ptr<const CPVREpgInfoTag> epgTag = CPVRItem(item).GetEpgInfoTag();
1621 if (epgTag)
1622 bValue = !!CServiceBroker::GetPVRManager().Recordings()->GetRecordingForEpgTag(epgTag);
1623 return true;
1625 break;
1626 case LISTITEM_HAS_EPG:
1627 if (item->IsPVRChannel() || item->IsEPG() || item->IsPVRTimer())
1629 const std::shared_ptr<const CPVREpgInfoTag> epgTag = CPVRItem(item).GetEpgInfoTag();
1630 bValue = (epgTag != nullptr);
1631 return true;
1633 break;
1634 case LISTITEM_ISENCRYPTED:
1635 if (item->IsPVRChannel() || item->IsEPG())
1637 const std::shared_ptr<const CPVRChannel> channel = CPVRItem(item).GetChannel();
1638 if (channel)
1639 bValue = channel->IsEncrypted();
1640 return true;
1642 break;
1643 case LISTITEM_IS_NEW:
1644 if (item->IsEPG())
1646 if (item->GetEPGInfoTag())
1648 bValue = item->GetEPGInfoTag()->IsNew();
1649 return true;
1652 else if (item->IsPVRRecording())
1654 bValue = item->GetPVRRecordingInfoTag()->IsNew();
1655 return true;
1657 else if (item->IsPVRTimer() && item->GetPVRTimerInfoTag()->GetEpgInfoTag())
1659 bValue = item->GetPVRTimerInfoTag()->GetEpgInfoTag()->IsNew();
1660 return true;
1662 else if (item->IsPVRChannel())
1664 const std::shared_ptr<const CPVREpgInfoTag> epgNow =
1665 item->GetPVRChannelInfoTag()->GetEPGNow();
1666 bValue = epgNow ? epgNow->IsNew() : false;
1667 return true;
1669 break;
1670 case LISTITEM_IS_PREMIERE:
1671 if (item->IsEPG())
1673 bValue = item->GetEPGInfoTag()->IsPremiere();
1674 return true;
1676 else if (item->IsPVRRecording())
1678 bValue = item->GetPVRRecordingInfoTag()->IsPremiere();
1679 return true;
1681 else if (item->IsPVRTimer() && item->GetPVRTimerInfoTag()->GetEpgInfoTag())
1683 bValue = item->GetPVRTimerInfoTag()->GetEpgInfoTag()->IsPremiere();
1684 return true;
1686 else if (item->IsPVRChannel())
1688 const std::shared_ptr<const CPVREpgInfoTag> epgNow =
1689 item->GetPVRChannelInfoTag()->GetEPGNow();
1690 bValue = epgNow ? epgNow->IsPremiere() : false;
1691 return true;
1693 break;
1694 case LISTITEM_IS_FINALE:
1695 if (item->IsEPG())
1697 bValue = item->GetEPGInfoTag()->IsFinale();
1698 return true;
1700 else if (item->IsPVRRecording())
1702 bValue = item->GetPVRRecordingInfoTag()->IsFinale();
1703 return true;
1705 else if (item->IsPVRTimer() && item->GetPVRTimerInfoTag()->GetEpgInfoTag())
1707 bValue = item->GetPVRTimerInfoTag()->GetEpgInfoTag()->IsFinale();
1708 return true;
1710 else if (item->IsPVRChannel())
1712 const std::shared_ptr<const CPVREpgInfoTag> epgNow =
1713 item->GetPVRChannelInfoTag()->GetEPGNow();
1714 bValue = epgNow ? epgNow->IsFinale() : false;
1715 return true;
1717 break;
1718 case LISTITEM_IS_LIVE:
1719 if (item->IsEPG())
1721 bValue = item->GetEPGInfoTag()->IsLive();
1722 return true;
1724 else if (item->IsPVRRecording())
1726 bValue = item->GetPVRRecordingInfoTag()->IsLive();
1727 return true;
1729 else if (item->IsPVRTimer() && item->GetPVRTimerInfoTag()->GetEpgInfoTag())
1731 bValue = item->GetPVRTimerInfoTag()->GetEpgInfoTag()->IsLive();
1732 return true;
1734 else if (item->IsPVRChannel())
1736 const std::shared_ptr<const CPVREpgInfoTag> epgNow =
1737 item->GetPVRChannelInfoTag()->GetEPGNow();
1738 bValue = epgNow ? epgNow->IsLive() : false;
1739 return true;
1741 break;
1742 case LISTITEM_ISPLAYING:
1743 if (item->IsPVRChannel())
1745 const std::shared_ptr<const CPVRChannel> playingChannel{
1746 CServiceBroker::GetPVRManager().PlaybackState()->GetPlayingChannel()};
1747 if (playingChannel)
1749 const std::shared_ptr<const CPVRChannel> channel{item->GetPVRChannelInfoTag()};
1750 bValue = (channel->StorageId() == playingChannel->StorageId());
1751 return true;
1754 break;
1755 case MUSICPLAYER_CONTENT:
1756 case VIDEOPLAYER_CONTENT:
1757 if (item->IsPVRChannel())
1759 bValue = StringUtils::EqualsNoCase(info.GetData3(), "livetv");
1760 return bValue; // if no match for this provider, other providers shall be asked.
1762 break;
1763 case VIDEOPLAYER_HAS_INFO:
1764 if (item->IsPVRChannel())
1766 bValue = !item->GetPVRChannelInfoTag()->ChannelName().empty();
1767 return true;
1769 break;
1770 case VIDEOPLAYER_HAS_EPG:
1771 if (item->IsPVRChannel())
1773 bValue = (item->GetPVRChannelInfoTag()->GetEPGNow() != nullptr);
1774 return true;
1776 break;
1777 case VIDEOPLAYER_CAN_RESUME_LIVE_TV:
1778 if (item->IsPVRRecording())
1780 const std::shared_ptr<const CPVRRecording> recording = item->GetPVRRecordingInfoTag();
1781 const std::shared_ptr<const CPVREpg> epg =
1782 recording->Channel() ? recording->Channel()->GetEPG() : nullptr;
1783 const std::shared_ptr<const CPVREpgInfoTag> epgTag =
1784 CServiceBroker::GetPVRManager().EpgContainer().GetTagById(epg,
1785 recording->BroadcastUid());
1786 bValue = (epgTag && epgTag->IsActive());
1787 return true;
1789 break;
1790 case PLAYER_IS_CHANNEL_PREVIEW_ACTIVE:
1791 if (item->IsPVRChannel())
1793 if (m_previewAndPlayerShowInfo)
1795 bValue = true;
1797 else
1799 bValue = !m_videoInfo.valid;
1800 if (bValue && item->GetPVRChannelInfoTag()->IsRadio())
1801 bValue = !m_audioInfo.valid;
1803 return true;
1805 break;
1807 return false;
1810 bool CPVRGUIInfo::GetPVRBool(const CFileItem* item, const CGUIInfo& info, bool& bValue) const
1812 std::unique_lock<CCriticalSection> lock(m_critSection);
1814 switch (info.m_info)
1816 case PVR_IS_RECORDING:
1817 bValue = m_anyTimersInfo.HasRecordingTimers();
1818 return true;
1819 case PVR_IS_RECORDING_TV:
1820 bValue = m_tvTimersInfo.HasRecordingTimers();
1821 return true;
1822 case PVR_IS_RECORDING_RADIO:
1823 bValue = m_radioTimersInfo.HasRecordingTimers();
1824 return true;
1825 case PVR_HAS_TIMER:
1826 bValue = m_anyTimersInfo.HasTimers();
1827 return true;
1828 case PVR_HAS_TV_TIMER:
1829 bValue = m_tvTimersInfo.HasTimers();
1830 return true;
1831 case PVR_HAS_RADIO_TIMER:
1832 bValue = m_radioTimersInfo.HasTimers();
1833 return true;
1834 case PVR_HAS_TV_CHANNELS:
1835 bValue = m_bHasTVChannels;
1836 return true;
1837 case PVR_HAS_RADIO_CHANNELS:
1838 bValue = m_bHasRadioChannels;
1839 return true;
1840 case PVR_HAS_NONRECORDING_TIMER:
1841 bValue = m_anyTimersInfo.HasNonRecordingTimers();
1842 return true;
1843 case PVR_HAS_NONRECORDING_TV_TIMER:
1844 bValue = m_tvTimersInfo.HasNonRecordingTimers();
1845 return true;
1846 case PVR_HAS_NONRECORDING_RADIO_TIMER:
1847 bValue = m_radioTimersInfo.HasNonRecordingTimers();
1848 return true;
1849 case PVR_IS_PLAYING_TV:
1850 bValue = m_bIsPlayingTV;
1851 return true;
1852 case PVR_IS_PLAYING_RADIO:
1853 bValue = m_bIsPlayingRadio;
1854 return true;
1855 case PVR_IS_PLAYING_RECORDING:
1856 bValue = m_bIsPlayingRecording;
1857 return true;
1858 case PVR_IS_PLAYING_EPGTAG:
1859 bValue = m_bIsPlayingEpgTag;
1860 return true;
1861 case PVR_ACTUAL_STREAM_ENCRYPTED:
1862 bValue = m_bIsPlayingEncryptedStream;
1863 return true;
1864 case PVR_IS_TIMESHIFTING:
1865 bValue = m_timesInfo.IsTimeshifting();
1866 return true;
1867 case PVR_CAN_RECORD_PLAYING_CHANNEL:
1868 bValue = m_bCanRecordPlayingChannel;
1869 return true;
1870 case PVR_IS_RECORDING_PLAYING_CHANNEL:
1871 bValue = m_bIsRecordingPlayingChannel;
1872 return true;
1873 case PVR_IS_PLAYING_ACTIVE_RECORDING:
1874 bValue = m_bIsPlayingActiveRecording;
1875 return true;
1877 return false;
1880 bool CPVRGUIInfo::GetRadioRDSBool(const CFileItem* item, const CGUIInfo& info, bool& bValue) const
1882 if (!item->HasPVRChannelInfoTag())
1883 return false;
1885 const std::shared_ptr<const CPVRRadioRDSInfoTag> tag =
1886 item->GetPVRChannelInfoTag()->GetRadioRDSInfoTag();
1887 if (tag)
1889 switch (info.m_info)
1891 case RDS_HAS_RADIOTEXT:
1892 bValue = tag->IsPlayingRadioText();
1893 return true;
1894 case RDS_HAS_RADIOTEXT_PLUS:
1895 bValue = tag->IsPlayingRadioTextPlus();
1896 return true;
1897 case RDS_HAS_HOTLINE_DATA:
1898 bValue = (!tag->GetEMailHotline().empty() || !tag->GetPhoneHotline().empty());
1899 return true;
1900 case RDS_HAS_STUDIO_DATA:
1901 bValue = (!tag->GetEMailStudio().empty() || !tag->GetSMSStudio().empty() ||
1902 !tag->GetPhoneStudio().empty());
1903 return true;
1907 switch (info.m_info)
1909 case RDS_HAS_RDS:
1911 const auto& components = CServiceBroker::GetAppComponents();
1912 const auto appPlayer = components.GetComponent<CApplicationPlayer>();
1913 bValue = appPlayer->IsPlayingRDS();
1914 return true;
1918 return false;
1921 void CPVRGUIInfo::CharInfoBackendNumber(std::string& strValue) const
1923 size_t numBackends = m_backendProperties.size();
1925 if (numBackends > 0)
1926 strValue = StringUtils::Format("{0} {1} {2}", m_iCurrentActiveClient + 1,
1927 g_localizeStrings.Get(20163), numBackends);
1928 else
1929 strValue = g_localizeStrings.Get(14023);
1932 void CPVRGUIInfo::CharInfoTotalDiskSpace(std::string& strValue) const
1934 strValue = StringUtils::SizeToString(m_iBackendDiskTotal).c_str();
1937 void CPVRGUIInfo::CharInfoSignal(std::string& strValue) const
1939 strValue = StringUtils::Format("{} %", m_qualityInfo.Signal() / 655);
1942 void CPVRGUIInfo::CharInfoSNR(std::string& strValue) const
1944 strValue = StringUtils::Format("{} %", m_qualityInfo.SNR() / 655);
1947 void CPVRGUIInfo::CharInfoBER(std::string& strValue) const
1949 strValue = StringUtils::Format("{:08X}", m_qualityInfo.BER());
1952 void CPVRGUIInfo::CharInfoUNC(std::string& strValue) const
1954 strValue = StringUtils::Format("{:08X}", m_qualityInfo.UNC());
1957 void CPVRGUIInfo::CharInfoFrontendName(std::string& strValue) const
1959 strValue = m_qualityInfo.AdapterName();
1960 if (strValue.empty())
1961 strValue = g_localizeStrings.Get(13205);
1964 void CPVRGUIInfo::CharInfoFrontendStatus(std::string& strValue) const
1966 strValue = m_qualityInfo.AdapterStatus();
1967 if (strValue.empty())
1968 strValue = g_localizeStrings.Get(13205);
1971 void CPVRGUIInfo::CharInfoClientName(std::string& strValue) const
1973 m_updateBackendCacheRequested = true;
1974 strValue = m_strClientName;
1977 void CPVRGUIInfo::CharInfoInstanceName(std::string& strValue) const
1979 m_updateBackendCacheRequested = true;
1980 strValue = m_strInstanceName;
1983 void CPVRGUIInfo::CharInfoBackendName(std::string& strValue) const
1985 m_updateBackendCacheRequested = true;
1986 strValue = m_strBackendName;
1989 void CPVRGUIInfo::CharInfoBackendVersion(std::string& strValue) const
1991 m_updateBackendCacheRequested = true;
1992 strValue = m_strBackendVersion;
1995 void CPVRGUIInfo::CharInfoBackendHost(std::string& strValue) const
1997 m_updateBackendCacheRequested = true;
1998 strValue = m_strBackendHost;
2001 void CPVRGUIInfo::CharInfoBackendDiskspace(std::string& strValue) const
2003 m_updateBackendCacheRequested = true;
2005 auto diskTotal = m_iBackendDiskTotal;
2006 auto diskUsed = m_iBackendDiskUsed;
2008 if (diskTotal > 0)
2010 strValue = StringUtils::Format(g_localizeStrings.Get(802),
2011 StringUtils::SizeToString(diskTotal - diskUsed),
2012 StringUtils::SizeToString(diskTotal));
2014 else
2015 strValue = g_localizeStrings.Get(13205);
2018 void CPVRGUIInfo::CharInfoBackendProviders(std::string& strValue) const
2020 m_updateBackendCacheRequested = true;
2021 strValue = m_strBackendProviders;
2024 void CPVRGUIInfo::CharInfoBackendChannelGroups(std::string& strValue) const
2026 m_updateBackendCacheRequested = true;
2027 strValue = m_strBackendChannelGroups;
2030 void CPVRGUIInfo::CharInfoBackendChannels(std::string& strValue) const
2032 m_updateBackendCacheRequested = true;
2033 strValue = m_strBackendChannels;
2036 void CPVRGUIInfo::CharInfoBackendTimers(std::string& strValue) const
2038 m_updateBackendCacheRequested = true;
2039 strValue = m_strBackendTimers;
2042 void CPVRGUIInfo::CharInfoBackendRecordings(std::string& strValue) const
2044 m_updateBackendCacheRequested = true;
2045 strValue = m_strBackendRecordings;
2048 void CPVRGUIInfo::CharInfoBackendDeletedRecordings(std::string& strValue) const
2050 m_updateBackendCacheRequested = true;
2051 strValue = m_strBackendDeletedRecordings;
2054 void CPVRGUIInfo::CharInfoPlayingClientName(std::string& strValue) const
2056 if (m_strPlayingClientName.empty())
2057 strValue = g_localizeStrings.Get(13205);
2058 else
2059 strValue = m_strPlayingClientName;
2062 void CPVRGUIInfo::CharInfoEncryption(std::string& strValue) const
2064 if (m_descrambleInfo.Caid() != PVR_DESCRAMBLE_INFO_NOT_AVAILABLE)
2066 // prefer dynamically updated info, if available
2067 strValue = CPVRChannel::GetEncryptionName(m_descrambleInfo.Caid());
2068 return;
2070 else
2072 const std::shared_ptr<const CPVRChannel> channel =
2073 CServiceBroker::GetPVRManager().PlaybackState()->GetPlayingChannel();
2074 if (channel)
2076 strValue = channel->EncryptionName();
2077 return;
2081 strValue.clear();
2084 void CPVRGUIInfo::CharInfoService(std::string& strValue) const
2086 strValue = m_qualityInfo.ServiceName();
2087 if (strValue.empty())
2088 strValue = g_localizeStrings.Get(13205);
2091 void CPVRGUIInfo::CharInfoMux(std::string& strValue) const
2093 strValue = m_qualityInfo.MuxName();
2094 if (strValue.empty())
2095 strValue = g_localizeStrings.Get(13205);
2098 void CPVRGUIInfo::CharInfoProvider(std::string& strValue) const
2100 strValue = m_qualityInfo.ProviderName();
2101 if (strValue.empty())
2102 strValue = g_localizeStrings.Get(13205);
2105 void CPVRGUIInfo::UpdateBackendCache()
2107 std::unique_lock<CCriticalSection> lock(m_critSection);
2109 // Update the backend information for all backends if
2110 // an update has been requested
2111 if (m_iCurrentActiveClient == 0 && m_updateBackendCacheRequested)
2113 std::vector<SBackend> backendProperties;
2115 CSingleExit exit(m_critSection);
2116 backendProperties = CServiceBroker::GetPVRManager().Clients()->GetBackendProperties();
2119 m_backendProperties = backendProperties;
2120 m_updateBackendCacheRequested = false;
2123 // Store some defaults
2124 m_strClientName = g_localizeStrings.Get(13205);
2125 m_strInstanceName = g_localizeStrings.Get(13205);
2126 m_strBackendName = g_localizeStrings.Get(13205);
2127 m_strBackendVersion = g_localizeStrings.Get(13205);
2128 m_strBackendHost = g_localizeStrings.Get(13205);
2129 m_strBackendProviders = g_localizeStrings.Get(13205);
2130 m_strBackendChannelGroups = g_localizeStrings.Get(13205);
2131 m_strBackendChannels = g_localizeStrings.Get(13205);
2132 m_strBackendTimers = g_localizeStrings.Get(13205);
2133 m_strBackendRecordings = g_localizeStrings.Get(13205);
2134 m_strBackendDeletedRecordings = g_localizeStrings.Get(13205);
2135 m_iBackendDiskTotal = 0;
2136 m_iBackendDiskUsed = 0;
2138 // Update with values from the current client when we have at least one
2139 if (!m_backendProperties.empty())
2141 const auto& backend = m_backendProperties[m_iCurrentActiveClient];
2143 m_strClientName = backend.clientname;
2144 m_strInstanceName = backend.instancename;
2145 m_strBackendName = backend.name;
2146 m_strBackendVersion = backend.version;
2147 m_strBackendHost = backend.host;
2149 // We always display one extra as the add-on itself counts as a provider
2150 if (backend.numProviders >= 0)
2151 m_strBackendProviders = std::to_string(backend.numProviders + 1);
2153 if (backend.numChannelGroups >= 0)
2154 m_strBackendChannelGroups = std::to_string(backend.numChannelGroups);
2156 if (backend.numChannels >= 0)
2157 m_strBackendChannels = std::to_string(backend.numChannels);
2159 if (backend.numTimers >= 0)
2160 m_strBackendTimers = std::to_string(backend.numTimers);
2162 if (backend.numRecordings >= 0)
2163 m_strBackendRecordings = std::to_string(backend.numRecordings);
2165 if (backend.numDeletedRecordings >= 0)
2166 m_strBackendDeletedRecordings = std::to_string(backend.numDeletedRecordings);
2168 m_iBackendDiskTotal = backend.diskTotal;
2169 m_iBackendDiskUsed = backend.diskUsed;
2172 // Update the current active client, eventually wrapping around
2173 if (++m_iCurrentActiveClient >= m_backendProperties.size())
2174 m_iCurrentActiveClient = 0;
2177 void CPVRGUIInfo::UpdateTimersCache()
2179 m_anyTimersInfo.UpdateTimersCache();
2180 m_tvTimersInfo.UpdateTimersCache();
2181 m_radioTimersInfo.UpdateTimersCache();
2184 void CPVRGUIInfo::UpdateTimersToggle()
2186 m_anyTimersInfo.UpdateTimersToggle();
2187 m_tvTimersInfo.UpdateTimersToggle();
2188 m_radioTimersInfo.UpdateTimersToggle();
2191 void CPVRGUIInfo::UpdateNextTimer()
2193 m_anyTimersInfo.UpdateNextTimer();
2194 m_tvTimersInfo.UpdateNextTimer();
2195 m_radioTimersInfo.UpdateNextTimer();
2198 int CPVRGUIInfo::GetTimeShiftSeekPercent() const
2200 int progress = m_timesInfo.GetTimeshiftProgressPlayPosition();
2202 const auto& components = CServiceBroker::GetAppComponents();
2203 const auto appPlayer = components.GetComponent<CApplicationPlayer>();
2204 int seekSize = appPlayer->GetSeekHandler().GetSeekSize();
2205 if (seekSize != 0)
2207 int total = m_timesInfo.GetTimeshiftProgressDuration();
2209 const double totalTime = static_cast<double>(total);
2210 if (totalTime == 0.0)
2211 return 0;
2213 const double percentPerSecond = 100.0 / totalTime;
2214 double percent = progress + percentPerSecond * seekSize;
2215 percent = std::max(0.0, std::min(percent, 100.0));
2216 return MathUtils::round_int(percent);
2218 return progress;