Hi list,

In reference to [1], and to give this a push-up, I've attached an
updated patch for program guide scroll for VDR-1.7.17. The patch also
fixes the non-working scrolling in longer descriptions. If anyone needs
this fixed for VDR < 1.7.17, let me know.

Cheers,

Udo

[1] http://www.linuxtv.org/pipermail/vdr/2010-June/023122.html
diff -Naurp vdr-1.7.17/menu.c vdr-1.7.17-menueventnext/menu.c
--- vdr-1.7.17/menu.c	2011-02-27 13:37:48.000000000 +0100
+++ vdr-1.7.17-menueventnext/menu.c	2011-03-19 19:03:23.000000000 +0100
@@ -1220,27 +1220,99 @@ eOSState cMenuTimers::ProcessKey(eKeys K
      Add(new cMenuTimerItem(Timers.Get(TimerNumber)), true);
      Display();
      }
-  if (Key != kNone)
+  if (Key != kNone && !HasSubMenu())
      SetHelpKeys();
   return state;
 }
 
 // --- cMenuEvent ------------------------------------------------------------
 
-cMenuEvent::cMenuEvent(const cEvent *Event, bool CanSwitch, bool Buttons)
+cMenuEvent::cMenuEvent(const cEvent *Event)
 :cOsdMenu(tr("Event"))
 {
   event = Event;
+  eventNr = 0;
+  eventSequence = NULL;
+  green = NULL;
+  yellow = NULL;
+  UpdateEvent();
+}
+
+cMenuEvent::cMenuEvent(const cEventSequence *Events, int EventNr)
+:cOsdMenu(tr("Event"))
+{
+  eventSequence = Events;
+  eventNr = EventNr;
+  green = NULL;
+  yellow = NULL;
+  UpdateEvent();
+}
+
+cMenuEvent::~cMenuEvent() {
+  if (green)
+     free(green);
+  if (yellow)
+     free(yellow);
+}
+
+void cMenuEvent::UpdateEvent()
+{
+  const cEvent *eventPrev = NULL;
+  const cEvent *eventNext = NULL;
+  int TimerMatch = tmNone;
+  otherChannel = 0;
+
+  if (eventSequence) {
+     event = eventSequence->GetEvent(eventNr);
+     eventPrev = eventSequence->GetEvent(eventNr-1);
+     eventNext = eventSequence->GetEvent(eventNr+1);
+     }
+
   if (event) {
      cChannel *channel = Channels.GetByChannelID(event->ChannelID(), true);
      if (channel) {
         SetTitle(channel->Name());
-        int TimerMatch = tmNone;
-        Timers.GetMatch(event, &TimerMatch);
-        if (Buttons)
-           SetHelp(TimerMatch == tmFull ? tr("Button$Timer") : tr("Button$Record"), NULL, NULL, CanSwitch ? tr("Button$Switch") : NULL);
+        if (channel->Number() != cDevice::CurrentChannel())
+           otherChannel = channel->Number();
         }
+     Timers.GetMatch(event, &TimerMatch);
      }
+
+  if (green) {
+     free(green);
+     green = NULL;
+     }
+  if (eventPrev) {
+     if (eventPrev->ChannelID() == event->ChannelID()) {
+        time_t tstart = eventPrev->StartTime();
+        struct tm tm_r;
+        struct tm *time = localtime_r(&tstart, &tm_r);
+        asprintf(&green, "%02d:%02d", time->tm_hour, time->tm_min);
+        }
+     else {
+        cChannel *channel = Channels.GetByChannelID(eventPrev->ChannelID(), true);
+        green = strdup(channel->Name());
+        }
+     }
+
+  if (yellow) {
+     free(yellow);
+     yellow = NULL;
+     }
+  if (eventNext) {
+     if (eventNext->ChannelID() == event->ChannelID()) {
+        time_t tstart = eventNext->StartTime();
+        struct tm tm_r;
+        struct tm *time = localtime_r(&tstart, &tm_r);
+        asprintf(&yellow, "%02d:%02d", time->tm_hour, time->tm_min);
+        }
+     else {
+        cChannel *channel = Channels.GetByChannelID(eventNext->ChannelID(), true);
+        yellow = strdup(channel->Name());
+        }
+     }
+
+  SetHelp(TimerMatch == tmFull ? tr("Button$Timer") : tr("Button$Record"), green, yellow, otherChannel ? tr("Button$Switch") : NULL);
 }
 
 void cMenuEvent::Display(void)
