diff -u vdr-1.3.31-org/channels.h vdr-1.3.31/channels.h
--- vdr-1.3.31-org/channels.h	2005-08-06 13:23:32.000000000 +0200
+++ vdr-1.3.31/channels.h	2005-09-03 18:32:15.000000000 +0200
@@ -164,6 +164,10 @@
   int Tid(void) const { return tid; }
   int Sid(void) const { return sid; }
   int Rid(void) const { return rid; }
+  bool IsTV(void)    const { return (vpid > 0)  && (Apid(0)>0); }
+  bool IsRadio(void) const { return (vpid == 0) && (Apid(0)>0); }
+  bool IsData(void) const { return (Dpid(0) > 0); }
+  bool IsCrypted(void) const { return (Ca() > 4); }
   int Number(void) const { return number; }
   void SetNumber(int Number) { number = Number; }
   bool GroupSep(void) const { return groupSep; }
diff -u vdr-1.3.31-org/menu.c vdr-1.3.31/menu.c
--- vdr-1.3.31-org/menu.c	2005-08-27 11:37:23.000000000 +0200
+++ vdr-1.3.31/menu.c	2005-09-03 19:16:19.000000000 +0200
@@ -371,7 +372,13 @@
      if (sortMode == csmProvider)
         asprintf(&buffer, "%d\t%s - %s", channel->Number(), channel->Provider(), channel->Name());
      else
-        asprintf(&buffer, "%d\t%s", channel->Number(), channel->Name());
+        asprintf(&buffer, "%4d  %s%s%s%s  %s", channel->Number(), 
+	                                 channel->Vpid()>0 ? "t":" ", 
+					 (channel->Vpid()==0) && (channel->Apid(0) > 0) ? "r":" ",
+					 (channel->Dpid(0) > 0) ? "d":" ",
+					 channel->Ca(0)>4  ? "x":" ", 
+					 channel->Name()
+	);
      }
   else
      asprintf(&buffer, "---\t%s ----------------------------------------------------------------", channel->Name());
@@ -385,6 +392,8 @@
   void Setup(void);
   cChannel *GetChannel(int Index);
   void Propagate(void);
+  bool IsFiltered(void);
+  int onlyTV, onlyRadio, onlyUncrypt;
 protected:
   eOSState Switch(void);
   eOSState Edit(void);
@@ -400,6 +409,7 @@
 cMenuChannels::cMenuChannels(void)
 :cOsdMenu(tr("Channels"), CHNUMWIDTH)
 {
+  onlyTV = onlyRadio = onlyUncrypt = 0;
   Setup();
   Channels.IncBeingEdited();
 }
@@ -415,19 +425,38 @@
   if (!currentChannel)
      currentChannel = Channels.GetByNumber(cDevice::CurrentChannel());
   cMenuChannelItem *currentItem = NULL;
+  cMenuChannelItem *lastUsedItem = NULL;
+  cMenuChannelItem *firstUsedItem = NULL;
   Clear();
+  
   for (cChannel *channel = Channels.First(); channel; channel = Channels.Next(channel)) {
-      if (!channel->GroupSep() || cMenuChannelItem::SortMode() == cMenuChannelItem::csmNumber && *channel->Name()) {
-         cMenuChannelItem *item = new cMenuChannelItem(channel);
-         Add(item);
-         if (channel == currentChannel)
-            currentItem = item;
-         }
+      if ((!channel->GroupSep() || cMenuChannelItem::SortMode() == cMenuChannelItem::csmNumber)
+            && *channel->Name()  //Channel must have a name
+	    && (channel->GroupSep() || //Do not filter Groupseperators
+            	(  !(onlyTV      && !channel->IsTV()     ) 
+  		&& !(onlyRadio   && !channel->IsRadio()  )
+		&& !(onlyUncrypt && channel->IsCrypted() ) 
+	    ))) {
+            cMenuChannelItem *item = new cMenuChannelItem(channel);
+            Add(item);
+            if (channel == currentChannel)
+        	currentItem = item;
+	    if (!channel->GroupSep()) {
+		lastUsedItem = item;
+		if( !firstUsedItem )
+		    firstUsedItem = item;
+	    }
+      } else {
+            if (channel == currentChannel)
+        	currentItem = lastUsedItem; // current channel is now invisible, so we use the nearest channel
       }
+  }
   if (cMenuChannelItem::SortMode() != cMenuChannelItem::csmNumber)
      Sort();
+  if (!currentItem) // happens, if after filtering the first line is a groupsep
+     currentItem = firstUsedItem;
   SetCurrent(currentItem);
-  SetHelp(tr("Edit"), tr("New"), tr("Delete"), cMenuChannelItem::SortMode() == cMenuChannelItem::csmNumber ? tr("Mark") : NULL);
+  SetHelp(tr("Edit"), tr("New"), tr("Delete"), !IsFiltered() && cMenuChannelItem::SortMode() == cMenuChannelItem::csmNumber ? tr("Mark") : NULL);
   Display();
 }
 
@@ -446,6 +475,11 @@
   Channels.SetModified(true);
 }
 
+bool cMenuChannels::IsFiltered(void)
+{
+  return onlyTV || onlyRadio || onlyUncrypt;
+}
+
 eOSState cMenuChannels::Switch(void)
 {
   if (HasSubMenu())
@@ -533,11 +567,36 @@
               case k0:      cMenuChannelItem::IncSortMode();
                             Setup();
                             break;
+              case k1:      // show all channels (default)
+	                    onlyTV = onlyRadio = onlyUncrypt = 0;
+                            Setup();
+			    Skins.Message(mtStatus, "All channels");
+                            break;
+              case k2:      // show only TV-channels with sound
+	                    onlyTV = !0;
+			    onlyRadio = 0;
+                            Setup();
+			    Skins.Message(mtStatus, "Show only tv channels");
+                            break;
+              case k3:      // show only radio/broadcast
+	                    onlyTV = 0;
+	                    onlyRadio = !0;
+                            Setup();
+			    Skins.Message(mtStatus, "Show only radio channels");
+                            break;
+              case k4:      // switch Crypt
+	                    onlyUncrypt = !onlyUncrypt;
+                            Setup();
+			    if( onlyUncrypt ) 
+			       Skins.Message(mtStatus, "Show only uncrypted channels");
+			    else
+			       Skins.Message(mtStatus, "Show uncrypted and crypted channels");
+                            break;
               case kOk:     return Switch();
               case kRed:    return Edit();
               case kGreen:  return New();
               case kYellow: return Delete();
-              case kBlue:   if (!HasSubMenu() && cMenuChannelItem::SortMode() == cMenuChannelItem::csmNumber)
+              case kBlue:   if (!HasSubMenu() && !IsFiltered() && cMenuChannelItem::SortMode() == cMenuChannelItem::csmNumber)
                                Mark();
                             break;
               default: break;

