summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKlaus Schmidinger <kls (at) cadsoft (dot) de>2001-08-26 18:00:00 +0200
committerKlaus Schmidinger <kls (at) cadsoft (dot) de>2001-08-26 18:00:00 +0200
commitae8fe25312b6b0ec18fd0c6c2a275f334ada02db (patch)
tree5ab0a9157534b6118ae61ee895c5d8c003a32d04
parent371bf0665eda455c67926999f52b4850cd8529e4 (diff)
downloadvdr-patch-lnbsharing-ae8fe25312b6b0ec18fd0c6c2a275f334ada02db.tar.gz
vdr-patch-lnbsharing-ae8fe25312b6b0ec18fd0c6c2a275f334ada02db.tar.bz2
Version 0.93vdr-0.93
- The menus and the channel display now show the current date and time. - The new Setup parameter MaxVideoFileSize can be used to customize the maximum size of the recorded video files. - Fixed a bug in handling repeating timers that record over midnight (the calculation of matching timers has been completely rewritten). - Timers that are currently recording are now marked with '#' in the "Timers" menu. - Timers are now sorted in the "Timers" menu, showing the sequence in which they will be recording. This can be disabled in the "Setup" menu. Note that the "Mark" button doesn't work if timers are displayed sorted.
-rw-r--r--HISTORY13
-rw-r--r--MANUAL25
-rw-r--r--channels.conf2
-rw-r--r--config.c157
-rw-r--r--config.h16
-rw-r--r--dvbapi.c22
-rw-r--r--dvbapi.h11
-rw-r--r--i18n.c29
-rw-r--r--interface.c4
-rw-r--r--libdtv/x.txt55
-rw-r--r--menu.c66
-rw-r--r--osd.c12
-rw-r--r--osd.h6
-rw-r--r--tools.c34
-rw-r--r--tools.h5
-rw-r--r--vdr.c4
16 files changed, 344 insertions, 117 deletions
diff --git a/HISTORY b/HISTORY
index b76067b..250d857 100644
--- a/HISTORY
+++ b/HISTORY
@@ -663,3 +663,16 @@ Video Disk Recorder Revision History
- Fixed broken recordings after a driver buffer overflow.
- Fixed the chirping sound after Pause/Play of a DVD (thanks to Andreas
Schultz).
+
+2001-08-26: Version 0.93
+
+- The menus and the channel display now show the current date and time.
+- The new Setup parameter MaxVideoFileSize can be used to customize the
+ maximum size of the recorded video files.
+- Fixed a bug in handling repeating timers that record over midnight (the
+ calculation of matching timers has been completely rewritten).
+- Timers that are currently recording are now marked with '#' in the "Timers"
+ menu.
+- Timers are now sorted in the "Timers" menu, showing the sequence in which
+ they will be recording. This can be disabled in the "Setup" menu. Note
+ that the "Mark" button doesn't work if timers are displayed sorted.
diff --git a/MANUAL b/MANUAL
index 9d77481..ae93099 100644
--- a/MANUAL
+++ b/MANUAL
@@ -8,7 +8,7 @@ Video Disk Recorder User's Manual
possible, several keys have different meanings in the various
modes:
- Key Normal Main Channels Timer Edit/New Recordings Replay
+ Key Normal Main Channels Timers Edit/New Recordings Replay
Up Ch up Crsr up Crsr up Crsr up Crsr up Crsr up Play
Down Ch down Crsr down Crsr down Crsr down Crsr down Crsr down Pause
@@ -20,9 +20,12 @@ Video Disk Recorder User's Manual
Red - Record Edit Edit - Play Jump
Green - Language New New - Rewind Skip -60s
Yellow - Eject DVD Delete Delete - Delete Skip +60s
- Blue - Resume Mark Mark - Summary Stop
+ Blue - Resume Mark Mark(1) - Summary Stop
0..9 Ch select - - - Numeric inp. - Editing
+ (1) The "Mark" button in the "Timers" menu only works if sorting the timers
+ has been disabled in the "Setup" menu.
+
* Navigating through the On Screen Menus
The "Main" menu can be called up with the "Menu" key of your remote
@@ -34,7 +37,8 @@ Video Disk Recorder User's Manual
any changes that might have been made in the current menu.
In the "Timers" menu, the current timer can be enabled or disabled with
- the "Right" or "Left" key, respectively (enabled timers are marked with ">").
+ the "Right" or "Left" key, respectively (enabled timers are marked with '>',
+ timers that are currently recording are marked with '#').
"Ok" here opens the "Edit timer" menu.
Textual options, like channel names or recording file names, can be edited
@@ -296,6 +300,12 @@ Video Disk Recorder User's Manual
OSDLanguage = 0 Defines the language used to display the OSD texts.
0 = Englisch
1 = Deutsch
+ 2 = Slovenian
+ 3 = Italian
+ 4 = Dutch
+ 5 = Portugese
+ 6 = French
+ 7 = Norwegian
PrimaryDVB = 1 Defines the primary DVB interface (i.e. the one that
will display the menus and will react on input through
@@ -373,6 +383,10 @@ Video Disk Recorder User's Manual
connection after which the connection is automatically
closed. Default is 300, a value of 0 means no timeout.
+ SortTimers = 1 Turns sorting the timers in the "Timers" menu on/off.
+ Timers are sorted by ascending start times, with the
+ first one being the next timer that will start.
+
PrimaryLimit = 0 The minimum priority a timer must have to be allowed to
use the primary DVB interface, or to force another timer
with higher priority to use the primary DVB interface.
@@ -398,6 +412,11 @@ Video Disk Recorder User's Manual
OSDwidth = 52 The width and height of the OSD .
OSDheight = 18 The valid ranges are width=40...56, height=12...21.
+ MaxVideoFileSize=2000 The maximum size of a single recorded video file in MB.
+ The valid range is 100...2000. Default is 2000, but
+ you may want to use smaller values if you are planning
+ on archiving a recording to CD.
+
* Executing system commands
The "Main" menu option "Commands" allows you to execute any system commands
diff --git a/channels.conf b/channels.conf
index 1f62f70..9c90491 100644
--- a/channels.conf
+++ b/channels.conf
@@ -192,4 +192,6 @@ Video Italia:12610:v:0:22000:121:122:0:0:12220
AC 3 promo:12670:v:0:22000:308:256:0:0:0
ORF/ZDF:12699:h:0:22000:506:507:0:0:13012
VIVA:12670:v:0:22000:309:310:0:0:12732
+VIVA2:12552:v:0:22000:171:172:0:0:12120
MTV Central Europe:12699:v:0:22000:3031:3032:0:0:28643
+IFA-TV:10832:h:0:22000:132:133:32:0:7251
diff --git a/config.c b/config.c
index aed3254..ad4b9da 100644
--- a/config.c
+++ b/config.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: config.c 1.55 2001/08/17 13:02:01 kls Exp $
+ * $Id: config.c 1.59 2001/08/26 14:46:43 kls Exp $
*/
#include "config.h"
@@ -394,6 +394,13 @@ cTimer& cTimer::operator= (const cTimer &Timer)
return *this;
}
+bool cTimer::operator< (const cTimer &Timer)
+{
+ time_t t1 = StartTime();
+ time_t t2 = (*(cTimer *)&Timer).StartTime();
+ return t1 < t2 || (t1 == t2 && priority > Timer.priority);
+}
+
const char *cTimer::ToText(cTimer *Timer)
{
delete buffer;
@@ -415,13 +422,6 @@ int cTimer::TimeToInt(int t)
return (t / 100 * 60 + t % 100) * 60;
}
-time_t cTimer::Day(time_t t)
-{
- struct tm d = *localtime(&t);
- d.tm_hour = d.tm_min = d.tm_sec = 0;
- return mktime(&d);
-}
-
int cTimer::ParseDay(const char *s)
{
char *tail;
@@ -511,43 +511,66 @@ bool cTimer::IsSingleEvent(void)
return (day & 0x80000000) == 0;
}
+int cTimer::GetMDay(time_t t)
+{
+ return localtime(&t)->tm_mday;
+}
+
+int cTimer::GetWDay(time_t t)
+{
+ int weekday = localtime(&t)->tm_wday;
+ return weekday == 0 ? 6 : weekday - 1; // we start with monday==0!
+}
+
+bool cTimer::DayMatches(time_t t)
+{
+ return IsSingleEvent() ? GetMDay(t) == day : (day & (1 << GetWDay(t))) != 0;
+}
+
+time_t cTimer::IncDay(time_t t, int Days)
+{
+ tm tm = *localtime(&t);
+ tm.tm_mday += Days; // now tm_mday may be out of its valid range
+ int h = tm.tm_hour; // save original hour to compensate for DST change
+ t = mktime(&tm); // normalize all values
+ tm.tm_hour = h; // compensate for DST change
+ return mktime(&tm); // calculate final result
+}
+
+time_t cTimer::SetTime(time_t t, int SecondsFromMidnight)
+{
+ tm tm = *localtime(&t);
+ tm.tm_hour = SecondsFromMidnight / 3600;
+ tm.tm_min = (SecondsFromMidnight % 3600) / 60;
+ tm.tm_sec = SecondsFromMidnight % 60;
+ return mktime(&tm);
+}
+
bool cTimer::Matches(time_t t)
{
- if (active) {
- if (t == 0)
- t = time(NULL);
- struct tm now = *localtime(&t);
- int weekday = now.tm_wday == 0 ? 6 : now.tm_wday - 1; // we start with monday==0!
- int begin = TimeToInt(start);
- int end = TimeToInt(stop);
- bool twoDays = (end < begin);
-
- bool todayMatches = false, yesterdayMatches = false;
- if ((day & 0x80000000) != 0) {
- if ((day & (1 << weekday)) != 0)
- todayMatches = true;
- else if (twoDays) {
- int yesterday = weekday == 0 ? 6 : weekday - 1;
- if ((day & (1 << yesterday)) != 0)
- yesterdayMatches = true;
- }
- }
- else if (day == now.tm_mday)
- todayMatches = true;
- else if (twoDays) {
- time_t ty = t - SECSINDAY;
- if (day == localtime(&ty)->tm_mday)
- yesterdayMatches = true;
- }
- if (todayMatches || (twoDays && yesterdayMatches)) {
- startTime = Day(t - (yesterdayMatches ? SECSINDAY : 0)) + begin;
- stopTime = startTime + (twoDays ? SECSINDAY - begin + end : end - begin);
- }
- else
- startTime = stopTime = 0;
- return startTime <= t && t <= stopTime;
- }
- return false;
+ startTime = stopTime = 0;
+ if (t == 0)
+ t = time(NULL);
+
+ int begin = TimeToInt(start); // seconds from midnight
+ int length = TimeToInt(stop) - begin;
+ if (length < 0)
+ length += SECSINDAY;
+
+ int DaysToCheck = IsSingleEvent() ? 31 : 7;
+ 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 (t <= b) {
+ startTime = a;
+ stopTime = b;
+ break;
+ }
+ }
+ }
+ return active && startTime <= t && t <= stopTime;
}
time_t cTimer::StartTime(void)
@@ -575,21 +598,6 @@ void cTimer::SetPending(bool Pending)
pending = Pending;
}
-cTimer *cTimer::GetMatch(void)
-{
- time_t t = time(NULL); // all timers must be checked against the exact same time to correctly handle Priority!
- cTimer *t0 = NULL;
- cTimer *ti = (cTimer *)Timers.First();
- while (ti) {
- if (!ti->recording && ti->Matches(t)) {
- if (!t0 || ti->priority > t0->priority)
- t0 = ti;
- }
- ti = (cTimer *)ti->Next();
- }
- return t0;
-}
-
// --- cCommand -------------------------------------------------------------
char *cCommand::result = NULL;
@@ -753,6 +761,33 @@ cTimer *cTimers::GetTimer(cTimer *Timer)
return NULL;
}
+cTimer *cTimers::GetMatch(void)
+{
+ time_t t = time(NULL); // all timers must be checked against the exact same time to correctly handle Priority!
+ cTimer *t0 = NULL;
+ cTimer *ti = First();
+ while (ti) {
+ if (!ti->recording && ti->Matches(t)) {
+ if (!t0 || ti->priority > t0->priority)
+ t0 = ti;
+ }
+ ti = (cTimer *)ti->Next();
+ }
+ return t0;
+}
+
+cTimer *cTimers::GetNextActiveTimer(void)
+{
+ cTimer *t0 = NULL;
+ cTimer *ti = First();
+ while (ti) {
+ if (ti->active && (!t0 || *ti < *t0))
+ t0 = ti;
+ ti = (cTimer *)ti->Next();
+ }
+ return t0;
+}
+
// -- cSetup -----------------------------------------------------------------
cSetup Setup;
@@ -776,6 +811,7 @@ cSetup::cSetup(void)
EPGScanTimeout = 5;
EPGBugfixLevel = 2;
SVDRPTimeout = 300;
+ SortTimers = 1;
PrimaryLimit = 0;
DefaultPriority = 50;
DefaultLifetime = 50;
@@ -783,6 +819,7 @@ cSetup::cSetup(void)
ChannelInfoPos = 0;
OSDwidth = 52;
OSDheight = 18;
+ MaxVideoFileSize = MAXVIDEOFILESIZE;
CurrentChannel = -1;
}
@@ -807,6 +844,7 @@ bool cSetup::Parse(char *s)
else if (!strcasecmp(Name, "EPGScanTimeout")) EPGScanTimeout = atoi(Value);
else if (!strcasecmp(Name, "EPGBugfixLevel")) EPGBugfixLevel = atoi(Value);
else if (!strcasecmp(Name, "SVDRPTimeout")) SVDRPTimeout = atoi(Value);
+ else if (!strcasecmp(Name, "SortTimers")) SortTimers = atoi(Value);
else if (!strcasecmp(Name, "PrimaryLimit")) PrimaryLimit = atoi(Value);
else if (!strcasecmp(Name, "DefaultPriority")) DefaultPriority = atoi(Value);
else if (!strcasecmp(Name, "DefaultLifetime")) DefaultLifetime = atoi(Value);
@@ -814,6 +852,7 @@ bool cSetup::Parse(char *s)
else if (!strcasecmp(Name, "ChannelInfoPos")) ChannelInfoPos = atoi(Value);
else if (!strcasecmp(Name, "OSDwidth")) OSDwidth = atoi(Value);
else if (!strcasecmp(Name, "OSDheight")) OSDheight = atoi(Value);
+ else if (!strcasecmp(Name, "MaxVideoFileSize")) MaxVideoFileSize = atoi(Value);
else if (!strcasecmp(Name, "CurrentChannel")) CurrentChannel = atoi(Value);
else
return false;
@@ -873,6 +912,7 @@ bool cSetup::Save(const char *FileName)
fprintf(f, "EPGScanTimeout = %d\n", EPGScanTimeout);
fprintf(f, "EPGBugfixLevel = %d\n", EPGBugfixLevel);
fprintf(f, "SVDRPTimeout = %d\n", SVDRPTimeout);
+ fprintf(f, "SortTimers = %d\n", SortTimers);
fprintf(f, "PrimaryLimit = %d\n", PrimaryLimit);
fprintf(f, "DefaultPriority = %d\n", DefaultPriority);
fprintf(f, "DefaultLifetime = %d\n", DefaultLifetime);
@@ -880,6 +920,7 @@ bool cSetup::Save(const char *FileName)
fprintf(f, "ChannelInfoPos = %d\n", ChannelInfoPos);
fprintf(f, "OSDwidth = %d\n", OSDwidth);
fprintf(f, "OSDheight = %d\n", OSDheight);
+ fprintf(f, "MaxVideoFileSize = %d\n", MaxVideoFileSize);
fprintf(f, "CurrentChannel = %d\n", CurrentChannel);
f.Close();
isyslog(LOG_INFO, "saved setup to %s", FileName);
diff --git a/config.h b/config.h
index ce77598..70f3574 100644
--- a/config.h
+++ b/config.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: config.h 1.61 2001/08/17 13:00:48 kls Exp $
+ * $Id: config.h 1.66 2001/08/26 14:46:53 kls Exp $
*/
#ifndef __CONFIG_H
@@ -19,7 +19,7 @@
#include "eit.h"
#include "tools.h"
-#define VDRVERSION "0.92"
+#define VDRVERSION "0.93"
#define MaxBuffer 10000
@@ -137,18 +137,22 @@ public:
cTimer(const cEventInfo *EventInfo);
virtual ~cTimer();
cTimer& operator= (const cTimer &Timer);
+ bool operator< (const cTimer &Timer);
const char *ToText(void);
bool Parse(const char *s);
bool Save(FILE *f);
bool IsSingleEvent(void);
+ int GetMDay(time_t t);
+ int GetWDay(time_t t);
+ bool DayMatches(time_t t);
+ time_t IncDay(time_t t, int Days);
+ time_t SetTime(time_t t, int SecondsFromMidnight);
bool Matches(time_t t = 0);
time_t StartTime(void);
time_t StopTime(void);
void SetRecording(bool Recording);
void SetPending(bool Pending);
- static cTimer *GetMatch(void);
static int TimeToInt(int t);
- static time_t Day(time_t t);
static int ParseDay(const char *s);
static const char *PrintDay(int d);
};
@@ -251,6 +255,8 @@ public:
class cTimers : public cConfig<cTimer> {
public:
cTimer *GetTimer(cTimer *Timer);
+ cTimer *GetMatch(void);
+ cTimer *GetNextActiveTimer(void);
};
class cCommands : public cConfig<cCommand> {};
@@ -282,11 +288,13 @@ public:
int EPGScanTimeout;
int EPGBugfixLevel;
int SVDRPTimeout;
+ int SortTimers;
int PrimaryLimit;
int DefaultPriority, DefaultLifetime;
int VideoFormat;
int ChannelInfoPos;
int OSDwidth, OSDheight;
+ int MaxVideoFileSize;
int CurrentChannel;
cSetup(void);
bool Load(const char *FileName);
diff --git a/dvbapi.c b/dvbapi.c
index 6ff39b3..51434e1 100644
--- a/dvbapi.c
+++ b/dvbapi.c
@@ -7,7 +7,7 @@
* DVD support initially written by Andreas Schultz <aschultz@warp10.net>
* based on dvdplayer-0.5 by Matjaz Thaler <matjaz.thaler@guest.arnes.si>
*
- * $Id: dvbapi.c 1.109 2001/08/19 15:09:48 kls Exp $
+ * $Id: dvbapi.c 1.110 2001/08/25 13:52:38 kls Exp $
*/
//#define DVDDEBUG 1
@@ -50,20 +50,16 @@ extern "C" {
#define DEV_OST_VIDEO "/dev/ost/video"
#define DEV_OST_AUDIO "/dev/ost/audio"
+#define KILOBYTE(n) ((n) * 1024)
+#define MEGABYTE(n) ((n) * 1024 * 1024)
+
// The size of the array used to buffer video data:
// (must be larger than MINVIDEODATA - see remux.h)
-#define VIDEOBUFSIZE (1024*1024)
+#define VIDEOBUFSIZE MEGABYTE(1)
// The maximum size of a single frame:
-#define MAXFRAMESIZE (192*1024)
-
-// The maximum file size is limited by the range that can be covered
-// with 'int'. 4GB might be possible (if the range is considered
-// 'unsigned'), 2GB should be possible (even if the range is considered
-// 'signed'), so let's use 1GB for absolute safety (the actual file size
-// may be slightly higher because we stop recording only before the next
-// 'I' frame, to have a complete Group Of Pictures):
-#define MAXVIDEOFILESIZE (1024*1024*1024) // Byte
+#define MAXFRAMESIZE KILOBYTE(192)
+
#define MAXFILESPERRECORDING 255
#define MINFREEDISKSPACE (512) // MB
@@ -517,7 +513,7 @@ bool cRecordBuffer::RunningLowOnDiskSpace(void)
bool cRecordBuffer::NextFile(void)
{
if (recordFile >= 0 && pictureType == I_FRAME) { // every file shall start with an I_FRAME
- if (fileSize > MAXVIDEOFILESIZE || RunningLowOnDiskSpace()) {
+ if (fileSize > MEGABYTE(Setup.MaxVideoFileSize) || RunningLowOnDiskSpace()) {
recordFile = fileName.NextFile();
fileSize = 0;
}
@@ -2217,7 +2213,7 @@ void cCuttingBuffer::Action(void)
// Write one frame:
if (PictureType == I_FRAME) { // every file shall start with an I_FRAME
- if (FileSize > MAXVIDEOFILESIZE) {
+ if (FileSize > MEGABYTE(Setup.MaxVideoFileSize)) {
toFile = toFileName->NextFile();
if (toFile < 0)
break;
diff --git a/dvbapi.h b/dvbapi.h
index 2cd57bf..c93a9f3 100644
--- a/dvbapi.h
+++ b/dvbapi.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: dvbapi.h 1.46 2001/08/11 12:22:01 kls Exp $
+ * $Id: dvbapi.h 1.47 2001/08/25 13:37:00 kls Exp $
*/
#ifndef __DVBAPI_H
@@ -42,6 +42,15 @@ typedef struct CRect {
#define FRAMESPERSEC 25
+// The maximum file size is limited by the range that can be covered
+// with 'int'. 4GB might be possible (if the range is considered
+// 'unsigned'), 2GB should be possible (even if the range is considered
+// 'signed'), so let's use 2000MB for absolute safety (the actual file size
+// may be slightly higher because we stop recording only before the next
+// 'I' frame, to have a complete Group Of Pictures):
+#define MAXVIDEOFILESIZE 2000 // MB
+#define MINVIDEOFILESIZE 100 // MB
+
const char *IndexToHMSF(int Index, bool WithFrame = false);
// Converts the given index to a string, optionally containing the frame number.
int HMSFToIndex(const char *HMSF);
diff --git a/i18n.c b/i18n.c
index 9878228..35a6bb1 100644
--- a/i18n.c
+++ b/i18n.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: i18n.c 1.32 2001/08/17 13:03:15 kls Exp $
+ * $Id: i18n.c 1.35 2001/08/26 13:45:10 kls Exp $
*
* Slovenian translations provided by Miha Setina <mihasetina@softhome.net>
* Italian translations provided by Alberto Carraro <bertocar@tin.it>
@@ -794,6 +794,15 @@ const tPhrase Phrases[] = {
"Temps maxi SVDRP",
"Ubrukt SVDRP-levetid",
},
+ { "SortTimers",
+ "Timer sortieren",
+ "", // TODO
+ "", // TODO
+ "", // TODO
+ "", // TODO
+ "", // TODO
+ "", // TODO
+ },
{ "PrimaryLimit",
"Primär-Limit",
"", // TODO
@@ -857,6 +866,15 @@ const tPhrase Phrases[] = {
"Hauteur affichage",
"", // TODO
},
+ { "MaxVideoFileSize",
+ "Max. Video Dateigröße",
+ "", // TODO
+ "", // TODO
+ "", // TODO
+ "", // TODO
+ "", // TODO
+ "", // TODO
+ },
// The days of the week:
{ "MTWTFSS",
"MDMDFSS",
@@ -867,6 +885,15 @@ const tPhrase Phrases[] = {
"LMMJVSD",
"MTOTFLS",
},
+ { "MonTueWedThuFriSatSun", // must all be 3 letters!
+ "MonDieMitDonFreSamSon",
+ "", // TODO
+ "", // TODO
+ "", // TODO
+ "", // TODO
+ "", // TODO
+ "", // TODO
+ },
// Learning keys:
{ "Learning Remote Control Keys",
"Fernbedienungs-Codes lernen",
diff --git a/interface.c b/interface.c
index e2d83b3..1e06f4a 100644
--- a/interface.c
+++ b/interface.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: interface.c 1.40 2001/08/07 16:23:28 kls Exp $
+ * $Id: interface.c 1.41 2001/08/25 13:15:00 kls Exp $
*/
#include "interface.h"
@@ -271,7 +271,7 @@ void cInterface::Title(const char *s)
unsigned int n = t - s;
if (n >= sizeof(buffer))
n = sizeof(buffer) - 1;
- strn0cpy(buffer, s, n);
+ strn0cpy(buffer, s, n + 1);
Write(1, 0, buffer, clrBlack, clrCyan);
t++;
Write(-(cDvbApi::PrimaryDvbApi->WidthInCells(t) + 1), 0, t, clrBlack, clrCyan);
diff --git a/libdtv/x.txt b/libdtv/x.txt
new file mode 100644
index 0000000..0d12ddd
--- /dev/null
+++ b/libdtv/x.txt
@@ -0,0 +1,55 @@
+Hallo ZDF-EPG-Redaktion!
+
+Es würde mich interessieren, warum im digitalen EPG des
+ZDF (über Astra) die Beschreibung der Sendungen oftmals
+Trennungsstriche und zusätzliche Leerzeichen enthält.
+So zum Beispiel bei folgendem Eintrag:
+
+----------------------------------------------------
+ ZDF 23.08 10:50 - 11:35
+
+ Mit Leib und Seele
+
+ Der einzige Mensch
+
+ Stehlin hat die Frühmesse abge- sagt und sein
+ Kommen im Pfarr- haus angekündigt. August, erbost
+ über die Heimlichkeiten und Re- dereien von
+ Stutz, erzwingt eine Aussprache mit Stehlin.
+----------------------------------------------------
+
+der ohne Trennungsstriche so aussehen könnte:
+
+----------------------------------------------------
+ ZDF 23.08 10:50 - 11:35
+
+ Mit Leib und Seele
+
+ Der einzige Mensch
+
+ Stehlin hat die Frühmesse abgesagt und sein
+ Kommen im Pfarrhaus angekündigt. August, erbost
+ über die Heimlichkeiten und Redereien von Stutz,
+ erzwingt eine Aussprache mit Stehlin.
+----------------------------------------------------
+
+Ich kann mir das nur so erklären, daß Sie konkrete Annahmen
+darüber machen, mit welcher Zeilenlänge die Set-Top-Box diese
+Texte darstellt - aber das ist in meinen Augen eine ziemlich
+verwegene Annahme, denn es sollte ja wohl der STB überlassen bleiben,
+wie groß das Fenster für die Darstellung des EPG ist.
+
+Pro-7 zum Beispiel macht sowas nicht, wodurch der Text deultich
+besser dargestellt wird.
+
+Wenn Sie wenigstens nach dem (bzw. statt des) Bindestrich(s) ein deutlich
+erkennbares Sonderzeichen einfügen würden, dann könnte man das zuverlässig
+herausfiltern, aber so macht der ZDF-EPG immer wieder einen
+schlechten Eindruck.
+
+Über eine Antwort von Ihnen würde ich mich sehr freuen.
+
+MfG
+Klaus Schmidinger
+
+
diff --git a/menu.c b/menu.c
index 4cc43f0..6d6eae8 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.105 2001/08/19 14:45:31 kls Exp $
+ * $Id: menu.c 1.109 2001/08/26 14:03:27 kls Exp $
*/
#include "menu.h"
@@ -957,25 +957,30 @@ eOSState cMenuEditTimer::ProcessKey(eKeys Key)
class cMenuTimerItem : public cOsdItem {
private:
- int index;
cTimer *timer;
public:
- cMenuTimerItem(int Index, cTimer *Timer);
+ cMenuTimerItem(cTimer *Timer);
+ virtual bool operator< (const cListObject &ListObject);
virtual void Set(void);
+ cTimer *Timer(void) { return timer; }
};
-cMenuTimerItem::cMenuTimerItem(int Index, cTimer *Timer)
+cMenuTimerItem::cMenuTimerItem(cTimer *Timer)
{
- index = Index;
timer = Timer;
Set();
}
+bool cMenuTimerItem::operator< (const cListObject &ListObject)
+{
+ return *timer < *((cMenuTimerItem *)&ListObject)->timer;
+}
+
void cMenuTimerItem::Set(void)
{
char *buffer = NULL;
asprintf(&buffer, "%c\t%d\t%s\t%02d:%02d\t%02d:%02d\t%s",
- timer->active ? '>' : ' ',
+ timer->active ? timer->recording ? '#' : '>' : ' ',
timer->channel,
timer->PrintDay(timer->day),
timer->start / 100,
@@ -996,6 +1001,7 @@ private:
eOSState Del(void);
virtual void Move(int From, int To);
eOSState Summary(void);
+ cTimer *CurrentTimer(void);
public:
cMenuTimers(void);
virtual eOSState ProcessKey(eKeys Key);
@@ -1008,15 +1014,23 @@ cMenuTimers::cMenuTimers(void)
cTimer *timer;
while ((timer = Timers.Get(i)) != NULL) {
- Add(new cMenuTimerItem(i, timer));
+ Add(new cMenuTimerItem(timer));
i++;
}
- SetHelp(tr("Edit"), tr("New"), tr("Delete"), tr("Mark"));
+ if (Setup.SortTimers)
+ Sort();
+ SetHelp(tr("Edit"), tr("New"), tr("Delete"), Setup.SortTimers ? NULL : tr("Mark"));
+}
+
+cTimer *cMenuTimers::CurrentTimer(void)
+{
+ cMenuTimerItem *item = (cMenuTimerItem *)Get(Current());
+ return item ? item->Timer() : NULL;
}
eOSState cMenuTimers::Activate(bool On)
{
- cTimer *timer = Timers.Get(Current());
+ cTimer *timer = CurrentTimer();
if (timer && timer->active != On) {
timer->active = On;
RefreshCurrent();
@@ -1031,8 +1045,8 @@ eOSState cMenuTimers::Edit(void)
{
if (HasSubMenu() || Count() == 0)
return osContinue;
- isyslog(LOG_INFO, "editing timer %d", Current() + 1);
- return AddSubMenu(new cMenuEditTimer(Current()));
+ isyslog(LOG_INFO, "editing timer %d", CurrentTimer()->Index() + 1);
+ return AddSubMenu(new cMenuEditTimer(CurrentTimer()->Index()));
}
eOSState cMenuTimers::New(void)
@@ -1041,22 +1055,22 @@ eOSState cMenuTimers::New(void)
return osContinue;
cTimer *timer = new cTimer;
Timers.Add(timer);
- Add(new cMenuTimerItem(timer->Index()/*XXX*/, timer), true);
+ Add(new cMenuTimerItem(timer), true);
Timers.Save();
isyslog(LOG_INFO, "timer %d added", timer->Index() + 1);
- return AddSubMenu(new cMenuEditTimer(Current(), true));
+ return AddSubMenu(new cMenuEditTimer(timer->Index(), true));
}
eOSState cMenuTimers::Del(void)
{
// Check if this timer is active:
- int Index = Current();
- cTimer *ti = Timers.Get(Index);
+ cTimer *ti = CurrentTimer();
if (ti) {
if (!ti->recording) {
if (Interface->Confirm(tr("Delete timer?"))) {
- Timers.Del(Timers.Get(Index));
- cOsdMenu::Del(Index);
+ int Index = ti->Index();
+ Timers.Del(ti);
+ cOsdMenu::Del(Current());
Timers.Save();
Display();
isyslog(LOG_INFO, "timer %d deleted", Index + 1);
@@ -1081,7 +1095,7 @@ eOSState cMenuTimers::Summary(void)
{
if (HasSubMenu() || Count() == 0)
return osContinue;
- cTimer *ti = Timers.Get(Current());
+ cTimer *ti = CurrentTimer();
if (ti && ti->summary && *ti->summary)
return AddSubMenu(new cMenuText(tr("Summary"), ti->summary));
return Edit(); // convenience for people not using the Summary feature ;-)
@@ -1109,7 +1123,9 @@ eOSState cMenuTimers::ProcessKey(eKeys Key)
case kRed: return Edit();
case kGreen: return New();
case kYellow: return Del();
- case kBlue: Mark(); break;
+ case kBlue: if (!Setup.SortTimers)
+ Mark();
+ break;
default: break;
}
}
@@ -1137,6 +1153,7 @@ cMenuEvent::cMenuEvent(const cEventInfo *EventInfo, bool CanSwitch)
char *buffer;
asprintf(&buffer, "%-17.*s\t%.*s %s - %s", 17, channel->name, 5, eventInfo->GetDate(), eventInfo->GetTimeString(), eventInfo->GetEndTimeString());
SetTitle(buffer, false);
+ delete buffer;
int Line = 2;
cMenuTextItem *item;
const char *Title = eventInfo->GetTitle();
@@ -1377,7 +1394,8 @@ void cMenuSchedule::PrepareSchedule(cChannel *Channel)
Clear();
char *buffer = NULL;
asprintf(&buffer, tr("Schedule - %s"), Channel->name);
- SetTitle(buffer, false);
+ SetTitle(buffer);
+ delete buffer;
if (schedules) {
const cSchedule *Schedule = Channel->pnr ? schedules->GetSchedule(Channel->pnr) : schedules->GetSchedule();
int num = Schedule->NumEvents();
@@ -1704,6 +1722,7 @@ void cMenuSetup::Set(void)
Add(new cMenuEditIntItem( tr("EPGScanTimeout"), &data.EPGScanTimeout));
Add(new cMenuEditIntItem( tr("EPGBugfixLevel"), &data.EPGBugfixLevel, 0, 3));
Add(new cMenuEditIntItem( tr("SVDRPTimeout"), &data.SVDRPTimeout));
+ Add(new cMenuEditBoolItem(tr("SortTimers"), &data.SortTimers));
Add(new cMenuEditIntItem( tr("PrimaryLimit"), &data.PrimaryLimit, 0, MAXPRIORITY));
Add(new cMenuEditIntItem( tr("DefaultPriority"), &data.DefaultPriority, 0, MAXPRIORITY));
Add(new cMenuEditIntItem( tr("DefaultLifetime"), &data.DefaultLifetime, 0, MAXLIFETIME));
@@ -1711,6 +1730,7 @@ void cMenuSetup::Set(void)
Add(new cMenuEditBoolItem(tr("ChannelInfoPos"), &data.ChannelInfoPos, tr("bottom"), tr("top")));
Add(new cMenuEditIntItem( tr("OSDwidth"), &data.OSDwidth, MINOSDWIDTH, MAXOSDWIDTH));
Add(new cMenuEditIntItem( tr("OSDheight"), &data.OSDheight, MINOSDHEIGHT, MAXOSDHEIGHT));
+ Add(new cMenuEditIntItem( tr("MaxVideoFileSize"), &data.MaxVideoFileSize, MINVIDEOFILESIZE, MAXVIDEOFILESIZE));
}
eOSState cMenuSetup::ProcessKey(eKeys Key)
@@ -1951,10 +1971,8 @@ void cDisplayChannel::DisplayChannel(const cChannel *Channel)
snprintf(buffer, BufSize, "%s", Channel ? Channel->name : tr("*** Invalid Channel ***"));
Interface->Fill(0, 0, Setup.OSDwidth, 1, clrBackground);
Interface->Write(0, 0, buffer);
- time_t t = time(NULL);
- struct tm *now = localtime(&t);
- snprintf(buffer, BufSize, "%02d:%02d", now->tm_hour, now->tm_min);
- Interface->Write(-5, 0, buffer);
+ const char *date = DayDateTime();
+ Interface->Write(-strlen(date), 0, date);
}
void cDisplayChannel::DisplayInfo(void)
diff --git a/osd.c b/osd.c
index daedc1e..02f4374 100644
--- a/osd.c
+++ b/osd.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: osd.c 1.17 2001/08/02 14:18:17 kls Exp $
+ * $Id: osd.c 1.18 2001/08/25 13:15:16 kls Exp $
*/
#include "osd.h"
@@ -78,7 +78,8 @@ cOsdMenu::cOsdMenu(const char *Title, int c0, int c1, int c2, int c3, int c4)
{
hasHotkeys = false;
visible = false;
- title = strdup(Title);
+ title = NULL;
+ SetTitle(Title);
cols[0] = c0;
cols[1] = c1;
cols[2] = c2;
@@ -109,10 +110,13 @@ void cOsdMenu::SetStatus(const char *s)
Interface->Status(status);
}
-void cOsdMenu::SetTitle(const char *Title, bool Copy)
+void cOsdMenu::SetTitle(const char *Title, bool ShowDate)
{
delete title;
- title = Copy ? strdup(Title) : Title;
+ if (ShowDate)
+ asprintf(&title, "%s\t%s", Title, DayDateTime(time(NULL)));
+ else
+ title = strdup(Title);
}
void cOsdMenu::SetHelp(const char *Red, const char *Green, const char *Yellow, const char *Blue)
diff --git a/osd.h b/osd.h
index ec1b115..2d243f1 100644
--- a/osd.h
+++ b/osd.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: osd.h 1.23 2001/08/02 13:48:34 kls Exp $
+ * $Id: osd.h 1.24 2001/08/25 12:56:46 kls Exp $
*/
#ifndef __OSD_H
@@ -72,7 +72,7 @@ public:
class cOsdMenu : public cOsdBase, public cList<cOsdItem> {
private:
- const char *title;
+ char *title;
int cols[cInterface::MaxCols];
int first, current, marked;
cOsdMenu *subMenu;
@@ -94,7 +94,7 @@ protected:
eOSState AddSubMenu(cOsdMenu *SubMenu);
bool HasSubMenu(void) { return subMenu; }
void SetStatus(const char *s);
- void SetTitle(const char *Title, bool Copy = true);
+ void SetTitle(const char *Title, bool ShowDate = true);
void SetHelp(const char *Red, const char *Green = NULL, const char *Yellow = NULL, const char *Blue = NULL);
virtual void Del(int Index);
public:
diff --git a/tools.c b/tools.c
index 30b675b..f51bc85 100644
--- a/tools.c
+++ b/tools.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: tools.c 1.40 2001/08/17 12:45:42 kls Exp $
+ * $Id: tools.c 1.43 2001/08/26 15:45:41 kls Exp $
*/
#define _GNU_SOURCE
@@ -17,7 +17,9 @@
#endif
#include <stdlib.h>
#include <sys/time.h>
+#include <time.h>
#include <unistd.h>
+#include "i18n.h"
#define MaxBuffer 1000
@@ -395,6 +397,20 @@ bool SpinUpDisk(const char *FileName)
return false;
}
+const char *DayDateTime(time_t t)
+{
+ static char buffer[32];
+ if (t == 0)
+ time(&t);
+ tm *tm = localtime(&t);
+ int weekday = tm->tm_wday == 0 ? 6 : tm->tm_wday - 1; // we start with monday==0!
+ const char *day = tr("MonTueWedThuFriSatSun");
+ day += weekday * 3;
+ strncpy(buffer, day, 3);
+ snprintf(buffer + 3, sizeof(buffer) - 3, " %2d.%02d %02d:%02d", tm->tm_mday, tm->tm_mon + 1, tm->tm_hour, tm->tm_min);
+ return buffer;
+}
+
// --- cFile -----------------------------------------------------------------
bool cFile::files[FD_SETSIZE] = { false };
@@ -677,3 +693,19 @@ int cListBase::Count(void) const
return n;
}
+void cListBase::Sort(void)
+{
+ bool swapped;
+ do {
+ swapped = false;
+ cListObject *object = objects;
+ while (object) {
+ if (object->Next() && *object->Next() < *object) {
+ Move(object->Next(), object);
+ swapped = true;
+ }
+ object = object->Next();
+ }
+ } while (swapped);
+}
+
diff --git a/tools.h b/tools.h
index af7958f..2f89f3f 100644
--- a/tools.h
+++ b/tools.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: tools.h 1.29 2001/08/17 12:44:39 kls Exp $
+ * $Id: tools.h 1.31 2001/08/26 12:52:49 kls Exp $
*/
#ifndef __TOOLS_H
@@ -55,6 +55,7 @@ bool RemoveFileOrDir(const char *FileName, bool FollowSymlinks = false);
bool RemoveEmptyDirectories(const char *DirName, bool RemoveThis = false);
char *ReadLink(const char *FileName);
bool SpinUpDisk(const char *FileName);
+const char *DayDateTime(time_t t = 0);
class cFile {
private:
@@ -94,6 +95,7 @@ private:
public:
cListObject(void);
virtual ~cListObject();
+ virtual bool operator< (const cListObject &ListObject) { return false; }
void Append(cListObject *Object);
void Unlink(void);
int Index(void);
@@ -114,6 +116,7 @@ public:
virtual void Clear(void);
cListObject *Get(int Index) const;
int Count(void) const;
+ void Sort(void);
};
template<class T> class cList : public cListBase {
diff --git a/vdr.c b/vdr.c
index af30541..3f8f8da 100644
--- a/vdr.c
+++ b/vdr.c
@@ -22,7 +22,7 @@
*
* The project's page is at http://www.cadsoft.de/people/kls/vdr
*
- * $Id: vdr.c 1.63 2001/08/11 15:33:30 kls Exp $
+ * $Id: vdr.c 1.64 2001/08/26 15:02:00 kls Exp $
*/
#include <getopt.h>
@@ -323,7 +323,7 @@ int main(int argc, char *argv[])
}
// Timers and Recordings:
if (!Menu) {
- cTimer *Timer = cTimer::GetMatch();
+ cTimer *Timer = Timers.GetMatch();
if (Timer) {
if (!cRecordControls::Start(Timer))
Timer->SetPending(true);