mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
The day of a timer is now stored as a full date in ISO notation
This commit is contained in:
parent
ae5ee879d0
commit
ccc7c4a2d8
@ -1296,3 +1296,6 @@ Luca Olivetti <luca@ventoso.org>
|
|||||||
Mikko Salo <mikko.salo@ppe.inet.fi>
|
Mikko Salo <mikko.salo@ppe.inet.fi>
|
||||||
for suggesting to make the setup option "DVB/Video display format" available only
|
for suggesting to make the setup option "DVB/Video display format" available only
|
||||||
if "Video format" is set to "4:3"
|
if "Video format" is set to "4:3"
|
||||||
|
|
||||||
|
Roman Krenický <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.
|
- Fixed handling repeated kAudio keys.
|
||||||
- Improved displaying the the current audio track in the ST:TNG channel display.
|
- 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"
|
- The setup option "DVB/Video display format" is now only available if "Video format"
|
||||||
is set to "4:3" (suggested by Mikko Salo).
|
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
|
- 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
|
seen within the last 30 seconds - otherwise recording is done as if no VPS was
|
||||||
available.
|
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ý).
|
||||||
|
10
MANUAL
10
MANUAL
@ -381,10 +381,9 @@ Version 1.2
|
|||||||
Any changes made in the "Channels" list (like renaming or
|
Any changes made in the "Channels" list (like renaming or
|
||||||
reordering channels) will be automatically reflected in the
|
reordering channels) will be automatically reflected in the
|
||||||
timers settings.
|
timers settings.
|
||||||
Day: The day on which this timer shall start. This can be either a
|
Day: The day on which this timer shall start. This can be a
|
||||||
"day of month" (1..31), which allows programming a "single shot"
|
date (like 2005-03-19), which allows programming a "single shot"
|
||||||
timer that hits once and is deleted after it ends. Single shot
|
timer that hits once and is deleted after it ends.
|
||||||
timers can be programmed up to one month into the future.
|
|
||||||
Another option here are "repeating timers" which are defined
|
Another option here are "repeating timers" which are defined
|
||||||
by listing the days of the week on which they shall record.
|
by listing the days of the week on which they shall record.
|
||||||
For example, a timer that shall record every monday and wednesday
|
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.
|
The '0' key toggles between a single shot and a repeating timer.
|
||||||
If "Day" indicates a repeating timer, the keys '1'...'7' can be
|
If "Day" indicates a repeating timer, the keys '1'...'7' can be
|
||||||
used to toggle the individual days ('1' is monday).
|
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.
|
Start: The start time of the timer in hh:mm as 24 hour ("military") time.
|
||||||
Stop: The stop time of the timer.
|
Stop: The stop time of the timer.
|
||||||
VPS: Defines whether the timer shall use VPS (if available). If this
|
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
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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"
|
#include "menu.h"
|
||||||
@ -632,7 +632,7 @@ cMenuEditTimer::cMenuEditTimer(cTimer *Timer, bool New)
|
|||||||
channel = data.Channel()->Number();
|
channel = data.Channel()->Number();
|
||||||
Add(new cMenuEditBitItem( tr("Active"), &data.flags, tfActive));
|
Add(new cMenuEditBitItem( tr("Active"), &data.flags, tfActive));
|
||||||
Add(new cMenuEditChanItem(tr("Channel"), &channel));
|
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("Start"), &data.start));
|
||||||
Add(new cMenuEditTimeItem(tr("Stop"), &data.stop));
|
Add(new cMenuEditTimeItem(tr("Stop"), &data.stop));
|
||||||
Add(new cMenuEditBitItem( tr("VPS"), &data.flags, tfVps));
|
Add(new cMenuEditBitItem( tr("VPS"), &data.flags, tfVps));
|
||||||
@ -654,13 +654,12 @@ cMenuEditTimer::~cMenuEditTimer()
|
|||||||
void cMenuEditTimer::SetFirstDayItem(void)
|
void cMenuEditTimer::SetFirstDayItem(void)
|
||||||
{
|
{
|
||||||
if (!firstday && !data.IsSingleEvent()) {
|
if (!firstday && !data.IsSingleEvent()) {
|
||||||
Add(firstday = new cMenuEditDateItem(tr("First day"), &data.firstday));
|
Add(firstday = new cMenuEditDateItem(tr("First day"), &data.day));
|
||||||
Display();
|
Display();
|
||||||
}
|
}
|
||||||
else if (firstday && data.IsSingleEvent()) {
|
else if (firstday && data.IsSingleEvent()) {
|
||||||
Del(firstday->Index());
|
Del(firstday->Index());
|
||||||
firstday = NULL;
|
firstday = NULL;
|
||||||
data.firstday = 0;
|
|
||||||
Display();
|
Display();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -739,7 +738,7 @@ void cMenuTimerItem::Set(void)
|
|||||||
timer->Channel()->Number(),
|
timer->Channel()->Number(),
|
||||||
timer->IsSingleEvent() ? *WeekDayName(timer->StartTime()) : "",
|
timer->IsSingleEvent() ? *WeekDayName(timer->StartTime()) : "",
|
||||||
timer->IsSingleEvent() ? " " : "",
|
timer->IsSingleEvent() ? " " : "",
|
||||||
*timer->PrintDay(timer->Day()),
|
*timer->PrintDay(timer->Day(), timer->WeekDays()),
|
||||||
timer->Start() / 100,
|
timer->Start() / 100,
|
||||||
timer->Start() % 100,
|
timer->Start() % 100,
|
||||||
timer->Stop() / 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
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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"
|
#include "menuitems.h"
|
||||||
@ -535,117 +535,35 @@ eOSState cMenuEditTranItem::ProcessKey(eKeys Key)
|
|||||||
return state;
|
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::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)
|
:cMenuEditItem(Name)
|
||||||
{
|
{
|
||||||
value = Value;
|
value = Value;
|
||||||
|
weekdays = WeekDays;
|
||||||
|
oldvalue = 0;
|
||||||
|
dayindex = 0;
|
||||||
Set();
|
Set();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -653,7 +571,11 @@ void cMenuEditDateItem::Set(void)
|
|||||||
{
|
{
|
||||||
#define DATEBUFFERSIZE 32
|
#define DATEBUFFERSIZE 32
|
||||||
char buf[DATEBUFFERSIZE];
|
char buf[DATEBUFFERSIZE];
|
||||||
if (*value) {
|
if (weekdays && *weekdays) {
|
||||||
|
SetValue(cTimer::PrintDay(0, *weekdays));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (*value) {
|
||||||
struct tm tm_r;
|
struct tm tm_r;
|
||||||
localtime_r(value, &tm_r);
|
localtime_r(value, &tm_r);
|
||||||
strftime(buf, DATEBUFFERSIZE, "%Y-%m-%d ", &tm_r);
|
strftime(buf, DATEBUFFERSIZE, "%Y-%m-%d ", &tm_r);
|
||||||
@ -669,15 +591,73 @@ eOSState cMenuEditDateItem::ProcessKey(eKeys Key)
|
|||||||
eOSState state = cMenuEditItem::ProcessKey(Key);
|
eOSState state = cMenuEditItem::ProcessKey(Key);
|
||||||
|
|
||||||
if (state == osUnknown) {
|
if (state == osUnknown) {
|
||||||
|
time_t now = time(NULL);
|
||||||
if (NORMALKEY(Key) == kLeft) { // TODO might want to increase the delta if repeated quickly?
|
if (NORMALKEY(Key) == kLeft) { // TODO might want to increase the delta if repeated quickly?
|
||||||
*value -= SECSINDAY;
|
if (!weekdays || !*weekdays) {
|
||||||
if (*value < time(NULL))
|
// Decrement single day:
|
||||||
*value = 0;
|
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) {
|
else if (NORMALKEY(Key) == kRight) {
|
||||||
if (!*value)
|
if (!weekdays || !*weekdays) {
|
||||||
*value = cTimer::SetTime(time(NULL), 0);
|
// Increment single day:
|
||||||
*value += SECSINDAY;
|
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
|
else
|
||||||
return state;
|
return state;
|
||||||
|
20
menuitems.h
20
menuitems.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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
|
#ifndef __MENUITEMS_H
|
||||||
@ -118,24 +118,16 @@ public:
|
|||||||
virtual eOSState ProcessKey(eKeys Key);
|
virtual eOSState ProcessKey(eKeys Key);
|
||||||
};
|
};
|
||||||
|
|
||||||
class cMenuEditDayItem : public cMenuEditIntItem {
|
class cMenuEditDateItem : public cMenuEditItem {
|
||||||
private:
|
private:
|
||||||
static int days[];
|
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;
|
time_t *value;
|
||||||
|
int *weekdays;
|
||||||
|
time_t oldvalue;
|
||||||
|
int dayindex;
|
||||||
virtual void Set(void);
|
virtual void Set(void);
|
||||||
public:
|
public:
|
||||||
cMenuEditDateItem(const char *Name, time_t *Value);
|
cMenuEditDateItem(const char *Name, time_t *Value, int *WeekDays = NULL);
|
||||||
virtual eOSState ProcessKey(eKeys Key);
|
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
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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"
|
#include "timers.h"
|
||||||
@ -30,7 +30,8 @@ cTimer::cTimer(bool Instant, bool Pause)
|
|||||||
time_t t = time(NULL);
|
time_t t = time(NULL);
|
||||||
struct tm tm_r;
|
struct tm tm_r;
|
||||||
struct tm *now = localtime_r(&t, &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;
|
start = now->tm_hour * 100 + now->tm_min;
|
||||||
stop = now->tm_hour * 60 + now->tm_min + Setup.InstantRecordTime;
|
stop = now->tm_hour * 60 + now->tm_min + Setup.InstantRecordTime;
|
||||||
stop = (stop / 60) * 100 + (stop % 60);
|
stop = (stop / 60) * 100 + (stop % 60);
|
||||||
@ -39,7 +40,6 @@ cTimer::cTimer(bool Instant, bool Pause)
|
|||||||
priority = Pause ? Setup.PausePriority : Setup.DefaultPriority;
|
priority = Pause ? Setup.PausePriority : Setup.DefaultPriority;
|
||||||
lifetime = Pause ? Setup.PauseLifetime : Setup.DefaultLifetime;
|
lifetime = Pause ? Setup.PauseLifetime : Setup.DefaultLifetime;
|
||||||
*file = 0;
|
*file = 0;
|
||||||
firstday = 0;
|
|
||||||
summary = NULL;
|
summary = NULL;
|
||||||
event = NULL;
|
event = NULL;
|
||||||
if (Instant && channel)
|
if (Instant && channel)
|
||||||
@ -62,7 +62,8 @@ cTimer::cTimer(const cEvent *Event)
|
|||||||
}
|
}
|
||||||
struct tm tm_r;
|
struct tm tm_r;
|
||||||
struct tm *time = localtime_r(&tstart, &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;
|
start = time->tm_hour * 100 + time->tm_min;
|
||||||
time = localtime_r(&tstop, &tm_r);
|
time = localtime_r(&tstop, &tm_r);
|
||||||
stop = time->tm_hour * 100 + time->tm_min;
|
stop = time->tm_hour * 100 + time->tm_min;
|
||||||
@ -74,7 +75,6 @@ cTimer::cTimer(const cEvent *Event)
|
|||||||
const char *Title = Event->Title();
|
const char *Title = Event->Title();
|
||||||
if (!isempty(Title))
|
if (!isempty(Title))
|
||||||
strn0cpy(file, Event->Title(), sizeof(file));
|
strn0cpy(file, Event->Title(), sizeof(file));
|
||||||
firstday = 0;
|
|
||||||
summary = NULL;
|
summary = NULL;
|
||||||
event = Event;
|
event = Event;
|
||||||
}
|
}
|
||||||
@ -109,7 +109,7 @@ cString cTimer::ToText(bool UseChannelID)
|
|||||||
char *buffer;
|
char *buffer;
|
||||||
strreplace(file, ':', '|');
|
strreplace(file, ':', '|');
|
||||||
strreplace(summary, '\n', '|');
|
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(summary, '|', '\n');
|
||||||
strreplace(file, '|', ':');
|
strreplace(file, '|', ':');
|
||||||
return cString(buffer, true);
|
return cString(buffer, true);
|
||||||
@ -120,74 +120,93 @@ int cTimer::TimeToInt(int t)
|
|||||||
return (t / 100 * 60 + t % 100) * 60;
|
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;
|
// possible formats are:
|
||||||
int d = strtol(s, &tail, 10);
|
// 19
|
||||||
if (FirstDay)
|
// 2005-03-19
|
||||||
*FirstDay = 0;
|
// MTWTFSS
|
||||||
if (tail && *tail) {
|
// MTWTFSS@19
|
||||||
d = 0;
|
// MTWTFSS@2005-03-19
|
||||||
if (tail == s) {
|
|
||||||
const char *first = strchr(s, '@');
|
Day = 0;
|
||||||
int l = first ? first - s : strlen(s);
|
WeekDays = 0;
|
||||||
if (l == 7) {
|
s = skipspace(s);
|
||||||
for (const char *p = s + 6; p >= s; p--) {
|
if (!*s)
|
||||||
d <<= 1;
|
return false;
|
||||||
d |= (*p != '-');
|
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)
|
if (a || !isdigit(*s)) {
|
||||||
d = 0;
|
if ((a && a - s == 7) || strlen(s) == 7) {
|
||||||
return d;
|
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
|
#define DAYBUFFERSIZE 32
|
||||||
char buffer[DAYBUFFERSIZE];
|
char buffer[DAYBUFFERSIZE];
|
||||||
if ((d & 0x80000000) != 0) {
|
char *b = buffer;
|
||||||
char *b = buffer;
|
if (WeekDays) {
|
||||||
const char *w = tr("MTWTFSS");
|
const char *w = tr("MTWTFSS");
|
||||||
while (*w) {
|
while (*w) {
|
||||||
*b++ = (d & 1) ? *w : '-';
|
*b++ = (WeekDays & 1) ? *w : '-';
|
||||||
d >>= 1;
|
WeekDays >>= 1;
|
||||||
w++;
|
w++;
|
||||||
}
|
}
|
||||||
if (FirstDay) {
|
if (Day)
|
||||||
struct tm tm_r;
|
*b++ = '@';
|
||||||
localtime_r(&FirstDay, &tm_r);
|
|
||||||
b += strftime(b, DAYBUFFERSIZE - (b - buffer), "@%Y-%m-%d", &tm_r);
|
|
||||||
}
|
|
||||||
*b = 0;
|
|
||||||
}
|
}
|
||||||
else
|
if (Day) {
|
||||||
sprintf(buffer, "%d", d);
|
struct tm tm_r;
|
||||||
|
localtime_r(&Day, &tm_r);
|
||||||
|
b += strftime(b, DAYBUFFERSIZE - (b - buffer), "%Y-%m-%d", &tm_r);
|
||||||
|
}
|
||||||
|
*b = 0;
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
cString cTimer::PrintFirstDay(void)
|
cString cTimer::PrintFirstDay(void)
|
||||||
{
|
{
|
||||||
if (firstday) {
|
if (weekdays) {
|
||||||
cString s = PrintDay(day, firstday);
|
cString s = PrintDay(day, weekdays);
|
||||||
if (strlen(s) == 18)
|
if (strlen(s) == 18)
|
||||||
return *s + 8;
|
return *s + 8;
|
||||||
}
|
}
|
||||||
@ -223,8 +242,7 @@ bool cTimer::Parse(const char *s)
|
|||||||
summary = NULL;
|
summary = NULL;
|
||||||
}
|
}
|
||||||
//TODO add more plausibility checks
|
//TODO add more plausibility checks
|
||||||
day = ParseDay(daybuffer, &firstday);
|
result = ParseDay(daybuffer, day, weekdays);
|
||||||
result = day != 0;
|
|
||||||
strn0cpy(file, filebuffer, MaxFileName);
|
strn0cpy(file, filebuffer, MaxFileName);
|
||||||
strreplace(file, '|', ':');
|
strreplace(file, '|', ':');
|
||||||
strreplace(summary, '|', '\n');
|
strreplace(summary, '|', '\n');
|
||||||
@ -251,7 +269,7 @@ bool cTimer::Save(FILE *f)
|
|||||||
|
|
||||||
bool cTimer::IsSingleEvent(void) const
|
bool cTimer::IsSingleEvent(void) const
|
||||||
{
|
{
|
||||||
return (day & 0x80000000) == 0;
|
return !weekdays;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cTimer::GetMDay(time_t t)
|
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!
|
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
|
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)
|
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)
|
if (length < 0)
|
||||||
length += SECSINDAY;
|
length += SECSINDAY;
|
||||||
|
|
||||||
int DaysToCheck = IsSingleEvent() ? 61 : 7; // 61 to handle months with 31/30/31
|
if (IsSingleEvent()) {
|
||||||
for (int i = -1; i <= DaysToCheck; i++) {
|
startTime = SetTime(day, begin);
|
||||||
time_t t0 = IncDay(t, i);
|
stopTime = startTime + length;
|
||||||
if (DayMatches(t0)) {
|
}
|
||||||
time_t a = SetTime(t0, begin);
|
else {
|
||||||
time_t b = a + length;
|
for (int i = -1; i <= 7; i++) {
|
||||||
if ((!firstday || a >= firstday) && t <= b) {
|
time_t t0 = IncDay(t, i);
|
||||||
startTime = a;
|
if (DayMatches(t0)) {
|
||||||
stopTime = b;
|
time_t a = SetTime(t0, begin);
|
||||||
break;
|
time_t b = a + length;
|
||||||
|
if ((!day || a >= day) && t <= b) {
|
||||||
|
startTime = a;
|
||||||
|
stopTime = b;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (!startTime)
|
||||||
if (!startTime)
|
startTime = day; // just to have something that's more than a week in the future
|
||||||
startTime = firstday; // 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
|
||||||
else if (!Directly && (t > startTime || t > firstday + SECSINDAY + 3600)) // +3600 in case of DST change
|
day = 0;
|
||||||
firstday = 0;
|
}
|
||||||
|
|
||||||
if (HasFlags(tfActive)) {
|
if (HasFlags(tfActive)) {
|
||||||
if (HasFlags(tfVps) && !Directly && event && event->Vps() && event->SeenWithin(30)) {
|
if (HasFlags(tfVps) && !Directly && event && event->Vps() && event->SeenWithin(30)) {
|
||||||
@ -446,7 +458,7 @@ bool cTimer::HasFlags(int Flags) const
|
|||||||
|
|
||||||
void cTimer::Skip(void)
|
void cTimer::Skip(void)
|
||||||
{
|
{
|
||||||
firstday = IncDay(SetTime(StartTime(), 0), 1);
|
day = IncDay(SetTime(StartTime(), 0), 1);
|
||||||
event = NULL;
|
event = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -454,8 +466,8 @@ void cTimer::OnOff(void)
|
|||||||
{
|
{
|
||||||
if (IsSingleEvent())
|
if (IsSingleEvent())
|
||||||
InvFlags(tfActive);
|
InvFlags(tfActive);
|
||||||
else if (firstday) {
|
else if (day) {
|
||||||
firstday = 0;
|
day = 0;
|
||||||
ClrFlags(tfActive);
|
ClrFlags(tfActive);
|
||||||
}
|
}
|
||||||
else if (HasFlags(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
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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
|
#ifndef __TIMERS_H
|
||||||
@ -30,13 +30,13 @@ private:
|
|||||||
bool recording, pending, inVpsMargin;
|
bool recording, pending, inVpsMargin;
|
||||||
int flags;
|
int flags;
|
||||||
cChannel *channel;
|
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 start;
|
||||||
int stop;
|
int stop;
|
||||||
int priority;
|
int priority;
|
||||||
int lifetime;
|
int lifetime;
|
||||||
char file[MaxFileName];
|
char file[MaxFileName];
|
||||||
mutable time_t firstday;
|
|
||||||
char *summary;
|
char *summary;
|
||||||
const cEvent *event;
|
const cEvent *event;
|
||||||
public:
|
public:
|
||||||
@ -50,13 +50,14 @@ public:
|
|||||||
bool InVpsMargin(void) { return inVpsMargin; }
|
bool InVpsMargin(void) { return inVpsMargin; }
|
||||||
int Flags(void) { return flags; }
|
int Flags(void) { return flags; }
|
||||||
const cChannel *Channel(void) { return channel; }
|
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 Start(void) { return start; }
|
||||||
int Stop(void) { return stop; }
|
int Stop(void) { return stop; }
|
||||||
int Priority(void) { return priority; }
|
int Priority(void) { return priority; }
|
||||||
int Lifetime(void) { return lifetime; }
|
int Lifetime(void) { return lifetime; }
|
||||||
const char *File(void) { return file; }
|
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; }
|
const char *Summary(void) { return summary; }
|
||||||
cString ToText(bool UseChannelID = false);
|
cString ToText(bool UseChannelID = false);
|
||||||
const cEvent *Event(void) { return event; }
|
const cEvent *Event(void) { return event; }
|
||||||
@ -65,7 +66,6 @@ public:
|
|||||||
bool IsSingleEvent(void) const;
|
bool IsSingleEvent(void) const;
|
||||||
static int GetMDay(time_t t);
|
static int GetMDay(time_t t);
|
||||||
static int GetWDay(time_t t);
|
static int GetWDay(time_t t);
|
||||||
static int GetWDayFromMDay(int MDay);
|
|
||||||
bool DayMatches(time_t t) const;
|
bool DayMatches(time_t t) const;
|
||||||
static time_t IncDay(time_t t, int Days);
|
static time_t IncDay(time_t t, int Days);
|
||||||
static time_t SetTime(time_t t, int SecondsFromMidnight);
|
static time_t SetTime(time_t t, int SecondsFromMidnight);
|
||||||
@ -86,8 +86,8 @@ public:
|
|||||||
void OnOff(void);
|
void OnOff(void);
|
||||||
cString PrintFirstDay(void);
|
cString PrintFirstDay(void);
|
||||||
static int TimeToInt(int t);
|
static int TimeToInt(int t);
|
||||||
static int ParseDay(const char *s, time_t *FirstDay = NULL);
|
static bool ParseDay(const char *s, time_t &Day, int &WeekDays);
|
||||||
static cString PrintDay(int d, time_t FirstDay = 0);
|
static cString PrintDay(time_t Day, int WeekDays);
|
||||||
};
|
};
|
||||||
|
|
||||||
class cTimers : public cConfig<cTimer> {
|
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
|
.\" License as specified in the file COPYING that comes with the
|
||||||
.\" vdr distribution.
|
.\" 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
|
.SH NAME
|
||||||
vdr file formats - the Video Disk Recorder Files
|
vdr file formats - the Video Disk Recorder Files
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
@ -231,8 +231,13 @@ commands, the channels are given as numbers.
|
|||||||
.B Day
|
.B Day
|
||||||
The day when this timer shall record.
|
The day when this timer shall record.
|
||||||
|
|
||||||
If this is a `single-shot' timer, this is the day of month on which this
|
If this is a `single-shot' timer, this is the date on which this
|
||||||
timer shall record. This must be in the range \fB1...31\fR.
|
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
|
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
|
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
|
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
|
on weekends. The same result could be achieved with \fBABCDE\-\-\fR (this is
|
||||||
used to allow setting the days with language specific characters).
|
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
|
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,
|
timer shall hit for the first time. The format for this is \fB@YYYY\-MM\-DD\fR,
|
||||||
|
Loading…
Reference in New Issue
Block a user