@@ -1251,6 +1323,44 @@ void cMenuEvent::Display(void)
      cStatus::MsgOsdTextItem(event->Description());
 }
 
+eOSState cMenuEvent::Record(void)
+{
+  if (event) {
+     int tm = tmNone;
+     cTimer *timer = Timers.GetMatch(event, &tm);
+     if (timer)
+        return AddSubMenu(new cMenuEditTimer(timer));
+
+     timer = new cTimer(event);
+     cTimer *t = Timers.GetTimer(timer);
+     if (t) {
+        delete timer;
+        timer = t;
+        return AddSubMenu(new cMenuEditTimer(timer));
+        }
+     else {
+        Timers.Add(timer);
+        Timers.SetModified();
+        isyslog("timer %s added (active)", *timer->ToDescr());
+        if (timer->Matches(0, false, NEWTIMERLIMIT))
+           return AddSubMenu(new cMenuEditTimer(timer));
+        UpdateEvent();
+        Display();
+        }
+     }
+  return osContinue;
+}
+
+eOSState cMenuEvent::Switch(void)
+{
+  if (otherChannel) {
+     if (Channels.SwitchTo(otherChannel))
+        return osEnd;
+     }
+  Skins.Message(mtError, tr("Can't switch channel!"));
+  return osContinue;
+}
+
 eOSState cMenuEvent::ProcessKey(eKeys Key)
 {
   switch (int(Key)) {
@@ -1269,16 +1379,35 @@ eOSState cMenuEvent::ProcessKey(eKeys Ke
     default: break;
     }
 
+  bool HadSubMenu = HasSubMenu();
   eOSState state = cOsdMenu::ProcessKey(Key);
 
   if (state == osUnknown) {
      switch (Key) {
-       case kGreen:
-       case kYellow: return osContinue;
+       case kRecord:
+       case kRed:    return Record();
+       case kGreen:  if (eventSequence && eventNr > 0) {
+                        eventNr--;
+                        UpdateEvent();
+                        Display();
+                        }
+                     return osContinue;
+       case kYellow: if (eventSequence && eventNr < eventSequence->GetEventCount()-1) {
+                        eventNr++;
+                        UpdateEvent();
+                        Display();
+                        }
+                     return osContinue;
+       case kBlue:   return Switch();
        case kOk:     return osBack;
        default: break;
        }
      }
+  else if (!HasSubMenu() && HadSubMenu) {
+     UpdateEvent();
+     Display();
+     }
+
   return state;
 }
 
@@ -1352,7 +1481,7 @@ bool cMenuScheduleItem::Update(bool Forc
 
 // --- cMenuWhatsOn ----------------------------------------------------------
 
-class cMenuWhatsOn : public cOsdMenu {
+class cMenuWhatsOn : public cOsdMenu, public cEventSequence {
 private:
   bool now;
   int helpKeys;
@@ -1369,6 +1498,8 @@ public:
   static void SetCurrentChannel(int ChannelNr) { currentChannel = ChannelNr; }
   static const cEvent *ScheduleEvent(void);
   virtual eOSState ProcessKey(eKeys Key);
+  virtual const cEvent* GetEvent(int Nr) const;
+  virtual int GetEventCount() const;
   };
 
 int cMenuWhatsOn::currentChannel = 0;
@@ -1499,7 +1630,7 @@ eOSState cMenuWhatsOn::ProcessKey(eKeys
        case kBlue:   return Switch();
        case kInfo:
        case kOk:     if (Count())
-                        return AddSubMenu(new cMenuEvent(((cMenuScheduleItem *)Get(Current()))->event, true, true));
+                        return AddSubMenu(new cMenuEvent(this, Current()));
                      break;
        default:      break;
        }
@@ -1513,9 +1644,19 @@ eOSState cMenuWhatsOn::ProcessKey(eKeys
   return state;
 }
 
+const cEvent* cMenuWhatsOn::GetEvent(int Nr) const {
+  if (Nr >= 0 && Nr < Count())
+     return ((cMenuScheduleItem *)Get(Nr))->event;
+  return NULL;
+  }
+
+int cMenuWhatsOn::GetEventCount() const {
+  return Count();
+  }
+
 // --- cMenuSchedule ---------------------------------------------------------
 
-class cMenuSchedule : public cOsdMenu {
+class cMenuSchedule : public cOsdMenu, public cEventSequence {
 private:
   cSchedulesLock schedulesLock;
   const cSchedules *schedules;
@@ -1536,6 +1677,8 @@ public:
   cMenuSchedule(void);
   virtual ~cMenuSchedule();
   virtual eOSState ProcessKey(eKeys Key);
+  virtual const cEvent* GetEvent(int Nr) const;
+  virtual int GetEventCount() const;
   };
 
 cMenuSchedule::cMenuSchedule(void)
@@ -1765,7 +1908,7 @@ eOSState cMenuSchedule::ProcessKey(eKeys
                      break;
        case kInfo:
        case kOk:     if (Count())
-                        return AddSubMenu(new cMenuEvent(((cMenuScheduleItem *)Get(Current()))->event, otherChannel, true));
+                        return AddSubMenu(new cMenuEvent(this, Current()));
                      break;
        default:      break;
        }
@@ -1793,6 +1936,16 @@ eOSState cMenuSchedule::ProcessKey(eKeys
   return state;
 }
 
+const cEvent* cMenuSchedule::GetEvent(int Nr) const {
+  if (Nr >= 0 && Nr < Count())
+     return ((cMenuScheduleItem *)Get(Nr))->event;
+  return NULL;
+  }
+
+int cMenuSchedule::GetEventCount() const {
+  return Count();
+  }
+
 // --- cMenuCommands ---------------------------------------------------------
 
 cMenuCommands::cMenuCommands(const char *Title, cList<cNestedItem> *Commands, const char *Parameters)
diff -Naurp vdr-1.7.17/menu.h vdr-1.7.17-menueventnext/menu.h
--- vdr-1.7.17/menu.h	2010-03-06 17:15:59.000000000 +0100
+++ vdr-1.7.17-menueventnext/menu.h	2011-03-19 18:58:42.000000000 +0100
@@ -86,12 +86,28 @@ public:
   virtual eOSState ProcessKey(eKeys Key);
   };
 
+class cEventSequence {
+public:
+  virtual const cEvent* GetEvent(int Nr) const = 0;
+  virtual int GetEventCount() const = 0;
+};
+
 class cMenuEvent : public cOsdMenu {
 private:
   const cEvent *event;
+  const cEventSequence *eventSequence;
+  int eventNr;
+  int otherChannel;
+  char *green;
+  char *yellow;
+  void UpdateEvent();
 public:
-  cMenuEvent(const cEvent *Event, bool CanSwitch = false, bool Buttons = false);
+  cMenuEvent(const cEvent *Event);
+  cMenuEvent(const cEventSequence *Events, int EventNr);
+  virtual ~cMenuEvent();
   virtual void Display(void);
+  eOSState Record(void);
+  eOSState Switch(void);
   virtual eOSState ProcessKey(eKeys Key);
   };
 
_______________________________________________
vdr mailing list
vdr@linuxtv.org
http://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr

Reply via email to