diff options
author | Kai Sommerfeld <kai.sommerfeld@gmx.com> | 2016-06-30 08:13:22 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-06-30 08:13:22 +0200 |
commit | 48b8b7106f1c118efb7d030d6570a69144fa7593 (patch) | |
tree | 57c262d665f62b67eb17eff2428dc9e0d545f7f6 | |
parent | c6f500aca43a4fa8f08b2f13e4f68566f155daf9 (diff) | |
parent | c9ffde49b0e727bd84d6ffd423ca3d8c834cd37a (diff) |
Merge pull request #10042 from ksooo/pvr-multi-epgtag-timers
[PVR] Guide window: Fix timer icons for manual (not epg-tag based) timers
-rw-r--r-- | xbmc/epg/Epg.cpp | 19 | ||||
-rw-r--r-- | xbmc/epg/Epg.h | 8 | ||||
-rw-r--r-- | xbmc/epg/EpgContainer.cpp | 19 | ||||
-rw-r--r-- | xbmc/epg/EpgContainer.h | 49 | ||||
-rw-r--r-- | xbmc/pvr/timers/PVRTimerInfoTag.cpp | 20 | ||||
-rw-r--r-- | xbmc/pvr/timers/PVRTimerInfoTag.h | 15 | ||||
-rw-r--r-- | xbmc/pvr/timers/PVRTimers.cpp | 43 | ||||
-rw-r--r-- | xbmc/pvr/windows/GUIWindowPVRBase.cpp | 8 |
8 files changed, 135 insertions, 46 deletions
diff --git a/xbmc/epg/Epg.cpp b/xbmc/epg/Epg.cpp index 2fab77f6ee..b8e09b80b8 100644 --- a/xbmc/epg/Epg.cpp +++ b/xbmc/epg/Epg.cpp @@ -268,6 +268,25 @@ CEpgInfoTagPtr CEpg::GetTagBetween(const CDateTime &beginTime, const CDateTime & return CEpgInfoTagPtr(); } +std::vector<CEpgInfoTagPtr> CEpg::GetTagsBetween(const CDateTime &beginTime, const CDateTime &endTime) const +{ + std::vector<CEpgInfoTagPtr> epgTags; + + CSingleLock lock(m_critSection); + for (const auto &infoTag : m_tags) + { + if (infoTag.second->StartAsUTC() >= beginTime) + { + if (infoTag.second->EndAsUTC() <= endTime) + epgTags.emplace_back(infoTag.second); + else + break; // done. + } + } + + return epgTags; +} + void CEpg::AddEntry(const CEpgInfoTag &tag) { CEpgInfoTagPtr newTag; diff --git a/xbmc/epg/Epg.h b/xbmc/epg/Epg.h index 7095b96d58..d47c8d0410 100644 --- a/xbmc/epg/Epg.h +++ b/xbmc/epg/Epg.h @@ -175,6 +175,14 @@ namespace EPG CEpgInfoTagPtr GetTagBetween(const CDateTime &beginTime, const CDateTime &endTime) const; /*! + * Get all events occuring between the given begin and end time. + * @param beginTime Minimum start time in UTC of the event. + * @param endTime Maximum end time in UTC of the event. + * @return The tags found or an empty vector if none was found. + */ + std::vector<CEpgInfoTagPtr> GetTagsBetween(const CDateTime &beginTime, const CDateTime &endTime) const; + + /*! * @brief Get the event matching the given unique broadcast id * @param iUniqueBroadcastId The uid to look up * @return The matching event or NULL if it wasn't found. diff --git a/xbmc/epg/EpgContainer.cpp b/xbmc/epg/EpgContainer.cpp index 8c61418d62..023aa7de65 100644 --- a/xbmc/epg/EpgContainer.cpp +++ b/xbmc/epg/EpgContainer.cpp @@ -31,6 +31,7 @@ #include "pvr/channels/PVRChannelGroupsContainer.h" #include "pvr/PVRManager.h" #include "pvr/recordings/PVRRecordings.h" +#include "pvr/timers/PVRTimerInfoTag.h" #include "settings/AdvancedSettings.h" #include "settings/lib/Setting.h" #include "settings/Settings.h" @@ -389,6 +390,22 @@ CEpgInfoTagPtr CEpgContainer::GetTagById(const CPVRChannelPtr &channel, unsigned return retval; } +std::vector<CEpgInfoTagPtr> CEpgContainer::GetEpgTagsForTimer(const CPVRTimerInfoTagPtr &timer) const +{ + CPVRChannelPtr channel(timer->ChannelTag()); + + if (!channel) + channel = timer->UpdateChannel(); + + if (channel) + { + const CEpgPtr epg(channel->GetEPG()); + if (epg) + return epg->GetTagsBetween(timer->StartAsUTC(), timer->EndAsUTC()); + } + return std::vector<CEpgInfoTagPtr>(); +} + void CEpgContainer::InsertFromDatabase(int iEpgID, const std::string &strName, const std::string &strScraperName) { // table might already have been created when pvr channels were loaded @@ -415,7 +432,7 @@ void CEpgContainer::InsertFromDatabase(int iEpgID, const std::string &strName, c } } -CEpgPtr CEpgContainer::CreateChannelEpg(CPVRChannelPtr channel) +CEpgPtr CEpgContainer::CreateChannelEpg(const CPVRChannelPtr &channel) { if (!channel) return CEpgPtr(); diff --git a/xbmc/epg/EpgContainer.h b/xbmc/epg/EpgContainer.h index 9e7e6b8189..5c0bfb9862 100644 --- a/xbmc/epg/EpgContainer.h +++ b/xbmc/epg/EpgContainer.h @@ -76,29 +76,29 @@ namespace EPG * @brief Start the EPG update thread. * @param bAsync Should the EPG container starts asynchronously */ - virtual void Start(bool bAsync); + void Start(bool bAsync); /*! * @brief Stop the EPG update thread. * @return */ - virtual bool Stop(void); + bool Stop(void); /*! * @brief Clear all EPG entries. * @param bClearDb Clear the database too if true. */ - virtual void Clear(bool bClearDb = false); + void Clear(bool bClearDb = false); /*! * @brief Stop the update thread and unload all data. */ - virtual void Unload(void); + void Unload(void); /*! * @brief Clear the EPG and all it's database entries. */ - virtual void Reset(void) { Clear(true); } + void Reset(void) { Clear(true); } /*! * @brief Check whether the EpgContainer has fully started. @@ -112,7 +112,7 @@ namespace EPG * @param bDeleteFromDatabase Delete this table from the database too if true. * @return */ - virtual bool DeleteEpg(const CEpg &epg, bool bDeleteFromDatabase = false); + bool DeleteEpg(const CEpg &epg, bool bDeleteFromDatabase = false); /*! * @brief Process a notification from an observable. @@ -123,7 +123,7 @@ namespace EPG virtual void OnSettingChanged(const CSetting *setting) override; - CEpgPtr CreateChannelEpg(PVR::CPVRChannelPtr channel); + CEpgPtr CreateChannelEpg(const PVR::CPVRChannelPtr &channel); /*! * @brief Get all EPG tables and apply a filter. @@ -131,26 +131,26 @@ namespace EPG * @param filter The filter to apply. * @return The amount of entries that were added. */ - virtual int GetEPGSearch(CFileItemList &results, const EpgSearchFilter &filter); + int GetEPGSearch(CFileItemList &results, const EpgSearchFilter &filter); /*! * @brief Get the start time of the first entry. * @return The start time. */ - virtual const CDateTime GetFirstEPGDate(void); + const CDateTime GetFirstEPGDate(void); /*! * @brief Get the end time of the last entry. * @return The end time. */ - virtual const CDateTime GetLastEPGDate(void); + const CDateTime GetLastEPGDate(void); /*! * @brief Get an EPG table given it's ID. * @param iEpgId The database ID of the table. * @return The table or NULL if it wasn't found. */ - virtual CEpgPtr GetById(int iEpgId) const; + CEpgPtr GetById(int iEpgId) const; /*! * @brief Get the EPG event with the given event id @@ -158,13 +158,20 @@ namespace EPG * @param iBroadcastId The event id to get * @return The requested event, or an empty tag when not found */ - virtual CEpgInfoTagPtr GetTagById(const PVR::CPVRChannelPtr &channel, unsigned int iBroadcastId) const; + CEpgInfoTagPtr GetTagById(const PVR::CPVRChannelPtr &channel, unsigned int iBroadcastId) const; + + /*! + * @brief Get the EPG events matching the given timer + * @param timer The timer to get the matching events for. + * @return The matching events, or an empty vector when no matching tag was found + */ + std::vector<CEpgInfoTagPtr> GetEpgTagsForTimer(const PVR::CPVRTimerInfoTagPtr &timer) const; /*! * @brief Notify EPG table observers when the currently active tag changed. * @return True if the check was done, false if it was not the right time to check */ - virtual bool CheckPlayingEvents(void); + bool CheckPlayingEvents(void); /*! * @brief The next EPG ID to be given to a table when the db isn't being used. @@ -175,13 +182,13 @@ namespace EPG /*! * @brief Close the progress bar if it's visible. */ - virtual void CloseProgressDialog(void); + void CloseProgressDialog(void); /*! * @brief Show the progress bar * @param bUpdating True if updating epg entries, false if just loading them from db */ - virtual void ShowProgressDialog(bool bUpdating = true); + void ShowProgressDialog(bool bUpdating = true); /*! * @brief Update the progress bar. @@ -189,12 +196,12 @@ namespace EPG * @param iMax The maximum position. * @param strText The text to display. */ - virtual void UpdateProgressDialog(int iCurrent, int iMax, const std::string &strText); + void UpdateProgressDialog(int iCurrent, int iMax, const std::string &strText); /*! * @return True to not to store EPG entries in the database. */ - virtual bool IgnoreDB(void) const { return m_bIgnoreDbForClient; } + bool IgnoreDB(void) const { return m_bIgnoreDbForClient; } /*! * @brief Wait for an EPG update to finish. @@ -230,25 +237,25 @@ namespace EPG * @brief Load the EPG settings. * @return True if the settings were loaded successfully, false otherwise. */ - virtual bool LoadSettings(void); + bool LoadSettings(void); /*! * @brief Remove old EPG entries. * @return True if the old entries were removed successfully, false otherwise. */ - virtual bool RemoveOldEntries(void); + bool RemoveOldEntries(void); /*! * @brief Load and update the EPG data. * @param bOnlyPending Only check and update EPG tables with pending manual updates * @return True if the update has not been interrupted, false otherwise. */ - virtual bool UpdateEPG(bool bOnlyPending = false); + bool UpdateEPG(bool bOnlyPending = false); /*! * @return True if a running update should be interrupted, false otherwise. */ - virtual bool InterruptUpdate(void) const; + bool InterruptUpdate(void) const; /*! * @brief EPG update thread diff --git a/xbmc/pvr/timers/PVRTimerInfoTag.cpp b/xbmc/pvr/timers/PVRTimerInfoTag.cpp index 01011b1c48..2ff44d441d 100644 --- a/xbmc/pvr/timers/PVRTimerInfoTag.cpp +++ b/xbmc/pvr/timers/PVRTimerInfoTag.cpp @@ -988,17 +988,22 @@ CEpgInfoTagPtr CPVRTimerInfoTag::GetEpgInfoTag(bool bCreate /* = true */) const return m_epgTag; } -void CPVRTimerInfoTag::ClearEpgTag(void) +void CPVRTimerInfoTag::SetEpgTag(const CEpgInfoTagPtr &tag) { - CEpgInfoTagPtr deletedTag; + CEpgInfoTagPtr previousTag; { CSingleLock lock(m_critSection); - deletedTag = m_epgTag; - m_epgTag.reset(); + previousTag = m_epgTag; + m_epgTag = tag; } - if (deletedTag) - deletedTag->ClearTimer(); + if (previousTag) + previousTag->ClearTimer(); +} + +void CPVRTimerInfoTag::ClearEpgTag(void) +{ + SetEpgTag(CEpgInfoTagPtr()); } CPVRChannelPtr CPVRTimerInfoTag::ChannelTag(void) const @@ -1006,10 +1011,11 @@ CPVRChannelPtr CPVRTimerInfoTag::ChannelTag(void) const return m_channel; } -void CPVRTimerInfoTag::UpdateChannel(void) +CPVRChannelPtr CPVRTimerInfoTag::UpdateChannel(void) { CSingleLock lock(m_critSection); m_channel = g_PVRChannelGroups->Get(m_bIsRadio)->GetGroupAll()->GetByUniqueID(m_iClientChannelUid, m_iClientId); + return m_channel; } const std::string& CPVRTimerInfoTag::Title(void) const diff --git a/xbmc/pvr/timers/PVRTimerInfoTag.h b/xbmc/pvr/timers/PVRTimerInfoTag.h index 6058f5d0cc..988f67043c 100644 --- a/xbmc/pvr/timers/PVRTimerInfoTag.h +++ b/xbmc/pvr/timers/PVRTimerInfoTag.h @@ -232,9 +232,22 @@ namespace PVR bool RenameOnClient(const std::string &strNewName); bool UpdateOnClient(); + /*! + * @brief Associate the given epg tag with this timer; before, clear old timer at associated epg tag, if any. + * @param tag The epg tag to assign. + */ + void SetEpgTag(const EPG::CEpgInfoTagPtr &tag); + + /*! + * @brief Clear the epg tag associated with this timer; before, clear this timer at associated epg tag, if any. + */ void ClearEpgTag(void); - void UpdateChannel(void); + /*! + * @brief Update the channel associated with this timer. + * @return the channel for the timer. Can be empty for epg based repeating timers (e.g. "match any channel" rules) + */ + CPVRChannelPtr UpdateChannel(void); /*! * @brief Return string representation for any possible combination of weekdays. diff --git a/xbmc/pvr/timers/PVRTimers.cpp b/xbmc/pvr/timers/PVRTimers.cpp index ffce949902..8f48b52d2c 100644 --- a/xbmc/pvr/timers/PVRTimers.cpp +++ b/xbmc/pvr/timers/PVRTimers.cpp @@ -105,24 +105,38 @@ bool CPVRTimers::IsRecording(void) const bool CPVRTimers::SetEpgTagTimer(const CPVRTimerInfoTagPtr &timer) { - const CEpgInfoTagPtr epgTag(timer->GetEpgInfoTag()); - if (epgTag) - { - epgTag->SetTimer(timer); - return true; - } - return false; + if (timer->IsRepeating() || timer->m_bStartAnyTime || timer->m_bEndAnyTime) + return false; + + std::vector<CEpgInfoTagPtr> tags(g_EpgContainer.GetEpgTagsForTimer(timer)); + + if (tags.empty()) + return false; + + // assign first matching epg tag to the timer. + timer->SetEpgTag(tags.front()); + + // assign timer to every matching epg tag. + for (const auto &tag : tags) + tag->SetTimer(timer); + + return true; } bool CPVRTimers::ClearEpgTagTimer(const CPVRTimerInfoTagPtr &timer) { - const CEpgInfoTagPtr epgTag(timer->GetEpgInfoTag()); - if (epgTag) - { - epgTag->ClearTimer(); - return true; - } - return false; + if (timer->IsRepeating() || timer->m_bStartAnyTime || timer->m_bEndAnyTime) + return false; + + std::vector<CEpgInfoTagPtr> tags(g_EpgContainer.GetEpgTagsForTimer(timer)); + + if (tags.empty()) + return false; + + for (const auto &tag : tags) + tag->ClearTimer(); + + return true; } bool CPVRTimers::UpdateEntries(const CPVRTimers &timers, const std::vector<int> &failedClients) @@ -144,6 +158,7 @@ bool CPVRTimers::UpdateEntries(const CPVRTimers &timers, const std::vector<int> { /* if it's present, update the current tag */ bool bStateChanged(existingTimer->m_state != (*timerIt)->m_state); + ClearEpgTagTimer(existingTimer); if (existingTimer->UpdateEntry(*timerIt)) { SetEpgTagTimer(existingTimer); diff --git a/xbmc/pvr/windows/GUIWindowPVRBase.cpp b/xbmc/pvr/windows/GUIWindowPVRBase.cpp index 3308ffccff..310aba0f46 100644 --- a/xbmc/pvr/windows/GUIWindowPVRBase.cpp +++ b/xbmc/pvr/windows/GUIWindowPVRBase.cpp @@ -587,8 +587,12 @@ bool CGUIWindowPVRBase::EditTimer(CFileItem *item) return false; } - if (ShowTimerSettings(timer) && !timer->GetTimerType()->IsReadOnly()) - return g_PVRTimers->UpdateTimer(timer); + // clone the timer. + const CPVRTimerInfoTagPtr newTimer(new CPVRTimerInfoTag); + newTimer->UpdateEntry(timer); + + if (ShowTimerSettings(newTimer) && !timer->GetTimerType()->IsReadOnly()) + return g_PVRTimers->UpdateTimer(newTimer); return false; } |