summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKlaus Schmidinger <vdr@tvdr.de>2002-10-19 15:33:37 +0200
committerKlaus Schmidinger <vdr@tvdr.de>2002-10-19 15:33:37 +0200
commitab4ceb29a033f8a3cc051d5ea9a6f20ca6e75f8a (patch)
treebefea69b48e6187abae6b836b51c823e76846763
parent16f3d3fc5d2f883241147db6ed9622a58f73b7c0 (diff)
downloadvdr-ab4ceb29a033f8a3cc051d5ea9a6f20ca6e75f8a.tar.gz
vdr-ab4ceb29a033f8a3cc051d5ea9a6f20ca6e75f8a.tar.bz2
Implemented gaps in channel numbering
-rw-r--r--HISTORY5
-rw-r--r--channels.c73
-rw-r--r--channels.h4
-rw-r--r--device.c6
-rw-r--r--eitscan.c6
-rw-r--r--menu.c59
-rw-r--r--svdrp.c26
-rw-r--r--tools.c9
-rw-r--r--tools.h3
-rw-r--r--vdr.516
10 files changed, 137 insertions, 70 deletions
diff --git a/HISTORY b/HISTORY
index e55ff53b..df92d6b4 100644
--- a/HISTORY
+++ b/HISTORY
@@ -1619,3 +1619,8 @@ Video Disk Recorder Revision History
- Fixed a small glitch when switching channels (thanks to Dennis Noordsij for
reporting this one).
- Fixed handling multiple 'CaCaps' entries in 'setup.conf'.
+- Group separators in 'channels.conf' may now be given like ':@201 My Channels',
+ where '@201' indicates the number to be given to the next channel. This can be
+ used to create 'gaps' in the channel numbering (see 'man 5 vdr'). BE CAREFUL
+ TO UPDATE YOUR 'timers.conf' ACCORDINGLY IF INSERTING THIS NEW FEATURE INTO YOUR
+ 'channels.conf' FILE!
diff --git a/channels.c b/channels.c
index f86f8efb..5dd4b742 100644
--- a/channels.c
+++ b/channels.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: channels.c 1.3 2002/10/06 12:41:49 kls Exp $
+ * $Id: channels.c 1.4 2002/10/19 14:46:05 kls Exp $
*/
#include "channels.h"
@@ -158,6 +158,7 @@ cChannel::cChannel(void)
tpid = 0;
ca = 0;
sid = 0;
+ number = 0;
groupSep = false;
//XXX
polarization = 'v';
@@ -282,8 +283,12 @@ const char *cChannel::ToText(cChannel *Channel)
strreplace(s, ':', '|');
}
free(buffer);
- if (Channel->groupSep)
- asprintf(&buffer, ":%s\n", s);
+ if (Channel->groupSep) {
+ if (Channel->number)
+ asprintf(&buffer, ":@%d %s\n", Channel->number, s);
+ else
+ asprintf(&buffer, ":%s\n", s);
+ }
else {
char apidbuf[32];
char *q = apidbuf;
@@ -308,13 +313,17 @@ const char *cChannel::ToText(void)
bool cChannel::Parse(const char *s)
{
if (*s == ':') {
- if (*++s) {
- strn0cpy(name, s, MaxChannelName);
- groupSep = true;
- number = 0;
+ groupSep = true;
+ if (*++s == '@' && *++s) {
+ char *p = NULL;
+ errno = 0;
+ int n = strtol(s, &p, 10);
+ if (!errno && p != s && n > 0) {
+ number = n;
+ s = p;
+ }
}
- else
- return false;
+ strn0cpy(name, skipspace(s), MaxChannelName);
}
else {
groupSep = false;
@@ -400,35 +409,39 @@ int cChannels::GetNextNormal(int Idx)
void cChannels::ReNumber( void )
{
- int Number = 0;
- cChannel *ch = (cChannel *)First();
- while (ch) {
- if (!ch->GroupSep())
- ch->SetNumber(++Number);
- ch = (cChannel *)ch->Next();
- }
- maxNumber = Number;
+ int Number = 1;
+ for (cChannel *channel = First(); channel; channel = Next(channel)) {
+ if (channel->GroupSep()) {
+ if (channel->Number() > Number)
+ Number = channel->Number();
+ }
+ else
+ channel->SetNumber(Number++);
+ }
+ maxNumber = Number - 1;
}
-cChannel *cChannels::GetByNumber(int Number)
+cChannel *cChannels::GetByNumber(int Number, int SkipGap)
{
- cChannel *channel = (cChannel *)First();
- while (channel) {
- if (!channel->GroupSep() && channel->Number() == Number)
- return channel;
- channel = (cChannel *)channel->Next();
- }
+ cChannel *previous = NULL;
+ for (cChannel *channel = First(); channel; channel = Next(channel)) {
+ if (!channel->GroupSep()) {
+ if (channel->Number() == Number)
+ return channel;
+ else if (SkipGap && channel->Number() > Number)
+ return SkipGap > 0 ? channel : previous;
+ previous = channel;
+ }
+ }
return NULL;
}
cChannel *cChannels::GetByServiceID(unsigned short ServiceId)
{
- cChannel *channel = (cChannel *)First();
- while (channel) {
- if (!channel->GroupSep() && channel->Sid() == ServiceId)
- return channel;
- channel = (cChannel *)channel->Next();
- }
+ for (cChannel *channel = First(); channel; channel = Next(channel)) {
+ if (!channel->GroupSep() && channel->Sid() == ServiceId)
+ return channel;
+ }
return NULL;
}
diff --git a/channels.h b/channels.h
index 8a784f75..d014cf3a 100644
--- a/channels.h
+++ b/channels.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: channels.h 1.1 2002/10/05 13:53:15 kls Exp $
+ * $Id: channels.h 1.2 2002/10/19 11:48:02 kls Exp $
*/
#ifndef __CHANNELS_H
@@ -112,7 +112,7 @@ public:
int GetPrevGroup(int Idx); // Get previous channel group
int GetNextNormal(int Idx); // Get next normal channel (not group)
void ReNumber(void); // Recalculate 'number' based on channel type
- cChannel *GetByNumber(int Number);
+ cChannel *GetByNumber(int Number, int SkipGap = 0);
cChannel *GetByServiceID(unsigned short ServiceId);
const char *GetChannelNameByNumber(int Number);
bool SwitchTo(int Number);
diff --git a/device.c b/device.c
index 637632b4..bfe4edbc 100644
--- a/device.c
+++ b/device.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: device.c 1.27 2002/10/12 13:24:37 kls Exp $
+ * $Id: device.c 1.28 2002/10/19 11:48:02 kls Exp $
*/
#include "device.h"
@@ -324,11 +324,11 @@ bool cDevice::SwitchChannel(int Direction)
int first = n;
PrimaryDevice()->StopReplay(); // otherwise a running Transfer Mode would block channels
cChannel *channel;
- while ((channel = Channels.GetByNumber(n)) != NULL) {
+ while ((channel = Channels.GetByNumber(n, Direction)) != NULL) {
// try only channels which are currently available
if (PrimaryDevice()->ProvidesChannel(channel, Setup.PrimaryLimit) || GetDevice(channel, 0))
break;
- n += Direction;
+ n = channel->Number() + 1;
}
if (channel) {
int d = n - first;
diff --git a/eitscan.c b/eitscan.c
index c29b6b57..2a89cec9 100644
--- a/eitscan.c
+++ b/eitscan.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: eitscan.c 1.8 2002/10/05 13:44:35 kls Exp $
+ * $Id: eitscan.c 1.9 2002/10/19 11:48:02 kls Exp $
*/
#include "eitscan.h"
@@ -63,7 +63,7 @@ void cEITScanner::Process(void)
ch = 1;
numTransponders = 0;
}
- cChannel *Channel = Channels.GetByNumber(ch);
+ cChannel *Channel = Channels.GetByNumber(ch, 1);
if (Channel) {
if (!Device->ProvidesChannel(Channel))
break;
@@ -75,7 +75,7 @@ void cEITScanner::Process(void)
break;
}
}
- ch++;
+ ch = Channel->Number() + 1;
}
}
}
diff --git a/menu.c b/menu.c
index 077922a1..286820ef 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.217 2002/10/13 12:10:54 kls Exp $
+ * $Id: menu.c 1.218 2002/10/19 15:33:37 kls Exp $
*/
#include "menu.h"
@@ -33,7 +33,7 @@
#define MAXRECORDCONTROLS (MAXDEVICES * MAXRECEIVERS)
#define MAXINSTANTRECTIME (24 * 60 - 1) // 23:59 hours
-#define CHNUMWIDTH (Channels.Count() > 999 ? 5 : 4) // there are people with more than 999 channels...
+#define CHNUMWIDTH (numdigits(Channels.MaxNumber()) + 1)
// --- cMenuEditChanItem -----------------------------------------------------
@@ -42,6 +42,7 @@ protected:
virtual void Set(void);
public:
cMenuEditChanItem(const char *Name, int *Value);
+ virtual eOSState ProcessKey(eKeys Key);
};
cMenuEditChanItem::cMenuEditChanItem(const char *Name, int *Value)
@@ -54,13 +55,32 @@ void cMenuEditChanItem::Set(void)
{
char buf[255];
cChannel *channel = Channels.GetByNumber(*value);
- if (channel)
- snprintf(buf, sizeof(buf), "%d %s", *value, channel->Name());
- else
- *buf = 0;
+ snprintf(buf, sizeof(buf), "%d %s", *value, channel ? channel->Name() : "");
SetValue(buf);
}
+eOSState cMenuEditChanItem::ProcessKey(eKeys Key)
+{
+ int delta = 1;
+
+ switch (Key) {
+ case kLeft|k_Repeat:
+ case kLeft: delta = -1;
+ case kRight|k_Repeat:
+ case kRight:
+ {
+ cChannel *channel = Channels.GetByNumber(*value + delta, delta);
+ if (channel) {
+ *value = channel->Number();
+ Set();
+ }
+ }
+ break;
+ default : return cMenuEditIntItem::ProcessKey(Key);
+ }
+ return osContinue;
+}
+
// --- cMenuEditTranItem -----------------------------------------------------
class cMenuEditTranItem : public cMenuEditChanItem {
@@ -2383,10 +2403,17 @@ void cDisplayChannel::DisplayChannel(const cChannel *Channel)
{
int BufSize = Width() + 1;
char buffer[BufSize];
- if (Channel && Channel->Number() > 0)
- snprintf(buffer, BufSize, "%d%s %s", Channel->Number(), number ? "-" : "", Channel->Name());
+ *buffer = 0;
+ if (Channel) {
+ if (Channel->Number() > 0)
+ snprintf(buffer, BufSize, "%d%s %s", Channel->Number(), number ? "-" : "", Channel->Name());
+ else if (Channel->Name())
+ snprintf(buffer, BufSize, "%s", Channel->Name());
+ }
+ else if (number)
+ snprintf(buffer, BufSize, "%d-", number);
else
- snprintf(buffer, BufSize, "%s", Channel ? Channel->Name() : tr("*** Invalid Channel ***"));
+ snprintf(buffer, BufSize, "%s", tr("*** Invalid Channel ***"));
Interface->Fill(0, 0, Setup.OSDwidth, 1, clrBackground);
Interface->Write(0, 0, buffer);
const char *date = DayDateTime();
@@ -2468,10 +2495,6 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key)
cChannel *channel = Channels.GetByNumber(number);
DisplayChannel(channel);
lastTime = time_ms();
- if (!channel) {
- number = -1;
- lastTime += 1000;
- }
}
}
break;
@@ -2505,8 +2528,14 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key)
break;
case kNone:
if (number && time_ms() - lastTime > DIRECTCHANNELTIMEOUT) {
- if (number > 0 && !Channels.SwitchTo(number))
- number = -1;
+ if (Channels.GetByNumber(number))
+ Channels.SwitchTo(number);
+ else {
+ number = 0;
+ DisplayChannel(NULL);
+ lastTime = time_ms();
+ return osContinue;
+ }
return osEnd;
}
break;
diff --git a/svdrp.c b/svdrp.c
index 41171493..114be09a 100644
--- a/svdrp.c
+++ b/svdrp.c
@@ -10,7 +10,7 @@
* and interact with the Video Disk Recorder - or write a full featured
* graphical interface that sits on top of an SVDRP connection.
*
- * $Id: svdrp.c 1.45 2002/10/13 09:31:31 kls Exp $
+ * $Id: svdrp.c 1.46 2002/10/19 11:48:02 kls Exp $
*/
#include "svdrp.h"
@@ -413,12 +413,12 @@ void cSVDRP::CmdCHAN(const char *Option)
else {
int i = 1;
cChannel *channel;
- while ((channel = Channels.GetByNumber(i)) != NULL) {
+ while ((channel = Channels.GetByNumber(i, 1)) != NULL) {
if (strcasecmp(channel->Name(), Option) == 0) {
n = i;
break;
}
- i++;
+ i = channel->Number() + 1;
}
}
if (n < 0) {
@@ -640,7 +640,7 @@ void cSVDRP::CmdLSTC(const char *Option)
int i = 1;
cChannel *next = NULL;
while (i <= Channels.MaxNumber()) {
- cChannel *channel = Channels.GetByNumber(i);
+ cChannel *channel = Channels.GetByNumber(i, 1);
if (channel) {
if (strcasestr(channel->Name(), Option)) {
if (next)
@@ -652,7 +652,7 @@ void cSVDRP::CmdLSTC(const char *Option)
Reply(501, "Channel \"%d\" not found", i);
return;
}
- i++;
+ i = channel->Number() + 1;
}
if (next)
Reply(250, "%d %s", next->Number(), next->ToText());
@@ -661,13 +661,15 @@ void cSVDRP::CmdLSTC(const char *Option)
}
}
else if (Channels.MaxNumber() >= 1) {
- for (int i = 1; i <= Channels.MaxNumber(); i++) {
- cChannel *channel = Channels.GetByNumber(i);
- if (channel)
- Reply(i < Channels.MaxNumber() ? -250 : 250, "%d %s", channel->Number(), channel->ToText());
- else
- Reply(501, "Channel \"%d\" not found", i);
- }
+ int i = 1;
+ while (i <= Channels.MaxNumber()) {
+ cChannel *channel = Channels.GetByNumber(i, 1);
+ if (channel)
+ Reply(channel->Number() < Channels.MaxNumber() ? -250 : 250, "%d %s", channel->Number(), channel->ToText());
+ else
+ Reply(501, "Channel \"%d\" not found", i);
+ i = channel->Number() + 1;
+ }
}
else
Reply(550, "No channels defined");
diff --git a/tools.c b/tools.c
index b3b64fc9..df2d5705 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.71 2002/09/09 21:35:49 kls Exp $
+ * $Id: tools.c 1.72 2002/10/19 12:32:53 kls Exp $
*/
#include "tools.h"
@@ -207,6 +207,13 @@ bool isempty(const char *s)
return !(s && *skipspace(s));
}
+int numdigits(int n)
+{
+ char buf[16];
+ snprintf(buf, sizeof(buf), "%d", n);
+ return strlen(buf);
+}
+
int time_ms(void)
{
static time_t t0 = 0;
diff --git a/tools.h b/tools.h
index f8bf43f2..08f2429b 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.50 2002/09/08 10:22:29 kls Exp $
+ * $Id: tools.h 1.51 2002/10/19 12:31:50 kls Exp $
*/
#ifndef __TOOLS_H
@@ -64,6 +64,7 @@ const char *strescape(const char *s, const char *chars); // returns a statically
bool startswith(const char *s, const char *p);
bool endswith(const char *s, const char *p);
bool isempty(const char *s);
+int numdigits(int n);
int time_ms(void);
void delay_ms(int ms);
bool isnumber(const char *s);
diff --git a/vdr.5 b/vdr.5
index ccb7b924..1d4e25ad 100644
--- a/vdr.5
+++ b/vdr.5
@@ -8,9 +8,9 @@
.\" License as specified in the file COPYING that comes with the
.\" vdr distribution.
.\"
-.\" $Id: vdr.5 1.8 2002/10/13 12:14:49 kls Exp $
+.\" $Id: vdr.5 1.9 2002/10/19 12:45:23 kls Exp $
.\"
-.TH vdr 5 "7 Sep 2002" "1.2.0" "Video Disk Recorder Files"
+.TH vdr 5 "7 Oct 2002" "1.2.0" "Video Disk Recorder Files"
.SH NAME
vdr file formats - the Video Disk Recorder Files
.SH DESCRIPTION
@@ -26,12 +26,22 @@ character, followed by arbitrary text. Example:
\fB:First group\fR
+Group delimiters may also be used to specify the number of the next channel.
+To do this, the character '@' and a number must immediately follow the ':',
+as in
+
+\fB:@201 First group\fR
+
+The given number must be larger than the number of any previous channel
+(otherwise it is silently ignored).
+
A \fBchannel definition\fR is a line with channel data, where the fields
are separated by ':' characters. Example:
\fBRTL:12188:h:S19.2E:27500:163:104:105:0:12003\fR
-The line number of a channel definition (not counting group separators!)
+The line number of a channel definition (not counting group separators,
+and based on a possible previous '@...' parameter)
defines the channel's number in OSD menus and the \fItimers.conf\fR file.
The fields in a channel definition have the following meaning (from left