Patch #2: What's on at Prime Time?

Message ID 200509261448.25245.lists@magoa.net
State New
Headers

Commit Message

Sascha Volkenandt Sept. 26, 2005, 12:48 p.m. UTC
  Hi list,

I'll be releasing this and a few other patches for VDR 1.3.33, which have 
evolved during the last months while working on XeatreOS (a distribution 
based on LinVDR 0.7, which is used for the Xeatre boxes, 
http://www.xeatre.tv/). Some of their functionality may already be included 
in plugins or other patches. Nevertheless, I'd like to release them now, and 
let everybody decide whether they are useful or not. 


This one adds a "What's on at Prime Time" to the schedules. Prime Time is 
configurable and defaults to 20:15. When not used by "Switch", the blue 
button can be used to access this function. Otherwise, the green button can 
be used to cycle between Now, Next and Prime Time.

Greetings,
Sascha Volkenandt
  

Patch

diff -Nru vdr-1.3.33-orig/config.c vdr-1.3.33/config.c
--- vdr-1.3.33-orig/config.c	Fri Sep  9 17:08:59 2005
+++ vdr-1.3.33/config.c	Mon Sep 26 14:37:54 2005
@@ -303,6 +303,8 @@ 
   CurrentChannel = -1;
   CurrentVolume = MAXVOLUME;
   CurrentDolby = 0;
+  PrimeTime = 2015;
+  sprintf(PrimeTimeText, tr("At %02d:%02d"), PrimeTime / 100, PrimeTime % 100);
 }
 
 cSetup& cSetup::operator= (const cSetup &s)
@@ -361,6 +363,7 @@ 
             result = false;
             }
          }
+     sprintf(PrimeTimeText, tr("At %02d:%02d"), PrimeTime / 100, PrimeTime % 100);
      return result;
      }
   return false;
@@ -461,6 +464,7 @@ 
   else if (!strcasecmp(Name, "CurrentChannel"))      CurrentChannel     = atoi(Value);
   else if (!strcasecmp(Name, "CurrentVolume"))       CurrentVolume      = atoi(Value);
   else if (!strcasecmp(Name, "CurrentDolby"))        CurrentDolby       = atoi(Value);
+  else if (!strcasecmp(Name, "PrimeTime"))           PrimeTime          = atoi(Value);
   else
      return false;
   return true;
@@ -526,6 +530,8 @@ 
   Store("CurrentChannel",     CurrentChannel);
   Store("CurrentVolume",      CurrentVolume);
   Store("CurrentDolby",       CurrentDolby);
+  Store("PrimeTime",          PrimeTime);
+  sprintf(PrimeTimeText, tr("At %02d:%02d"), PrimeTime / 100, PrimeTime % 100);
 
   Sort();
 
diff -Nru vdr-1.3.33-orig/config.h vdr-1.3.33/config.h
--- vdr-1.3.33-orig/config.h	Wed Sep 14 18:04:09 2005
+++ vdr-1.3.33/config.h	Mon Sep 26 14:38:19 2005
@@ -255,7 +255,9 @@ 
   int CurrentChannel;
   int CurrentVolume;
   int CurrentDolby;
+  int PrimeTime;
   int __EndData__;
+  char PrimeTimeText[10];
   cSetup(void);
   cSetup& operator= (const cSetup &s);
   bool Load(const char *FileName);
diff -Nru vdr-1.3.33-orig/i18n.c vdr-1.3.33/i18n.c
--- vdr-1.3.33-orig/i18n.c	Sun Sep 25 13:57:04 2005
+++ vdr-1.3.33/i18n.c	Mon Sep 26 14:36:53 2005
@@ -504,6 +504,27 @@ 
     "Järgmisena eetris",
     "Hvad vises som det næste?",
   },
