mirror of
				https://github.com/vdr-projects/vdr.git
				synced 2025-03-01 10:50:46 +00:00 
			
		
		
		
	The day of a timer is now stored as a full date in ISO notation
This commit is contained in:
		@@ -1296,3 +1296,6 @@ Luca Olivetti <luca@ventoso.org>
 | 
			
		||||
Mikko Salo <mikko.salo@ppe.inet.fi>
 | 
			
		||||
 for suggesting to make the setup option "DVB/Video display format" available only
 | 
			
		||||
 if "Video format" is set to "4:3"
 | 
			
		||||
 | 
			
		||||
Roman Krenick<63> <free-rtk@gmx.de>
 | 
			
		||||
 for a patch that was used a a basis for changing a timer's day handling to full date
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										5
									
								
								HISTORY
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								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<63>).
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								MANUAL
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								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
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										9
									
								
								menu.c
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								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,
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										208
									
								
								menuitems.c
									
									
									
									
									
								
							
							
						
						
									
										208
									
								
								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;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										20
									
								
								menuitems.h
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								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);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										188
									
								
								timers.c
									
									
									
									
									
								
							
							
						
						
									
										188
									
								
								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))
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										16
									
								
								timers.h
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								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<cTimer> {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										14
									
								
								vdr.5
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								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,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user