bool CPVRTimers::UpdateFromClient(const CPVRTimerInfoTag &timer) { CSingleLock lock(m_critSection); CPVRTimerInfoTagPtr tag = GetByClient(timer.m_iClientId, timer.m_iClientIndex); if (!tag) { tag = CPVRTimerInfoTagPtr(new CPVRTimerInfoTag()); vector<CPVRTimerInfoTagPtr>* addEntry = NULL; map<CDateTime, vector<CPVRTimerInfoTagPtr>* >::iterator itr = m_tags.find(timer.StartAsUTC()); if (itr == m_tags.end()) { addEntry = new vector<CPVRTimerInfoTagPtr>; m_tags.insert(make_pair(timer.StartAsUTC(), addEntry)); } else { addEntry = itr->second; } addEntry->push_back(tag); } UpdateEpgEvent(tag); return tag->UpdateEntry(timer); }
CFileItemPtr CPVRTimers::GetTimerForEpgTag(const CFileItem *item) const { if (item && item->HasEPGInfoTag() && item->GetEPGInfoTag()->ChannelTag()) { const CEpgInfoTagPtr epgTag(item->GetEPGInfoTag()); const CPVRChannelPtr channel(epgTag->ChannelTag()); CSingleLock lock(m_critSection); for (MapTags::const_iterator it = m_tags.begin(); it != m_tags.end(); ++it) { for (VecTimerInfoTag::const_iterator timerIt = it->second->begin(); timerIt != it->second->end(); ++timerIt) { CPVRTimerInfoTagPtr timer = *timerIt; if (timer->GetEpgInfoTag() == epgTag || (timer->m_iClientChannelUid == channel->UniqueID() && timer->m_bIsRadio == channel->IsRadio() && timer->StartAsUTC() <= epgTag->StartAsUTC() && timer->EndAsUTC() >= epgTag->EndAsUTC())) { CFileItemPtr fileItem(new CFileItem(timer)); return fileItem; } } } } CFileItemPtr fileItem; return fileItem; }
bool CGUIWindowPVRTimersBase::ActionShowTimer(CFileItem *item) { if (!g_PVRClients->SupportsTimers()) { CGUIDialogOK::ShowAndGetInput(CVariant{19033}, CVariant{19215}); // "Information", "The PVR backend does not support timers." return false; } bool bReturn = false; /* Check if "Add timer..." entry is pressed by OK, if yes create a new timer and open settings dialog, otherwise open settings for selected timer entry */ if (URIUtils::PathEquals(item->GetPath(), CPVRTimersPath::PATH_ADDTIMER)) { bReturn = ShowNewTimerDialog(); } else { const CPVRTimerInfoTagPtr tag(item->GetPVRTimerInfoTag()); if (ShowTimerSettings(tag) && !tag->GetTimerType()->IsReadOnly()) { /* Update timer on pvr backend */ bReturn = g_PVRTimers->UpdateTimer(tag); } } return bReturn; }
void CPVRGUIInfo::TimerInfo::UpdateTimersToggle() { if (!TimerInfoToggle()) return; std::string strActiveTimerTitle; std::string strActiveTimerChannelName; std::string strActiveTimerChannelIcon; std::string strActiveTimerTime; /* safe to fetch these unlocked, since they're updated from the same thread as this one */ if (m_iRecordingTimerAmount > 0) { std::vector<CFileItemPtr> activeTags = GetActiveRecordings(); if (m_iTimerInfoToggleCurrent < activeTags.size() && activeTags.at(m_iTimerInfoToggleCurrent)->HasPVRTimerInfoTag()) { CPVRTimerInfoTagPtr tag = activeTags.at(m_iTimerInfoToggleCurrent)->GetPVRTimerInfoTag(); strActiveTimerTitle = StringUtils::Format("%s", tag->Title().c_str()); strActiveTimerChannelName = StringUtils::Format("%s", tag->ChannelName().c_str()); strActiveTimerChannelIcon = StringUtils::Format("%s", tag->ChannelIcon().c_str()); strActiveTimerTime = StringUtils::Format("%s", tag->StartAsLocalTime().GetAsLocalizedDateTime(false, false).c_str()); } } CSingleLock lock(m_critSection); m_strActiveTimerTitle = strActiveTimerTitle; m_strActiveTimerChannelName = strActiveTimerChannelName; m_strActiveTimerChannelIcon = strActiveTimerChannelIcon; m_strActiveTimerTime = strActiveTimerTime; }
int EpgSearchFilter::FilterTimers(CFileItemList &results) { int iRemoved(0); if (!g_PVRManager.IsStarted()) return iRemoved; std::vector<CFileItemPtr> timers = g_PVRTimers->GetActiveTimers(); // TODO inefficient! for (unsigned int iTimerPtr = 0; iTimerPtr < timers.size(); iTimerPtr++) { CFileItemPtr fileItem = timers.at(iTimerPtr); if (!fileItem || !fileItem->HasPVRTimerInfoTag()) continue; CPVRTimerInfoTagPtr timer = fileItem->GetPVRTimerInfoTag(); if (!timer) continue; for (int iResultPtr = 0; iResultPtr < results.Size(); iResultPtr++) { const CEpgInfoTagPtr epgentry(results.Get(iResultPtr)->GetEPGInfoTag()); if (!epgentry || *epgentry->ChannelTag() != *timer->ChannelTag() || epgentry->StartAsUTC() < timer->StartAsUTC() || epgentry->EndAsUTC() > timer->EndAsUTC()) continue; results.Remove(iResultPtr); iResultPtr--; ++iRemoved; } } return iRemoved; }
CFileItemPtr CPVRTimers::GetTimerRule(const CFileItem *item) const { CPVRTimerInfoTagPtr timer; if (item && item->HasEPGInfoTag()) timer = item->GetEPGInfoTag()->Timer(); else if (item && item->HasPVRTimerInfoTag()) timer = item->GetPVRTimerInfoTag(); if (timer) { unsigned int iRuleId = timer->GetTimerRuleId(); if (iRuleId != PVR_TIMER_NO_PARENT) { int iClientId = timer->m_iClientId; CSingleLock lock(m_critSection); for (const auto &tagsEntry : m_tags) { for (const auto &timersEntry : *tagsEntry.second) { if (timersEntry->m_iClientId == iClientId && timersEntry->m_iClientIndex == iRuleId) return CFileItemPtr(new CFileItem(timersEntry)); } } } } return CFileItemPtr(); }
void CPVRTimers::UpdateEpgEvent(CPVRTimerInfoTagPtr timer) { CSingleLock lock(timer->m_critSection); /* already got an epg event set */ if (timer->m_epgTag) return; /* try to get the channel */ CPVRChannelPtr channel = g_PVRChannelGroups->GetByUniqueID(timer->m_iClientChannelUid, timer->m_iClientId); if (!channel) return; /* try to get the EPG table */ CEpg *epg = channel->GetEPG(); if (!epg) return; /* try to set the timer on the epg tag that matches with a 2 minute margin */ CEpgInfoTagPtr epgTag = epg->GetTagBetween(timer->StartAsUTC() - CDateTimeSpan(0, 0, 2, 0), timer->EndAsUTC() + CDateTimeSpan(0, 0, 2, 0)); if (!epgTag) epgTag = epg->GetTagAround(timer->StartAsUTC()); if (epgTag) { timer->m_epgTag = epgTag; timer->m_genre = epgTag->Genre(); timer->m_iGenreType = epgTag->GenreType(); timer->m_iGenreSubType = epgTag->GenreSubType(); epgTag->SetTimer(timer); } }
bool CPVRTimers::UpdateFromClient(const CPVRTimerInfoTagPtr &timer) { CSingleLock lock(m_critSection); CPVRTimerInfoTagPtr tag = GetByClient(timer->m_iClientId, timer->m_iClientIndex); if (!tag) { tag = CPVRTimerInfoTagPtr(new CPVRTimerInfoTag()); VecTimerInfoTag* addEntry = NULL; MapTags::iterator itr = m_tags.find(timer->StartAsUTC()); if (itr == m_tags.end()) { addEntry = new VecTimerInfoTag; m_tags.insert(std::make_pair(timer->StartAsUTC(), addEntry)); } else { addEntry = itr->second; } tag->m_iTimerId = ++m_iLastId; addEntry->push_back(tag); } UpdateEpgEvent(tag); return tag->UpdateEntry(timer); }
bool CGUIWindowPVRTimers::OnContextButtonActivate(CFileItem *item, CONTEXT_BUTTON button) { bool bReturn = false; if (button == CONTEXT_BUTTON_ACTIVATE) { bReturn = true; if (!item->HasPVRTimerInfoTag()) return bReturn; CPVRTimerInfoTagPtr timer = item->GetPVRTimerInfoTag(); int iLabelId; if (timer->IsActive()) { timer->m_state = PVR_TIMER_STATE_CANCELLED; iLabelId = 13106; } else { timer->m_state = PVR_TIMER_STATE_SCHEDULED; iLabelId = 305; } CGUIDialogOK::ShowAndGetInput(19033, 19040, 0, iLabelId); g_PVRTimers->UpdateTimer(*item); } return bReturn; }
bool CPVRTimers::DeleteTimersOnChannel(const CPVRChannel &channel, bool bDeleteRepeating /* = true */, bool bCurrentlyActiveOnly /* = false */) { bool bReturn = false; CSingleLock lock(m_critSection); for (map<CDateTime, vector<CPVRTimerInfoTagPtr>* >::reverse_iterator it = m_tags.rbegin(); it != m_tags.rend(); it++) { for (vector<CPVRTimerInfoTagPtr>::iterator timerIt = it->second->begin(); timerIt != it->second->end(); timerIt++) { CPVRTimerInfoTagPtr timer = (*timerIt); if (bCurrentlyActiveOnly && (CDateTime::GetCurrentDateTime() < timer->StartAsLocalTime() || CDateTime::GetCurrentDateTime() > timer->EndAsLocalTime())) continue; if (!bDeleteRepeating && timer->m_bIsRepeating) continue; if (timer->ChannelNumber() == channel.ChannelNumber() && timer->m_bIsRadio == channel.IsRadio()) { bReturn = timer->DeleteFromClient(true) || bReturn; it->second->erase(timerIt); } } } return bReturn; }
bool CPVRGUIActions::ConfirmDeleteTimer(const CPVRTimerInfoTagPtr &timer, bool &bDeleteRule) const { bool bConfirmed(false); if (timer->GetTimerRuleId() != PVR_TIMER_NO_PARENT) { // timer was scheduled by a timer rule. prompt user for confirmation for deleting the timer rule, including scheduled timers. bool bCancel(false); bDeleteRule = CGUIDialogYesNo::ShowAndGetInput(CVariant{122}, // "Confirm delete" CVariant{840}, // "Do you want to delete only this timer or also the timer rule that has scheduled it?" CVariant{""}, CVariant{timer->Title()}, bCancel, CVariant{841}, // "Only this" CVariant{593}, // "All" 0); // no autoclose bConfirmed = !bCancel; } else { bDeleteRule = false; // prompt user for confirmation for deleting the timer bConfirmed = CGUIDialogYesNo::ShowAndGetInput(CVariant{122}, // "Confirm delete" timer->IsTimerRule() ? CVariant{845} // "Are you sure you want to delete this timer rule and all timers it has scheduled?" : CVariant{846}, // "Are you sure you want to delete this timer?" CVariant{""}, CVariant{timer->Title()}); } return bConfirmed; }
bool CPVRTimers::DeleteTimer(const CFileItem &item, bool bForce /* = false */, bool bDeleteSchedule /* = false */) { /* Check if a CPVRTimerInfoTag is inside file item */ if (!item.IsPVRTimer()) { CLog::Log(LOGERROR, "PVRTimers - %s - no TimerInfoTag given", __FUNCTION__); return false; } CPVRTimerInfoTagPtr tag = item.GetPVRTimerInfoTag(); if (!tag) return false; if (bDeleteSchedule) { /* delete the repeating timer that scheduled this timer. */ tag = g_PVRTimers->GetByClient(tag->m_iClientId, tag->GetTimerScheduleId()); if (!tag) { CLog::Log(LOGERROR, "PVRTimers - %s - unable to obtain parent timer for given timer", __FUNCTION__); return false; } } return tag->DeleteFromClient(bForce); }
void CEpgInfoTag::ClearTimer(void) { CPVRTimerInfoTagPtr previousTag; previousTag = m_timer; CPVRTimerInfoTagPtr empty; m_timer = empty; if (previousTag) previousTag->ClearEpgTag(); }
bool CGUIWindowPVRBase::DeleteTimer(CFileItem *item, bool bIsRecording, bool bDeleteRule) { CPVRTimerInfoTagPtr timer; if (item->IsPVRTimer()) { timer = item->GetPVRTimerInfoTag(); } else if (item->IsEPG()) { timer = item->GetEPGInfoTag()->Timer(); } else if (item->IsPVRChannel()) { const CEpgInfoTagPtr epgTag(item->GetPVRChannelInfoTag()->GetEPGNow()); if (epgTag) timer = epgTag->Timer(); // cheap method, but not reliable as timers get set at epg tags asychrounously if (!timer) timer = g_PVRTimers->GetActiveTimerForChannel(item->GetPVRChannelInfoTag()); // more expensive, but reliable and works even for channels with no epg data } if (!timer) { CLog::Log(LOGERROR, "CGUIWindowPVRBase - %s - no timer!", __FUNCTION__); return false; } if (bDeleteRule && !timer->IsRepeating()) timer = g_PVRTimers->GetTimerRule(timer); if (!timer) { CLog::Log(LOGERROR, "CGUIWindowPVRBase - %s - no timer rule!", __FUNCTION__); return false; } if (bIsRecording) { if (ConfirmStopRecording(timer)) return g_PVRTimers->DeleteTimer(timer, true, false); } else if (timer->HasTimerType() && timer->GetTimerType()->IsReadOnly()) { return false; } else { bool bAlsoDeleteRule(false); if (ConfirmDeleteTimer(timer, bAlsoDeleteRule)) return g_PVRTimers->DeleteTimer(timer, false, bAlsoDeleteRule); } return false; }
bool CPVRTimersContainer::UpdateFromClient(const CPVRTimerInfoTagPtr &timer) { CSingleLock lock(m_critSection); CPVRTimerInfoTagPtr tag = GetByClient(timer->m_iClientId, timer->m_iClientIndex); if (!tag) { tag.reset(new CPVRTimerInfoTag()); tag->m_iTimerId = ++m_iLastId; InsertTimer(tag); } return tag->UpdateEntry(timer); }
void CPVRTimersContainer::InsertTimer(const CPVRTimerInfoTagPtr &newTimer) { auto it = m_tags.find(newTimer->m_bStartAnyTime ? CDateTime() : newTimer->StartAsUTC()); if (it == m_tags.end()) { VecTimerInfoTag addEntry({newTimer}); m_tags.insert(std::make_pair(newTimer->m_bStartAnyTime ? CDateTime() : newTimer->StartAsUTC(), addEntry)); } else { it->second.emplace_back(newTimer); } }
void CEpgInfoTag::ClearTimer(void) { CPVRTimerInfoTagPtr previousTag; { CSingleLock lock(m_critSection); previousTag = m_timer; CPVRTimerInfoTagPtr empty; m_timer = empty; } if (previousTag) previousTag->ClearEpgTag(); }
void CGUIWindowPVRTimers::UpdateButtons(void) { SET_CONTROL_SELECTED(GetID(), CONTROL_BTNTIMERTYPEFILTER, CSettings::Get().GetBool("pvrtimers.timertypefilter")); CGUIWindowPVRBase::UpdateButtons(); std::string strHeaderTitle; if (m_currentFileItem && m_currentFileItem->HasPVRTimerInfoTag()) { CPVRTimerInfoTagPtr timer = m_currentFileItem->GetPVRTimerInfoTag(); strHeaderTitle = timer->Title(); } SET_CONTROL_LABEL(CONTROL_LABEL_HEADER1, strHeaderTitle); }
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>(); }
bool CPVRTimers::DeleteTimer(const CFileItem &item, bool bForce /* = false */, bool bDeleteSchedule /* = false */) { /* Check if a CPVRTimerInfoTag is inside file item */ if (!item.IsPVRTimer()) { CLog::Log(LOGERROR, "PVRTimers - %s - no TimerInfoTag given", __FUNCTION__); return false; } const CPVRTimerInfoTagPtr tag = item.GetPVRTimerInfoTag(); if (!tag) return false; return tag->DeleteFromClient(bForce, bDeleteSchedule); }
bool CPVRTimers::RenameTimer(CFileItem &item, const std::string &strNewName) { /* Check if a CPVRTimerInfoTag is inside file item */ if (!item.IsPVRTimer()) { CLog::Log(LOGERROR, "PVRTimers - %s - no TimerInfoTag given", __FUNCTION__); return false; } CPVRTimerInfoTagPtr tag = item.GetPVRTimerInfoTag(); if (!tag) return false; return tag->RenameOnClient(strNewName); }
bool CPVRTimers::UpdateTimer(CFileItem &item) { /* Check if a CPVRTimerInfoTag is inside file item */ if (!item.IsPVRTimer()) { CLog::Log(LOGERROR, "PVRTimers - %s - no TimerInfoTag given", __FUNCTION__); return false; } CPVRTimerInfoTagPtr tag = item.GetPVRTimerInfoTag(); if (!tag) return false; return tag->UpdateOnClient(); }
void CGUIWindowPVRTimersBase::UpdateButtons(void) { SET_CONTROL_SELECTED(GetID(), CONTROL_BTNHIDEDISABLEDTIMERS, CSettings::GetInstance().GetBool(CSettings::SETTING_PVRTIMERS_HIDEDISABLEDTIMERS)); CGUIWindowPVRBase::UpdateButtons(); std::string strHeaderTitle; if (m_currentFileItem && m_currentFileItem->HasPVRTimerInfoTag()) { CPVRTimerInfoTagPtr timer = m_currentFileItem->GetPVRTimerInfoTag(); strHeaderTitle = timer->Title(); } SET_CONTROL_LABEL(CONTROL_LABEL_HEADER1, strHeaderTitle); }
bool CPVRGUIActions::ConfirmStopRecording(const CPVRTimerInfoTagPtr &timer) const { return CGUIDialogYesNo::ShowAndGetInput(CVariant{847}, // "Confirm stop recording" CVariant{848}, // "Are you sure you want to stop this recording?" CVariant{""}, CVariant{timer->Title()}); }
bool CPVRManager::AllLocalBackendsIdle(CPVRTimerInfoTagPtr& causingEvent) const { if (m_timers) { // active recording on local backend? std::vector<CFileItemPtr> recordings = m_timers->GetActiveRecordings(); for (std::vector<CFileItemPtr>::const_iterator timerIt = recordings.begin(); timerIt != recordings.end(); ++timerIt) { if (EventOccursOnLocalBackend(*timerIt)) { causingEvent = (*timerIt)->GetPVRTimerInfoTag(); return false; } } // soon recording on local backend? if (IsNextEventWithinBackendIdleTime()) { CFileItemPtr item = m_timers->GetNextActiveTimer(); if (item.get() == NULL) { // Next event is due to automatic daily wakeup of PVR! causingEvent.reset(); return false; } if (EventOccursOnLocalBackend(item)) { causingEvent = item->GetPVRTimerInfoTag(); return false; } } } return true; }
bool CPVRGUIActions::ToggleTimer(const CFileItemPtr &item) const { if (!item->HasEPGInfoTag()) return false; const CPVRTimerInfoTagPtr timer(CPVRItem(item).GetTimerInfoTag()); if (timer) { if (timer->IsRecording()) return StopRecording(item); else return DeleteTimer(item); } else return AddTimer(item, false); }
JSONRPC_STATUS CPVROperations::DeleteTimer(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) { if (!g_PVRManager.IsStarted()) return FailedToExecute; CPVRTimers* timers = g_PVRTimers; CPVRTimerInfoTagPtr timer = timers->GetById(parameterObject["timerid"].asInteger()); if (!timer) return InvalidParams; if (timers->DeleteTimer(timer, timer->IsRecording(), false)) return ACK; return FailedToExecute; }
void CPVRGUIInfo::TimerInfo::UpdateNextTimer() { std::string strNextRecordingTitle; std::string strNextRecordingChannelName; std::string strNextRecordingChannelIcon; std::string strNextRecordingTime; std::string strNextTimerInfo; CFileItemPtr tag = GetNextActiveTimer(); if (tag && tag->HasPVRTimerInfoTag()) { CPVRTimerInfoTagPtr timer = tag->GetPVRTimerInfoTag(); strNextRecordingTitle = StringUtils::Format("%s", timer->Title().c_str()); strNextRecordingChannelName = StringUtils::Format("%s", timer->ChannelName().c_str()); strNextRecordingChannelIcon = StringUtils::Format("%s", timer->ChannelIcon().c_str()); strNextRecordingTime = StringUtils::Format("%s", timer->StartAsLocalTime().GetAsLocalizedDateTime(false, false).c_str()); strNextTimerInfo = StringUtils::Format("%s %s %s %s", g_localizeStrings.Get(19106).c_str(), timer->StartAsLocalTime().GetAsLocalizedDate(true).c_str(), g_localizeStrings.Get(19107).c_str(), timer->StartAsLocalTime().GetAsLocalizedTime("HH:mm", false).c_str()); } CSingleLock lock(m_critSection); m_strNextRecordingTitle = strNextRecordingTitle; m_strNextRecordingChannelName = strNextRecordingChannelName; m_strNextRecordingChannelIcon = strNextRecordingChannelIcon; m_strNextRecordingTime = strNextRecordingTime; m_strNextTimerInfo = strNextTimerInfo; }
CFileItemPtr CPVRTimers::GetNextActiveTimer(void) const { CSingleLock lock(m_critSection); for (map<CDateTime, vector<CPVRTimerInfoTagPtr>* >::const_iterator it = m_tags.begin(); it != m_tags.end(); it++) { for (vector<CPVRTimerInfoTagPtr>::const_iterator timerIt = it->second->begin(); timerIt != it->second->end(); timerIt++) { CPVRTimerInfoTagPtr current = *timerIt; if (current->IsActive() && !current->IsRecording()) { CFileItemPtr fileItem(new CFileItem(*current)); return fileItem; } } } CFileItemPtr fileItem; return fileItem; }
CFileItemPtr CPVRTimers::GetNextActiveTimer(void) const { CSingleLock lock(m_critSection); for (MapTags::const_iterator it = m_tags.begin(); it != m_tags.end(); ++it) { for (VecTimerInfoTag::const_iterator timerIt = it->second->begin(); timerIt != it->second->end(); ++timerIt) { CPVRTimerInfoTagPtr current = *timerIt; if (current->IsActive() && !current->IsRecording() && !current->IsRepeating()) { CFileItemPtr fileItem(new CFileItem(current)); return fileItem; } } } CFileItemPtr fileItem; return fileItem; }