Implemented gaps in channel numbering

This commit is contained in:
Klaus Schmidinger 2002-10-19 15:33:37 +02:00
parent 16f3d3fc5d
commit ab4ceb29a0
10 changed files with 137 additions and 70 deletions

View File

@ -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!

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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;
}
}
}

59
menu.c
View File

@ -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;

26
svdrp.c
View File

@ -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");

View File

@ -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;

View File

@ -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);

16
vdr.5
View File

@ -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