summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--HISTORY6
-rw-r--r--menu.c6
-rw-r--r--timers.c104
-rw-r--r--timers.h4
4 files changed, 71 insertions, 49 deletions
diff --git a/HISTORY b/HISTORY
index 45202255..ecbeb164 100644
--- a/HISTORY
+++ b/HISTORY
@@ -4395,3 +4395,9 @@ Video Disk Recorder Revision History
- The "Blue" key in the "Timers" menu now displays the EPG info of the event the
selected timer will record (if available). The "On/Off" function has been shifted
to the "Red" button. Editing a timer is done by pressing "Ok".
+- When determining which event a timer is going to record, all available events
+ in the future are now taken into account (no more limit to 4 hours in the
+ future). This has been done so that the event info is available in the "Timers"
+ menu when pressing the "Blue" button. In order to avoid unnecessary work, each
+ timer now has its own timestamp to control whether its schedule has changed
+ since the last time its event has been set.
diff --git a/menu.c b/menu.c
index ecc5225f..d15c017f 100644
--- a/menu.c
+++ b/menu.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: menu.c 1.421 2006/02/25 15:00:09 kls Exp $
+ * $Id: menu.c 1.422 2006/02/25 15:41:40 kls Exp $
*/
#include "menu.h"
@@ -691,6 +691,7 @@ eOSState cMenuEditTimer::ProcessKey(eKeys Key)
if (addIfConfirmed)
Timers.Add(timer);
timer->Matches();
+ timer->SetEventFromSchedule();
Timers.SetModified();
isyslog("timer %s %s (%s)", *timer->ToDescr(), addIfConfirmed ? "added" : "modified", timer->HasFlags(tfActive) ? "active" : "inactive");
addIfConfirmed = false;
@@ -828,6 +829,7 @@ eOSState cMenuTimers::OnOff(void)
cTimer *timer = CurrentTimer();
if (timer) {
timer->OnOff();
+ timer->SetEventFromSchedule();
RefreshCurrent();
DisplayCurrent(true);
if (timer->FirstDay())
@@ -896,7 +898,7 @@ eOSState cMenuTimers::ProcessKey(eKeys Key)
if (state == osUnknown) {
switch (Key) {
case kOk: return Edit();
- case kRed: return OnOff();
+ case kRed: state = OnOff(); break; // must go through SetHelpKeys()!
case kGreen: return New();
case kYellow: return Delete();
case kBlue: return Info();
diff --git a/timers.c b/timers.c
index ed5387de..b5e77cdb 100644
--- a/timers.c
+++ b/timers.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: timers.c 1.47 2006/02/25 10:44:50 kls Exp $
+ * $Id: timers.c 1.48 2006/02/25 15:57:56 kls Exp $
*/
#include "timers.h"
@@ -23,6 +23,7 @@
cTimer::cTimer(bool Instant, bool Pause, cChannel *Channel)
{
startTime = stopTime = 0;
+ lastSetEvent = 0;
recording = pending = inVpsMargin = false;
flags = tfNone;
if (Instant)
@@ -50,6 +51,7 @@ cTimer::cTimer(bool Instant, bool Pause, cChannel *Channel)
cTimer::cTimer(const cEvent *Event)
{
startTime = stopTime = 0;
+ lastSetEvent = event->Schedule() ? event->Schedule()->Modified() : 0;
recording = pending = inVpsMargin = false;
flags = tfActive;
if (Event->Vps() && Setup.UseVps)
@@ -91,6 +93,7 @@ cTimer& cTimer::operator= (const cTimer &Timer)
if (aux)
aux = strdup(aux);
event = NULL;
+ lastSetEvent = 0;
return *this;
}
@@ -423,6 +426,55 @@ time_t cTimer::StopTime(void) const
return stopTime;
}
+#define EPGLIMITPAST (2 * 3600) // time in seconds in the past within which EPG events will be taken into consideration
+
+void cTimer::SetEventFromSchedule(const cSchedules *Schedules)
+{
+ cSchedulesLock SchedulesLock;
+ if (!Schedules) {
+ lastSetEvent = 0; // forces setting the event, even if the schedule hasn't been modified
+ if (!(Schedules = cSchedules::Schedules(SchedulesLock)))
+ return;
+ }
+ const cSchedule *Schedule = Schedules->GetSchedule(Channel());
+ if (Schedule) {
+ if (!lastSetEvent || Schedule->Modified() >= lastSetEvent) {
+ const cEvent *Event = NULL;
+ int Overlap = 0;
+ int Distance = INT_MIN;
+ time_t now = time(NULL);
+ for (const cEvent *e = Schedule->Events()->First(); e; e = Schedule->Events()->Next(e)) {
+ if (e->EndTime() < now - EPGLIMITPAST)
+ continue; // skip old events
+ int overlap = 0;
+ Matches(e, &overlap);
+ if (overlap && overlap >= Overlap) {
+ int distance = 0;
+ if (now < e->StartTime())
+ distance = e->StartTime() - now;
+ else if (now > e->EndTime())
+ distance = e->EndTime() - now;
+ if (Event && overlap == Overlap) {
+ if (Overlap > FULLMATCH) { // this means VPS
+ if (abs(Distance) < abs(distance))
+ break; // we've already found the closest VPS event
+ }
+ else if (e->Duration() <= Event->Duration())
+ continue; // if overlap is the same, we take the longer event
+ }
+ Overlap = overlap;
+ Distance = distance;
+ Event = e;
+ }
+ }
+ if (Event && Event->EndTime() < now - EXPIRELATENCY && !Event->IsRunning())
+ Event = NULL;
+ SetEvent(Event);
+ }
+ }
+ lastSetEvent = time(NULL);
+}
+
void cTimer::SetEvent(const cEvent *Event)
{
if (event != Event) { //XXX TODO check event data, too???
@@ -488,7 +540,7 @@ bool cTimer::HasFlags(uint Flags) const
void cTimer::Skip(void)
{
day = IncDay(SetTime(StartTime(), 0), 1);
- event = NULL;
+ SetEvent(NULL);
}
void cTimer::OnOff(void)
@@ -503,7 +555,7 @@ void cTimer::OnOff(void)
Skip();
else
SetFlags(tfActive);
- event = NULL;
+ SetEvent(NULL);
Matches(); // refresh start and end time
}
@@ -591,9 +643,6 @@ bool cTimers::Modified(int &State)
return Result;
}
-#define EPGLIMITPAST (2 * 3600) // time in seconds around now, within which EPG events will be taken into consideration
-#define EPGLIMITFUTURE (4 * 3600)
-
void cTimers::SetEvents(void)
{
if (time(NULL) - lastSetEvents < 5)
@@ -603,46 +652,9 @@ void cTimers::SetEvents(void)
if (Schedules) {
if (!lastSetEvents || Schedules->Modified() >= lastSetEvents) {
for (cTimer *ti = First(); ti; ti = Next(ti)) {
- const cSchedule *Schedule = Schedules->GetSchedule(ti->Channel());
- if (Schedule) {
- if (!lastSetEvents || Schedule->Modified() >= lastSetEvents) {
- const cEvent *Event = NULL;
- int Overlap = 0;
- int Distance = INT_MIN;
- time_t now = time(NULL);
- for (const cEvent *e = Schedule->Events()->First(); e; e = Schedule->Events()->Next(e)) {
- if (cRemote::HasKeys())
- return; // react immediately on user input
- if (e->EndTime() < now - EPGLIMITPAST)
- continue; // skip old events
- if (e->StartTime() > now + EPGLIMITFUTURE)
- break; // no need to process events too far in the future
- int overlap = 0;
- ti->Matches(e, &overlap);
- if (overlap && overlap >= Overlap) {
- int distance = 0;
- if (now < e->StartTime())
- distance = e->StartTime() - now;
- else if (now > e->EndTime())
- distance = e->EndTime() - now;
- if (Event && overlap == Overlap) {
- if (Overlap > FULLMATCH) { // this means VPS
- if (abs(Distance) < abs(distance))
- break; // we've already found the closest VPS event
- }
- else if (e->Duration() <= Event->Duration())
- continue; // if overlap is the same, we take the longer event
- }
- Overlap = overlap;
- Distance = distance;
- Event = e;
- }
- }
- if (Event && Event->EndTime() < now - EXPIRELATENCY && !Event->IsRunning())
- Event = NULL;
- ti->SetEvent(Event);
- }
- }
+ if (cRemote::HasKeys())
+ return; // react immediately on user input
+ ti->SetEventFromSchedule(Schedules);
}
}
}
diff --git a/timers.h b/timers.h
index 7da77014..f49b48dd 100644
--- a/timers.h
+++ b/timers.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: timers.h 1.25 2006/02/25 10:42:10 kls Exp $
+ * $Id: timers.h 1.26 2006/02/25 15:05:09 kls Exp $
*/
#ifndef __TIMERS_H
@@ -28,6 +28,7 @@ class cTimer : public cListObject {
friend class cMenuEditTimer;
private:
mutable time_t startTime, stopTime;
+ time_t lastSetEvent;
bool recording, pending, inVpsMargin;
uint flags;
cChannel *channel;
@@ -77,6 +78,7 @@ public:
bool Expired(void) const;
time_t StartTime(void) const;
time_t StopTime(void) const;
+ void SetEventFromSchedule(const cSchedules *Schedules = NULL);
void SetEvent(const cEvent *Event);
void SetRecording(bool Recording);
void SetPending(bool Pending);