re-add (unused) blinking point in radio infobar to make e2 happy...
[enigma2.git] / lib / python / Screens / ChannelSelection.py
index acd53bc5faa7a4c9e3b62d2496685e9e9dea4c9e..1ccddf75ed49702cf9e1ac7281c32479340e8a45 100644 (file)
@@ -1,20 +1,24 @@
 from Screen import Screen
 from Components.Button import Button
 from Components.ServiceList import ServiceList
-from Components.ActionMap import NumberActionMap, ActionMap
+from Components.ActionMap import NumberActionMap, ActionMap, HelpableActionMap
 from Components.MenuList import MenuList
 from Components.ServiceEventTracker import ServiceEventTracker
 from EpgSelection import EPGSelection
-from enigma import eServiceReference, eEPGCache, eServiceCenter, eServiceCenterPtr, iMutableServiceListPtr, iStaticServiceInformationPtr, eTimer, eDVBDB, iPlayableService, iServiceInformation
+from enigma import eServiceReference, eEPGCache, eServiceCenter, eTimer, eDVBDB, iPlayableService, iServiceInformation
 from Components.config import config, ConfigSubsection, ConfigText
 from Screens.FixedMenu import FixedMenu
 from Tools.NumericalTextInput import NumericalTextInput
 from Components.NimManager import nimmanager
 from Components.Sources.Clock import Clock
+from Components.Sources.RdsDecoder import RdsDecoder
 from Components.Input import Input
 from Components.ParentalControl import parentalControl
+from Components.Pixmap import BlinkingPixmapConditional
 from Screens.InputBox import InputBox, PinInput
 from Screens.MessageBox import MessageBox
+from Screens.ServiceInfo import ServiceInfo
+from Screens.RdsDisplay import RassInteractive
 from ServiceReference import ServiceReference
 from Tools.BoundFunction import boundFunction
 from re import *
@@ -35,9 +39,7 @@ class BouquetSelector(Screen):
                                "ok": self.okbuttonClick,
                                "cancel": self.cancelClick
                        })
-               entrys = [ ]
-               for x in bouquets:
-                       entrys.append((x[0], x[1]))
+               entrys = [ (x[0], x[1]) for x in bouquets ]
                self["menu"] = MenuList(entrys, enableWrapAround)
 
        def getCurrent(self):
@@ -56,6 +58,15 @@ class BouquetSelector(Screen):
        def cancelClick(self):
                self.close(False)
 
+# csel.bouquet_mark_edit values
+OFF = 0
+EDIT_BOUQUET = 1
+EDIT_ALTERNATIVES = 2
+
+def apend_when_current_valid(current, menu, args):
+       if current and current.valid():
+               menu.append(args)
+
 class ChannelContextMenu(Screen):
        def __init__(self, session, csel):
                Screen.__init__(self, session)
@@ -69,58 +80,72 @@ class ChannelContextMenu(Screen):
                        })
                menu = [ ]
 
+               current = csel.getCurrentSelection()
                current_root = csel.getRoot()
-               current_sel_path = csel.getCurrentSelection().getPath()
-               current_sel_flags = csel.getCurrentSelection().flags
+               current_sel_path = current.getPath()
+               current_sel_flags = current.flags
                inBouquetRootList = current_root and current_root.getPath().find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
                inBouquet = csel.getMutableList() is not None
                haveBouquets = config.usage.multibouquet.value
 
-               if not csel.bouquet_mark_edit and not csel.movemode:
+               if not (len(current_sel_path) or current_sel_flags & (eServiceReference.isDirectory|eServiceReference.isMarker)):
+                       apend_when_current_valid(current, menu, (_("show transponder info"), self.showServiceInformations))
+               if csel.bouquet_mark_edit == OFF and not csel.movemode:
                        if not inBouquetRootList:
-                               if (csel.getCurrentSelection().flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory:
+                               isPlayable = not (current_sel_flags & (eServiceReference.isMarker|eServiceReference.isDirectory))
+                               if isPlayable:
                                        if config.ParentalControl.configured.value:
                                                if parentalControl.getProtectionLevel(csel.getCurrentSelection().toCompareString()) == -1:
-                                                       menu.append((_("add to parental protection"), boundFunction(self.addParentalProtection, csel.getCurrentSelection())))
+                                                       apend_when_current_valid(current, menu, (_("add to parental protection"), boundFunction(self.addParentalProtection, csel.getCurrentSelection())))
                                                else:
-                                                       menu.append((_("remove from parental protection"), boundFunction(self.removeParentalProtection, csel.getCurrentSelection())))
+                                                       apend_when_current_valid(current, menu, (_("remove from parental protection"), boundFunction(self.removeParentalProtection, csel.getCurrentSelection())))
                                        if haveBouquets:
-                                               menu.append((_("add service to bouquet"), self.addServiceToBouquetSelected))
+                                               apend_when_current_valid(current, menu, (_("add service to bouquet"), self.addServiceToBouquetSelected))
                                        else:
-                                               menu.append((_("add service to favourites"), self.addServiceToBouquetSelected))
+                                               apend_when_current_valid(current, menu, (_("add service to favourites"), self.addServiceToBouquetSelected))
                                else:
                                        if haveBouquets:
                                                if not inBouquet and current_sel_path.find("PROVIDERS") == -1:
-                                                       menu.append((_("copy to bouquets"), self.copyCurrentToBouquetList))
+                                                       apend_when_current_valid(current, menu, (_("copy to bouquets"), self.copyCurrentToBouquetList))
                                        if current_sel_path.find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
-                                               menu.append((_("remove all new found flags"), self.removeAllNewFoundFlags))
+                                               apend_when_current_valid(current, menu, (_("remove all new found flags"), self.removeAllNewFoundFlags))
                                if inBouquet:
-                                       menu.append((_("remove entry"), self.removeCurrentService))
-                               if current_root is not None and current_root.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
-                                       menu.append((_("remove new found flag"), self.removeNewFoundFlag))
+                                       apend_when_current_valid(current, menu, (_("remove entry"), self.removeCurrentService))
+                               if current_root and current_root.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
+                                       apend_when_current_valid(current, menu, (_("remove new found flag"), self.removeNewFoundFlag))
                        else:
                                        menu.append((_("add bouquet"), self.showBouquetInputBox))
-                                       menu.append((_("remove entry"), self.removeBouquet))
+                                       apend_when_current_valid(current, menu, (_("remove entry"), self.removeBouquet))
 
                if inBouquet: # current list is editable?
-                       if not csel.bouquet_mark_edit:
+                       if csel.bouquet_mark_edit == OFF:
                                if not csel.movemode:
-                                       menu.append((_("add marker"), self.showMarkerInputBox))
-                                       menu.append((_("enable move mode"), self.toggleMoveMode))
-                                       if not inBouquetRootList:
+                                       apend_when_current_valid(current, menu, (_("enable move mode"), self.toggleMoveMode))
+                                       if not inBouquetRootList and current_root and not (current_root.flags & eServiceReference.isGroup):
+                                               menu.append((_("add marker"), self.showMarkerInputBox))
                                                if haveBouquets:
-                                                       menu.append((_("enable bouquet edit"), self.bouquetMarkStart))
+                                                       apend_when_current_valid(current, menu, (_("enable bouquet edit"), self.bouquetMarkStart))
                                                else:
-                                                       menu.append((_("enable favourite edit"), self.bouquetMarkStart))
+                                                       apend_when_current_valid(current, menu, (_("enable favourite edit"), self.bouquetMarkStart))
+                                               if current_sel_flags & eServiceReference.isGroup:
+                                                       apend_when_current_valid(current, menu, (_("edit alternatives"), self.editAlternativeServices))
+                                                       apend_when_current_valid(current, menu, (_("show alternatives"), self.showAlternativeServices))
+                                                       apend_when_current_valid(current, menu, (_("remove all alternatives"), self.removeAlternativeServices))
+                                               elif not current_sel_flags & eServiceReference.isMarker:
+                                                       apend_when_current_valid(current, menu, (_("add alternatives"), self.addAlternativeServices))
                                else:
-                                       menu.append((_("disable move mode"), self.toggleMoveMode))
-                       elif not inBouquetRootList:
-                               if haveBouquets:
-                                       menu.append((_("end bouquet edit"), self.bouquetMarkEnd))
-                                       menu.append((_("abort bouquet edit"), self.bouquetMarkAbort))
+                                       apend_when_current_valid(current, menu, (_("disable move mode"), self.toggleMoveMode))
+                       else:
+                               if csel.bouquet_mark_edit == EDIT_BOUQUET:
+                                       if haveBouquets:
+                                               apend_when_current_valid(current, menu, (_("end bouquet edit"), self.bouquetMarkEnd))
+                                               apend_when_current_valid(current, menu, (_("abort bouquet edit"), self.bouquetMarkAbort))
+                                       else:
+                                               apend_when_current_valid(current, menu, (_("end favourites edit"), self.bouquetMarkEnd))
+                                               apend_when_current_valid(current, menu, (_("abort favourites edit"), self.bouquetMarkAbort))
                                else:
-                                       menu.append((_("end favourites edit"), self.bouquetMarkEnd))
-                                       menu.append((_("abort favourites edit"), self.bouquetMarkAbort))
+                                               apend_when_current_valid(current, menu, (_("end alternatives edit"), self.bouquetMarkEnd))
+                                               apend_when_current_valid(current, menu, (_("abort alternatives edit"), self.bouquetMarkAbort))
 
                menu.append((_("back"), self.cancelClick))
                self["menu"] = MenuList(menu)
@@ -130,7 +155,10 @@ class ChannelContextMenu(Screen):
 
        def cancelClick(self):
                self.close(False)
-               
+
+       def showServiceInformations(self):
+               self.session.open( ServiceInfo, self.csel.getCurrentSelection() )
+
        def showBouquetInputBox(self):
                self.session.openWithCallback(self.bouquetInputCallback, InputBox, title=_("Please enter a name for the new bouquet"), text="bouquetname", maxSize=False, type=Input.TEXT)
 
@@ -201,7 +229,7 @@ class ChannelContextMenu(Screen):
                self.close()
 
        def bouquetMarkStart(self):
-               self.csel.startMarkedEdit()
+               self.csel.startMarkedEdit(EDIT_BOUQUET)
                self.close()
 
        def bouquetMarkEnd(self):
@@ -227,6 +255,23 @@ class ChannelContextMenu(Screen):
                                eDVBDB.getInstance().removeFlags(FLAG_SERVICE_NEW_FOUND, -1, -1, -1, satpos)
                self.close()
 
+       def editAlternativeServices(self):
+               self.csel.startMarkedEdit(EDIT_ALTERNATIVES)
+               self.close()
+
+       def showAlternativeServices(self):
+               self.csel.enterPath(self.csel.getCurrentSelection())
+               self.close()
+
+       def removeAlternativeServices(self):
+               self.csel.removeAlternativeServices()
+               self.close()
+
+       def addAlternativeServices(self):
+               self.csel.addAlternativeServices()
+               self.csel.startMarkedEdit(EDIT_ALTERNATIVES)
+               self.close()
+
 class ChannelSelectionEPG:
        def __init__(self):
                self["ChannelSelectEPGActions"] = ActionMap(["ChannelSelectEPGActions"],
@@ -246,7 +291,7 @@ class ChannelSelectionEdit:
        def __init__(self):
                self.entry_marked = False
                self.movemode = False
-               self.bouquet_mark_edit = False
+               self.bouquet_mark_edit = OFF
                self.mutableList = None
                self.__marked = [ ]
                self.saved_title = None
@@ -310,6 +355,39 @@ class ChannelSelectionEdit:
                                break
                        cnt+=1
 
+       def addAlternativeServices(self):
+               cur_service = ServiceReference(self.getCurrentSelection())
+               root = self.getRoot()
+               cur_root = root and ServiceReference(root)
+               mutableBouquet = cur_root.list().startEdit()
+               if mutableBouquet:
+                       name = cur_service.getServiceName()
+                       print "NAME", name
+                       if self.mode == MODE_TV:
+                               str = '1:134:1:0:0:0:0:0:0:0:FROM BOUQUET \"alternatives.%s.tv\" ORDER BY bouquet'%(self.buildBouquetID(name))
+                       else:
+                               str = '1:134:2:0:0:0:0:0:0:0:FROM BOUQUET \"alternatives.%s.radio\" ORDER BY bouquet'%(self.buildBouquetID(name))
+                       new_ref = ServiceReference(str)
+                       if not mutableBouquet.addService(new_ref.ref, cur_service.ref):
+                               mutableBouquet.removeService(cur_service.ref)
+                               mutableBouquet.flushChanges()
+                               eDVBDB.getInstance().reloadBouquets()
+                               mutableAlternatives = new_ref.list().startEdit()
+                               if mutableAlternatives:
+                                       mutableAlternatives.setListName(name)
+                                       if mutableAlternatives.addService(cur_service.ref):
+                                               print "add", cur_service.toString(), "to new alternatives failed"
+                                       mutableAlternatives.flushChanges()
+                                       self.servicelist.addService(new_ref.ref, True)
+                                       self.servicelist.removeCurrent()
+                                       self.servicelist.moveUp()
+                               else:
+                                       print "get mutable list for new created alternatives failed"
+                       else:
+                               print "add", str, "to", cur_root.getServiceName(), "failed"
+               else:
+                       print "bouquetlist is not editable"
+
        def addBouquet(self, bName, services):
                serviceHandler = eServiceCenter.getInstance()
                mutableBouquetList = serviceHandler.list(self.bouquet_root).startEdit()
@@ -336,8 +414,8 @@ class ChannelSelectionEdit:
                                        print "get mutable list for new created bouquet failed"
                                # do some voodoo to check if current_root is equal to bouquet_root
                                cur_root = self.getRoot();
-                               str1 = cur_root.toString()
-                               pos1 = str1.find("FROM BOUQUET")
+                               str1 = cur_root and cur_root.toString()
+                               pos1 = str1 and str1.find("FROM BOUQUET") or -1
                                pos2 = self.bouquet_rootstr.find("FROM BOUQUET")
                                if pos1 != -1 and pos2 != -1 and str1[pos1:] == self.bouquet_rootstr[pos2:]:
                                        self.servicelist.addService(new_bouquet_ref)
@@ -353,8 +431,29 @@ class ChannelSelectionEdit:
                services = serviceHandler.list(provider.ref)
                self.addBouquet(providerName, services and services.getContent('R', True))
 
+       def removeAlternativeServices(self):
+               cur_service = ServiceReference(self.getCurrentSelection())
+               root = self.getRoot()
+               cur_root = root and ServiceReference(root)
+               list = cur_service.list()
+               first_in_alternative = list and list.getNext()
+               if first_in_alternative:
+                       edit_root = cur_root and cur_root.list().startEdit()
+                       if edit_root:
+                               if not edit_root.addService(first_in_alternative, cur_service.ref):
+                                       self.servicelist.addService(first_in_alternative, True)
+                               else:
+                                       print "couldn't add first alternative service to current root"
+                       else:
+                               print "couldn't edit current root!!"
+               else:
+                       print "remove empty alternative list !!"
+               self.removeBouquet()
+               self.servicelist.moveUp()
+
        def removeBouquet(self):
                refstr = self.getCurrentSelection().toString()
+               print "removeBouquet", refstr
                self.bouquetNumOffsetCache = { }
                pos = refstr.find('FROM BOUQUET "')
                filename = None
@@ -371,23 +470,29 @@ class ChannelSelectionEdit:
                        print "error during remove of", filename
 
 #  multiple marked entry stuff ( edit mode, later multiepg selection )
-       def startMarkedEdit(self):
+       def startMarkedEdit(self, type):
+               self.savedPath = self.servicePath[:]
+               if type == EDIT_ALTERNATIVES:
+                       self.enterPath(self.getCurrentSelection())
                self.mutableList = self.getMutableList()
                # add all services from the current list to internal marked set in listboxservicecontent
                self.clearMarks() # this clears the internal marked set in the listboxservicecontent
                self.saved_title = self.instance.getTitle()
                pos = self.saved_title.find(')')
                new_title = self.saved_title[:pos+1]
-               if config.usage.multibouquet.value:
-                       new_title += ' ' + _("[bouquet edit]")
+               if type == EDIT_ALTERNATIVES:
+                       self.bouquet_mark_edit = EDIT_ALTERNATIVES
+                       new_title += ' ' + _("[alternative edit]")
                else:
-                       new_title += ' ' + _("[favourite edit]")
+                       self.bouquet_mark_edit = EDIT_BOUQUET
+                       if config.usage.multibouquet.value:
+                               new_title += ' ' + _("[bouquet edit]")
+                       else:
+                               new_title += ' ' + _("[favourite edit]")
                self.setTitle(new_title)
-               self.bouquet_mark_edit = True
                self.__marked = self.servicelist.getRootServices()
                for x in self.__marked:
                        self.servicelist.addMarked(eServiceReference(x))
-               self.savedPath = self.servicePath[:]
                self.showAllServices()
 
        def endMarkedEdit(self, abort):
@@ -408,7 +513,7 @@ class ChannelSelectionEdit:
                                self.mutableList.flushChanges()
                self.__marked = []
                self.clearMarks()
-               self.bouquet_mark_edit = False
+               self.bouquet_mark_edit = OFF
                self.mutableList = None
                self.setTitle(self.saved_title)
                self.saved_title = None
@@ -448,7 +553,7 @@ class ChannelSelectionEdit:
                                mutableList.flushChanges()
                                # do some voodoo to check if current_root is equal to dest
                                cur_root = self.getRoot();
-                               str1 = cur_root.toString()
+                               str1 = cur_root and cur_root.toString() or -1
                                str2 = dest.toString()
                                pos1 = str1.find("FROM BOUQUET")
                                pos2 = str2.find("FROM BOUQUET")
@@ -465,7 +570,8 @@ class ChannelSelectionEdit:
                        self.mutableList = None
                        self.setTitle(self.saved_title)
                        self.saved_title = None
-                       if self.getRoot() == self.bouquet_root:
+                       cur_root = self.getRoot()
+                       if cur_root and cur_root == self.bouquet_root:
                                self.bouquetNumOffsetCache = { }
                else:
                        self.mutableList = self.getMutableList()
@@ -481,7 +587,7 @@ class ChannelSelectionEdit:
                if self.movemode: #movemode active?
                        self.channelSelected() # unmark
                        self.toggleMoveMode() # disable move mode
-               elif self.bouquet_mark_edit:
+               elif self.bouquet_mark_edit != OFF:
                        self.endMarkedEdit(True) # abort edit mode
 
        def toggleMoveMarked(self):
@@ -550,17 +656,9 @@ class ChannelSelectionBase(Screen):
                        })
                self.recallBouquetMode()
 
