diff -Naur vdr-1.6.0/menu.h vdr-1.6.0-MenuEventNext/menu.h
--- vdr-1.6.0/menu.h	2008-02-10 17:01:53.000000000 +0100
+++ vdr-1.6.0-MenuEventNext/menu.h	2010-06-19 15:33:20.000000000 +0200
@@ -45,12 +45,28 @@
   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;
-public:
-  cMenuEvent(const cEvent *Event, bool CanSwitch = false, bool Buttons = false);
+  const cEventSequence *eventSequence;
+  int eventNr;
+  int otherChannel;
+  char *green;
+  char *yellow;
+  void UpdateEvent();
+public:
+  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);
   };
 
diff -Naur vdr-1.6.0/menu.c vdr-1.6.0-MenuEventNext/menu.c
--- vdr-1.6.0/menu.c	2008-03-16 12:15:28.000000000 +0100
+++ vdr-1.6.0-MenuEventNext/menu.c	2010-06-19 16:38:35.000000000 +0200
@@ -974,27 +974,99 @@
      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)
@@ -1005,34 +1077,87 @@
      cStatus::MsgOsdTextItem(event->Description());
 }
 
-eOSState cMenuEvent::ProcessKey(eKeys Key)
+eOSState cMenuEvent::Record(void)
 {
-  switch (Key) {
-    case kUp|k_Repeat:
-    case kUp:
-    case kDown|k_Repeat:
-    case kDown:
-    case kLeft|k_Repeat:
-    case kLeft:
-    case kRight|k_Repeat:
-    case kRight:
-                  DisplayMenu()->Scroll(NORMALKEY(Key) == kUp || NORMALKEY(Key) == kLeft, NORMALKEY(Key) == kLeft || NORMALKEY(Key) == kRight);
-                  cStatus::MsgOsdTextItem(NULL, NORMALKEY(Key) == kUp || NORMALKEY(Key) == kLeft);
-                  return osContinue;
-    case kInfo:   return osBack;
-    default: break;
-    }
+  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)
+{
+  bool HadSubMenu = HasSubMenu();
   eOSState state = cOsdMenu::ProcessKey(Key);
 
   if (state == osUnknown) {
      switch (Key) {
-       case kGreen:
-       case kYellow: return osContinue;
+       case kUp|k_Repeat:
+       case kUp:
+       case kDown|k_Repeat:
+       case kDown:
+       case kLeft|k_Repeat:
+       case kLeft:
+       case kRight|k_Repeat:
+       case kRight:
+                     DisplayMenu()->Scroll(NORMALKEY(Key) == kUp || NORMALKEY(Key) == kLeft, NORMALKEY(Key) == kLeft || NORMALKEY(Key) == kRight);
+                     cStatus::MsgOsdTextItem(NULL, NORMALKEY(Key) == kUp || NORMALKEY(Key) == kLeft);
+                     return osContinue;
+       case kInfo:   return osBack;
+       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;
 }
 
@@ -1106,7 +1231,7 @@
 
 // --- cMenuWhatsOn ----------------------------------------------------------
 
-class cMenuWhatsOn : public cOsdMenu {
+class cMenuWhatsOn : public cOsdMenu, public cEventSequence {
 private:
   bool now;
   int helpKeys;
@@ -1123,6 +1248,8 @@
   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;
@@ -1253,7 +1380,7 @@
        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;
        }
@@ -1267,9 +1394,19 @@
   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;
@@ -1290,6 +1427,8 @@
   cMenuSchedule(void);
   virtual ~cMenuSchedule();
   virtual eOSState ProcessKey(eKeys Key);
+  virtual const cEvent* GetEvent(int Nr) const;
+  virtual int GetEventCount() const;
   };
 
 cMenuSchedule::cMenuSchedule(void)
@@ -1518,7 +1657,7 @@
                      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;
        }
@@ -1546,6 +1685,16 @@
   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 ---------------------------------------------------------
 
 class cMenuCommands : public cOsdMenu {

