fix possibility for bluescreen
[enigma2.git] / lib / python / Screens / ChannelSelection.py
index 905d4558ffb37956f55edf93fed8792eb479aa9a..e2dbd6b5e7eeeb6b24e9a93972d000bfeebf293e 100644 (file)
@@ -3,16 +3,21 @@ from Components.Button import Button
 from Components.ServiceList import ServiceList
 from Components.ActionMap import NumberActionMap, ActionMap
 from Components.MenuList import MenuList
 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 EpgSelection import EPGSelection
-from enigma import eServiceReference, eEPGCache, eEPGCachePtr, eServiceCenter, eServiceCenterPtr, iMutableServiceListPtr, iStaticServiceInformationPtr, eTimer, eDVBDB
-from Components.config import config, configElement, ConfigSubsection, configText, currentConfigSelectionElement
+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.Input import Input
 from Screens.FixedMenu import FixedMenu
 from Tools.NumericalTextInput import NumericalTextInput
 from Components.NimManager import nimmanager
 from Components.Sources.Clock import Clock
 from Components.Input import Input
-from Screens.InputBox import InputBox
+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 ServiceReference import ServiceReference
+from Tools.BoundFunction import boundFunction
 from re import *
 from os import remove
 
 from re import *
 from os import remove
 
@@ -52,6 +57,11 @@ class BouquetSelector(Screen):
        def cancelClick(self):
                self.close(False)
 
        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)
 class ChannelContextMenu(Screen):
        def __init__(self, session, csel):
                Screen.__init__(self, session)
@@ -70,11 +80,19 @@ class ChannelContextMenu(Screen):
                current_sel_flags = csel.getCurrentSelection().flags
                inBouquetRootList = current_root and current_root.getPath().find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
                inBouquet = csel.getMutableList() is not None
                current_sel_flags = csel.getCurrentSelection().flags
                inBouquetRootList = current_root and current_root.getPath().find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
                inBouquet = csel.getMutableList() is not None
-               haveBouquets = csel.bouquet_root.getPath().find('FROM BOUQUET "bouquets.') != -1
+               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 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())))
+                                               else:
+                                                       menu.append((_("remove from parental protection"), boundFunction(self.removeParentalProtection, csel.getCurrentSelection())))
                                        if haveBouquets:
                                                menu.append((_("add service to bouquet"), self.addServiceToBouquetSelected))
                                        else:
                                        if haveBouquets:
                                                menu.append((_("add service to bouquet"), self.addServiceToBouquetSelected))
                                        else:
@@ -82,35 +100,46 @@ class ChannelContextMenu(Screen):
                                else:
                                        if haveBouquets:
                                                if not inBouquet and current_sel_path.find("PROVIDERS") == -1:
                                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:
                                        if current_sel_path.find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
                                                menu.append((_("remove all new found flags"), self.removeAllNewFoundFlags))
                                if inBouquet:
-                                       menu.append((_("remove service"), self.removeCurrentService))
-                               if current_root.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
+                                       menu.append((_("remove entry"), self.removeCurrentService))
+                               if current_root and current_root.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
                                        menu.append((_("remove new found flag"), self.removeNewFoundFlag))
                                        menu.append((_("remove new found flag"), self.removeNewFoundFlag))
-                       elif haveBouquets:
-                               menu.append((_("remove bouquet"), self.removeBouquet))
+                       else:
+                                       menu.append((_("add bouquet"), self.showBouquetInputBox))
+                                       menu.append((_("remove entry"), self.removeBouquet))
 
                if inBouquet: # current list is editable?
 
                if inBouquet: # current list is editable?
-                       if not csel.bouquet_mark_edit:
+                       if csel.bouquet_mark_edit == OFF:
                                if not csel.movemode:
                                        menu.append((_("enable move mode"), self.toggleMoveMode))
                                if not csel.movemode:
                                        menu.append((_("enable move mode"), self.toggleMoveMode))
-                                       menu.append((_("add bouquet..."), self.showBouquetInputBox))
-                                       if not inBouquetRootList:
+                                       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))
                                                else:
                                                        menu.append((_("enable favourite edit"), self.bouquetMarkStart))
                                                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))
                                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:
                                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)
 
                menu.append((_("back"), self.cancelClick))
                self["menu"] = MenuList(menu)
