mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Implemented gaps in channel numbering
This commit is contained in:
parent
16f3d3fc5d
commit
ab4ceb29a0
5
HISTORY
5
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!
|
||||
|
57
channels.c
57
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)
|
||||
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;
|
||||
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,34 +409,38 @@ 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();
|
||||
int Number = 1;
|
||||
for (cChannel *channel = First(); channel; channel = Next(channel)) {
|
||||
if (channel->GroupSep()) {
|
||||
if (channel->Number() > Number)
|
||||
Number = channel->Number();
|
||||
}
|
||||
maxNumber = 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)
|
||||
cChannel *previous = NULL;
|
||||
for (cChannel *channel = First(); channel; channel = Next(channel)) {
|
||||
if (!channel->GroupSep()) {
|
||||
if (channel->Number() == Number)
|
||||
return channel;
|
||||
channel = (cChannel *)channel->Next();
|
||||
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) {
|
||||
for (cChannel *channel = First(); channel; channel = Next(channel)) {
|
||||
if (!channel->GroupSep() && channel->Sid() == ServiceId)
|
||||
return channel;
|
||||
channel = (cChannel *)channel->Next();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -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);
|
||||
|
6
device.c
6
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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
57
menu.c
57
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)
|
||||
*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;
|
||||
|
18
svdrp.c
18
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,12 +661,14 @@ void cSVDRP::CmdLSTC(const char *Option)
|
||||
}
|
||||
}
|
||||
else if (Channels.MaxNumber() >= 1) {
|
||||
for (int i = 1; i <= Channels.MaxNumber(); i++) {
|
||||
cChannel *channel = Channels.GetByNumber(i);
|
||||
int i = 1;
|
||||
while (i <= Channels.MaxNumber()) {
|
||||
cChannel *channel = Channels.GetByNumber(i, 1);
|
||||
if (channel)
|
||||
Reply(i < Channels.MaxNumber() ? -250 : 250, "%d %s", channel->Number(), channel->ToText());
|
||||
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
|
||||
|
9
tools.c
9
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;
|
||||
|
3
tools.h
3
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);
|
||||
|
16
vdr.5
16
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
|
||||
|
Loading…
Reference in New Issue
Block a user