From ccc7c4a2d897f5e291a28d438a4fee9c6e45cd26 Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Sat, 19 Mar 2005 15:38:43 +0100 Subject: [PATCH] The day of a timer is now stored as a full date in ISO notation --- CONTRIBUTORS | 3 + HISTORY | 5 +- MANUAL | 10 ++- menu.c | 9 +-- menuitems.c | 208 +++++++++++++++++++++++---------------------------- menuitems.h | 20 ++--- timers.c | 188 ++++++++++++++++++++++++---------------------- timers.h | 16 ++-- vdr.5 | 14 +++- 9 files changed, 235 insertions(+), 238 deletions(-) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index daf5d7f9..08f6ccfc 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -1296,3 +1296,6 @@ Luca Olivetti Mikko Salo for suggesting to make the setup option "DVB/Video display format" available only if "Video format" is set to "4:3" + +Roman Krenický + for a patch that was used a a basis for changing a timer's day handling to full date diff --git a/HISTORY b/HISTORY index 3d6197e7..8c6ad821 100644 --- a/HISTORY +++ b/HISTORY @@ -3444,7 +3444,7 @@ Video Disk Recorder Revision History - Fixed handling repeated kAudio keys. - Improved displaying the the current audio track in the ST:TNG channel display. -2005-03-13: Version 1.3.23 +2005-03-19: Version 1.3.23 - The setup option "DVB/Video display format" is now only available if "Video format" is set to "4:3" (suggested by Mikko Salo). @@ -3461,3 +3461,6 @@ Video Disk Recorder Revision History - The running status of a VPS event is now only taken seriously if that event has been seen within the last 30 seconds - otherwise recording is done as if no VPS was available. +- The day of a timer is now stored as a full date in ISO notation ("YYYY-MM-DD") in + 'timers.conf' and for the result of the SVDRP command LSTT (based in parts on a + patch by Roman Krenický). diff --git a/MANUAL b/MANUAL index a8d3a57b..ebf8ce02 100644 --- a/MANUAL +++ b/MANUAL @@ -381,10 +381,9 @@ Version 1.2 Any changes made in the "Channels" list (like renaming or reordering channels) will be automatically reflected in the timers settings. - Day: The day on which this timer shall start. This can be either a - "day of month" (1..31), which allows programming a "single shot" - timer that hits once and is deleted after it ends. Single shot - timers can be programmed up to one month into the future. + Day: The day on which this timer shall start. This can be a + date (like 2005-03-19), which allows programming a "single shot" + timer that hits once and is deleted after it ends. Another option here are "repeating timers" which are defined by listing the days of the week on which they shall record. For example, a timer that shall record every monday and wednesday @@ -392,6 +391,9 @@ Version 1.2 The '0' key toggles between a single shot and a repeating timer. If "Day" indicates a repeating timer, the keys '1'...'7' can be used to toggle the individual days ('1' is monday). + You can also switch to a set of predefined repeating timer settings + by pressing the "Left" key when the day is the present day. To return + to the single shot mode just press "Right" until a date is displayed. Start: The start time of the timer in hh:mm as 24 hour ("military") time. Stop: The stop time of the timer. VPS: Defines whether the timer shall use VPS (if available). If this diff --git a/menu.c b/menu.c index a6bac7d8..de5969a5 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.343 2005/03/05 15:43:10 kls Exp $ + * $Id: menu.c 1.344 2005/03/19 14:23:43 kls Exp $ */ #include "menu.h" @@ -632,7 +632,7 @@ cMenuEditTimer::cMenuEditTimer(cTimer *Timer, bool New) channel = data.Channel()->Number(); Add(new cMenuEditBitItem( tr("Active"), &data.flags, tfActive)); Add(new cMenuEditChanItem(tr("Channel"), &channel)); - Add(new cMenuEditDayItem( tr("Day"), &data.day)); + Add(new cMenuEditDateItem(tr("Day"), &data.day, &data.weekdays)); Add(new cMenuEditTimeItem(tr("Start"), &data.start)); Add(new cMenuEditTimeItem(tr("Stop"), &data.stop)); Add(new cMenuEditBitItem( tr("VPS"), &data.flags, tfVps)); @@ -654,13 +654,12 @@ cMenuEditTimer::~cMenuEditTimer() void cMenuEditTimer::SetFirstDayItem(void) { if (!firstday && !data.IsSingleEvent()) { - Add(firstday = new cMenuEditDateItem(tr("First day"), &data.firstday)); + Add(firstday = new cMenuEditDateItem(tr("First day"), &data.day)); Display(); } else if (firstday && data.IsSingleEvent()) { Del(firstday->Index()); firstday = NULL; - data.firstday = 0; Display(); } } @@ -739,7 +738,7 @@ void cMenuTimerItem::Set(void) timer->Channel()->Number(), timer->IsSingleEvent() ? *WeekDayName(timer->StartTime()) : "", timer->IsSingleEvent() ? " " : "", - *timer->PrintDay(timer->Day()), + *timer->PrintDay(timer->Day(), timer->WeekDays()), timer->Start() / 100, timer->Start() % 100, timer->Stop() / 100, diff --git a/menuitems.c b/menuitems.c index 9b86db4b..18b001ee 100644 --- a/menuitems.c +++ b/menuitems.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menuitems.c 1.21 2004/11/21 13:24:10 kls Exp $ + * $Id: menuitems.c 1.22 2005/03/19 15:33:34 kls Exp $ */ #include "menuitems.h" @@ -535,117 +535,35 @@ eOSState cMenuEditTranItem::ProcessKey(eKeys Key) return state; } -// --- cMenuEditDayItem ------------------------------------------------------ - -int cMenuEditDayItem::days[] ={ cTimer::ParseDay("M------"), - cTimer::ParseDay("-T-----"), - cTimer::ParseDay("--W----"), - cTimer::ParseDay("---T---"), - cTimer::ParseDay("----F--"), - cTimer::ParseDay("-----S-"), - cTimer::ParseDay("------S"), - cTimer::ParseDay("MTWTF--"), - cTimer::ParseDay("MTWTFS-"), - cTimer::ParseDay("MTWTFSS"), - cTimer::ParseDay("-----SS"), - 0 }; - -cMenuEditDayItem::cMenuEditDayItem(const char *Name, int *Value) -:cMenuEditIntItem(Name, Value, -INT_MAX, 31) -{ - d = -1; - md = 0; - if (*value < 0) { - int n = 0; - while (days[n]) { - if (days[n] == *value) { - d = n; - break; - } - n++; - } - } - Set(); -} - -void cMenuEditDayItem::Set(void) -{ - SetValue(cTimer::PrintDay(*value)); -} - -eOSState cMenuEditDayItem::ProcessKey(eKeys Key) -{ - switch (Key) { - case kLeft|k_Repeat: - case kLeft: if (d > 0) - *value = days[--d]; - else if (d == 0) { - *value = 31; - d = -1; - } - else if (*value == 1) { - d = sizeof(days) / sizeof(int) - 2; - *value = days[d]; - } - else - return cMenuEditIntItem::ProcessKey(Key); - Set(); - break; - case kRight|k_Repeat: - case kRight: if (d >= 0) { - *value = days[++d]; - if (*value == 0) { - *value = 1; - d = -1; - } - } - else if (*value == 31) { - d = 0; - *value = days[d]; - } - else - return cMenuEditIntItem::ProcessKey(Key); - Set(); - break; - default: { - if (d >= 0) { - if (k1 <= Key && Key <= k7) { - int v = *value ^ (1 << (Key - k1)); - if ((v & 0xFF) != 0) { - *value = v; // can't let this become all 0 - Set(); - } - break; - } - } - int v = *value; - eOSState result = cMenuEditIntItem::ProcessKey(Key); - if (result == osContinue && Key == k0) { - if (d >= 0) { - *value = md ? md : cTimer::GetMDay(time(NULL)); - md = 0; - d = -1; - Set(); - } - else if (*value == 0 || *value == v) { - md = v; - d = cTimer::GetWDayFromMDay(v); - *value = days[d]; - Set(); - } - } - return result; - } - } - return osContinue; -} - // --- cMenuEditDateItem ----------------------------------------------------- -cMenuEditDateItem::cMenuEditDateItem(const char *Name, time_t *Value) +static int ParseWeekDays(const char *s) +{ + time_t day; + int weekdays; + return cTimer::ParseDay(s, day, weekdays) ? weekdays : 0; +} + +int cMenuEditDateItem::days[] = { ParseWeekDays("M------"), + ParseWeekDays("-T-----"), + ParseWeekDays("--W----"), + ParseWeekDays("---T---"), + ParseWeekDays("----F--"), + ParseWeekDays("-----S-"), + ParseWeekDays("------S"), + ParseWeekDays("MTWTF--"), + ParseWeekDays("MTWTFS-"), + ParseWeekDays("MTWTFSS"), + ParseWeekDays("-----SS"), + 0 }; + +cMenuEditDateItem::cMenuEditDateItem(const char *Name, time_t *Value, int *WeekDays) :cMenuEditItem(Name) { value = Value; + weekdays = WeekDays; + oldvalue = 0; + dayindex = 0; Set(); } @@ -653,7 +571,11 @@ void cMenuEditDateItem::Set(void) { #define DATEBUFFERSIZE 32 char buf[DATEBUFFERSIZE]; - if (*value) { + if (weekdays && *weekdays) { + SetValue(cTimer::PrintDay(0, *weekdays)); + return; + } + else if (*value) { struct tm tm_r; localtime_r(value, &tm_r); strftime(buf, DATEBUFFERSIZE, "%Y-%m-%d ", &tm_r); @@ -669,15 +591,73 @@ eOSState cMenuEditDateItem::ProcessKey(eKeys Key) eOSState state = cMenuEditItem::ProcessKey(Key); if (state == osUnknown) { + time_t now = time(NULL); if (NORMALKEY(Key) == kLeft) { // TODO might want to increase the delta if repeated quickly? - *value -= SECSINDAY; - if (*value < time(NULL)) - *value = 0; + if (!weekdays || !*weekdays) { + // Decrement single day: + time_t v = *value; + v -= SECSINDAY; + if (v < now) { + if (now <= v + SECSINDAY) { // switched from tomorrow to today + if (!weekdays) + v = 0; + } + else if (weekdays) { // switched from today to yesterday, so enter weekdays mode + v = 0; + dayindex = sizeof(days) / sizeof(int) - 2; + *weekdays = days[dayindex]; + } + else // don't go before today + v = *value; + } + *value = v; + } + else { + // Decrement weekday index: + if (dayindex > 0) + *weekdays = days[--dayindex]; + } } else if (NORMALKEY(Key) == kRight) { - if (!*value) - *value = cTimer::SetTime(time(NULL), 0); - *value += SECSINDAY; + if (!weekdays || !*weekdays) { + // Increment single day: + if (!*value) + *value = cTimer::SetTime(now, 0); + *value += SECSINDAY; + } + else { + // Increment weekday index: + *weekdays = days[++dayindex]; + if (!*weekdays) { // was last weekday entry, so switch to today + *value = cTimer::SetTime(now, 0); + dayindex = 0; + } + } + } + else if (weekdays) { + if (Key == k0) { + // Toggle between weekdays and single day: + if (*weekdays) { + *value = cTimer::SetTime(oldvalue ? oldvalue : now, 0); + oldvalue = 0; + *weekdays = 0; + } + else { + *weekdays = days[cTimer::GetWDay(*value)]; + oldvalue = *value; + *value = 0; + } + } + else if (k1 <= Key && Key <= k7) { + // Toggle individual weekdays: + if (*weekdays) { + int v = *weekdays ^ (1 << (Key - k1)); + if (v != 0) + *weekdays = v; // can't let this become all 0 + } + } + else + return state; } else return state; diff --git a/menuitems.h b/menuitems.h index 28904013..b45fc960 100644 --- a/menuitems.h +++ b/menuitems.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menuitems.h 1.10 2004/11/21 13:23:00 kls Exp $ + * $Id: menuitems.h 1.11 2005/03/19 15:02:57 kls Exp $ */ #ifndef __MENUITEMS_H @@ -118,24 +118,16 @@ public: virtual eOSState ProcessKey(eKeys Key); }; -class cMenuEditDayItem : public cMenuEditIntItem { +class cMenuEditDateItem : public cMenuEditItem { private: static int days[]; - int d; - int md; -protected: - virtual void Set(void); -public: - cMenuEditDayItem(const char *Name, int *Value); - virtual eOSState ProcessKey(eKeys Key); - }; - -class cMenuEditDateItem : public cMenuEditItem { -protected: time_t *value; + int *weekdays; + time_t oldvalue; + int dayindex; virtual void Set(void); public: - cMenuEditDateItem(const char *Name, time_t *Value); + cMenuEditDateItem(const char *Name, time_t *Value, int *WeekDays = NULL); virtual eOSState ProcessKey(eKeys Key); }; diff --git a/timers.c b/timers.c index 63bff33c..e24fb207 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.24 2005/03/13 12:53:51 kls Exp $ + * $Id: timers.c 1.25 2005/03/19 15:20:58 kls Exp $ */ #include "timers.h" @@ -30,7 +30,8 @@ cTimer::cTimer(bool Instant, bool Pause) time_t t = time(NULL); struct tm tm_r; struct tm *now = localtime_r(&t, &tm_r); - day = now->tm_mday; + day = SetTime(t, 0); + weekdays = 0; start = now->tm_hour * 100 + now->tm_min; stop = now->tm_hour * 60 + now->tm_min + Setup.InstantRecordTime; stop = (stop / 60) * 100 + (stop % 60); @@ -39,7 +40,6 @@ cTimer::cTimer(bool Instant, bool Pause) priority = Pause ? Setup.PausePriority : Setup.DefaultPriority; lifetime = Pause ? Setup.PauseLifetime : Setup.DefaultLifetime; *file = 0; - firstday = 0; summary = NULL; event = NULL; if (Instant && channel) @@ -62,7 +62,8 @@ cTimer::cTimer(const cEvent *Event) } struct tm tm_r; struct tm *time = localtime_r(&tstart, &tm_r); - day = time->tm_mday; + day = SetTime(tstart, 0); + weekdays = 0; start = time->tm_hour * 100 + time->tm_min; time = localtime_r(&tstop, &tm_r); stop = time->tm_hour * 100 + time->tm_min; @@ -74,7 +75,6 @@ cTimer::cTimer(const cEvent *Event) const char *Title = Event->Title(); if (!isempty(Title)) strn0cpy(file, Event->Title(), sizeof(file)); - firstday = 0; summary = NULL; event = Event; } @@ -109,7 +109,7 @@ cString cTimer::ToText(bool UseChannelID) char *buffer; strreplace(file, ':', '|'); strreplace(summary, '\n', '|'); - asprintf(&buffer, "%d:%s:%s:%04d:%04d:%d:%d:%s:%s\n", flags, UseChannelID ? *Channel()->GetChannelID().ToString() : *itoa(Channel()->Number()), *PrintDay(day, firstday), start, stop, priority, lifetime, file, summary ? summary : ""); + asprintf(&buffer, "%d:%s:%s:%04d:%04d:%d:%d:%s:%s\n", flags, UseChannelID ? *Channel()->GetChannelID().ToString() : *itoa(Channel()->Number()), *PrintDay(day, weekdays), start, stop, priority, lifetime, file, summary ? summary : ""); strreplace(summary, '|', '\n'); strreplace(file, '|', ':'); return cString(buffer, true); @@ -120,74 +120,93 @@ int cTimer::TimeToInt(int t) return (t / 100 * 60 + t % 100) * 60; } -int cTimer::ParseDay(const char *s, time_t *FirstDay) +bool cTimer::ParseDay(const char *s, time_t &Day, int &WeekDays) { - char *tail; - int d = strtol(s, &tail, 10); - if (FirstDay) - *FirstDay = 0; - if (tail && *tail) { - d = 0; - if (tail == s) { - const char *first = strchr(s, '@'); - int l = first ? first - s : strlen(s); - if (l == 7) { - for (const char *p = s + 6; p >= s; p--) { - d <<= 1; - d |= (*p != '-'); + // possible formats are: + // 19 + // 2005-03-19 + // MTWTFSS + // MTWTFSS@19 + // MTWTFSS@2005-03-19 + + Day = 0; + WeekDays = 0; + s = skipspace(s); + if (!*s) + return false; + const char *a = strchr(s, '@'); + const char *d = a ? a + 1 : isdigit(*s) ? s : NULL; + if (d) { + if (strlen(d) == 10) { + struct tm tm_r; + if (3 == sscanf(d, "%d-%d-%d", &tm_r.tm_year, &tm_r.tm_mon, &tm_r.tm_mday)) { + tm_r.tm_year -= 1900; + tm_r.tm_mon--; + tm_r.tm_hour = tm_r.tm_min = tm_r.tm_sec = 0; + tm_r.tm_isdst = -1; // makes sure mktime() will determine the correct DST setting + Day = mktime(&tm_r); + } + else + return false; + } + else { + // handle "day of month" for compatibility with older versions: + char *tail = NULL; + int day = strtol(s, &tail, 10); + if (tail && *tail || day < 1 || day > 31) + return false; + time_t t = time(NULL); + int DaysToCheck = 61; // 61 to handle months with 31/30/31 + for (int i = -1; i <= DaysToCheck; i++) { + time_t t0 = IncDay(t, i); + if (GetMDay(t0) == day) { + Day = SetTime(t0, 0); + break; } - d |= 0x80000000; - } - if (FirstDay && first) { - ++first; - if (strlen(first) == 10) { - struct tm tm_r; - if (3 == sscanf(first, "%d-%d-%d", &tm_r.tm_year, &tm_r.tm_mon, &tm_r.tm_mday)) { - tm_r.tm_year -= 1900; - tm_r.tm_mon--; - tm_r.tm_hour = tm_r.tm_min = tm_r.tm_sec = 0; - tm_r.tm_isdst = -1; // makes sure mktime() will determine the correct DST setting - *FirstDay = mktime(&tm_r); - } - } - else - d = 0; - } + } } } - else if (d < 1 || d > 31) - d = 0; - return d; + if (a || !isdigit(*s)) { + if ((a && a - s == 7) || strlen(s) == 7) { + for (const char *p = s + 6; p >= s; p--) { + WeekDays <<= 1; + WeekDays |= (*p != '-'); + } + } + else + return false; + } + return true; } -cString cTimer::PrintDay(int d, time_t FirstDay) +cString cTimer::PrintDay(time_t Day, int WeekDays) { #define DAYBUFFERSIZE 32 char buffer[DAYBUFFERSIZE]; - if ((d & 0x80000000) != 0) { - char *b = buffer; + char *b = buffer; + if (WeekDays) { const char *w = tr("MTWTFSS"); while (*w) { - *b++ = (d & 1) ? *w : '-'; - d >>= 1; + *b++ = (WeekDays & 1) ? *w : '-'; + WeekDays >>= 1; w++; } - if (FirstDay) { - struct tm tm_r; - localtime_r(&FirstDay, &tm_r); - b += strftime(b, DAYBUFFERSIZE - (b - buffer), "@%Y-%m-%d", &tm_r); - } - *b = 0; + if (Day) + *b++ = '@'; } - else - sprintf(buffer, "%d", d); + if (Day) { + struct tm tm_r; + localtime_r(&Day, &tm_r); + b += strftime(b, DAYBUFFERSIZE - (b - buffer), "%Y-%m-%d", &tm_r); + } + *b = 0; return buffer; } cString cTimer::PrintFirstDay(void) { - if (firstday) { - cString s = PrintDay(day, firstday); + if (weekdays) { + cString s = PrintDay(day, weekdays); if (strlen(s) == 18) return *s + 8; } @@ -223,8 +242,7 @@ bool cTimer::Parse(const char *s) summary = NULL; } //TODO add more plausibility checks - day = ParseDay(daybuffer, &firstday); - result = day != 0; + result = ParseDay(daybuffer, day, weekdays); strn0cpy(file, filebuffer, MaxFileName); strreplace(file, '|', ':'); strreplace(summary, '|', '\n'); @@ -251,7 +269,7 @@ bool cTimer::Save(FILE *f) bool cTimer::IsSingleEvent(void) const { - return (day & 0x80000000) == 0; + return !weekdays; } int cTimer::GetMDay(time_t t) @@ -267,20 +285,9 @@ int cTimer::GetWDay(time_t t) return weekday == 0 ? 6 : weekday - 1; // we start with monday==0! } -int cTimer::GetWDayFromMDay(int MDay) -{ - time_t now = time(NULL); - for (int i = -1; i <= 28; i++) { // looking 4 weeks into the future should be enough - time_t t0 = IncDay(now, i); - if (GetMDay(t0) == MDay) - return GetWDay(t0); - } - return GetWDay(now); // just to return something -} - bool cTimer::DayMatches(time_t t) const { - return IsSingleEvent() ? GetMDay(t) == day : (day & (1 << GetWDay(t))) != 0; + return IsSingleEvent() ? SetTime(t, 0) == day : (weekdays & (1 << GetWDay(t))) != 0; } time_t cTimer::IncDay(time_t t, int Days) @@ -324,23 +331,28 @@ bool cTimer::Matches(time_t t, bool Directly) const if (length < 0) length += SECSINDAY; - int DaysToCheck = IsSingleEvent() ? 61 : 7; // 61 to handle months with 31/30/31 - for (int i = -1; i <= DaysToCheck; i++) { - time_t t0 = IncDay(t, i); - if (DayMatches(t0)) { - time_t a = SetTime(t0, begin); - time_t b = a + length; - if ((!firstday || a >= firstday) && t <= b) { - startTime = a; - stopTime = b; - break; + if (IsSingleEvent()) { + startTime = SetTime(day, begin); + stopTime = startTime + length; + } + else { + for (int i = -1; i <= 7; i++) { + time_t t0 = IncDay(t, i); + if (DayMatches(t0)) { + time_t a = SetTime(t0, begin); + time_t b = a + length; + if ((!day || a >= day) && t <= b) { + startTime = a; + stopTime = b; + break; + } } } - } - if (!startTime) - startTime = firstday; // just to have something that's more than a week in the future - else if (!Directly && (t > startTime || t > firstday + SECSINDAY + 3600)) // +3600 in case of DST change - firstday = 0; + if (!startTime) + startTime = day; // just to have something that's more than a week in the future + else if (!Directly && (t > startTime || t > day + SECSINDAY + 3600)) // +3600 in case of DST change + day = 0; + } if (HasFlags(tfActive)) { if (HasFlags(tfVps) && !Directly && event && event->Vps() && event->SeenWithin(30)) { @@ -446,7 +458,7 @@ bool cTimer::HasFlags(int Flags) const void cTimer::Skip(void) { - firstday = IncDay(SetTime(StartTime(), 0), 1); + day = IncDay(SetTime(StartTime(), 0), 1); event = NULL; } @@ -454,8 +466,8 @@ void cTimer::OnOff(void) { if (IsSingleEvent()) InvFlags(tfActive); - else if (firstday) { - firstday = 0; + else if (day) { + day = 0; ClrFlags(tfActive); } else if (HasFlags(tfActive)) diff --git a/timers.h b/timers.h index ac83dd5c..9c611b88 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.14 2005/03/12 16:27:36 kls Exp $ + * $Id: timers.h 1.15 2005/03/19 14:22:11 kls Exp $ */ #ifndef __TIMERS_H @@ -30,13 +30,13 @@ private: bool recording, pending, inVpsMargin; int flags; cChannel *channel; - int day; + mutable time_t day; /// midnight of the day this timer shall hit, or of the first day it shall hit in case of a repeating timer + int weekdays; /// bitmask, lowest bits: SSFTWTM (the 'M' is the LSB) int start; int stop; int priority; int lifetime; char file[MaxFileName]; - mutable time_t firstday; char *summary; const cEvent *event; public: @@ -50,13 +50,14 @@ public: bool InVpsMargin(void) { return inVpsMargin; } int Flags(void) { return flags; } const cChannel *Channel(void) { return channel; } - int Day(void) { return day; } + time_t Day(void) { return day; } + int WeekDays(void) { return weekdays; } int Start(void) { return start; } int Stop(void) { return stop; } int Priority(void) { return priority; } int Lifetime(void) { return lifetime; } const char *File(void) { return file; } - time_t FirstDay(void) { return firstday; } + time_t FirstDay(void) { return weekdays ? day : 0; } const char *Summary(void) { return summary; } cString ToText(bool UseChannelID = false); const cEvent *Event(void) { return event; } @@ -65,7 +66,6 @@ public: bool IsSingleEvent(void) const; static int GetMDay(time_t t); static int GetWDay(time_t t); - static int GetWDayFromMDay(int MDay); bool DayMatches(time_t t) const; static time_t IncDay(time_t t, int Days); static time_t SetTime(time_t t, int SecondsFromMidnight); @@ -86,8 +86,8 @@ public: void OnOff(void); cString PrintFirstDay(void); static int TimeToInt(int t); - static int ParseDay(const char *s, time_t *FirstDay = NULL); - static cString PrintDay(int d, time_t FirstDay = 0); + static bool ParseDay(const char *s, time_t &Day, int &WeekDays); + static cString PrintDay(time_t Day, int WeekDays); }; class cTimers : public cConfig { diff --git a/vdr.5 b/vdr.5 index db33a157..5333be7c 100644 --- a/vdr.5 +++ b/vdr.5 @@ -8,9 +8,9 @@ .\" License as specified in the file COPYING that comes with the .\" vdr distribution. .\" -.\" $Id: vdr.5 1.34 2005/01/23 13:31:40 kls Exp $ +.\" $Id: vdr.5 1.35 2005/03/19 15:20:47 kls Exp $ .\" -.TH vdr 5 "19 Dec 2004" "1.3.18" "Video Disk Recorder Files" +.TH vdr 5 "19 Mar 2005" "1.3.23" "Video Disk Recorder Files" .SH NAME vdr file formats - the Video Disk Recorder Files .SH DESCRIPTION @@ -231,8 +231,13 @@ commands, the channels are given as numbers. .B Day The day when this timer shall record. -If this is a `single-shot' timer, this is the day of month on which this -timer shall record. This must be in the range \fB1...31\fR. +If this is a `single-shot' timer, this is the date on which this +timer shall record, given in ISO notation (\fBYYYY-MM-DD\fR), as in: + +.B 2005-03-19 + +For compatibility with earlier versions of VDR this may also be just the day of month +on which this timer shall record (must be in the range \fB1...31\fR). In case of a `repeating' timer this is a string consisting of exactly seven characters, where each character position corresponds to one day of the week @@ -245,6 +250,7 @@ cause the timer to record on that day. Example: will define a timer that records on Monday thru Friday and does not record on weekends. The same result could be achieved with \fBABCDE\-\-\fR (this is used to allow setting the days with language specific characters). +Note that only letters may be used here, no digits. The day definition of a `repeating' timer may be followed by the date when that timer shall hit for the first time. The format for this is \fB@YYYY\-MM\-DD\fR,