@@ -120,13 +149,31 @@ class ChannelContextMenu(Screen):
 
        def cancelClick(self):
                self.close(False)
 
        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)
 
        def bouquetInputCallback(self, bouquet):
                if bouquet is not None:
        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)
 
        def bouquetInputCallback(self, bouquet):
                if bouquet is not None:
-                       self.csel.addBouquet(bouquet, None, True)
+                       self.csel.addBouquet(bouquet, None)
+               self.close()
+
+       def addParentalProtection(self, service):
+               parentalControl.protectService(service.toCompareString())
+               self.close()
+
+       def removeParentalProtection(self, service):
+               self.session.openWithCallback(boundFunction(self.pinEntered, service.toCompareString()), PinInput, pinList = [config.ParentalControl.servicepin[0].value], triesEntry = config.ParentalControl.retries.servicepin, title = _("Enter the service pin"), windowTitle = _("Change pin code"))
+
+       def pinEntered(self, service, result):
+               if result:
+                       parentalControl.unProtectService(service)
+                       self.close()
+               else:
+                       self.session.openWithCallback(self.close, MessageBox, _("The pin code you entered is wrong."), MessageBox.TYPE_ERROR)
 
        def addServiceToBouquetSelected(self):
                bouquets = self.csel.getBouquetList()
 
        def addServiceToBouquetSelected(self):
                bouquets = self.csel.getBouquetList()
@@ -138,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])
                        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
 
        def bouquetSelClosed(self, recursive):
                self.bsel = None
@@ -154,8 +199,16 @@ class ChannelContextMenu(Screen):
                self.csel.removeBouquet()
                self.close()
 
                self.csel.removeBouquet()
                self.close()
 
+       def showMarkerInputBox(self):
+               self.session.openWithCallback(self.markerInputCallback, InputBox, title=_("Please enter a name for the new marker"), text="markername", maxSize=False, type=Input.TEXT)
+
+       def markerInputCallback(self, marker):
+               if marker is not None:
+                       self.csel.addMarker(marker)
+               self.close()
+
        def addCurrentServiceToBouquet(self, dest):
        def addCurrentServiceToBouquet(self, dest):
-               self.csel.addCurrentServiceToBouquet(dest)
+               self.csel.addServiceToBouquet(dest)
                if self.bsel is not None:
                        self.bsel.close(True)
                else:
                if self.bsel is not None:
                        self.bsel.close(True)
                else:
@@ -170,7 +223,7 @@ class ChannelContextMenu(Screen):
                self.close()
 
        def bouquetMarkStart(self):
                self.close()
 
        def bouquetMarkStart(self):
-               self.csel.startMarkedEdit()
+               self.csel.startMarkedEdit(EDIT_BOUQUET)
                self.close()
 
        def bouquetMarkEnd(self):
                self.close()
 
        def bouquetMarkEnd(self):
@@ -196,6 +249,23 @@ class ChannelContextMenu(Screen):
                                eDVBDB.getInstance().removeFlags(FLAG_SERVICE_NEW_FOUND, -1, -1, -1, satpos)
                self.close()
 
                                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"],
 class ChannelSelectionEPG:
        def __init__(self):
                self["ChannelSelectEPGActions"] = ActionMap(["ChannelSelectEPGActions"],
@@ -215,7 +285,7 @@ class ChannelSelectionEdit:
        def __init__(self):
                self.entry_marked = False
                self.movemode = False
        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
                self.mutableList = None
                self.__marked = [ ]
                self.saved_title = None
@@ -261,7 +331,58 @@ class ChannelSelectionEdit:
                                name += '_'
                return name
 
                                name += '_'
                return name
 
-       def addBouquet(self, bName, services, refresh=False):
+       def addMarker(self, name):
+               current = self.servicelist.getCurrent()
+               mutableList = self.getMutableList()
+               cnt = 0
+               while mutableList:
+                       str = '1:64:%d:0:0:0:0:0:0:0::%s'%(cnt, name)
+                       ref = eServiceReference(str)
+                       if current and current.valid():
+                               if not mutableList.addService(ref, current):
+                                       self.servicelist.addService(ref, True)
+                                       mutableList.flushChanges()
+                                       break
+                       elif not mutableList.addService(ref):
+                               self.servicelist.addService(ref, True)
+                               mutableList.flushChanges()
+                               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:(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()
                if mutableBouquetList:
                serviceHandler = eServiceCenter.getInstance()
                mutableBouquetList = serviceHandler.list(self.bouquet_root).startEdit()
                if mutableBouquetList:
@@ -273,7 +394,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):
                                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()
                                mutableBouquetList.flushChanges()
                                eDVBDB.getInstance().reloadBouquets()
                                mutableBouquet = serviceHandler.list(new_bouquet_ref).startEdit()
@@ -284,10 +404,15 @@ class ChannelSelectionEdit:
                                                        if mutableBouquet.addService(service):
                                                                print "add", service.toString(), "to new bouquet failed"
                                        mutableBouquet.flushChanges()
                                                        if mutableBouquet.addService(service):
                                                                print "add", service.toString(), "to new bouquet failed"
                                        mutableBouquet.flushChanges()
-                                       if refresh:
-                                               self.setRoot(self.getRoot())
                                else:
                                        print "get mutable list for new created bouquet failed"
                                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 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)
                        else:
                                print "add", str, "to bouquets failed"
                else:
                        else:
                                print "add", str, "to bouquets failed"
                else:
@@ -300,10 +425,32 @@ class ChannelSelectionEdit:
                services = serviceHandler.list(provider.ref)
                self.addBouquet(providerName, services and services.getContent('R', True))
 
                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()
        def removeBouquet(self):
                refstr = self.getCurrentSelection().toString()
+               print "removeBouquet", refstr
                self.bouquetNumOffsetCache = { }
                pos = refstr.find('FROM BOUQUET "')
                self.bouquetNumOffsetCache = { }
                pos = refstr.find('FROM BOUQUET "')
+               filename = None
                if pos != -1:
                        refstr = refstr[pos+14:]
                        pos = refstr.find('"')
                if pos != -1:
                        refstr = refstr[pos+14:]
                        pos = refstr.find('"')
@@ -311,29 +458,35 @@ class ChannelSelectionEdit:
                                filename = '/etc/enigma2/' + refstr[:pos] # FIXMEEE !!! HARDCODED /etc/enigma2
                self.removeCurrentService()
                try:
                                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
                except OSError:
                        print "error during remove of", filename
-               eDVBDB.getInstance().reloadBouquets()
 
 #  multiple marked entry stuff ( edit mode, later multiepg selection )
 
 #  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]
                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 self.bouquet_root.getPath().find('FROM BOUQUET "bouquets.') != -1:
-                       new_title += ' ' + _("[bouquet edit]")
+               if type == EDIT_ALTERNATIVES:
+                       self.bouquet_mark_edit = EDIT_ALTERNATIVES
+                       new_title += ' ' + _("[alternative edit]")
                else:
                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.setTitle(new_title)
-               self.bouquet_mark_edit = True
                self.__marked = self.servicelist.getRootServices()
                for x in self.__marked:
                        self.servicelist.addMarked(eServiceReference(x))
                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):
                self.showAllServices()
 
        def endMarkedEdit(self, abort):
@@ -354,7 +507,7 @@ class ChannelSelectionEdit:
                                self.mutableList.flushChanges()
                self.__marked = []
                self.clearMarks()
                                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
                self.mutableList = None
                self.setTitle(self.saved_title)
                self.saved_title = None
@@ -382,31 +535,42 @@ class ChannelSelectionEdit:
                        if not mutableList.removeService(ref):
                                self.bouquetNumOffsetCache = { }
                                mutableList.flushChanges() #FIXME dont flush on each single removed service
                        if not mutableList.removeService(ref):
                                self.bouquetNumOffsetCache = { }
                                mutableList.flushChanges() #FIXME dont flush on each single removed service
-                               self.setRoot(self.getRoot())
+                               self.servicelist.removeCurrent()
 
 
-       def addCurrentServiceToBouquet(self, dest):
+       def addServiceToBouquet(self, dest, service=None):
                mutableList = self.getMutableList(dest)
                if not mutableList is 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()
                                self.bouquetNumOffsetCache = { }
                                mutableList.flushChanges()
+                               # do some voodoo to check if current_root is equal to dest
+                               cur_root = self.getRoot();
+                               str1 = cur_root and cur_root.toString() or -1
+                               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
 
        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)
                        self.saved_title = None
                        self.mutableList.flushChanges() # FIXME add check if changes was made
                        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()
                        self.movemode = True
                                self.bouquetNumOffsetCache = { }
                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(')')
                        self.saved_title = self.instance.getTitle()
                        new_title = self.saved_title
                        pos = self.saved_title.find(')')
