do not add (type == X) to new created alternatives..
[enigma2.git] / lib / python / Screens / ChannelSelection.py
index 8d728f0c0b53ae24e18b2a4175333b2ceb199ae5..7847837455afa5d766083bd62b7ac14a3ba2342c 100644 (file)
@@ -5,7 +5,7 @@ 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, iPlayableService, iServiceInformation
+from enigma import eServiceReference, eEPGCache, eServiceCenter, eTimer, eDVBDB, iPlayableService, iServiceInformation
 from Components.config import config, ConfigSubsection, ConfigText
 from Screens.FixedMenu import FixedMenu
 from Tools.NumericalTextInput import NumericalTextInput
@@ -15,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 *
@@ -56,6 +57,15 @@ class BouquetSelector(Screen):
        def cancelClick(self):
                self.close(False)
 
+# csel.bouquet_mark_edit values
+OFF = 0
+EDIT_BOUQUET = 1
+EDIT_ALTERNATIVES = 2
+
+def apend_when_current_valid(current, menu, args):
+       if current and current.valid():
+               menu.append(args)
+
 class ChannelContextMenu(Screen):
        def __init__(self, session, csel):
                Screen.__init__(self, session)
@@ -69,60 +79,72 @@ class ChannelContextMenu(Screen):
                        })
                menu = [ ]
 
+               current = csel.getCurrentSelection()
                current_root = csel.getRoot()
-               current_sel_path = csel.getCurrentSelection().getPath()
-               current_sel_flags = csel.getCurrentSelection().flags
+               current_sel_path = current.getPath()
+               current_sel_flags = current.flags
                inBouquetRootList = current_root and current_root.getPath().find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
                inBouquet = csel.getMutableList() is not None
                haveBouquets = config.usage.multibouquet.value
 
-               if not csel.bouquet_mark_edit and not csel.movemode:
+               if not (len(current_sel_path) or current_sel_flags & (eServiceReference.isDirectory|eServiceReference.isMarker)):
+                       apend_when_current_valid(current, menu, (_("show transponder info"), self.showServiceInformations))
+               if csel.bouquet_mark_edit == OFF and not csel.movemode:
                        if not inBouquetRootList:
-                               flags = csel.getCurrentSelection().flags
-                               isPlayable = not ((flags & eServiceReference.isMarker) or (flags & eServiceReference.isDirectory))
+                               isPlayable = not (current_sel_flags & (eServiceReference.isMarker|eServiceReference.isDirectory))
                                if isPlayable:
                                        if config.ParentalControl.configured.value:
                                                if parentalControl.getProtectionLevel(csel.getCurrentSelection().toCompareString()) == -1:
-                                                       menu.append((_("add to parental protection"), boundFunction(self.addParentalProtection, csel.getCurrentSelection())))
+                                                       apend_when_current_valid(current, menu, (_("add to parental protection"), boundFunction(self.addParentalProtection, csel.getCurrentSelection())))
                                                else:
-                                                       menu.append((_("remove from parental protection"), boundFunction(self.removeParentalProtection, csel.getCurrentSelection())))
+                                                       apend_when_current_valid(current, menu, (_("remove from parental protection"), boundFunction(self.removeParentalProtection, csel.getCurrentSelection())))
                                        if haveBouquets:
-                                               menu.append((_("add service to bouquet"), self.addServiceToBouquetSelected))
+                                               apend_when_current_valid(current, menu, (_("add service to bouquet"), self.addServiceToBouquetSelected))
                                        else:
-                                               menu.append((_("add service to favourites"), self.addServiceToBouquetSelected))
+                                               apend_when_current_valid(current, menu, (_("add service to favourites"), self.addServiceToBouquetSelected))
                                else:
                                        if haveBouquets:
                                                if not inBouquet and current_sel_path.find("PROVIDERS") == -1:
-                                                       menu.append((_("copy to bouquets"), self.copyCurrentToBouquetList))
+                                                       apend_when_current_valid(current, menu, (_("copy to bouquets"), self.copyCurrentToBouquetList))
                                        if current_sel_path.find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
-                                               menu.append((_("remove all new found flags"), self.removeAllNewFoundFlags))
+                                               apend_when_current_valid(current, menu, (_("remove all new found flags"), self.removeAllNewFoundFlags))
                                if inBouquet:
-                                       menu.append((_("remove entry"), self.removeCurrentService))
-                               if current_root is not None and current_root.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
-                                       menu.append((_("remove new found flag"), self.removeNewFoundFlag))
+                                       apend_when_current_valid(current, menu, (_("remove entry"), self.removeCurrentService))
+                               if current_root and current_root.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
+                                       apend_when_current_valid(current, menu, (_("remove new found flag"), self.removeNewFoundFlag))
                        else:
                                        menu.append((_("add bouquet"), self.showBouquetInputBox))
-                                       menu.append((_("remove entry"), self.removeBouquet))
+                                       apend_when_current_valid(current, menu, (_("remove entry"), self.removeBouquet))
 
                if inBouquet: # current list is editable?
-                       if not csel.bouquet_mark_edit:
+                       if csel.bouquet_mark_edit == OFF:
                                if not csel.movemode:
-                                       menu.append((_("add marker"), self.showMarkerInputBox))
-                                       menu.append((_("enable move mode"), self.toggleMoveMode))
-                                       if not inBouquetRootList:
+                                       apend_when_current_valid(current, menu, (_("enable move mode"), self.toggleMoveMode))
+                                       if not inBouquetRootList and current_root and not (current_root.flags & eServiceReference.isGroup):
+                                               menu.append((_("add marker"), self.showMarkerInputBox))
                                                if haveBouquets:
-                                                       menu.append((_("enable bouquet edit"), self.bouquetMarkStart))
+                                                       apend_when_current_valid(current, menu, (_("enable bouquet edit"), self.bouquetMarkStart))
                                                else:
-                                                       menu.append((_("enable favourite edit"), self.bouquetMarkStart))
+                                                       apend_when_current_valid(current, menu, (_("enable favourite edit"), self.bouquetMarkStart))
+                                               if current_sel_flags & eServiceReference.isGroup:
+                                                       apend_when_current_valid(current, menu, (_("edit alternatives"), self.editAlternativeServices))
+                                                       apend_when_current_valid(current, menu, (_("show alternatives"), self.showAlternativeServices))
+                                                       apend_when_current_valid(current, menu, (_("remove all alternatives"), self.removeAlternativeServices))
+                                               elif not current_sel_flags & eServiceReference.isMarker:
+                                                       apend_when_current_valid(current, menu, (_("add alternatives"), self.addAlternativeServices))
                                else:
-                                       menu.append((_("disable move mode"), self.toggleMoveMode))
-                       elif not inBouquetRootList:
-                               if haveBouquets:
-                                       menu.append((_("end bouquet edit"), self.bouquetMarkEnd))
-                                       menu.append((_("abort bouquet edit"), self.bouquetMarkAbort))
+                                       apend_when_current_valid(current, menu, (_("disable move mode"), self.toggleMoveMode))
+                       else:
+                               if csel.bouquet_mark_edit == EDIT_BOUQUET:
+                                       if haveBouquets:
+                                               apend_when_current_valid(current, menu, (_("end bouquet edit"), self.bouquetMarkEnd))
+                                               apend_when_current_valid(current, menu, (_("abort bouquet edit"), self.bouquetMarkAbort))
+                                       else:
+                                               apend_when_current_valid(current, menu, (_("end favourites edit"), self.bouquetMarkEnd))
+                                               apend_when_current_valid(current, menu, (_("abort favourites edit"), self.bouquetMarkAbort))
                                else:
-                                       menu.append((_("end favourites edit"), self.bouquetMarkEnd))
-                                       menu.append((_("abort favourites edit"), self.bouquetMarkAbort))
+                                               apend_when_current_valid(current, menu, (_("end alternatives edit"), self.bouquetMarkEnd))
+                                               apend_when_current_valid(current, menu, (_("abort alternatives edit"), self.bouquetMarkAbort))
 
                menu.append((_("back"), self.cancelClick))
                self["menu"] = MenuList(menu)
@@ -132,7 +154,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)
 
@@ -203,7 +228,7 @@ class ChannelContextMenu(Screen):
                self.close()
 
        def bouquetMarkStart(self):
-               self.csel.startMarkedEdit()
+               self.csel.startMarkedEdit(EDIT_BOUQUET)
                self.close()
 
        def bouquetMarkEnd(self):
@@ -229,6 +254,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"],
@@ -248,7 +290,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
@@ -312,6 +354,39 @@ class ChannelSelectionEdit:
                                break
                        cnt+=1
 