-       def appendDVBTypes(self, ref):
-               path = ref.getPath()
-               pos = path.find(' FROM BOUQUET')
-               if pos != -1:
-                       return eServiceReference(self.service_types + path[pos:])
-               return ref
-
        def getBouquetNumOffset(self, bouquet):
                if not config.usage.multibouquet.value:
                        return 0
-               bouquet = self.appendDVBTypes(bouquet)
                str = bouquet.toString()
                offsetCount = 0
                if not self.bouquetNumOffsetCache.has_key(str):
@@ -568,11 +666,11 @@ class ChannelSelectionBase(Screen):
                        bouquetlist = serviceHandler.list(self.bouquet_root)
                        if not bouquetlist is None:
                                while True:
-                                       bouquetIterator = self.appendDVBTypes(bouquetlist.getNext())
+                                       bouquetIterator = bouquetlist.getNext()
                                        if not bouquetIterator.valid(): #end of list
                                                break
                                        self.bouquetNumOffsetCache[bouquetIterator.toString()]=offsetCount
-                                       if ((bouquetIterator.flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory):
+                                       if not (bouquetIterator.flags & eServiceReference.isDirectory):
                                                continue
                                        servicelist = serviceHandler.list(bouquetIterator)
                                        if not servicelist is None:
@@ -580,22 +678,22 @@ class ChannelSelectionBase(Screen):
                                                        serviceIterator = servicelist.getNext()
                                                        if not serviceIterator.valid(): #check if end of list
                                                                break
-                                                       if serviceIterator.flags: #playable services have no flags
-                                                               continue
-                                                       offsetCount += 1
+                                                       playable = not (serviceIterator.flags & (eServiceReference.isDirectory|eServiceReference.isMarker))
+                                                       if playable:
+                                                               offsetCount += 1
                return self.bouquetNumOffsetCache.get(str, offsetCount)
 
        def recallBouquetMode(self):
                if self.mode == MODE_TV:
                        self.service_types = service_types_tv
                        if config.usage.multibouquet.value:
-                               self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET "bouquets.tv" ORDER BY bouquet'
+                               self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "bouquets.tv" ORDER BY bouquet'
                        else:
                                self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.tv" ORDER BY bouquet'%(self.service_types)
                else:
                        self.service_types = service_types_radio
                        if config.usage.multibouquet.value:
-                               self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET "bouquets.radio" ORDER BY bouquet'
+                               self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "bouquets.radio" ORDER BY bouquet'
                        else:
                                self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.radio" ORDER BY bouquet'%(self.service_types)
                self.bouquet_root = eServiceReference(self.bouquet_rootstr)
@@ -625,13 +723,11 @@ class ChannelSelectionBase(Screen):
        def setRoot(self, root, justSet=False):
                path = root.getPath()
                inBouquetRootList = path.find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
-               pos = path.find(' FROM BOUQUET')
-               isBouquet = pos != -1
+               pos = path.find('FROM BOUQUET')
+               isBouquet = (pos != -1) and (root.flags & eServiceReference.isDirectory)
                if not inBouquetRootList and isBouquet:
                        self.servicelist.setMode(ServiceList.MODE_FAVOURITES)
                        self.servicelist.setNumberOffset(self.getBouquetNumOffset(root))
-                       refstr = self.service_types + path[pos:]
-                       root = eServiceReference(refstr)
                else:
                        self.servicelist.setMode(ServiceList.MODE_NORMAL)
                self.servicelist.setRoot(root, justSet)
@@ -872,9 +968,7 @@ class ChannelSelectionBase(Screen):
                                        s = list.getNext()
                                        if not s.valid():
                                                break
-                                       if (s.flags & eServiceReference.isGroup):
-                                               continue
-                                       if (s.flags & eServiceReference.flagDirectory) == eServiceReference.flagDirectory:
+                                       if s.flags & eServiceReference.isDirectory:
                                                info = serviceHandler.info(s)
                                                if info:
                                                        bouquets.append((info.getName(s), s))
@@ -886,21 +980,6 @@ class ChannelSelectionBase(Screen):
                        return bouquets
                return None
 
-       def getGroupList(self):
-               groups = [ ]
-               serviceHandler = eServiceCenter.getInstance()
-               list = serviceHandler.list(self.bouquet_root)
-               if list:
-                       while True:
-                               s = list.getNext()
-                               if not s.valid():
-                                       break
-                               if (s.flags & eServiceReference.isGroup) and (s.flags & eServiceReference.flagDirectory) == eServiceReference.flagDirectory:
-                                       info = serviceHandler.info(s)
-                                       if info:
-                                               groups.append((info.getName(s), s))
-               return groups
-
        def keyNumber0(self, num):
                if len(self.servicePath) > 1:
                        self.keyGoUp()
@@ -972,6 +1051,10 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                self.lastservice = config.tv.lastservice
                self.lastroot = config.tv.lastroot
                self.revertMode = None
+               config.usage.multibouquet.addNotifier(self.multibouquet_config_changed)
+
+       def multibouquet_config_changed(self, val):
+               self.recallBouquetMode()
 
        def __evServiceStart(self):
                service = self.session.nav.getCurrentService()
@@ -1029,11 +1112,14 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                        self.toggleMoveMarked()
                elif (ref.flags & 7) == 7:
                        self.enterPath(ref)
-               elif self.bouquet_mark_edit:
-                       self.doMark()
-               elif not (ref.flags & 64): # no marker
-                       self.zap()
-                       self.close(ref)
+               elif self.bouquet_mark_edit != OFF:
+                       if not (self.bouquet_mark_edit == EDIT_ALTERNATIVES and ref.flags & eServiceReference.isGroup):
+                               self.doMark()
+               elif not (ref.flags & eServiceReference.isMarker): # no marker
+                       root = self.getRoot()
+                       if not root or not (root.flags & eServiceReference.isGroup):
+                               self.zap()
+                               self.close(ref)
 
        #called from infoBar and channelSelected
        def zap(self):
@@ -1043,7 +1129,7 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                if ref is None or ref != nref:
                        self.session.nav.playService(nref)
                        self.saveRoot()
-                       self.saveChannel()
+                       self.saveChannel(nref)
                        config.servicelist.lastmode.save()
                        self.addToHistory(nref)
 
@@ -1082,11 +1168,12 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                self.saveRoot()
                plen = len(path)
                root = path[plen-1]
-               if self.getRoot() != root:
+               cur_root = self.getRoot()
+               if cur_root and cur_root != root:
                        self.setRoot(root)
                self.session.nav.playService(ref)
                self.setCurrentSelection(ref)
-               self.saveChannel()
+               self.saveChannel(ref)
 
        def saveRoot(self):
                path = ''
@@ -1123,8 +1210,7 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                                return True
                return False
 
-       def saveChannel(self):
-               ref = self.session.nav.getCurrentlyPlayingServiceReference()
+       def saveChannel(self, ref):
                if ref is not None:
                        refstr = ref.toString()
                else:
@@ -1173,32 +1259,32 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                self.revertMode = None
                self.close(None)
 
-from Screens.InfoBarGenerics import InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord, InfoBarRadioText
+from Screens.InfoBarGenerics import InfoBarEvent, InfoBarServiceName
 
-class RadioInfoBar(Screen, InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord):
+class RadioInfoBar(Screen, InfoBarEvent, InfoBarServiceName):
        def __init__(self, session):
                Screen.__init__(self, session)
                InfoBarEvent.__init__(self)
                InfoBarServiceName.__init__(self)
-               InfoBarInstantRecord.__init__(self)
                self["CurrentTime"] = Clock()
+               self["RdsDecoder"] = RdsDecoder(self.session.nav)
+               self["BlinkingPoint"] = BlinkingPixmapConditional()
+               self["BlinkingPoint"].hide()
 
-class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG, InfoBarRadioText):
-
+class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG):
        ALLOW_SUSPEND = True
 
