mirror of
				https://github.com/vdr-projects/vdr.git
				synced 2025-03-01 10:50:46 +00:00 
			
		
		
		
	Implemented gaps in channel numbering
This commit is contained in:
		
							
								
								
									
										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! | ||||
|   | ||||
							
								
								
									
										73
									
								
								channels.c
									
									
									
									
									
								
							
							
						
						
									
										73
									
								
								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; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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; | ||||
|                            } | ||||
|                      } | ||||
|                   } | ||||
|   | ||||
							
								
								
									
										59
									
								
								menu.c
									
									
									
									
									
								
							
							
						
						
									
										59
									
								
								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; | ||||
|   | ||||
							
								
								
									
										26
									
								
								svdrp.c
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								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"); | ||||
|   | ||||
							
								
								
									
										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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user