+       def addAlternativeServices(self):
+               cur_service = ServiceReference(self.getCurrentSelection())
+               root = self.getRoot()
+               cur_root = root and ServiceReference(root)
+               mutableBouquet = cur_root.list().startEdit()
+               if mutableBouquet:
+                       name = cur_service.getServiceName()
+                       print "NAME", name
+                       if self.mode == MODE_TV:
+                               str = '1:134:1:0:0:0:0:0:0:0:FROM BOUQUET \"alternatives.%s.tv\" ORDER BY bouquet'%(self.buildBouquetID(name))
+                       else:
+                               str = '1:134:2:0:0:0:0:0:0:0:FROM BOUQUET \"alternatives.%s.radio\" ORDER BY bouquet'%(self.buildBouquetID(name))
+                       new_ref = ServiceReference(str)
+                       if not mutableBouquet.addService(new_ref.ref, cur_service.ref):
+                               mutableBouquet.removeService(cur_service.ref)
+                               mutableBouquet.flushChanges()
+                               eDVBDB.getInstance().reloadBouquets()
+                               mutableAlternatives = new_ref.list().startEdit()
+                               if mutableAlternatives:
+                                       mutableAlternatives.setListName(name)
+                                       if mutableAlternatives.addService(cur_service.ref):
+                                               print "add", cur_service.toString(), "to new alternatives failed"
+                                       mutableAlternatives.flushChanges()
+                                       self.servicelist.addService(new_ref.ref, True)
+                                       self.servicelist.removeCurrent()
+                                       self.servicelist.moveUp()
+                               else:
+                                       print "get mutable list for new created alternatives failed"
+                       else:
+                               print "add", str, "to", cur_root.getServiceName(), "failed"
+               else:
+                       print "bouquetlist is not editable"
+
        def addBouquet(self, bName, services):
                serviceHandler = eServiceCenter.getInstance()
                mutableBouquetList = serviceHandler.list(self.bouquet_root).startEdit()
@@ -338,8 +413,8 @@ class ChannelSelectionEdit:
                                        print "get mutable list for new created bouquet failed"
                                # do some voodoo to check if current_root is equal to bouquet_root
                                cur_root = self.getRoot();
-                               str1 = cur_root.toString()
-                               pos1 = str1.find("FROM BOUQUET")
+                               str1 = cur_root and cur_root.toString()
+                               pos1 = str1 and str1.find("FROM BOUQUET") or -1
                                pos2 = self.bouquet_rootstr.find("FROM BOUQUET")
                                if pos1 != -1 and pos2 != -1 and str1[pos1:] == self.bouquet_rootstr[pos2:]:
                                        self.servicelist.addService(new_bouquet_ref)
@@ -355,8 +430,29 @@ class ChannelSelectionEdit:
                services = serviceHandler.list(provider.ref)
                self.addBouquet(providerName, services and services.getContent('R', True))
 
+       def removeAlternativeServices(self):
+               cur_service = ServiceReference(self.getCurrentSelection())
+               root = self.getRoot()
+               cur_root = root and ServiceReference(root)
+               list = cur_service.list()
+               first_in_alternative = list and list.getNext()
+               if first_in_alternative:
+                       edit_root = cur_root and cur_root.list().startEdit()
+                       if edit_root:
+                               if not edit_root.addService(first_in_alternative, cur_service.ref):
+                                       self.servicelist.addService(first_in_alternative, True)
+                               else:
+                                       print "couldn't add first alternative service to current root"
+                       else:
+                               print "couldn't edit current root!!"
+               else:
+                       print "remove empty alternative list !!"
+               self.removeBouquet()
+               self.servicelist.moveUp()
+
        def removeBouquet(self):
                refstr = self.getCurrentSelection().toString()
+               print "removeBouquet", refstr
                self.bouquetNumOffsetCache = { }
                pos = refstr.find('FROM BOUQUET "')
                filename = None
@@ -373,23 +469,29 @@ class ChannelSelectionEdit:
                        print "error during remove of", filename
 
 #  multiple marked entry stuff ( edit mode, later multiepg selection )
-       def startMarkedEdit(self):
+       def startMarkedEdit(self, type):
+               self.savedPath = self.servicePath[:]
+               if type == EDIT_ALTERNATIVES:
+                       self.enterPath(self.getCurrentSelection())
                self.mutableList = self.getMutableList()
                # add all services from the current list to internal marked set in listboxservicecontent
                self.clearMarks() # this clears the internal marked set in the listboxservicecontent
                self.saved_title = self.instance.getTitle()
                pos = self.saved_title.find(')')
                new_title = self.saved_title[:pos+1]