+  { "What's on at Prime Time?",
+    "Was läuft zur Prime Time?",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "",
+  },
   // Button texts (should not be more than 10 characters!):
   { "Edit",
     "Editieren",
@@ -819,6 +840,27 @@ 
     "Slijedi",
     "Järgmine",
     "Næste",
+  },
+  { "At %02d:%02d",
+    "Um %02d:%02d im TV",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "",
   },
   { "Button$Schedule",
     "Programm",
diff -Nru vdr-1.3.33-orig/menu.c vdr-1.3.33/menu.c
--- vdr-1.3.33-orig/menu.c	Sun Sep 25 15:37:21 2005
+++ vdr-1.3.33/menu.c	Mon Sep 26 14:42:23 2005
@@ -968,8 +968,11 @@ 
   eOSState Switch(void);
   static int currentChannel;
   static const cEvent *scheduleEvent;
+  static const char *whenStrings[3];
+  static char atString[10];
 public:
-  cMenuWhatsOn(const cSchedules *Schedules, bool Now, int CurrentChannelNr);
+  enum eWhen { wNow, wNext, wPrime, wMaxWhen };
+  cMenuWhatsOn(const cSchedules *Schedules, eWhen When, int CurrentChannelNr);
   static int CurrentChannel(void) { return currentChannel; }
   static void SetCurrentChannel(int ChannelNr) { currentChannel = ChannelNr; }
   static const cEvent *ScheduleEvent(void);
@@ -978,22 +981,54 @@ 
 
 int cMenuWhatsOn::currentChannel = 0;
 const cEvent *cMenuWhatsOn::scheduleEvent = NULL;
-
-cMenuWhatsOn::cMenuWhatsOn(const cSchedules *Schedules, bool Now, int CurrentChannelNr)
-:cOsdMenu(Now ? tr("What's on now?") : tr("What's on next?"), CHNUMWIDTH, 7, 6, 4)
+const char *cMenuWhatsOn::whenStrings[3] = { "What's on now?", "What's on next?", "What's on at Prime Time?" };
+char cMenuWhatsOn::atString[10] = "";
+  
+cMenuWhatsOn::cMenuWhatsOn(const cSchedules *Schedules, eWhen When, int CurrentChannelNr)
+:cOsdMenu(tr(whenStrings[When]), CHNUMWIDTH, 7, 6, 4, 4)
 {
   for (cChannel *Channel = Channels.First(); Channel; Channel = Channels.Next(Channel)) {
       if (!Channel->GroupSep()) {
          const cSchedule *Schedule = Schedules->GetSchedule(Channel->GetChannelID());
          if (Schedule) {
-            const cEvent *Event = Now ? Schedule->GetPresentEvent() : Schedule->GetFollowingEvent();
+            const cEvent *Event = NULL;
+            switch (When) {
+            case wNow:   Event = Schedule->GetPresentEvent(); break;
+            case wNext:  Event = Schedule->GetFollowingEvent(); break;
+            case wPrime: {
+                           time_t now = time(NULL);
+                           struct tm prime;
+                           time_t primestamp;
+                           localtime_r(&now, &prime);
+                           prime.tm_hour = Setup.PrimeTime / 100;
+                           prime.tm_min = Setup.PrimeTime % 100;
+                           primestamp = mktime(&prime);
+                           Event = Schedule->GetEventAround(primestamp);
+                           if (Event == NULL) {
+                              prime.tm_mday++; // gets normalized according to manual
+                              Event = Schedule->GetEventAround(mktime(&prime));
+                              }
+                           else if (Event->EndTime() < primestamp + 600) {
+                              prime.tm_min += 10;
+                              Event = Schedule->GetEventAround(mktime(&prime));
+                              }
+                         } // run into default
+            default:     break;
+            }
             if (Event)
                Add(new cMenuWhatsOnItem(Event, Channel), Channel->Number() == CurrentChannelNr);
             }
          }
       }
   currentChannel = CurrentChannelNr;
-  SetHelp(Count() ? tr("Record") : NULL, Now ? tr("Next") : tr("Now"), tr("Button$Schedule"), tr("Switch"));
+  const char *next = NULL;
+  switch (When) {
+  case wNow:   next = tr("Next"); break;
+  case wNext:  next = Setup.PrimeTimeText; break;
+  case wPrime: next = tr("Now"); // run into default
+  default:     break;
+  }
+  SetHelp(Count() ? tr("Record") : NULL, next, tr("Button$Schedule"), tr("Switch"));
 }
 
 const cEvent *cMenuWhatsOn::ScheduleEvent(void)
@@ -1083,8 +1118,9 @@ 
 class cMenuSchedule : public cOsdMenu {
 private:
   cSchedulesLock schedulesLock;
+  bool schedule;
   const cSchedules *schedules;
-  bool now, next;
+  cMenuWhatsOn::eWhen when;
   int otherChannel;
   eOSState Record(void);
   eOSState Switch(void);
@@ -1098,14 +1134,15 @@ 
 cMenuSchedule::cMenuSchedule(void)
 :cOsdMenu("", 7, 6, 4)
 {
-  now = next = false;
+  schedule = false;
+  when = (cMenuWhatsOn::eWhen)-1;
   otherChannel = 0;
   cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel());
   if (channel) {
      cMenuWhatsOn::SetCurrentChannel(channel->Number());
      schedules = cSchedules::Schedules(schedulesLock);
      PrepareSchedule(channel);
-     SetHelp(Count() ? tr("Record") : NULL, tr("Now"), tr("Next"));
+     SetHelp(Count() ? tr("Record") : NULL, tr("Now"), tr("Next"), Setup.PrimeTimeText);
      }
 }
 
@@ -1166,27 +1203,34 @@ 
   if (state == osUnknown) {
      switch (Key) {
        case kRecord:
-       case kRed:    return Record();
+       case kRed:    if (((cMenuScheduleItem *)Get(Current()))->event != NULL)
+                        return Record();
+                     break;
        case kGreen:  if (schedules) {
-                        if (!now && !next) {
+                        if (!schedule) {
                            int ChannelNr = 0;
                            if (Count()) {
                               cChannel *channel = Channels.GetByChannelID(((cMenuScheduleItem *)Get(Current()))->event->ChannelID(), true);
                               if (channel)
                                  ChannelNr = channel->Number();
                               }
-                           now = true;
-                           return AddSubMenu(new cMenuWhatsOn(schedules, true, ChannelNr));
+                           when = cMenuWhatsOn::wNow;
+                           schedule = true;
+                           return AddSubMenu(new cMenuWhatsOn(schedules, when, ChannelNr));
                            }
-                        now = !now;
-                        next = !next;
-                        return AddSubMenu(new cMenuWhatsOn(schedules, now, cMenuWhatsOn::CurrentChannel()));
+                        when = (cMenuWhatsOn::eWhen)((when + 1) % cMenuWhatsOn::wMaxWhen);
+                        return AddSubMenu(new cMenuWhatsOn(schedules, when, cMenuWhatsOn::CurrentChannel()));
+                        }
+       case kYellow: if (schedules) {
+                        when = cMenuWhatsOn::wNext;
+                        schedule = true;
+                        return AddSubMenu(new cMenuWhatsOn(schedules, cMenuWhatsOn::wNext, cMenuWhatsOn::CurrentChannel()));
                         }
-       case kYellow: if (schedules)
-                        return AddSubMenu(new cMenuWhatsOn(schedules, false, cMenuWhatsOn::CurrentChannel()));
                      break;
-       case kBlue:   if (Count())
+       case kBlue:   if (Count() && cDevice::CurrentChannel() != cMenuWhatsOn::CurrentChannel())
                         return Switch();
+                     else if (schedules)
+                        return AddSubMenu(new cMenuWhatsOn(schedules, cMenuWhatsOn::wPrime, cMenuWhatsOn::CurrentChannel()));
                      break;
        case kOk:     if (Count())
                         return AddSubMenu(new cMenuEvent(((cMenuScheduleItem *)Get(Current()))->event, otherChannel));
@@ -1195,16 +1239,18 @@ 
        }
      }
   else if (!HasSubMenu()) {
-     now = next = false;
+     schedule = false;
      const cEvent *ei = cMenuWhatsOn::ScheduleEvent();
      if (ei) {
         cChannel *channel = Channels.GetByChannelID(ei->ChannelID(), true);
         if (channel) {
            PrepareSchedule(channel);
+           const char *blue = Setup.PrimeTimeText;
            if (channel->Number() != cDevice::CurrentChannel()) {
               otherChannel = channel->Number();
-              SetHelp(Count() ? tr("Record") : NULL, tr("Now"), tr("Next"), tr("Switch"));
+              blue = tr("Switch");
               }
+           SetHelp(Count() ? tr("Record") : NULL, tr("Now"), tr("Next"), blue);
            Display();
            }
         }
@@ -1914,6 +1960,7 @@ 
   Add(new cMenuEditIntItem( tr("Setup.EPG$Preferred languages"),       &numLanguages, 0, I18nNumLanguages));
   for (int i = 0; i < numLanguages; i++)
      Add(new cMenuEditStraItem(tr("Setup.EPG$Preferred language"),     &data.EPGLanguages[i], I18nNumLanguages, I18nLanguages()));
+  Add(new cMenuEditTimeItem(tr("Setup.EPG$Prime Time"),                &data.PrimeTime));
 
   SetCurrent(Get(current));
   Display();