aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKai Sommerfeld <kai.sommerfeld@gmx.com>2016-06-30 08:13:22 +0200
committerGitHub <noreply@github.com>2016-06-30 08:13:22 +0200
commit48b8b7106f1c118efb7d030d6570a69144fa7593 (patch)
tree57c262d665f62b67eb17eff2428dc9e0d545f7f6
parentc6f500aca43a4fa8f08b2f13e4f68566f155daf9 (diff)
parentc9ffde49b0e727bd84d6ffd423ca3d8c834cd37a (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.cpp19
-rw-r--r--xbmc/epg/Epg.h8
-rw-r--r--xbmc/epg/EpgContainer.cpp19
-rw-r--r--xbmc/epg/EpgContainer.h49
-rw-r--r--xbmc/pvr/timers/PVRTimerInfoTag.cpp20
-rw-r--r--xbmc/pvr/timers/PVRTimerInfoTag.h15
-rw-r--r--xbmc/pvr/timers/PVRTimers.cpp43
-rw-r--r--xbmc/pvr/windows/GUIWindowPVRBase.cpp8
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;
}