diff options
author | Kai Sommerfeld <kai.sommerfeld@gmx.com> | 2018-03-13 12:03:55 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-03-13 12:03:55 +0100 |
commit | 78aafccf8fcf45e1b38f0af8b6003bc511f20f9a (patch) | |
tree | 007e7f6da4bbbf501c112a0d20cb207b12514ec5 | |
parent | 8897ae5fa3ed8c9af2ece99e1a42da76c42169f9 (diff) | |
parent | ecbbd6ac8ac330ff97d457709fe205cd11cd029c (diff) |
Merge pull request #13642 from ksooo/pvr-guiinfo
[PVR][guiinfo][Estuary] Bunch of PVR guiinfo fixes and improvements
-rw-r--r-- | addons/skin.estuary/xml/DialogSeekBar.xml | 16 | ||||
-rw-r--r-- | addons/skin.estuary/xml/Variables.xml | 1 | ||||
-rw-r--r-- | xbmc/GUIInfoManager.cpp | 57 | ||||
-rw-r--r-- | xbmc/GUIInfoManager.h | 2 | ||||
-rw-r--r-- | xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamPVRManager.cpp | 2 | ||||
-rw-r--r-- | xbmc/dialogs/GUIDialogSeekBar.cpp | 13 | ||||
-rw-r--r-- | xbmc/dialogs/GUIDialogSeekBar.h | 1 | ||||
-rw-r--r-- | xbmc/guiinfo/GUIInfoLabels.h | 4 | ||||
-rw-r--r-- | xbmc/pvr/PVRGUIInfo.cpp | 332 | ||||
-rw-r--r-- | xbmc/pvr/PVRGUIInfo.h | 27 | ||||
-rw-r--r-- | xbmc/pvr/PVRItem.cpp | 23 | ||||
-rw-r--r-- | xbmc/pvr/PVRItem.h | 1 | ||||
-rw-r--r-- | xbmc/pvr/PVRManager.cpp | 16 | ||||
-rw-r--r-- | xbmc/pvr/PVRManager.h | 23 |
14 files changed, 308 insertions, 210 deletions
diff --git a/addons/skin.estuary/xml/DialogSeekBar.xml b/addons/skin.estuary/xml/DialogSeekBar.xml index c37eb5a4e0..75464e6dc9 100644 --- a/addons/skin.estuary/xml/DialogSeekBar.xml +++ b/addons/skin.estuary/xml/DialogSeekBar.xml @@ -176,7 +176,7 @@ <align>center</align> <aligny>center</aligny> <font>font30</font> - <label>[B]$LOCALIZE[31026][/B] $INFO[PVR.timeshiftcur]</label> + <label>[B]$LOCALIZE[31026][/B] $INFO[PVR.TimeshiftCur] (-$INFO[PVR.TimeshiftOffset])</label> </control> <control type="progress"> <left>0</left> @@ -217,7 +217,7 @@ <info>Player.Progress</info> <texturebg border="3" colordiffuse="60FFFFFF">colors/white50.png</texturebg> <midtexture colordiffuse="button_focus">colors/white.png</midtexture> - <visible>!VideoPlayer.HasEpg</visible> + <visible>!VideoPlayer.HasEpg + !Player.ChannelPreviewActive</visible> </control> <control type="slider" id="401"> <left>5</left> @@ -227,7 +227,17 @@ <texturesliderbar colordiffuse="00FFFFFF">osd/progress/nub_bar.png</texturesliderbar> <textureslidernib colordiffuse="button_focus">osd/progress/nub_bar.png</textureslidernib> <textureslidernibfocus colordiffuse="button_focus">colors/white.png</textureslidernibfocus> - <visible>!VideoPlayer.HasEpg</visible> + <visible>Player.SeekEnabled + !VideoPlayer.HasEpg + !Player.ChannelPreviewActive</visible> + </control> + <control type="slider" id="402"> + <left>5</left> + <top>65</top> + <width>100%</width> + <height>25</height> + <texturesliderbar colordiffuse="00FFFFFF">osd/progress/nub_bar.png</texturesliderbar> + <textureslidernib colordiffuse="button_focus">osd/progress/nub_bar.png</textureslidernib> + <textureslidernibfocus colordiffuse="button_focus">colors/white.png</textureslidernibfocus> + <visible>Player.SeekEnabled + VideoPlayer.HasEpg + !Player.ChannelPreviewActive</visible> </control> </control> <control type="group"> diff --git a/addons/skin.estuary/xml/Variables.xml b/addons/skin.estuary/xml/Variables.xml index dd62e8c1c4..7960bed892 100644 --- a/addons/skin.estuary/xml/Variables.xml +++ b/addons/skin.estuary/xml/Variables.xml @@ -199,6 +199,7 @@ </variable> <variable name="SeekTimeLabelVar"> <value condition="!String.IsEmpty(Player.SeekNumeric)">[B]$INFO[Player.SeekNumeric(hh:mm:ss)][/B]</value> + <value condition="Player.Seeking + VideoPlayer.HasEPG">$INFO[PVR.EpgEventSeekTime]$INFO[PVR.EpgEventDuration, / ]</value> <value condition="Player.Seeking">$INFO[Player.SeekTime]$INFO[Player.Duration, / ]</value> <value condition="VideoPlayer.HasEpg">$INFO[PVR.EpgEventElapsedTime]$INFO[PVR.EpgEventDuration, / ]</value> <value>$INFO[Player.Time]$INFO[Player.Duration, / ]</value> diff --git a/xbmc/GUIInfoManager.cpp b/xbmc/GUIInfoManager.cpp index 17120d7b48..e4774f5051 100644 --- a/xbmc/GUIInfoManager.cpp +++ b/xbmc/GUIInfoManager.cpp @@ -2011,10 +2011,15 @@ const infomap musicplayer[] = {{ "title", MUSICPLAYER_TITLE }, /// Returns the stereoscopic mode of the currently playing video (possible /// values: see \ref ListItem_StereoscopicMode "ListItem.StereoscopicMode") /// } +/// \table_row3{ <b>`VideoPlayer.StartTime`</b>, +/// \anchor VideoPlayer_StartTime +/// _string_, +/// Start date and time of the currently playing epg event or recording (PVR). +/// } /// \table_row3{ <b>`VideoPlayer.EndTime`</b>, /// \anchor VideoPlayer_EndTime /// _string_, -/// End date of the currently playing programme (PVR). +/// End date and time of the currently playing epg event or recording (PVR). /// } /// \table_row3{ <b>`VideoPlayer.NextTitle`</b>, /// \anchor VideoPlayer_NextTitle @@ -2122,6 +2127,7 @@ const infomap videoplayer[] = {{ "title", VIDEOPLAYER_TITLE }, { "hassubtitles", VIDEOPLAYER_HASSUBTITLES }, { "subtitlesenabled", VIDEOPLAYER_SUBTITLESENABLED }, { "subtitleslanguage",VIDEOPLAYER_SUBTITLES_LANG }, + { "starttime", VIDEOPLAYER_STARTTIME }, { "endtime", VIDEOPLAYER_ENDTIME }, { "nexttitle", VIDEOPLAYER_NEXT_TITLE }, { "nextgenre", VIDEOPLAYER_NEXT_GENRE }, @@ -4381,6 +4387,11 @@ const infomap playlist[] = {{ "length", PLAYLIST_LENGTH }, /// _string_, /// Returns the remaining time for currently playing epg event /// } +/// \table_row3{ <b>`PVR.EpgEventSeekTime`</b>, +/// \anchor PVR_EpgEventSeekTime +/// _string_, +/// Returns the time the user is seeking within the currently playing epg event +/// } /// \table_row3{ <b>`PVR.EpgEventFinishTime`</b>, /// \anchor PVR_EpgEventFinishTime /// _string_, @@ -4486,6 +4497,11 @@ const infomap playlist[] = {{ "length", PLAYLIST_LENGTH }, /// _integer_, /// Returns the position of currently timeshifted title on TV as integer /// } +/// \table_row3{ <b>`PVR.TimeShiftOffset`</b>, +/// \anchor PVR_TimeShiftOffset +/// _integer_, +/// Returns the delta of timeshifted time to actual time +/// } /// \table_row3{ <b>`PVR.TVNowRecordingTitle`</b>, /// \anchor PVR_TVNowRecordingTitle /// _string_, @@ -4648,6 +4664,7 @@ const infomap pvr[] = {{ "isrecording", PVR_IS_RECORDING { "epgeventelapsedtime", PVR_EPG_EVENT_ELAPSED_TIME }, { "epgeventremainingtime", PVR_EPG_EVENT_REMAINING_TIME }, { "epgeventfinishtime", PVR_EPG_EVENT_FINISH_TIME }, + { "epgeventseektime", PVR_EPG_EVENT_SEEK_TIME }, { "epgeventprogress", PVR_EPG_EVENT_PROGRESS }, { "actstreamclient", PVR_ACTUAL_STREAM_CLIENT }, { "actstreamdevice", PVR_ACTUAL_STREAM_DEVICE }, @@ -4668,6 +4685,7 @@ const infomap pvr[] = {{ "isrecording", PVR_IS_RECORDING { "timeshiftend", PVR_TIMESHIFT_END_TIME }, { "timeshiftcur", PVR_TIMESHIFT_PLAY_TIME }, { "timeshiftprogress", PVR_TIMESHIFT_PROGRESS }, + { "timeshiftoffset", PVR_TIMESHIFT_OFFSET }, { "nowrecordingtitle", PVR_NOW_RECORDING_TITLE }, { "nowrecordingdatetime", PVR_NOW_RECORDING_DATETIME }, { "nowrecordingchannel", PVR_NOW_RECORDING_CHANNEL }, @@ -5574,10 +5592,13 @@ int CGUIInfoManager::TranslateSingleString(const std::string &strCondition, bool } else if (cat.name == "videoplayer") { - for (size_t i = 0; i < sizeof(player_times) / sizeof(infomap); i++) //! @todo remove these, they're repeats + if (prop.name != "starttime") // player.starttime is semantically different from videoplayer.starttime which has its own implementation! { - if (prop.name == player_times[i].str) - return AddMultiInfo(GUIInfo(player_times[i].val, TranslateTimeFormat(prop.param()))); + for (size_t i = 0; i < sizeof(player_times) / sizeof(infomap); i++) //! @todo remove these, they're repeats + { + if (prop.name == player_times[i].str) + return AddMultiInfo(GUIInfo(player_times[i].val, TranslateTimeFormat(prop.param()))); + } } if (prop.name == "content" && prop.num_params()) { @@ -6019,6 +6040,7 @@ std::string CGUIInfoManager::GetLabel(int info, int contextWindow, std::string * case PVR_TIMESHIFT_START_TIME: case PVR_TIMESHIFT_END_TIME: case PVR_TIMESHIFT_PLAY_TIME: + case PVR_TIMESHIFT_OFFSET: case PVR_TV_NOW_RECORDING_TITLE: case PVR_TV_NOW_RECORDING_CHANNEL: case PVR_TV_NOW_RECORDING_CHAN_ICO: @@ -6037,6 +6059,9 @@ std::string CGUIInfoManager::GetLabel(int info, int contextWindow, std::string * case PVR_RADIO_NEXT_RECORDING_DATETIME: CServiceBroker::GetPVRManager().TranslateCharInfo(info, strLabel); break; + case PVR_EPG_EVENT_SEEK_TIME: + CServiceBroker::GetPVRManager().GetSeekTimeLabel(g_application.GetAppPlayer().GetSeekHandler().GetSeekSize(), strLabel); + break; case PVR_CHANNEL_NUMBER_INPUT: strLabel = CServiceBroker::GetPVRManager().GUIActions()->GetChannelNumberInputHandler().GetChannelNumberAsString(); break; @@ -8794,7 +8819,7 @@ std::string CGUIInfoManager::GetVideoLabel(int item) if (m_currentFile->IsPVR()) { std::string strValue; - if (CServiceBroker::GetPVRManager().GetVideoLabel(*m_currentFile, item, strValue)) + if (CServiceBroker::GetPVRManager().GetVideoLabel(m_currentFile, item, strValue)) return strValue; } @@ -9032,6 +9057,28 @@ std::string CGUIInfoManager::GetCurrentPlayTimeRemaining(TIME_FORMAT format) con return ""; } +int CGUIInfoManager::GetEpgEventProgress() const +{ + return std::lrintf(static_cast<float>(CServiceBroker::GetPVRManager().GetElapsedTime()) / CServiceBroker::GetPVRManager().GetTotalTime() * 100.0f); +} + +int CGUIInfoManager::GetEpgEventSeekPercent() const +{ + int seekSize = g_application.GetAppPlayer().GetSeekHandler().GetSeekSize(); + if (seekSize != 0) + { + float elapsedTime = static_cast<float>(CServiceBroker::GetPVRManager().GetElapsedTime() / 1000); + float totalTime = static_cast<float>(CServiceBroker::GetPVRManager().GetTotalTime() / 1000); + float percentPerSecond = 100.0f / totalTime; + float percent = elapsedTime / totalTime * 100.0f + percentPerSecond * seekSize; + return std::lrintf(percent); + } + else + { + return GetEpgEventProgress(); + } +} + void CGUIInfoManager::ResetCurrentItem() { m_currentFile->Reset(); diff --git a/xbmc/GUIInfoManager.h b/xbmc/GUIInfoManager.h index 02f4a345af..6e1dd0d996 100644 --- a/xbmc/GUIInfoManager.h +++ b/xbmc/GUIInfoManager.h @@ -175,6 +175,8 @@ public: int GetTotalPlayTime() const; float GetSeekPercent() const; std::string GetCurrentPlayTimeRemaining(TIME_FORMAT format) const; + int GetEpgEventProgress() const; + int GetEpgEventSeekPercent() const; bool GetDisplayAfterSeek(); void SetDisplayAfterSeek(unsigned int timeOut = 2500, int seekOffset = 0); diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamPVRManager.cpp b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamPVRManager.cpp index 7f7a9946b0..3af9ba714d 100644 --- a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamPVRManager.cpp +++ b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamPVRManager.cpp @@ -205,7 +205,7 @@ int CDVDInputStreamPVRManager::GetTotalTime() int CDVDInputStreamPVRManager::GetTime() { if (!m_isRecording) - return CServiceBroker::GetPVRManager().GetStartTime(); + return CServiceBroker::GetPVRManager().GetElapsedTime(); return 0; } diff --git a/xbmc/dialogs/GUIDialogSeekBar.cpp b/xbmc/dialogs/GUIDialogSeekBar.cpp index 26f18192da..482f690b59 100644 --- a/xbmc/dialogs/GUIDialogSeekBar.cpp +++ b/xbmc/dialogs/GUIDialogSeekBar.cpp @@ -25,7 +25,8 @@ #include "GUIInfoManager.h" #include "SeekHandler.h" -#define POPUP_SEEK_PROGRESS 401 +#define POPUP_SEEK_PROGRESS 401 +#define POPUP_SEEK_EPG_EVENT_PROGRESS 402 CGUIDialogSeekBar::CGUIDialogSeekBar(void) : CGUIDialog(WINDOW_DIALOG_SEEK_BAR, "DialogSeekBar.xml", DialogModalityType::MODELESS) @@ -43,7 +44,8 @@ bool CGUIDialogSeekBar::OnMessage(CGUIMessage& message) case GUI_MSG_WINDOW_DEINIT: return CGUIDialog::OnMessage(message); case GUI_MSG_ITEM_SELECT: - if (message.GetSenderId() == GetID() && message.GetControlId() == POPUP_SEEK_PROGRESS) + if (message.GetSenderId() == GetID() && + (message.GetControlId() == POPUP_SEEK_PROGRESS || message.GetControlId() == POPUP_SEEK_EPG_EVENT_PROGRESS)) return CGUIDialog::OnMessage(message); break; case GUI_MSG_REFRESH_TIMER: @@ -67,5 +69,12 @@ void CGUIDialogSeekBar::FrameMove() if (percent != m_lastPercent) CONTROL_SELECT_ITEM(POPUP_SEEK_PROGRESS, m_lastPercent = percent); + unsigned int epgEventPercent = g_application.GetAppPlayer().GetSeekHandler().InProgress() + ? g_infoManager.GetEpgEventSeekPercent() + : g_infoManager.GetEpgEventProgress(); + + if (epgEventPercent != m_lastEpgEventPercent) + CONTROL_SELECT_ITEM(POPUP_SEEK_EPG_EVENT_PROGRESS, m_lastEpgEventPercent = epgEventPercent); + CGUIDialog::FrameMove(); } diff --git a/xbmc/dialogs/GUIDialogSeekBar.h b/xbmc/dialogs/GUIDialogSeekBar.h index 63a23a6abe..d012e366fb 100644 --- a/xbmc/dialogs/GUIDialogSeekBar.h +++ b/xbmc/dialogs/GUIDialogSeekBar.h @@ -31,4 +31,5 @@ public: void FrameMove() override; private: unsigned int m_lastPercent = ~0U; + unsigned int m_lastEpgEventPercent = ~0U; }; diff --git a/xbmc/guiinfo/GUIInfoLabels.h b/xbmc/guiinfo/GUIInfoLabels.h index 0bdcd0cfa2..d0ec637a07 100644 --- a/xbmc/guiinfo/GUIInfoLabels.h +++ b/xbmc/guiinfo/GUIInfoLabels.h @@ -529,7 +529,9 @@ #define PVR_CHANNEL_NUMBER_INPUT (PVR_STRINGS_START + 59) #define PVR_EPG_EVENT_REMAINING_TIME (PVR_STRINGS_START + 60) #define PVR_EPG_EVENT_FINISH_TIME (PVR_STRINGS_START + 61) -#define PVR_STRINGS_END PVR_EPG_EVENT_FINISH_TIME +#define PVR_TIMESHIFT_OFFSET (PVR_STRINGS_START + 62) +#define PVR_EPG_EVENT_SEEK_TIME (PVR_STRINGS_START + 63) +#define PVR_STRINGS_END PVR_EPG_EVENT_SEEK_TIME #define ADSP_CONDITIONS_START 1300 #define ADSP_IS_ACTIVE (ADSP_CONDITIONS_START) diff --git a/xbmc/pvr/PVRGUIInfo.cpp b/xbmc/pvr/PVRGUIInfo.cpp index 35bcfbfe62..9f1340c5e6 100644 --- a/xbmc/pvr/PVRGUIInfo.cpp +++ b/xbmc/pvr/PVRGUIInfo.cpp @@ -33,6 +33,7 @@ #include "threads/SingleLock.h" #include "utils/StringUtils.h" +#include "pvr/PVRItem.h" #include "pvr/PVRManager.h" #include "pvr/addons/PVRClients.h" #include "pvr/channels/PVRChannel.h" @@ -88,6 +89,7 @@ void CPVRGUIInfo::ResetProperties(void) m_iTimeshiftStartTime = time_t(0); m_iTimeshiftEndTime = time_t(0); m_iTimeshiftPlayTime = time_t(0); + m_iTimeshiftOffset = 0; m_strTimeshiftStartTime.clear(); m_strTimeshiftEndTime.clear(); m_strTimeshiftPlayTime.clear(); @@ -227,6 +229,7 @@ void CPVRGUIInfo::UpdateMisc(void) bool bCanRecordPlayingChannel = bStarted && CServiceBroker::GetPVRManager().CanRecordOnPlayingChannel(); bool bIsRecordingPlayingChannel = bStarted && CServiceBroker::GetPVRManager().IsRecordingOnPlayingChannel(); std::string strPlayingTVGroup = (bStarted && bIsPlayingTV) ? CServiceBroker::GetPVRManager().GetPlayingGroup(false)->GroupName() : ""; + std::string strPlayingRadioGroup = (bStarted && bIsPlayingRadio) ? CServiceBroker::GetPVRManager().GetPlayingGroup(true)->GroupName() : ""; CSingleLock lock(m_critSection); m_strPlayingClientName = strPlayingClientName; @@ -240,6 +243,7 @@ void CPVRGUIInfo::UpdateMisc(void) m_bHasTVChannels = bHasTVChannels; m_bHasRadioChannels = bHasRadioChannels; m_strPlayingTVGroup = strPlayingTVGroup; + m_strPlayingRadioGroup = strPlayingRadioGroup; m_bCanRecordPlayingChannel = bCanRecordPlayingChannel; m_bIsRecordingPlayingChannel = bIsRecordingPlayingChannel; } @@ -258,6 +262,8 @@ void CPVRGUIInfo::UpdateTimeshift(void) m_iTimeshiftStartTime = 0; m_iTimeshiftEndTime = 0; m_iTimeshiftPlayTime = 0; + m_iLastTimeshiftUpdate = 0; + m_iTimeshiftOffset = 0; m_strTimeshiftStartTime.clear(); m_strTimeshiftEndTime.clear(); m_strTimeshiftPlayTime.clear(); @@ -266,17 +272,21 @@ void CPVRGUIInfo::UpdateTimeshift(void) } bool bIsTimeshifting = CServiceBroker::GetPVRManager().Clients()->IsTimeshifting(); + time_t now = std::time(nullptr); time_t iStartTime = CServiceBroker::GetDataCacheCore().GetStartTime(); time_t iPlayTime = CServiceBroker::GetDataCacheCore().GetPlayTime() / 1000; time_t iMinTime = bIsTimeshifting ? CServiceBroker::GetDataCacheCore().GetMinTime() / 1000 : 0; time_t iMaxTime = bIsTimeshifting ? CServiceBroker::GetDataCacheCore().GetMaxTime() / 1000 : 0; + bool bPlaying = CServiceBroker::GetDataCacheCore().GetSpeed() == 1.0; CSingleLock lock(m_critSection); + m_iLastTimeshiftUpdate = now; + if (!iStartTime) { if (m_iStartTime == 0) - iStartTime = std::time(nullptr); + iStartTime = now; else iStartTime = m_iStartTime; } @@ -288,15 +298,17 @@ void CPVRGUIInfo::UpdateTimeshift(void) if (m_iTimeshiftEndTime > m_iTimeshiftStartTime) { - // getstreamtimes api + // timeshifting supported m_iTimeshiftPlayTime = iStartTime + iPlayTime; } - else + else if (bPlaying) { - // legacy api - m_iTimeshiftPlayTime = std::time(nullptr); + // timeshifting not supported + m_iTimeshiftPlayTime = now - m_iTimeshiftOffset; } + m_iTimeshiftOffset = now - m_iTimeshiftPlayTime; + CDateTime tmp; tmp.SetFromUTCDateTime(m_iTimeshiftStartTime); m_strTimeshiftStartTime = tmp.GetAsLocalizedTime("", false); @@ -476,6 +488,9 @@ bool CPVRGUIInfo::TranslateCharInfo(DWORD dwInfo, std::string &strValue) const case PVR_TIMESHIFT_PLAY_TIME: CharInfoTimeshiftPlayTime(strValue); break; + case PVR_TIMESHIFT_OFFSET: + CharInfoTimeshiftOffset(strValue); + break; default: strValue.clear(); bReturn = false; @@ -564,14 +579,16 @@ int CPVRGUIInfo::TranslateIntInfo(const CFileItem &item, DWORD dwInfo) const if (dwInfo == PVR_EPG_EVENT_PROGRESS) { CPVREpgInfoTagPtr epgTag; - const CPVRChannelPtr channel = item.GetPVRChannelInfoTag(); if (channel) epgTag = channel->GetEPGNow(); if (!epgTag) epgTag = item.GetEPGInfoTag(); - if (epgTag) + + if (epgTag && epgTag != GetPlayingTag()) iReturn = std::lrintf(epgTag->ProgressPercentage()); + else + iReturn = std::lrintf(static_cast<float>(GetElapsedTime()) / m_iDuration * 100); } else if (dwInfo == PVR_ACTUAL_STREAM_SIG_PROGR) iReturn = (int) ((float) m_qualityInfo.iSignal / 0xFFFF * 100); @@ -593,59 +610,9 @@ int CPVRGUIInfo::TranslateIntInfo(const CFileItem &item, DWORD dwInfo) const return iReturn; } -#define GET_CURRENT_VIDEO_LABEL_WITH_CONDITION(value_getter_function, condition) \ - if (channel) \ - epgTag = channel->GetEPGNow(); \ - \ - if (epgTag && condition) \ - { \ - strValue = value_getter_function; \ - return true; \ - } \ - return false; \ - -#define GET_CURRENT_VIDEO_LABEL(value_getter_function) \ - GET_CURRENT_VIDEO_LABEL_WITH_CONDITION(value_getter_function, true) - -#define GET_CURRENT_VIDEO_LABEL_OR_DEFAULT(value_getter_function, default_value_getter_function) \ - if (channel) \ - epgTag = channel->GetEPGNow(); \ - \ - if (epgTag) \ - strValue = value_getter_function; \ - else \ - strValue = default_value_getter_function; \ - \ - return true; \ - -#define GET_NEXT_VIDEO_LABEL_WITH_CONDITION(value_getter_function, condition) \ - if (channel) \ - epgTag = channel->GetEPGNext(); \ - \ - if (epgTag && condition) \ - { \ - strValue = value_getter_function; \ - return true; \ - } \ - return false; \ - -#define GET_NEXT_VIDEO_LABEL(value_getter_function) \ - GET_NEXT_VIDEO_LABEL_WITH_CONDITION(value_getter_function, true) - -#define GET_NEXT_VIDEO_LABEL_OR_DEFAULT(value_getter_function, default_value_getter_function) \ - if (channel) \ - epgTag = channel->GetEPGNext(); \ - \ - if (epgTag) \ - strValue = value_getter_function; \ - else \ - strValue = default_value_getter_function; \ - \ - return true; \ - -bool CPVRGUIInfo::GetVideoLabel(const CFileItem &item, int iLabel, std::string &strValue) const -{ - const CPVRRecordingPtr recording(item.GetPVRRecordingInfoTag()); +bool CPVRGUIInfo::GetVideoLabel(const CFileItem *item, int iLabel, std::string &strValue) const +{ + const CPVRRecordingPtr recording(item->GetPVRRecordingInfoTag()); if (recording) { // Note: CPVRRecoding is derived from CVideoInfoTag. All base class properties will be handled @@ -687,176 +654,198 @@ bool CPVRGUIInfo::GetVideoLabel(const CFileItem &item, int iLabel, std::string & } case VIDEOPLAYER_CHANNEL_GROUP: { - if (!recording->IsRadio()) - { - strValue = CServiceBroker::GetPVRManager().GetPlayingTVGroupName(); - return true; - } - break; + strValue = recording->IsRadio() ? m_strPlayingRadioGroup : m_strPlayingTVGroup; + return true; } } return false; } - CPVRChannelPtr channel(item.GetPVRChannelInfoTag()); - CPVREpgInfoTagPtr epgTag(item.GetEPGInfoTag()); + CPVREpgInfoTagPtr epgTag; + CPVRChannelPtr channel; + switch (iLabel) + { + case VIDEOPLAYER_NEXT_TITLE: + case VIDEOPLAYER_NEXT_GENRE: + case VIDEOPLAYER_NEXT_PLOT: + case VIDEOPLAYER_NEXT_PLOT_OUTLINE: + case VIDEOPLAYER_NEXT_STARTTIME: + case VIDEOPLAYER_NEXT_ENDTIME: + case VIDEOPLAYER_NEXT_DURATION: + { + CPVRItem pvrItem(item); + epgTag = pvrItem.GetNextEpgInfoTag(); + channel = pvrItem.GetChannel(); + break; + } + default: + { + CPVRItem pvrItem(item); + epgTag = pvrItem.GetEpgInfoTag(); + channel = pvrItem.GetChannel(); + break; + } + } - if (channel || epgTag) + if (epgTag) { + // 'Now playing' / 'next playing' EPG infos switch (iLabel) { - // 'Now playing' infos case VIDEOPLAYER_TITLE: + case VIDEOPLAYER_NEXT_TITLE: { - GET_CURRENT_VIDEO_LABEL_OR_DEFAULT(epgTag->Title(), - CServiceBroker::GetSettings().GetBool(CSettings::SETTING_EPG_HIDENOINFOAVAILABLE) - ? "" - : g_localizeStrings.Get(19055)); // no information available + strValue = epgTag->Title(); + return true; } case VIDEOPLAYER_GENRE: + case VIDEOPLAYER_NEXT_GENRE: { - GET_CURRENT_VIDEO_LABEL(epgTag->GetGenresLabel()); + strValue = epgTag->GetGenresLabel(); + return true; } case VIDEOPLAYER_PLOT: + case VIDEOPLAYER_NEXT_PLOT: { - GET_CURRENT_VIDEO_LABEL(epgTag->Plot()); + strValue = epgTag->Plot(); + return true; } case VIDEOPLAYER_PLOT_OUTLINE: + case VIDEOPLAYER_NEXT_PLOT_OUTLINE: { - GET_CURRENT_VIDEO_LABEL(epgTag->PlotOutline()); + strValue = epgTag->PlotOutline(); + return true; } case VIDEOPLAYER_STARTTIME: + case VIDEOPLAYER_NEXT_STARTTIME: { - GET_CURRENT_VIDEO_LABEL_OR_DEFAULT(epgTag->StartAsLocalTime().GetAsLocalizedTime("", false), - CDateTime::GetCurrentDateTime().GetAsLocalizedTime("", false)); // @todo: really current time? + strValue = epgTag->StartAsLocalTime().GetAsLocalizedTime("", false); + return true; } case VIDEOPLAYER_ENDTIME: + case VIDEOPLAYER_NEXT_ENDTIME: { - GET_CURRENT_VIDEO_LABEL_OR_DEFAULT(epgTag->EndAsLocalTime().GetAsLocalizedTime("", false), - CDateTime::GetCurrentDateTime().GetAsLocalizedTime("", false)); // @todo: really current time? + strValue = epgTag->EndAsLocalTime().GetAsLocalizedTime("", false); + return true; + } + // note: for some reason, there is no VIDEOPLAYER_DURATION + case VIDEOPLAYER_NEXT_DURATION: + { + if (epgTag->GetDuration() > 0) + { + strValue = StringUtils::SecondsToTimeString(epgTag->GetDuration()); + return true; + } + return false; } case VIDEOPLAYER_IMDBNUMBER: { - GET_CURRENT_VIDEO_LABEL(epgTag->IMDBNumber()); + strValue = epgTag->IMDBNumber(); + return true; } case VIDEOPLAYER_ORIGINALTITLE: { - GET_CURRENT_VIDEO_LABEL(epgTag->OriginalTitle()); + strValue = epgTag->OriginalTitle(); + return true; } case VIDEOPLAYER_YEAR: { - GET_CURRENT_VIDEO_LABEL_WITH_CONDITION(StringUtils::Format("%i", epgTag->Year()), epgTag->Year() > 0); + if (epgTag->Year() > 0) + { + strValue = StringUtils::Format("%i", epgTag->Year()); + return true; + } + return false; } case VIDEOPLAYER_EPISODE: { - if (channel) - epgTag = channel->GetEPGNow(); - - if (epgTag && epgTag->EpisodeNumber() > 0) + if (epgTag->EpisodeNumber() > 0) { if (epgTag->SeriesNumber() == 0) // prefix episode with 'S' strValue = StringUtils::Format("S%i", epgTag->EpisodeNumber()); else strValue = StringUtils::Format("%i", epgTag->EpisodeNumber()); - return true; } - break; + return false; } case VIDEOPLAYER_SEASON: { - GET_CURRENT_VIDEO_LABEL_WITH_CONDITION(StringUtils::Format("%i", epgTag->SeriesNumber()), epgTag->SeriesNumber() > 0); + if (epgTag->SeriesNumber() > 0) + { + strValue = StringUtils::Format("%i", epgTag->SeriesNumber()); + return true; + } + return false; } case VIDEOPLAYER_EPISODENAME: { - GET_CURRENT_VIDEO_LABEL(epgTag->EpisodeName()); + strValue = epgTag->EpisodeName(); + return true; } case VIDEOPLAYER_CAST: { - GET_CURRENT_VIDEO_LABEL(epgTag->GetCastLabel()); + strValue = epgTag->GetCastLabel(); + return true; } case VIDEOPLAYER_DIRECTOR: { - GET_CURRENT_VIDEO_LABEL(epgTag->GetDirectorsLabel()); + strValue = epgTag->GetDirectorsLabel(); + return true; } case VIDEOPLAYER_WRITER: { - GET_CURRENT_VIDEO_LABEL(epgTag->GetWritersLabel()); + strValue = epgTag->GetWritersLabel(); + return true; } case VIDEOPLAYER_PARENTAL_RATING: { - GET_CURRENT_VIDEO_LABEL_WITH_CONDITION(StringUtils::Format("%i", epgTag->ParentalRating()), epgTag->ParentalRating() > 0); - } - - // 'Next playing' infos - case VIDEOPLAYER_NEXT_TITLE: - { - GET_NEXT_VIDEO_LABEL_OR_DEFAULT(epgTag->Title(), - CServiceBroker::GetSettings().GetBool(CSettings::SETTING_EPG_HIDENOINFOAVAILABLE) - ? "" - : g_localizeStrings.Get(19055)); // no information available - } - case VIDEOPLAYER_NEXT_GENRE: - { - GET_NEXT_VIDEO_LABEL(epgTag->GetGenresLabel()); - } - case VIDEOPLAYER_NEXT_PLOT: - { - GET_NEXT_VIDEO_LABEL(epgTag->Plot()); - } - case VIDEOPLAYER_NEXT_PLOT_OUTLINE: - { - GET_NEXT_VIDEO_LABEL(epgTag->PlotOutline()); - } - case VIDEOPLAYER_NEXT_STARTTIME: - { - GET_NEXT_VIDEO_LABEL(epgTag->StartAsLocalTime().GetAsLocalizedTime("", false)); - } - case VIDEOPLAYER_NEXT_ENDTIME: - { - GET_NEXT_VIDEO_LABEL(epgTag->EndAsLocalTime().GetAsLocalizedTime("", false)); - } - case VIDEOPLAYER_NEXT_DURATION: - { - GET_NEXT_VIDEO_LABEL_WITH_CONDITION(StringUtils::SecondsToTimeString(epgTag->GetDuration()), epgTag->GetDuration() > 0); + if (epgTag->ParentalRating() > 0) + { + strValue = StringUtils::Format("%i", epgTag->ParentalRating()); + return true; + } + return false; } + } + } - // General channel infos + if (channel) + { + // General channel infos + switch (iLabel) + { case VIDEOPLAYER_CHANNEL_NAME: { - if (!channel && epgTag) - channel = epgTag->Channel(); - - if (channel) - { - strValue = channel->ChannelName(); - return true; - } - break; + strValue = channel->ChannelName(); + return true; } case VIDEOPLAYER_CHANNEL_NUMBER: { - if (!channel && epgTag) - channel = epgTag->Channel(); - - if (channel) - { - strValue = channel->ChannelNumber().FormattedChannelNumber(); - return true; - } - break; + strValue = channel->ChannelNumber().FormattedChannelNumber(); + return true; } case VIDEOPLAYER_CHANNEL_GROUP: { - if (!channel && epgTag) - channel = epgTag->Channel(); - - if (channel && !channel->IsRadio()) - { - strValue = CServiceBroker::GetPVRManager().GetPlayingTVGroupName(); - return true; - } - break; + strValue = channel->IsRadio() ? m_strPlayingRadioGroup : m_strPlayingTVGroup; + return true; + } + } + } + + if (!epgTag) + { + // EPG fallback infos + switch (iLabel) + { + case VIDEOPLAYER_TITLE: + case VIDEOPLAYER_NEXT_TITLE: + { + if (CServiceBroker::GetSettings().GetBool(CSettings::SETTING_EPG_HIDENOINFOAVAILABLE)) + strValue.clear(); + else + strValue = g_localizeStrings.Get(19055); // no information available + return true; } } } @@ -864,6 +853,12 @@ bool CPVRGUIInfo::GetVideoLabel(const CFileItem &item, int iLabel, std::string & return false; } +bool CPVRGUIInfo::GetSeekTimeLabel(int iSeekSize, std::string &strValue) const +{ + strValue = StringUtils::SecondsToTimeString(GetElapsedTime() / 1000 + iSeekSize, TIME_FORMAT_GUESS).c_str(); + return true; +} + void CPVRGUIInfo::CharInfoEpgEventDuration(std::string &strValue) const { strValue = StringUtils::SecondsToTimeString(m_iDuration / 1000, TIME_FORMAT_GUESS).c_str(); @@ -884,20 +879,25 @@ void CPVRGUIInfo::CharInfoTimeshiftPlayTime(std::string &strValue) const strValue = m_strTimeshiftPlayTime; } +void CPVRGUIInfo::CharInfoTimeshiftOffset(std::string &strValue) const +{ + strValue = StringUtils::SecondsToTimeString(m_iTimeshiftOffset, TIME_FORMAT_GUESS).c_str(); +} + void CPVRGUIInfo::CharInfoEpgEventElapsedTime(std::string &strValue) const { - strValue = StringUtils::SecondsToTimeString(GetPlayingTime() / 1000, TIME_FORMAT_GUESS).c_str(); + strValue = StringUtils::SecondsToTimeString(GetElapsedTime() / 1000, TIME_FORMAT_GUESS).c_str(); } void CPVRGUIInfo::CharInfoEpgEventRemainingTime(std::string &strValue) const { - strValue = StringUtils::SecondsToTimeString((m_iDuration - GetPlayingTime()) / 1000, TIME_FORMAT_GUESS).c_str(); + strValue = StringUtils::SecondsToTimeString((m_iDuration - GetElapsedTime()) / 1000, TIME_FORMAT_GUESS).c_str(); } void CPVRGUIInfo::CharInfoEpgEventFinishTime(std::string &strValue) const { CDateTime finishTime = CDateTime::GetCurrentDateTime(); - finishTime += CDateTimeSpan(0, 0, 0, (m_iDuration - GetPlayingTime()) / 1000); + finishTime += CDateTimeSpan(0, 0, 0, (m_iDuration - GetElapsedTime()) / 1000); strValue = finishTime.GetAsLocalizedTime("", false); } @@ -1157,7 +1157,7 @@ int CPVRGUIInfo::GetDuration(void) const return m_iDuration; } -int CPVRGUIInfo::GetPlayingTime(void) const +int CPVRGUIInfo::GetElapsedTime(void) const { CSingleLock lock(m_critSection); @@ -1177,10 +1177,7 @@ int CPVRGUIInfo::GetPlayingTime(void) const CDateTime start = m_playingEpgTag ? CDateTime(m_playingEpgTag->StartAsUTC()) : CDateTime(m_iTimeshiftStartTime); CDateTimeSpan time = current > start ? current - start : CDateTimeSpan(0, 0, 0, 0); - return (time.GetDays() * 60 * 60 * 24 - + time.GetHours() * 60 * 60 - + time.GetMinutes() * 60 - + time.GetSeconds()) * 1000; + return time.GetSecondsTotal() * 1000; } else { @@ -1247,11 +1244,6 @@ void CPVRGUIInfo::UpdatePlayingTag(void) } } -std::string CPVRGUIInfo::GetPlayingTVGroup() -{ - return m_strPlayingTVGroup; -} - CPVRGUIInfo::TimerInfo::TimerInfo(void) { ResetProperties(); diff --git a/xbmc/pvr/PVRGUIInfo.h b/xbmc/pvr/PVRGUIInfo.h index bf4c716b62..4b7e29bd6b 100644 --- a/xbmc/pvr/PVRGUIInfo.h +++ b/xbmc/pvr/PVRGUIInfo.h @@ -56,7 +56,15 @@ namespace PVR * @param strValue Will be filled with the requested label value. * @return True if the requested label value was set, false otherwise. */ - bool GetVideoLabel(const CFileItem &item, int iLabel, std::string &strValue) const; + bool GetVideoLabel(const CFileItem *item, int iLabel, std::string &strValue) const; + + /*! + * @brief Get a GUIInfoManager seek time label for the currently playing epg tag. + * @param iSeekSize The seconds to be seeked from the current playback position. + * @param strValue Will be filled with the requested label value. + * @return True if the label value was set, false otherwise. + */ + bool GetSeekTimeLabel(int iSeekSize, std::string &strValue) const; /*! * @brief Get the total duration of the currently playing LiveTV item. @@ -65,10 +73,11 @@ namespace PVR int GetDuration(void) const; /*! - * @brief Get the current position in milliseconds since the start of a LiveTV item. - * @return The position in milliseconds or NULL if no channel is playing. + * @brief Get the elapsed time since the start of the currently playing epg event or if + * no epg is available since the start of the playback of a LiveTV item. + * @return The time in milliseconds or 0 if no channel is playing. */ - int GetPlayingTime(void) const; + int GetElapsedTime(void) const; /*! * @brief Clear the playing EPG tag. @@ -81,12 +90,6 @@ namespace PVR */ CPVREpgInfoTagPtr GetPlayingTag() const; - /*! - * @brief Get playing TV group. - * @return The currently playing TV group or NULL if no TV group is playing. - */ - std::string GetPlayingTVGroup(); - private: class TimerInfo { @@ -222,6 +225,7 @@ namespace PVR void CharInfoTimeshiftStartTime(std::string &strValue) const; void CharInfoTimeshiftEndTime(std::string &strValue) const; void CharInfoTimeshiftPlayTime(std::string &strValue) const; + void CharInfoTimeshiftOffset(std::string &strValue) const; /** @name GUIInfoManager data */ //@{ @@ -253,6 +257,7 @@ namespace PVR bool m_bCanRecordPlayingChannel; bool m_bIsRecordingPlayingChannel; std::string m_strPlayingTVGroup; + std::string m_strPlayingRadioGroup; //@} @@ -263,10 +268,12 @@ namespace PVR bool m_bHasTimeshiftData; bool m_bIsTimeshifting; + time_t m_iLastTimeshiftUpdate; time_t m_iStartTime; time_t m_iTimeshiftStartTime; time_t m_iTimeshiftEndTime; time_t m_iTimeshiftPlayTime; + unsigned int m_iTimeshiftOffset; std::string m_strTimeshiftStartTime; std::string m_strTimeshiftEndTime; std::string m_strTimeshiftPlayTime; diff --git a/xbmc/pvr/PVRItem.cpp b/xbmc/pvr/PVRItem.cpp index 710ad59574..f36bcd40ab 100644 --- a/xbmc/pvr/PVRItem.cpp +++ b/xbmc/pvr/PVRItem.cpp @@ -54,6 +54,29 @@ namespace PVR return CPVREpgInfoTagPtr(); } + CPVREpgInfoTagPtr CPVRItem::GetNextEpgInfoTag() const + { + if (m_item->IsEPG()) + { + return m_item->GetEPGInfoTag()->GetNextEvent(); + } + else if (m_item->IsPVRChannel()) + { + return m_item->GetPVRChannelInfoTag()->GetEPGNext(); + } + else if (m_item->IsPVRTimer()) + { + const CPVREpgInfoTagPtr current = m_item->GetPVRTimerInfoTag()->GetEpgInfoTag(); + if (current) + return current->GetNextEvent(); + } + else + { + CLog::Log(LOGERROR, "CPVRItem - %s - unsupported item type!", __FUNCTION__); + } + return CPVREpgInfoTagPtr(); + } + CPVRChannelPtr CPVRItem::GetChannel() const { if (m_item->IsPVRChannel()) diff --git a/xbmc/pvr/PVRItem.h b/xbmc/pvr/PVRItem.h index a21e4a226c..1ab45e31f8 100644 --- a/xbmc/pvr/PVRItem.h +++ b/xbmc/pvr/PVRItem.h @@ -35,6 +35,7 @@ namespace PVR explicit CPVRItem(const CFileItem *item) : m_item(item) {} CPVREpgInfoTagPtr GetEpgInfoTag() const; + CPVREpgInfoTagPtr GetNextEpgInfoTag() const; CPVRChannelPtr GetChannel() const; CPVRTimerInfoTagPtr GetTimerInfoTag() const; CPVRRecordingPtr GetRecording() const; diff --git a/xbmc/pvr/PVRManager.cpp b/xbmc/pvr/PVRManager.cpp index 967f95cc82..0125843d30 100644 --- a/xbmc/pvr/PVRManager.cpp +++ b/xbmc/pvr/PVRManager.cpp @@ -804,9 +804,9 @@ int CPVRManager::GetTotalTime(void) const return IsStarted() && m_guiInfo ? m_guiInfo->GetDuration() : 0; } -int CPVRManager::GetStartTime(void) const +int CPVRManager::GetElapsedTime(void) const { - return IsStarted() && m_guiInfo ? m_guiInfo->GetPlayingTime() : 0; + return IsStarted() && m_guiInfo ? m_guiInfo->GetElapsedTime() : 0; } bool CPVRManager::TranslateBoolInfo(DWORD dwInfo) const @@ -824,11 +824,16 @@ int CPVRManager::TranslateIntInfo(const CFileItem &item, DWORD dwInfo) const return IsStarted() && m_guiInfo ? m_guiInfo->TranslateIntInfo(item, dwInfo) : 0; } -bool CPVRManager::GetVideoLabel(const CFileItem &item, int iLabel, std::string &strValue) const +bool CPVRManager::GetVideoLabel(const CFileItem *item, int iLabel, std::string &strValue) const { return IsStarted() && m_guiInfo ? m_guiInfo->GetVideoLabel(item, iLabel, strValue) : false; } +bool CPVRManager::GetSeekTimeLabel(int iSeekSize, std::string &strValue) const +{ + return IsStarted() && m_guiInfo ? m_guiInfo->GetSeekTimeLabel(iSeekSize, strValue) : false; +} + bool CPVRManager::IsRecording(void) const { return IsStarted() && m_timers ? m_timers->IsRecording() : false; @@ -937,11 +942,6 @@ bool CPVRManager::CreateChannelEpgs(void) return m_bEpgsCreated; } -std::string CPVRManager::GetPlayingTVGroupName() -{ - return IsStarted() && m_guiInfo ? m_guiInfo->GetPlayingTVGroup() : ""; -} - void CPVRManager::UpdateLastWatched(const CPVRChannelPtr &channel) { time_t tNow; diff --git a/xbmc/pvr/PVRManager.h b/xbmc/pvr/PVRManager.h index e4df5d97f6..8c95a9c446 100644 --- a/xbmc/pvr/PVRManager.h +++ b/xbmc/pvr/PVRManager.h @@ -190,7 +190,15 @@ namespace PVR * @param strValue Will be filled with the requested label value. * @return True if the requested label value was set, false otherwise. */ - bool GetVideoLabel(const CFileItem &item, int iLabel, std::string &strValue) const; + bool GetVideoLabel(const CFileItem *item, int iLabel, std::string &strValue) const; + + /*! + * @brief Get a GUIInfoManager seek time label for the currently playing epg tag. + * @param iSeekSize The seconds to be seeked from the current playback position. + * @param strValue Will be filled with the requested label value. + * @return True if the label value was set, false otherwise. + */ + bool GetSeekTimeLabel(int iSeekSize, std::string &strValue) const; /*! * @brief Check if a TV channel, radio channel or recording is playing. @@ -395,10 +403,11 @@ namespace PVR int GetTotalTime(void) const; /*! - * @brief Get the current position in milliseconds since the start of a LiveTV item. - * @return The position in milliseconds or NULL if no channel is playing. + * @brief Get the elapsed time since the start of the currently playing epg event or if + * no epg is available since the start of the playback of a LiveTV item. + * @return The time in milliseconds or 0 if no channel is playing. */ - int GetStartTime(void) const; + int GetElapsedTime(void) const; /*! * @brief Check whether names are still correct after the language settings changed. @@ -459,12 +468,6 @@ namespace PVR bool CreateChannelEpgs(void); /*! - * @brief get the name of the channel group of the current playing channel - * @return name of channel if tv channel is playing - */ - std::string GetPlayingTVGroupName(); - - /*! * @brief Signal a connection change of a client */ void ConnectionStateChange(CPVRClient *client, std::string connectString, PVR_CONNECTION_STATE state, std::string message); |