-       def __init__(self, session):
+       def __init__(self, session, infobar):
                ChannelSelectionBase.__init__(self, session)
                ChannelSelectionEdit.__init__(self)
                ChannelSelectionEPG.__init__(self)
-               InfoBarRadioText.__init__(self)
-
+               self.infobar = infobar
                config.radio = ConfigSubsection();
                config.radio.lastservice = ConfigText()
                config.radio.lastroot = ConfigText()
                self.onLayoutFinish.append(self.onCreate)
 
-               self.info = session.instantiateDialog(RadioInfoBar)
+               self.info = session.instantiateDialog(RadioInfoBar) # our simple infobar
 
                self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
                        {
@@ -1214,6 +1300,37 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS
                                iPlayableService.evEnd: self.__evServiceEnd
                        })
 
+########## RDS Radiotext / Rass Support BEGIN
+               self.infobar = infobar # reference to real infobar (the one and only)
+               self["RdsDecoder"] = self.info["RdsDecoder"]
+               self["RdsActions"] = HelpableActionMap(self, "InfobarRdsActions",
+               {
+                       "startRassInteractive": (self.startRassInteractive, _("View Rass interactive..."))
+               },-1)
+               self["RdsActions"].setEnabled(False)
+               infobar.rds_display.onRassInteractivePossibilityChanged.append(self.RassInteractivePossibilityChanged)
+
+       def startRassInteractive(self):
+               self.info.hide();
+               self.infobar.rass_interactive = self.session.openWithCallback(self.RassInteractiveClosed, RassInteractive)
+
+       def RassInteractiveClosed(self):
+               self.info.show()
+               self.infobar.rass_interactive = None
+               self.infobar.RassSlidePicChanged()
+
+       def RassInteractivePossibilityChanged(self, state):
+               self["RdsActions"].setEnabled(state)
+########## RDS Radiotext / Rass Support END
+
+       def closeRadio(self):
+               self.infobar.rds_display.onRassInteractivePossibilityChanged.remove(self.RassInteractivePossibilityChanged)
+               self.info.hide()
+               #set previous tv service
+               lastservice=eServiceReference(config.tv.lastservice.value)
+               self.session.nav.playService(lastservice)
+               self.close(None)
+
        def __evServiceStart(self):
                service = self.session.nav.getCurrentService()
                if service:
@@ -1275,22 +1392,18 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS
                        self.toggleMoveMarked()
                elif (ref.flags & 7) == 7:
                        self.enterPath(ref)
-               elif self.bouquet_mark_edit:
-                       self.doMark()
-               elif not (ref.flags & 64): # no marker
-                       playingref = self.session.nav.getCurrentlyPlayingServiceReference()
-                       if playingref is None or playingref != ref:
-                               self.session.nav.playService(ref)
-                               config.radio.lastservice.value = ref.toString()
-                               config.radio.lastservice.save()
-                       self.saveRoot()
-
-       def closeRadio(self):
-               self.info.hide()
-               #set previous tv service
-               lastservice=eServiceReference(config.tv.lastservice.value)
-               self.session.nav.playService(lastservice)
-               self.close(None)
+               elif self.bouquet_mark_edit != OFF:
+                       if not (self.bouquet_mark_edit == EDIT_ALTERNATIVES and ref.flags & eServiceReference.isGroup):
+                               self.doMark()
+               elif not (ref.flags & eServiceReference.isMarker): # no marker
+                       cur_root = self.getRoot()
+                       if not cur_root or not (cur_root.flags & eServiceReference.isGroup):
+                               playingref = self.session.nav.getCurrentlyPlayingServiceReference()
+                               if playingref is None or playingref != ref:
+                                       self.session.nav.playService(ref)
+                                       config.radio.lastservice.value = ref.toString()
+                                       config.radio.lastservice.save()
+                               self.saveRoot()
 
 class SimpleChannelSelection(ChannelSelectionBase):
        def __init__(self, session, title):
@@ -1314,7 +1427,7 @@ class SimpleChannelSelection(ChannelSelectionBase):
                ref = self.getCurrentSelection()
                if (ref.flags & 7) == 7:
                        self.enterPath(ref)
-               elif not (ref.flags & 64):
+               elif not (ref.flags & eServiceReference.isMarker):
                        ref = self.getCurrentSelection()
                        self.close(ref)