@@ -417,7 +581,7 @@ class ChannelSelectionEdit:
                if self.movemode: #movemode active?
                        self.channelSelected() # unmark
                        self.toggleMoveMode() # disable move mode
                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):
                        self.endMarkedEdit(True) # abort edit mode
 
        def toggleMoveMarked(self):
@@ -434,14 +598,14 @@ class ChannelSelectionEdit:
 MODE_TV = 0
 MODE_RADIO = 1
 
 MODE_TV = 0
 MODE_RADIO = 1
 
+# this makes it much simple to implement a selectable radio or tv mode :)
+service_types_tv = '1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17) || (type == 195) || (type == 25)'
+service_types_radio = '1:7:2:0:0:0:0:0:0:0:(type == 2)'
+
 class ChannelSelectionBase(Screen):
        def __init__(self, session):
                Screen.__init__(self, session)
 
 class ChannelSelectionBase(Screen):
        def __init__(self, session):
                Screen.__init__(self, session)
 
-               # this makes it much simple to implement a selectable radio or tv mode :)
-               self.service_types_tv = '1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17) || (type == 195) || (type == 25)'
-               self.service_types_radio = '1:7:2:0:0:0:0:0:0:0:(type == 2)'
-
                self["key_red"] = Button(_("All"))
                self["key_green"] = Button(_("Satellites"))
                self["key_yellow"] = Button(_("Provider"))
                self["key_red"] = Button(_("All"))
                self["key_green"] = Button(_("Satellites"))
                self["key_yellow"] = Button(_("Provider"))
@@ -451,6 +615,7 @@ class ChannelSelectionBase(Screen):
                self.servicelist = self["list"]
 
                self.numericalTextInput = NumericalTextInput()
                self.servicelist = self["list"]
 
                self.numericalTextInput = NumericalTextInput()
+               self.numericalTextInput.setUseableChars(u'1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ')
 
                self.servicePathTV = [ ]
                self.servicePathRadio = [ ]
 
                self.servicePathTV = [ ]
                self.servicePathRadio = [ ]
@@ -458,7 +623,7 @@ class ChannelSelectionBase(Screen):
 
                self.mode = MODE_TV
 
 
                self.mode = MODE_TV
 
-               self.pathChangedDisabled = False
+               self.pathChangeDisabled = False
 
                self.bouquetNumOffsetCache = { }
 
 
                self.bouquetNumOffsetCache = { }
 
@@ -470,6 +635,8 @@ class ChannelSelectionBase(Screen):
                                "showSatellites": self.showSatellites,
                                "nextBouquet": self.nextBouquet,
                                "prevBouquet": self.prevBouquet,
                                "showSatellites": self.showSatellites,
                                "nextBouquet": self.nextBouquet,
                                "prevBouquet": self.prevBouquet,
+                               "nextMarker": self.nextMarker,
+                               "prevMarker": self.prevMarker,
                                "1": self.keyNumberGlobal,
                                "2": self.keyNumberGlobal,
                                "3": self.keyNumberGlobal,
                                "1": self.keyNumberGlobal,
                                "2": self.keyNumberGlobal,
                                "3": self.keyNumberGlobal,
@@ -481,6 +648,7 @@ class ChannelSelectionBase(Screen):
                                "9": self.keyNumberGlobal,
                                "0": self.keyNumber0
                        })
                                "9": self.keyNumberGlobal,
                                "0": self.keyNumber0
                        })
+               self.recallBouquetMode()
 
        def appendDVBTypes(self, ref):
                path = ref.getPath()
 
        def appendDVBTypes(self, ref):
                path = ref.getPath()
@@ -490,13 +658,12 @@ class ChannelSelectionBase(Screen):
                return ref
 
        def getBouquetNumOffset(self, bouquet):
                return ref
 
        def getBouquetNumOffset(self, bouquet):
-               if self.bouquet_root.getPath().find('FROM BOUQUET "bouquets.') == -1: #FIXME HACK
+               if not config.usage.multibouquet.value:
                        return 0
                bouquet = self.appendDVBTypes(bouquet)
                        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:
                        serviceHandler = eServiceCenter.getInstance()
                        bouquetlist = serviceHandler.list(self.bouquet_root)
                        if not bouquetlist is None:
@@ -505,7 +672,7 @@ class ChannelSelectionBase(Screen):
                                        if not bouquetIterator.valid(): #end of list
                                                break
                                        self.bouquetNumOffsetCache[bouquetIterator.toString()]=offsetCount
                                        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:
                                                continue
                                        servicelist = serviceHandler.list(bouquetIterator)
                                        if not servicelist is None:
@@ -513,21 +680,21 @@ class ChannelSelectionBase(Screen):
                                                        serviceIterator = servicelist.getNext()
                                                        if not serviceIterator.valid(): #check if end of list
                                                                break
                                                        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:
 
        def recallBouquetMode(self):
                if self.mode == MODE_TV:
-                       self.service_types = self.service_types_tv
-                       if currentConfigSelectionElement(config.usage.multibouquet) == "yes":
+                       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'
                        else:
                                self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.tv" ORDER BY bouquet'%(self.service_types)
                else:
                                self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:(type == 1) 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 = self.service_types_radio
-                       if currentConfigSelectionElement(config.usage.multibouquet) == "yes":
+                       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'
                        else:
                                self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.radio" ORDER BY bouquet'%(self.service_types)
                                self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET "bouquets.radio" ORDER BY bouquet'
                        else:
                                self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.radio" ORDER BY bouquet'%(self.service_types)
@@ -559,7 +726,7 @@ class ChannelSelectionBase(Screen):
                path = root.getPath()
                inBouquetRootList = path.find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
                pos = path.find(' FROM BOUQUET')
                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))
                if not inBouquetRootList and isBouquet:
                        self.servicelist.setMode(ServiceList.MODE_FAVOURITES)
                        self.servicelist.setNumberOffset(self.getBouquetNumOffset(root))
@@ -654,7 +821,7 @@ class ChannelSelectionBase(Screen):
                return False
 
        def showAllServices(self):
                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)
                        refstr = '%s ORDER BY name'%(self.service_types)
                        if not self.preEnterPath(refstr):
                                ref = eServiceReference(refstr)
@@ -664,7 +831,7 @@ class ChannelSelectionBase(Screen):
                                        self.enterPath(ref)
 
        def showSatellites(self):
                                        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)
                        refstr = '%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types)
                        if not self.preEnterPath(refstr):
                                ref = eServiceReference(refstr)
@@ -713,12 +880,12 @@ class ChannelSelectionBase(Screen):
                                                                        n = ("%s (%d.%d" + h + ")") % (service_name, orbpos / 10, orbpos % 10)
                                                                service.setName(n)
                                                        self.servicelist.addService(service)
                                                                        n = ("%s (%d.%d" + h + ")") % (service_name, orbpos / 10, orbpos % 10)
                                                                service.setName(n)
                                                        self.servicelist.addService(service)
-                                                       self.servicelist.finishFill()
-                                                       if prev is not None:
-                                                               self.setCurrentSelection(prev)
+                                               self.servicelist.finishFill()
+                                               if prev is not None:
+                                                       self.setCurrentSelection(prev)
 
        def showProviders(self):
 
        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)
                        refstr = '%s FROM PROVIDERS ORDER BY name'%(self.service_types)
                        if not self.preEnterPath(refstr):
                                ref = eServiceReference(refstr)
@@ -731,9 +898,14 @@ class ChannelSelectionBase(Screen):
                                                self.enterPath(ref)
 
        def changeBouquet(self, direction):
                                                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:
                                if direction < 0:
                                        self.moveUp()
                                else:
@@ -757,7 +929,7 @@ class ChannelSelectionBase(Screen):
                self.changeBouquet(-1)
 
        def showFavourites(self):
                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()
                        if not self.preEnterPath(self.bouquet_rootstr):
                                if self.isBasePathEqual(self.bouquet_root):
                                        self.pathUp()
@@ -768,8 +940,10 @@ class ChannelSelectionBase(Screen):
                                                self.enterPath(self.bouquet_root)
 
        def keyNumberGlobal(self, number):
                                                self.enterPath(self.bouquet_root)
 
        def keyNumberGlobal(self, number):
-               char = self.numericalTextInput.getKey(number)
-               self.servicelist.moveToChar(char)
+               unichar = self.numericalTextInput.getKey(number)
+               charstr = unichar.encode("utf-8")
+               if len(charstr) == 1:
+                       self.servicelist.moveToChar(charstr[0])
 
        def getRoot(self):
                return self.servicelist.getRoot()
 
        def getRoot(self):
                return self.servicelist.getRoot()