-               if config.usage.multibouquet.value:
-                       new_title += ' ' + _("[bouquet edit]")
+               if type == EDIT_ALTERNATIVES:
+                       self.bouquet_mark_edit = EDIT_ALTERNATIVES
+                       new_title += ' ' + _("[alternative edit]")
                else:
-                       new_title += ' ' + _("[favourite edit]")
+                       self.bouquet_mark_edit = EDIT_BOUQUET
+                       if config.usage.multibouquet.value:
+                               new_title += ' ' + _("[bouquet edit]")
+                       else:
+                               new_title += ' ' + _("[favourite edit]")
                self.setTitle(new_title)
-               self.bouquet_mark_edit = True
                self.__marked = self.servicelist.getRootServices()
                for x in self.__marked:
                        self.servicelist.addMarked(eServiceReference(x))
-               self.savedPath = self.servicePath[:]
                self.showAllServices()
 
        def endMarkedEdit(self, abort):
@@ -410,7 +512,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
@@ -450,7 +552,7 @@ class ChannelSelectionEdit:
                                mutableList.flushChanges()
                                # do some voodoo to check if current_root is equal to dest
                                cur_root = self.getRoot();
-                               str1 = cur_root.toString()
+                               str1 = cur_root and cur_root.toString() or -1
                                str2 = dest.toString()
                                pos1 = str1.find("FROM BOUQUET")
                                pos2 = str2.find("FROM BOUQUET")
@@ -467,7 +569,8 @@ class ChannelSelectionEdit:
                        self.mutableList = None
                        self.setTitle(self.saved_title)
                        self.saved_title = None
-                       if self.getRoot() == self.bouquet_root:
+                       cur_root = self.getRoot()
+                       if cur_root and cur_root == self.bouquet_root:
                                self.bouquetNumOffsetCache = { }
                else:
                        self.mutableList = self.getMutableList()
@@ -483,7 +586,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):
@@ -552,17 +655,9 @@ class ChannelSelectionBase(Screen):
                        })
                self.recallBouquetMode()
 
-       def appendDVBTypes(self, ref):
-               path = ref.getPath()
-               pos = path.find(' FROM BOUQUET')
-               if pos != -1:
-                       return eServiceReference(self.service_types + path[pos:])
-               return ref
-
        def getBouquetNumOffset(self, bouquet):
                if not config.usage.multibouquet.value:
                        return 0
-               bouquet = self.appendDVBTypes(bouquet)
                str = bouquet.toString()
                offsetCount = 0
                if not self.bouquetNumOffsetCache.has_key(str):
@@ -570,7 +665,7 @@ class ChannelSelectionBase(Screen):
                        bouquetlist = serviceHandler.list(self.bouquet_root)
                        if not bouquetlist is None:
                                while True:
-                                       bouquetIterator = self.appendDVBTypes(bouquetlist.getNext())
+                                       bouquetIterator = bouquetlist.getNext()
                                        if not bouquetIterator.valid(): #end of list
                                                break
                                        self.bouquetNumOffsetCache[bouquetIterator.toString()]=offsetCount
@@ -582,22 +677,22 @@ class ChannelSelectionBase(Screen):
                                                        serviceIterator = servicelist.getNext()
                                                        if not serviceIterator.valid(): #check if end of list
                                                                break
-                                                       if serviceIterator.flags: #playable services have no flags
-                                                               continue
-                                                       offsetCount += 1
+                                                       playable = not (serviceIterator.flags & (eServiceReference.isDirectory|eServiceReference.isMarker))
+                                                       if playable:
+                                                               offsetCount += 1
                return self.bouquetNumOffsetCache.get(str, offsetCount)
 
        def recallBouquetMode(self):
                if self.mode == MODE_TV:
                        self.service_types = service_types_tv
                        if config.usage.multibouquet.value:
-                               self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET "bouquets.tv" ORDER BY bouquet'
+                               self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "bouquets.tv" ORDER BY bouquet'
                        else:
                                self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.tv" ORDER BY bouquet'%(self.service_types)
                else:
                        self.service_types = service_types_radio
                        if config.usage.multibouquet.value:
-                               self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET "bouquets.radio" ORDER BY bouquet'
+                               self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "bouquets.radio" ORDER BY bouquet'
                        else:
                                self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.radio" ORDER BY bouquet'%(self.service_types)
                self.bouquet_root = eServiceReference(self.bouquet_rootstr)
@@ -627,13 +722,11 @@ class ChannelSelectionBase(Screen):
        def setRoot(self, root, justSet=False):
                path = root.getPath()
                inBouquetRootList = path.find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
-               pos = path.find(' FROM BOUQUET')
-               isBouquet = pos != -1
+               pos = path.find('FROM BOUQUET')
+               isBouquet = (pos != -1) and (root.flags & eServiceReference.isDirectory)
                if not inBouquetRootList and isBouquet:
                        self.servicelist.setMode(ServiceList.MODE_FAVOURITES)
                        self.servicelist.setNumberOffset(self.getBouquetNumOffset(root))
-                       refstr = self.service_types + path[pos:]
-                       root = eServiceReference(refstr)
                else:
                        self.servicelist.setMode(ServiceList.MODE_NORMAL)
                self.servicelist.setRoot(root, justSet)
@@ -886,21 +979,6 @@ class ChannelSelectionBase(Screen):
                        return bouquets
                return None
 
-       def getGroupList(self):
-               groups = [ ]
-               serviceHandler = eServiceCenter.getInstance()
-               list = serviceHandler.list(self.bouquet_root)
-               if list:
-                       while True:
-                               s = list.getNext()
-                               if not s.valid():
-                                       break
-                               if (s.flags & eServiceReference.isGroup) and (s.flags & eServiceReference.mustDescent):
-                                       info = serviceHandler.info(s)
-                                       if info:
-                                               groups.append((info.getName(s), s))
-               return groups
-
        def keyNumber0(self, num):
                if len(self.servicePath) > 1:
                        self.keyGoUp()
@@ -972,6 +1050,10 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                self.lastservice = config.tv.lastservice
                self.lastroot = config.tv.lastroot
                self.revertMode = None
+               config.usage.multibouquet.addNotifier(self.multibouquet_config_changed)
+
+       def multibouquet_config_changed(self, val):
+               self.recallBouquetMode()
 
        def __evServiceStart(self):
                service = self.session.nav.getCurrentService()
@@ -1029,11 +1111,14 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                        self.toggleMoveMarked()
                elif (ref.flags & 7) == 7:
                        self.enterPath(ref)
-               elif self.bouquet_mark_edit:
-                       self.doMark()
-               elif not (ref.flags & 64): # no marker
-                       self.zap()
-                       self.close(ref)
+               elif self.bouquet_mark_edit != OFF:
+                       if not (self.bouquet_mark_edit == EDIT_ALTERNATIVES and ref.flags & eServiceReference.isGroup):
+                               self.doMark()
+               elif not (ref.flags & eServiceReference.isMarker): # no marker
+                       root = self.getRoot()
+                       if not root or not (root.flags & eServiceReference.isGroup):
+                               self.zap()
+                               self.close(ref)
 
        #called from infoBar and channelSelected
        def zap(self):
@@ -1043,7 +1128,7 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                if ref is None or ref != nref:
                        self.session.nav.playService(nref)
                        self.saveRoot()
-                       self.saveChannel()
+                       self.saveChannel(nref)
                        config.servicelist.lastmode.save()
                        self.addToHistory(nref)
 
@@ -1082,11 +1167,12 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                self.saveRoot()
                plen = len(path)
                root = path[plen-1]
-               if self.getRoot() != root:
+               cur_root = self.getRoot()
+               if cur_root and cur_root != root:
                        self.setRoot(root)
                self.session.nav.playService(ref)
                self.setCurrentSelection(ref)
-               self.saveChannel()
+               self.saveChannel(ref)
 
        def saveRoot(self):
                path = ''
@@ -1123,8 +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:
@@ -1275,15 +1360,18 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS
                        self.toggleMoveMarked()
                elif (ref.flags & 7) == 7:
                        self.enterPath(ref)
-               elif self.bouquet_mark_edit:
-                       self.doMark()
-               elif not (ref.flags & 64): # no marker
-                       playingref = self.session.nav.getCurrentlyPlayingServiceReference()
-                       if playingref is None or playingref != ref:
-                               self.session.nav.playService(ref)
-                               config.radio.lastservice.value = ref.toString()
-                               config.radio.lastservice.save()
-                       self.saveRoot()
+               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()
@@ -1314,7 +1402,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)