bool CPVRTimers::UpdateEntries(const CPVRTimers &timers) { bool bChanged(false); bool bAddedOrDeleted(false); vector<CStdString> timerNotifications; CSingleLock lock(m_critSection); /* go through the timer list and check for updated or new timers */ for (map<CDateTime, vector<CPVRTimerInfoTagPtr>* >::const_iterator it = timers.m_tags.begin(); it != timers.m_tags.end(); it++) { for (vector<CPVRTimerInfoTagPtr>::const_iterator timerIt = it->second->begin(); timerIt != it->second->end(); timerIt++) { /* check if this timer is present in this container */ CPVRTimerInfoTagPtr existingTimer = GetByClient((*timerIt)->m_iClientId, (*timerIt)->m_iClientIndex); if (existingTimer) { /* if it's present, update the current tag */ bool bStateChanged(existingTimer->m_state != (*timerIt)->m_state); if (existingTimer->UpdateEntry(*(*timerIt))) { bChanged = true; UpdateEpgEvent(existingTimer); if (bStateChanged && g_PVRManager.IsStarted()) { CStdString strMessage; existingTimer->GetNotificationText(strMessage); timerNotifications.push_back(strMessage); } CLog::Log(LOGDEBUG,"PVRTimers - %s - updated timer %d on client %d", __FUNCTION__, (*timerIt)->m_iClientIndex, (*timerIt)->m_iClientId); } } else { /* new timer */ CPVRTimerInfoTagPtr newTimer = CPVRTimerInfoTagPtr(new CPVRTimerInfoTag); newTimer->UpdateEntry(*(*timerIt)); UpdateEpgEvent(newTimer); vector<CPVRTimerInfoTagPtr>* addEntry = NULL; map<CDateTime, vector<CPVRTimerInfoTagPtr>* >::iterator itr = m_tags.find(newTimer->StartAsUTC()); if (itr == m_tags.end()) { addEntry = new vector<CPVRTimerInfoTagPtr>; m_tags.insert(make_pair(newTimer->StartAsUTC(), addEntry)); } else { addEntry = itr->second; } addEntry->push_back(newTimer); UpdateEpgEvent(newTimer); bChanged = true; bAddedOrDeleted = true; if (g_PVRManager.IsStarted()) { CStdString strMessage; newTimer->GetNotificationText(strMessage); timerNotifications.push_back(strMessage); } CLog::Log(LOGDEBUG,"PVRTimers - %s - added timer %d on client %d", __FUNCTION__, (*timerIt)->m_iClientIndex, (*timerIt)->m_iClientId); } } } /* to collect timer with changed starting time */ vector<CPVRTimerInfoTagPtr> timersToMove; /* check for deleted timers */ for (map<CDateTime, vector<CPVRTimerInfoTagPtr>* >::iterator it = m_tags.begin(); it != m_tags.end();) { for (int iTimerPtr = it->second->size() - 1; iTimerPtr >= 0; iTimerPtr--) { CPVRTimerInfoTagPtr timer = it->second->at(iTimerPtr); if (!timers.GetByClient(timer->m_iClientId, timer->m_iClientIndex)) { /* timer was not found */ CLog::Log(LOGDEBUG,"PVRTimers - %s - deleted timer %d on client %d", __FUNCTION__, timer->m_iClientIndex, timer->m_iClientId); if (g_PVRManager.IsStarted()) { CStdString strMessage; strMessage.Format("%s: '%s'", (timer->EndAsUTC() <= CDateTime::GetCurrentDateTime().GetAsUTCDateTime()) ? g_localizeStrings.Get(19227) : g_localizeStrings.Get(19228), timer->m_strTitle.c_str()); timerNotifications.push_back(strMessage); } it->second->erase(it->second->begin() + iTimerPtr); bChanged = true; bAddedOrDeleted = true; } else if (timer->StartAsUTC() != it->first) { /* timer start has changed */ CLog::Log(LOGDEBUG,"PVRTimers - %s - changed start time timer %d on client %d", __FUNCTION__, timer->m_iClientIndex, timer->m_iClientId); timer->ClearEpgTag(); /* remember timer */ timersToMove.push_back(timer); /* remove timer for now, reinsert later */ it->second->erase(it->second->begin() + iTimerPtr); bChanged = true; bAddedOrDeleted = true; } } if (it->second->size() == 0) m_tags.erase(it++); else ++it; } /* reinsert timers with changed timer start */ for (vector<CPVRTimerInfoTagPtr>::const_iterator timerIt = timersToMove.begin(); timerIt != timersToMove.end(); timerIt++) { vector<CPVRTimerInfoTagPtr>* addEntry = NULL; map<CDateTime, vector<CPVRTimerInfoTagPtr>* >::const_iterator itr = m_tags.find((*timerIt)->StartAsUTC()); if (itr == m_tags.end()) { addEntry = new vector<CPVRTimerInfoTagPtr>; m_tags.insert(make_pair((*timerIt)->StartAsUTC(), addEntry)); } else { addEntry = itr->second; } addEntry->push_back(*timerIt); UpdateEpgEvent(*timerIt); } m_bIsUpdating = false; if (bChanged) { UpdateChannels(); SetChanged(); lock.Leave(); NotifyObservers(bAddedOrDeleted ? ObservableMessageTimersReset : ObservableMessageTimers); if (g_guiSettings.GetBool("pvrrecord.timernotifications")) { /* queue notifications */ for (unsigned int iNotificationPtr = 0; iNotificationPtr < timerNotifications.size(); iNotificationPtr++) { CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, g_localizeStrings.Get(19166), timerNotifications.at(iNotificationPtr)); } } } return bChanged; }
bool CPVRTimers::UpdateEntries(const CPVRTimers &timers) { bool bChanged(false); bool bAddedOrDeleted(false); std::vector<std::string> timerNotifications; CSingleLock lock(m_critSection); /* go through the timer list and check for updated or new timers */ for (MapTags::const_iterator it = timers.m_tags.begin(); it != timers.m_tags.end(); ++it) { for (VecTimerInfoTag::const_iterator timerIt = it->second->begin(); timerIt != it->second->end(); ++timerIt) { /* check if this timer is present in this container */ CPVRTimerInfoTagPtr existingTimer = GetByClient((*timerIt)->m_iClientId, (*timerIt)->m_iClientIndex); if (existingTimer) { /* if it's present, update the current tag */ bool bStateChanged(existingTimer->m_state != (*timerIt)->m_state); if (existingTimer->UpdateEntry(*timerIt)) { bChanged = true; UpdateEpgEvent(existingTimer); if (bStateChanged && g_PVRManager.IsStarted()) { std::string strMessage; existingTimer->GetNotificationText(strMessage); timerNotifications.push_back(strMessage); } CLog::Log(LOGDEBUG,"PVRTimers - %s - updated timer %d on client %d", __FUNCTION__, (*timerIt)->m_iClientIndex, (*timerIt)->m_iClientId); } } else { /* new timer */ CPVRTimerInfoTagPtr newTimer = CPVRTimerInfoTagPtr(new CPVRTimerInfoTag); newTimer->UpdateEntry(*timerIt); UpdateEpgEvent(newTimer); VecTimerInfoTag* addEntry = NULL; MapTags::iterator itr = m_tags.find(newTimer->StartAsUTC()); if (itr == m_tags.end()) { addEntry = new VecTimerInfoTag; m_tags.insert(std::make_pair(newTimer->StartAsUTC(), addEntry)); } else { addEntry = itr->second; } newTimer->m_iTimerId = ++m_iLastId; addEntry->push_back(newTimer); UpdateEpgEvent(newTimer); bChanged = true; bAddedOrDeleted = true; if (g_PVRManager.IsStarted()) { std::string strMessage; newTimer->GetNotificationText(strMessage); timerNotifications.push_back(strMessage); } CLog::Log(LOGDEBUG,"PVRTimers - %s - added timer %d on client %d", __FUNCTION__, (*timerIt)->m_iClientIndex, (*timerIt)->m_iClientId); } } } /* to collect timer with changed starting time */ VecTimerInfoTag timersToMove; /* check for deleted timers */ for (MapTags::iterator it = m_tags.begin(); it != m_tags.end();) { for (std::vector<CPVRTimerInfoTagPtr>::iterator it2 = it->second->begin(); it2 != it->second->end();) { CPVRTimerInfoTagPtr timer(*it2); if (!timers.GetByClient(timer->m_iClientId, timer->m_iClientIndex)) { /* timer was not found */ CLog::Log(LOGDEBUG,"PVRTimers - %s - deleted timer %d on client %d", __FUNCTION__, timer->m_iClientIndex, timer->m_iClientId); if (g_PVRManager.IsStarted()) timerNotifications.push_back(timer->GetDeletedNotificationText()); /** clear the EPG tag explicitly here, because it no longer happens automatically with shared pointers */ timer->ClearEpgTag(); it2 = it->second->erase(it2); bChanged = true; bAddedOrDeleted = true; } else if (timer->StartAsUTC() != it->first) { /* timer start has changed */ CLog::Log(LOGDEBUG,"PVRTimers - %s - changed start time timer %d on client %d", __FUNCTION__, timer->m_iClientIndex, timer->m_iClientId); timer->ClearEpgTag(); /* remember timer */ timersToMove.push_back(timer); /* remove timer for now, reinsert later */ it2 = it->second->erase(it2); bChanged = true; bAddedOrDeleted = true; } else { ++it2; } } if (it->second->empty()) it = m_tags.erase(it); else ++it; } /* reinsert timers with changed timer start */ for (VecTimerInfoTag::const_iterator timerIt = timersToMove.begin(); timerIt != timersToMove.end(); ++timerIt) { VecTimerInfoTag* addEntry = NULL; MapTags::const_iterator itr = m_tags.find((*timerIt)->StartAsUTC()); if (itr == m_tags.end()) { addEntry = new VecTimerInfoTag; m_tags.insert(std::make_pair((*timerIt)->StartAsUTC(), addEntry)); } else { addEntry = itr->second; } addEntry->push_back(*timerIt); UpdateEpgEvent(*timerIt); } m_bIsUpdating = false; if (bChanged) { UpdateChannels(); SetChanged(); lock.Leave(); NotifyObservers(bAddedOrDeleted ? ObservableMessageTimersReset : ObservableMessageTimers); if (CSettings::GetInstance().GetBool(CSettings::SETTING_PVRRECORD_TIMERNOTIFICATIONS)) { /* queue notifications */ for (unsigned int iNotificationPtr = 0; iNotificationPtr < timerNotifications.size(); iNotificationPtr++) { CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, g_localizeStrings.Get(19166), timerNotifications.at(iNotificationPtr)); } } } return bChanged; }
bool CPVRTimers::UpdateEntries(const CPVRTimers &timers, const std::vector<int> &failedClients) { bool bChanged(false); bool bAddedOrDeleted(false); std::vector< std::pair< int, std::string> > timerNotifications; CSingleLock lock(m_critSection); /* go through the timer list and check for updated or new timers */ for (MapTags::const_iterator it = timers.m_tags.begin(); it != timers.m_tags.end(); ++it) { for (VecTimerInfoTag::const_iterator timerIt = it->second->begin(); timerIt != it->second->end(); ++timerIt) { /* check if this timer is present in this container */ CPVRTimerInfoTagPtr existingTimer = GetByClient((*timerIt)->m_iClientId, (*timerIt)->m_iClientIndex); if (existingTimer) { /* if it's present, update the current tag */ bool bStateChanged(existingTimer->m_state != (*timerIt)->m_state); if (existingTimer->UpdateEntry(*timerIt)) { bChanged = true; existingTimer->ResetChildState(); if (bStateChanged && g_PVRManager.IsStarted()) { std::string strMessage; existingTimer->GetNotificationText(strMessage); timerNotifications.push_back(std::make_pair((*timerIt)->m_iClientId, strMessage)); } CLog::Log(LOGDEBUG,"PVRTimers - %s - updated timer %d on client %d", __FUNCTION__, (*timerIt)->m_iClientIndex, (*timerIt)->m_iClientId); } } else { /* new timer */ CPVRTimerInfoTagPtr newTimer = CPVRTimerInfoTagPtr(new CPVRTimerInfoTag); newTimer->UpdateEntry(*timerIt); VecTimerInfoTag* addEntry = NULL; MapTags::iterator itr = m_tags.find(newTimer->m_bStartAnyTime ? CDateTime() : newTimer->StartAsUTC()); if (itr == m_tags.end()) { addEntry = new VecTimerInfoTag; m_tags.insert(std::make_pair(newTimer->m_bStartAnyTime ? CDateTime() : newTimer->StartAsUTC(), addEntry)); } else { addEntry = itr->second; } newTimer->m_iTimerId = ++m_iLastId; addEntry->push_back(newTimer); bChanged = true; bAddedOrDeleted = true; if (g_PVRManager.IsStarted()) { std::string strMessage; newTimer->GetNotificationText(strMessage); timerNotifications.push_back(std::make_pair(newTimer->m_iClientId, strMessage)); } CLog::Log(LOGDEBUG,"PVRTimers - %s - added timer %d on client %d", __FUNCTION__, (*timerIt)->m_iClientIndex, (*timerIt)->m_iClientId); } } } /* to collect timer with changed starting time */ VecTimerInfoTag timersToMove; /* check for deleted timers */ for (MapTags::iterator it = m_tags.begin(); it != m_tags.end();) { for (std::vector<CPVRTimerInfoTagPtr>::iterator it2 = it->second->begin(); it2 != it->second->end();) { CPVRTimerInfoTagPtr timer(*it2); if (!timers.GetByClient(timer->m_iClientId, timer->m_iClientIndex)) { /* timer was not found */ bool bIgnoreTimer(false); for (const auto &failedClient : failedClients) { if (failedClient == timer->m_iClientId) { bIgnoreTimer = true; break; } } if (bIgnoreTimer) { ++it2; continue; } CLog::Log(LOGDEBUG,"PVRTimers - %s - deleted timer %d on client %d", __FUNCTION__, timer->m_iClientIndex, timer->m_iClientId); if (g_PVRManager.IsStarted()) timerNotifications.push_back(std::make_pair(timer->m_iClientId, timer->GetDeletedNotificationText())); /** clear the EPG tag explicitly here, because it no longer happens automatically with shared pointers */ timer->ClearEpgTag(); it2 = it->second->erase(it2); bChanged = true; bAddedOrDeleted = true; } else if ((timer->m_bStartAnyTime && it->first != CDateTime()) || (!timer->m_bStartAnyTime && timer->StartAsUTC() != it->first)) { /* timer start has changed */ CLog::Log(LOGDEBUG,"PVRTimers - %s - changed start time timer %d on client %d", __FUNCTION__, timer->m_iClientIndex, timer->m_iClientId); timer->ClearEpgTag(); /* remember timer */ timersToMove.push_back(timer); /* remove timer for now, reinsert later */ it2 = it->second->erase(it2); bChanged = true; bAddedOrDeleted = true; } else { ++it2; } } if (it->second->empty()) it = m_tags.erase(it); else ++it; } /* reinsert timers with changed timer start */ for (VecTimerInfoTag::const_iterator timerIt = timersToMove.begin(); timerIt != timersToMove.end(); ++timerIt) { VecTimerInfoTag* addEntry = NULL; MapTags::const_iterator itr = m_tags.find((*timerIt)->m_bStartAnyTime ? CDateTime() : (*timerIt)->StartAsUTC()); if (itr == m_tags.end()) { addEntry = new VecTimerInfoTag; m_tags.insert(std::make_pair((*timerIt)->m_bStartAnyTime ? CDateTime() : (*timerIt)->StartAsUTC(), addEntry)); } else { addEntry = itr->second; } addEntry->push_back(*timerIt); } /* update child information for all parent timers */ for (const auto &tagsEntry : m_tags) { for (const auto &timersEntry : *tagsEntry.second) { if (timersEntry->GetTimerRuleId() != PVR_TIMER_NO_PARENT) { const CPVRTimerInfoTagPtr parentTimer(GetByClient(timersEntry->m_iClientId, timersEntry->GetTimerRuleId())); if (parentTimer) parentTimer->UpdateChildState(timersEntry); } } } m_bIsUpdating = false; if (bChanged) { UpdateChannels(); SetChanged(); lock.Leave(); NotifyObservers(bAddedOrDeleted ? ObservableMessageTimersReset : ObservableMessageTimers); /* queue notifications / fill eventlog */ for (const auto &entry : timerNotifications) { if (CSettings::GetInstance().GetBool(CSettings::SETTING_PVRRECORD_TIMERNOTIFICATIONS)) CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, g_localizeStrings.Get(19166), entry.second); std::string strName; g_PVRClients->GetClientAddonName(entry.first, strName); std::string strIcon; g_PVRClients->GetClientAddonIcon(entry.first, strIcon); CEventLog::GetInstance().Add(EventPtr(new CNotificationEvent(strName, entry.second, strIcon, EventLevel::Information))); } } return bChanged; }