@@ -789,25 +963,24 @@ class ChannelSelectionBase(Screen):
                self.servicelist.setCurrent(service)
 
        def getBouquetList(self):
                self.servicelist.setCurrent(service)
 
        def getBouquetList(self):
-               serviceCount=0
                bouquets = [ ]
                serviceHandler = eServiceCenter.getInstance()
                bouquets = [ ]
                serviceHandler = eServiceCenter.getInstance()
-               list = serviceHandler.list(self.bouquet_root)
-               if not list is None:
-                       while True:
-                               s = list.getNext()
-                               if not s.valid():
-                                       break
-                               if ((s.flags & eServiceReference.flagDirectory) == eServiceReference.flagDirectory):
-                                       info = serviceHandler.info(s)
-                                       if not info is None:
-                                               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))
+               if config.usage.multibouquet.value:
+                       list = serviceHandler.list(self.bouquet_root)
+                       if list:
+                               while True:
+                                       s = list.getNext()
+                                       if not s.valid():
+                                               break
+                                       if s.flags & eServiceReference.isDirectory:
+                                               info = serviceHandler.info(s)
+                                               if info:
+                                                       bouquets.append((info.getName(s), s))
+                               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
 
                        return bouquets
                return None
 
@@ -832,17 +1005,23 @@ class ChannelSelectionBase(Screen):
                                        else:
                                                self.showAllServices()
 
                                        else:
                                                self.showAllServices()
 
+       def nextMarker(self):
+               self.servicelist.moveToNextMarker()
+
+       def prevMarker(self):
+               self.servicelist.moveToPrevMarker()
+
 HISTORYSIZE = 20
 
 #config for lastservice
 config.tv = ConfigSubsection()
 HISTORYSIZE = 20
 
 #config for lastservice
 config.tv = ConfigSubsection()
-config.tv.lastservice = configElement("config.tv.lastservice", configText, "", 0)
-config.tv.lastroot = configElement("config.tv.lastroot", configText, "", 0)
+config.tv.lastservice = ConfigText()
+config.tv.lastroot = ConfigText()
 config.radio = ConfigSubsection()
 config.radio = ConfigSubsection()
-config.radio.lastservice = configElement("config.radio.lastservice", configText, "", 0)
-config.radio.lastroot = configElement("config.radio.lastroot", configText, "", 0)
+config.radio.lastservice = ConfigText()
+config.radio.lastroot = ConfigText()
 config.servicelist = ConfigSubsection()
 config.servicelist = ConfigSubsection()
-config.servicelist.lastmode = configElement("config.servicelist.lastmode", configText, "tv", 0)
+config.servicelist.lastmode = ConfigText(default = "tv")
 
 class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG):
        def __init__(self, session):
 
 class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG):
        def __init__(self, session):
@@ -858,7 +1037,11 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                                "keyTV": self.setModeTv,
                        })
 
                                "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)
 
                self.lastChannelRootTimer = eTimer()
                self.lastChannelRootTimer.timeout.get().append(self.__onCreate)
@@ -872,6 +1055,21 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                self.lastservice = config.tv.lastservice
                self.lastroot = config.tv.lastroot
                self.revertMode = None
                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()
 
        def setMode(self):
                self.restoreRoot()
@@ -892,7 +1090,7 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
        def setModeRadio(self):
                if self.revertMode is None and config.servicelist.lastmode.value == "tv":
                        self.revertMode = MODE_TV
        def setModeRadio(self):
                if self.revertMode is None and config.servicelist.lastmode.value == "tv":
                        self.revertMode = MODE_TV
-               if currentConfigSelectionElement(config.usage.e1like_radio_mode) == "yes":
+               if config.usage.e1like_radio_mode.value:
                        self.history = self.history_radio
                        self.lastservice = config.radio.lastservice
                        self.lastroot = config.radio.lastroot
                        self.history = self.history_radio
                        self.lastservice = config.radio.lastservice
                        self.lastroot = config.radio.lastroot
@@ -901,7 +1099,7 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                        self.setMode()
 
        def __onCreate(self):
                        self.setMode()
 
        def __onCreate(self):
-               if currentConfigSelectionElement(config.usage.e1like_radio_mode) == "yes":
+               if config.usage.e1like_radio_mode.value:
                        if config.servicelist.lastmode.value == "tv":
                                self.setModeTv()
                        else:
                        if config.servicelist.lastmode.value == "tv":
                                self.setModeTv()
                        else:
@@ -912,25 +1110,20 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                if lastservice.valid():
                        self.zap()
 
                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)
        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()
-               else:
-                       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):
 
        #called from infoBar and channelSelected
        def zap(self):
@@ -940,7 +1133,7 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                if ref is None or ref != nref:
                        self.session.nav.playService(nref)
                        self.saveRoot()
                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)
 
                        config.servicelist.lastmode.save()
                        self.addToHistory(nref)
 
@@ -979,11 +1172,12 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                self.saveRoot()
                plen = len(path)
                root = path[plen-1]
                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.setRoot(root)
                self.session.nav.playService(ref)
                self.setCurrentSelection(ref)
-               self.saveChannel()
+               self.saveChannel(ref)
 
        def saveRoot(self):
                path = ''
 
        def saveRoot(self):
                path = ''
@@ -1020,8 +1214,7 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                                return True
                return False
 
                                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:
                if ref is not None:
                        refstr = ref.toString()
                else:
@@ -1070,7 +1263,7 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                self.revertMode = None
                self.close(None)
 
                self.revertMode = None
                self.close(None)
 
-from Screens.InfoBarGenerics import InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord
+from Screens.InfoBarGenerics import InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord, InfoBarRadioText
 
 class RadioInfoBar(Screen, InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord):
        def __init__(self, session):
 
 class RadioInfoBar(Screen, InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord):
        def __init__(self, session):
@@ -1080,15 +1273,19 @@ class RadioInfoBar(Screen, InfoBarEvent, InfoBarServiceName, InfoBarInstantRecor
                InfoBarInstantRecord.__init__(self)
                self["CurrentTime"] = Clock()
 
                InfoBarInstantRecord.__init__(self)
                self["CurrentTime"] = Clock()
 
-class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG):
+class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG, InfoBarRadioText):
+
+       ALLOW_SUSPEND = True
+
        def __init__(self, session):
                ChannelSelectionBase.__init__(self, session)
                ChannelSelectionEdit.__init__(self)
                ChannelSelectionEPG.__init__(self)
        def __init__(self, session):
                ChannelSelectionBase.__init__(self, session)
                ChannelSelectionEdit.__init__(self)
                ChannelSelectionEPG.__init__(self)
+               InfoBarRadioText.__init__(self)
 
                config.radio = ConfigSubsection();
 
                config.radio = ConfigSubsection();
-               config.radio.lastservice = configElement("config.radio.lastservice", configText, "", 0);
-               config.radio.lastroot = configElement("config.radio.lastroot", configText, "", 0);
+               config.radio.lastservice = ConfigText()
+               config.radio.lastroot = ConfigText()
                self.onLayoutFinish.append(self.onCreate)
 
                self.info = session.instantiateDialog(RadioInfoBar)
                self.onLayoutFinish.append(self.onCreate)
 
                self.info = session.instantiateDialog(RadioInfoBar)
@@ -1101,6 +1298,23 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS
                                "ok": self.channelSelected,
                        })
 
                                "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:
        def saveRoot(self):
                path = ''
                for i in self.servicePathRadio:
@@ -1143,7 +1357,6 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS
                if lastservice.valid():
                        self.servicelist.setCurrent(lastservice)
                        self.session.nav.playService(lastservice)
                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
                self.info.show()
 
        def channelSelected(self): # just return selected service
@@ -1152,16 +1365,18 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS
                        self.toggleMoveMarked()
                elif (ref.flags & 7) == 7:
                        self.enterPath(ref)
                        self.toggleMoveMarked()
                elif (ref.flags & 7) == 7:
                        self.enterPath(ref)
-               elif self.bouquet_mark_edit:
-                       self.doMark()
-               else:
-                       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
+                       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()
 
        def closeRadio(self):
                self.info.hide()
 
        def closeRadio(self):
                self.info.hide()
@@ -1192,7 +1407,7 @@ class SimpleChannelSelection(ChannelSelectionBase):
                ref = self.getCurrentSelection()
                if (ref.flags & 7) == 7:
                        self.enterPath(ref)
                ref = self.getCurrentSelection()
                if (ref.flags & 7) == 7:
                        self.enterPath(ref)
-               else:
+               elif not (ref.flags & eServiceReference.isMarker):
                        ref = self.getCurrentSelection()
                        self.close(ref)
 
                        ref = self.getCurrentSelection()
                        self.close(ref)