add "show transponder" info to service context menu in channellist
[vuplus_dvbapp] / lib / python / Screens / ChannelSelection.py
index 14721d3..db2789d 100644 (file)
@@ -3,8 +3,9 @@ from Components.Button import Button
 from Components.ServiceList import ServiceList
 from Components.ActionMap import NumberActionMap, ActionMap
 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
+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
@@ -14,6 +15,7 @@ from Components.Input import Input
 from Components.ParentalControl import parentalControl
 from Screens.InputBox import InputBox, PinInput
 from Screens.MessageBox import MessageBox
+from Screens.ServiceInfo import ServiceInfo
 from ServiceReference import ServiceReference
 from Tools.BoundFunction import boundFunction
 from re import *
@@ -55,6 +57,11 @@ class BouquetSelector(Screen):
        def cancelClick(self):
                self.close(False)
 
+# csel.bouquet_mark_edit values
+OFF = 0
+EDIT_BOUQUET = 1
+EDIT_ALTERNATIVES = 2
+
 class ChannelContextMenu(Screen):
        def __init__(self, session, csel):
                Screen.__init__(self, session)
@@ -75,9 +82,12 @@ class ChannelContextMenu(Screen):
                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):
+                       menu.append((_("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())))
@@ -90,7 +100,7 @@ class ChannelContextMenu(Screen):
                                else:
                                        if haveBouquets:
                                                if not inBouquet and current_sel_path.find("PROVIDERS") == -1:
-                                                       menu.append((_("copy to favourites"), self.copyCurrentToBouquetList))
+                                                       menu.append((_("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))
                                if inBouquet:
@@ -102,24 +112,34 @@ class ChannelContextMenu(Screen):
                                        menu.append((_("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:
+                                       if not inBouquetRootList and not current_root.flags & eServiceReference.isGroup:
+                                               menu.append((_("add marker"), self.showMarkerInputBox))
                                                if haveBouquets:
                                                        menu.append((_("enable bouquet edit"), self.bouquetMarkStart))
                                                else:
                                                        menu.append((_("enable favourite edit"), self.bouquetMarkStart))
+                                               if current_sel_flags & eServiceReference.isGroup:
+                                                       menu.append((_("edit alternatives"), self.editAlternativeServices))
+                                                       menu.append((_("show alternatives"), self.showAlternativeServices))
+                                                       menu.append((_("remove all alternatives"), self.removeAlternativeServices))
+                                               else:
+                                                       menu.append((_("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))
+                       else:
+                               if csel.bouquet_mark_edit == EDIT_BOUQUET:
+                                       if haveBouquets:
+                                               menu.append((_("end bouquet edit"), self.bouquetMarkEnd))
+                                               menu.append((_("abort bouquet edit"), self.bouquetMarkAbort))
+                                       else:
+                                               menu.append((_("end favourites edit"), self.bouquetMarkEnd))
+                                               menu.append((_("abort favourites edit"), self.bouquetMarkAbort))
                                else:
-                                       menu.append((_("end favourites edit"), self.bouquetMarkEnd))
-                                       menu.append((_("abort favourites edit"), self.bouquetMarkAbort))
+                                               menu.append((_("end alternatives edit"), self.bouquetMarkEnd))
+                                               menu.append((_("abort alternatives edit"), self.bouquetMarkAbort))
 
                menu.append((_("back"), self.cancelClick))
                self["menu"] = MenuList(menu)
@@ -129,7 +149,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)
 
@@ -162,8 +185,6 @@ class ChannelContextMenu(Screen):
                        self.bsel = self.session.openWithCallback(self.bouquetSelClosed, BouquetSelector, bouquets, self.addCurrentServiceToBouquet)
                elif cnt == 1: # add to only one existing bouquet
                        self.addCurrentServiceToBouquet(bouquets[0][1])
-               else: #no bouquets in root.. so assume only one favourite list is used
-                       self.addCurrentServiceToBouquet(self.csel.bouquet_root)
 
        def bouquetSelClosed(self, recursive):
                self.bsel = None
@@ -187,7 +208,7 @@ class ChannelContextMenu(Screen):
                self.close()
 
        def addCurrentServiceToBouquet(self, dest):
-               self.csel.addCurrentServiceToBouquet(dest)
+               self.csel.addServiceToBouquet(dest)
                if self.bsel is not None:
                        self.bsel.close(True)
                else:
@@ -202,7 +223,7 @@ class ChannelContextMenu(Screen):
                self.close()
 
        def bouquetMarkStart(self):
-               self.csel.startMarkedEdit()
+               self.csel.startMarkedEdit(EDIT_BOUQUET)
                self.close()
 
        def bouquetMarkEnd(self):
@@ -228,6 +249,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"],
@@ -247,7 +285,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
@@ -311,6 +349,38 @@ class ChannelSelectionEdit:
                                break
                        cnt+=1
 
+       def addAlternativeServices(self):
+               cur_service = ServiceReference(self.getCurrentSelection())
+               cur_root = ServiceReference(self.getRoot())
+               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:(type == 1) FROM BOUQUET \"alternatives.%s.tv\" ORDER BY bouquet'%(self.buildBouquetID(name))
+                       else:
+                               str = '1:134:2:0:0:0:0:0:0:0:(type == 2) 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()
@@ -323,7 +393,6 @@ class ChannelSelectionEdit:
                                str = '1:7:2:0:0:0:0:0:0:0:(type == 2) FROM BOUQUET \"userbouquet.%s.radio\" ORDER BY bouquet'%(self.buildBouquetID(bName))
                        new_bouquet_ref = eServiceReference(str)
                        if not mutableBouquetList.addService(new_bouquet_ref):
-                               self.bouquetNumOffsetCache = { }
                                mutableBouquetList.flushChanges()
                                eDVBDB.getInstance().reloadBouquets()
                                mutableBouquet = serviceHandler.list(new_bouquet_ref).startEdit()
@@ -333,13 +402,16 @@ class ChannelSelectionEdit:
                                                for service in services:
                                                        if mutableBouquet.addService(service):
                                                                print "add", service.toString(), "to new bouquet failed"
-                                                       else:
-                                                               current = self.servicelist.getCurrent()
-                                                               if current and current.toString() == self.bouquet_rootstr:
-                                                                       self.servicelist.addService(service, True)
                                        mutableBouquet.flushChanges()
                                else:
                                        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")
+                               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)
                        else:
                                print "add", str, "to bouquets failed"
                else:
@@ -352,10 +424,31 @@ class ChannelSelectionEdit:
                services = serviceHandler.list(provider.ref)
                self.addBouquet(providerName, services and services.getContent('R', True))
 
+       def removeAlternativeServices(self):
+               cur_service = ServiceReference(self.getCurrentSelection())
+               cur_root = ServiceReference(self.getRoot())
+               list = cur_service.list()
+               first_in_alternative = list and list.getNext()
+               if first_in_alternative:
+                       edit_root = 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
                if pos != -1:
                        refstr = refstr[pos+14:]
                        pos = refstr.find('"')
@@ -363,28 +456,35 @@ class ChannelSelectionEdit:
                                filename = '/etc/enigma2/' + refstr[:pos] # FIXMEEE !!! HARDCODED /etc/enigma2
                self.removeCurrentService()
                try:
-                       remove(filename)
+                       if filename is not None:
+                               remove(filename)
                except OSError:
                        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):
@@ -405,7 +505,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
@@ -435,19 +535,29 @@ class ChannelSelectionEdit:
                                mutableList.flushChanges() #FIXME dont flush on each single removed service
                                self.servicelist.removeCurrent()
 
-       def addCurrentServiceToBouquet(self, dest):
+       def addServiceToBouquet(self, dest, service=None):
                mutableList = self.getMutableList(dest)
                if not mutableList is None:
-                       if not mutableList.addService(self.servicelist.getCurrent()):
+                       if service is None: #use current selected service
+                               service = self.servicelist.getCurrent()
+                       if not mutableList.addService(service):
                                self.bouquetNumOffsetCache = { }
                                mutableList.flushChanges()
+                               # do some voodoo to check if current_root is equal to dest
+                               cur_root = self.getRoot();
+                               str1 = cur_root.toString()
+                               str2 = dest.toString()
+                               pos1 = str1.find("FROM BOUQUET")
+                               pos2 = str2.find("FROM BOUQUET")
+                               if pos1 != -1 and pos2 != -1 and str1[pos1:] == str2[pos2:]:
+                                       self.servicelist.addService(service)
 
        def toggleMoveMode(self):
                if self.movemode:
                        if self.entry_marked:
                                self.toggleMoveMarked() # unmark current entry
                        self.movemode = False
-                       self.pathChangedDisabled = False # re-enable path change
+                       self.pathChangeDisabled = False # re-enable path change
                        self.mutableList.flushChanges() # FIXME add check if changes was made
                        self.mutableList = None
                        self.setTitle(self.saved_title)
@@ -457,7 +567,7 @@ class ChannelSelectionEdit:
                else:
                        self.mutableList = self.getMutableList()
                        self.movemode = True
-                       self.pathChangedDisabled = True # no path change allowed in movemode
+                       self.pathChangeDisabled = True # no path change allowed in movemode
                        self.saved_title = self.instance.getTitle()
                        new_title = self.saved_title
                        pos = self.saved_title.find(')')
@@ -468,7 +578,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):
@@ -510,7 +620,7 @@ class ChannelSelectionBase(Screen):
 
                self.mode = MODE_TV
 
-               self.pathChangedDisabled = False
+               self.pathChangeDisabled = False
 
                self.bouquetNumOffsetCache = { }
 
@@ -545,13 +655,12 @@ class ChannelSelectionBase(Screen):
                return ref
 
        def getBouquetNumOffset(self, bouquet):
-               if config.usage.multibouquet.value:
+               if not config.usage.multibouquet.value:
                        return 0
                bouquet = self.appendDVBTypes(bouquet)
-               try:
-                       return self.bouquetNumOffsetCache[bouquet.toString()]
-               except:
-                       offsetCount = 0
+               str = bouquet.toString()
+               offsetCount = 0
+               if not self.bouquetNumOffsetCache.has_key(str):
                        serviceHandler = eServiceCenter.getInstance()
                        bouquetlist = serviceHandler.list(self.bouquet_root)
                        if not bouquetlist is None:
@@ -560,7 +669,7 @@ class ChannelSelectionBase(Screen):
                                        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:
@@ -568,10 +677,10 @@ 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
-               return self.bouquetNumOffsetCache.get(bouquet.toString(), offsetCount)
+                                                       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:
@@ -614,7 +723,7 @@ class ChannelSelectionBase(Screen):
                path = root.getPath()
                inBouquetRootList = path.find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
                pos = path.find(' FROM BOUQUET')
-               isBouquet = pos != -1
+               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))
@@ -709,7 +818,7 @@ class ChannelSelectionBase(Screen):
                return False
 
        def showAllServices(self):
-               if not self.pathChangedDisabled:
+               if not self.pathChangeDisabled:
                        refstr = '%s ORDER BY name'%(self.service_types)
                        if not self.preEnterPath(refstr):
                                ref = eServiceReference(refstr)
@@ -719,7 +828,7 @@ class ChannelSelectionBase(Screen):
                                        self.enterPath(ref)
 
        def showSatellites(self):
-               if not self.pathChangedDisabled:
+               if not self.pathChangeDisabled:
                        refstr = '%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types)
                        if not self.preEnterPath(refstr):
                                ref = eServiceReference(refstr)
@@ -773,7 +882,7 @@ class ChannelSelectionBase(Screen):
                                                        self.setCurrentSelection(prev)
 
        def showProviders(self):
-               if not self.pathChangedDisabled:
+               if not self.pathChangeDisabled:
                        refstr = '%s FROM PROVIDERS ORDER BY name'%(self.service_types)
                        if not self.preEnterPath(refstr):
                                ref = eServiceReference(refstr)
@@ -786,9 +895,14 @@ class ChannelSelectionBase(Screen):
                                                self.enterPath(ref)
 
        def changeBouquet(self, direction):
-               if not self.pathChangedDisabled:
-                       if self.isBasePathEqual(self.bouquet_root):
-                               self.pathUp()
+               if not self.pathChangeDisabled:
+                       if len(self.servicePath) > 1:
+                               #when enter satellite root list we must do some magic stuff..
+                               ref = eServiceReference('%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types))
+                               if self.isBasePathEqual(ref):
+                                       self.showSatellites()
+                               else:
+                                       self.pathUp()
                                if direction < 0:
                                        self.moveUp()
                                else:
@@ -812,7 +926,7 @@ class ChannelSelectionBase(Screen):
                self.changeBouquet(-1)
 
        def showFavourites(self):
-               if not self.pathChangedDisabled:
+               if not self.pathChangeDisabled:
                        if not self.preEnterPath(self.bouquet_rootstr):
                                if self.isBasePathEqual(self.bouquet_root):
                                        self.pathUp()
@@ -846,27 +960,25 @@ class ChannelSelectionBase(Screen):
                self.servicelist.setCurrent(service)
 
        def getBouquetList(self):
+               bouquets = [ ]
+               serviceHandler = eServiceCenter.getInstance()
                if config.usage.multibouquet.value:
-                       serviceCount=0
-                       bouquets = [ ]
-                       serviceHandler = eServiceCenter.getInstance()
                        list = serviceHandler.list(self.bouquet_root)
-                       if not list is None:
+                       if list:
                                while True:
                                        s = list.getNext()
                                        if not s.valid():
                                                break
-                                       if ((s.flags & eServiceReference.flagDirectory) == eServiceReference.flagDirectory):
+                                       if s.flags & eServiceReference.isDirectory:
                                                info = serviceHandler.info(s)
-                                               if not info is None:
+                                               if info:
                                                        bouquets.append((info.getName(s), s))
-                                       else:
-                                               serviceCount += 1
-                               if len(bouquets) == 0 and serviceCount > 0:
-                                       info = serviceHandler.info(self.bouquet_root)
-                                       if not info is None:
-                                               bouquets.append((info.getName(self.bouquet_root), self.bouquet_root))
                                return bouquets
+               else:
+                       info = serviceHandler.info(self.bouquet_root)
+                       if info:
+                               bouquets.append((info.getName(self.bouquet_root), self.bouquet_root))
+                       return bouquets
                return None
 
        def keyNumber0(self, num):
@@ -922,7 +1034,11 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                                "keyTV": self.setModeTv,
                        })
 
-               self.onShown.append(self.__onShown)
+               self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
+                       {
+                               iPlayableService.evStart: self.__evServiceStart,
+                               iPlayableService.evEnd: self.__evServiceEnd
+                       })
 
                self.lastChannelRootTimer = eTimer()
                self.lastChannelRootTimer.timeout.get().append(self.__onCreate)
@@ -936,6 +1052,21 @@ 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()
+               if service:
+                       info = service.info()
+                       if info:
+                               refstr = info.getInfoString(iServiceInformation.sServiceref)
+                               self.servicelist.setPlayableIgnoreService(eServiceReference(refstr))
+
+       def __evServiceEnd(self):
+               self.servicelist.setPlayableIgnoreService(eServiceReference())
 
        def setMode(self):
                self.restoreRoot()
@@ -976,25 +1107,19 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                if lastservice.valid():
                        self.zap()
 
-       def __onShown(self):
-               self.recallBouquetMode()
-               ref = self.session.nav.getCurrentlyPlayingServiceReference()
-               if ref is not None and ref.valid() and ref.getPath() == "":
-                       self.servicelist.setPlayableIgnoreService(ref)
-               else:
-                       self.servicelist.setPlayableIgnoreService(eServiceReference())
-
        def channelSelected(self):
                ref = self.getCurrentSelection()
                if self.movemode:
                        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
+                       if not (self.getRoot().flags & eServiceReference.isGroup):
+                               self.zap()
+                               self.close(ref)
 
        #called from infoBar and channelSelected
        def zap(self):
@@ -1004,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)
 
@@ -1047,7 +1172,7 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                        self.setRoot(root)
                self.session.nav.playService(ref)
                self.setCurrentSelection(ref)
-               self.saveChannel()
+               self.saveChannel(ref)
 
        def saveRoot(self):
                path = ''
@@ -1084,8 +1209,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:
@@ -1169,6 +1293,23 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS
                                "ok": self.channelSelected,
                        })
 
+               self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
+                       {
+                               iPlayableService.evStart: self.__evServiceStart,
+                               iPlayableService.evEnd: self.__evServiceEnd
+                       })
+
+       def __evServiceStart(self):
+               service = self.session.nav.getCurrentService()
+               if service:
+                       info = service.info()
+                       if info:
+                               refstr = info.getInfoString(iServiceInformation.sServiceref)
+                               self.servicelist.setPlayableIgnoreService(eServiceReference(refstr))
+
+       def __evServiceEnd(self):
+               self.servicelist.setPlayableIgnoreService(eServiceReference())
+
        def saveRoot(self):
                path = ''
                for i in self.servicePathRadio:
@@ -1211,7 +1352,6 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS
                if lastservice.valid():
                        self.servicelist.setCurrent(lastservice)
                        self.session.nav.playService(lastservice)
-                       self.servicelist.setPlayableIgnoreService(lastservice)
                self.info.show()
 
        def channelSelected(self): # just return selected service
@@ -1220,16 +1360,17 @@ 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)
-                               self.servicelist.setPlayableIgnoreService(ref)
-                               config.radio.lastservice.value = ref.toString()
-                               config.radio.lastservice.save()
-                       self.saveRoot()
+               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
+                       if not (self.getRoot().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()
 
        def closeRadio(self):
                self.info.hide()
@@ -1260,7 +1401,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)