another fix for alignement left
[enigma2.git] / lib / python / Screens / ChannelSelection.py
index 1604150d34ff413aabc92eba9183a93e3eacd827..7f5e10227a0da7b95565be1e98cf8572af0c1b38 100644 (file)
@@ -1,18 +1,23 @@
 from Screen import Screen
 from Components.Button import Button
 from Components.ServiceList import ServiceList
 from Screen import Screen
 from Components.Button import Button
 from Components.ServiceList import ServiceList
-from Components.ActionMap import ActionMap
+from Components.ActionMap import NumberActionMap, ActionMap
 from EpgSelection import EPGSelection
 from enigma import eServiceReference, eEPGCache, eEPGCachePtr, eServiceCenter, eServiceCenterPtr, iMutableServiceListPtr, iStaticServiceInformationPtr, eTimer
 from EpgSelection import EPGSelection
 from enigma import eServiceReference, eEPGCache, eEPGCachePtr, eServiceCenter, eServiceCenterPtr, iMutableServiceListPtr, iStaticServiceInformationPtr, eTimer
-from Components.config import config, configElement, ConfigSubsection, configText
-
+from Components.config import config, configElement, ConfigSubsection, configText, currentConfigSelectionElement
 from Screens.FixedMenu import FixedMenu
 from Screens.FixedMenu import FixedMenu
+from Tools.NumericalTextInput import NumericalTextInput
+from Components.NimManager import nimmanager
+from Components.ServiceName import ServiceName
+from Components.Clock import Clock
+from Components.EventInfo import EventInfo
+from re import *
 
 import xml.dom.minidom
 
 class BouquetSelector(FixedMenu):
 
 import xml.dom.minidom
 
 class BouquetSelector(FixedMenu):
-       def __init__(self, session, bouquets, parent):
-               self.parent=parent
+       def __init__(self, session, bouquets, selectedFunc):
+               self.selectedFunc=selectedFunc
                entrys = [ ]
                for x in bouquets:
                        entrys.append((x[0], self.bouquetSelected, x[1]))
                entrys = [ ]
                for x in bouquets:
                        entrys.append((x[0], self.bouquetSelected, x[1]))
@@ -20,8 +25,7 @@ class BouquetSelector(FixedMenu):
                self.skinName = "Menu"
 
        def bouquetSelected(self):
                self.skinName = "Menu"
 
        def bouquetSelected(self):
-               self.parent.addCurrentServiceToBouquet(self["menu"].getCurrent()[2])
-               self.close()
+               self.selectedFunc(self["menu"].getCurrent()[2])
 
 class ChannelContextMenu(FixedMenu):
        def __init__(self, session, csel):
 
 class ChannelContextMenu(FixedMenu):
        def __init__(self, session, csel):
@@ -29,51 +33,53 @@ class ChannelContextMenu(FixedMenu):
 
                menu = [ ]
 
 
                menu = [ ]
 
-               #HACK
-               inBouquetRootList = csel["list"].getRoot().toString().find('FROM BOUQUET "bouquets.') != -1
+               inBouquetRootList = csel.getRoot().getPath().find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
                inBouquet = csel.getMutableList() is not None
                inBouquet = csel.getMutableList() is not None
+               haveBouquets = csel.bouquet_root.getPath().find('FROM BOUQUET "bouquets.') != -1
 
                if not csel.bouquet_mark_edit and not csel.movemode and not inBouquetRootList:
 
                if not csel.bouquet_mark_edit and not csel.movemode and not inBouquetRootList:
-                       menu.append(("add service to bouquet", self.addServiceToBouquetSelected))
+                       if (csel.getCurrentSelection().flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory:
+                               if haveBouquets:
+                                       menu.append((_("add service to bouquet"), self.addServiceToBouquetSelected))
+                               else:
+                                       menu.append((_("add service to favourites"), self.addServiceToBouquetSelected))
                        if inBouquet:
                        if inBouquet:
-                               menu.append(("remove service", self.removeCurrentService))
+                               menu.append((_("remove service"), self.removeCurrentService))
 
                if inBouquet: # current list is editable?
                        if not csel.bouquet_mark_edit:
                                if not csel.movemode:
 
                if inBouquet: # current list is editable?
                        if not csel.bouquet_mark_edit:
                                if not csel.movemode:
-                                       menu.append(("enable move mode", self.toggleMoveMode))
-                                       if not inBouquetRootList: 
-                                               menu.append(("enable bouquet edit", self.bouquetMarkStart))
+                                       menu.append((_("enable move mode"), self.toggleMoveMode))
+                                       if not inBouquetRootList:
+                                               if haveBouquets:
+                                                       menu.append((_("enable bouquet edit"), self.bouquetMarkStart))
+                                               else:
+                                                       menu.append((_("enable favourite edit"), self.bouquetMarkStart))
                                else:
                                else:
-                                       menu.append(("disable move mode", self.toggleMoveMode))
-                       elif not inBouquetRootList: 
-                               menu.append(("end bouquet edit", self.bouquetMarkEnd))
-                               menu.append(("abort bouquet edit", self.bouquetMarkAbort))
+                                       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:
+                                       menu.append((_("end favourites edit"), self.bouquetMarkEnd))
+                                       menu.append((_("abort favourites edit"), self.bouquetMarkAbort))
 
 
-               menu.append(("back", self.close))
+               menu.append((_("back"), self.close))
 
 
-               FixedMenu.__init__(self, session, "Channel Selection", menu)
+               FixedMenu.__init__(self, session, _("Channel Selection"), menu)
                self.skinName = "Menu"
 
        def addServiceToBouquetSelected(self):
                self.skinName = "Menu"
 
        def addServiceToBouquetSelected(self):
-               bouquets = [ ]
-               serviceHandler = eServiceCenter.getInstance()
-               list = serviceHandler.list(self.csel.bouquet_root)
-               if not list is None:
-                       while 1:
-                               s = list.getNext()
-                               if not s.valid():
-                                       break
-                               if ((s.flags & eServiceReference.flagDirectory) == eServiceReference.flagDirectory):
-                                       info = serviceHandler.info(s)
-                                       if not info is None:
-                                               str = info.getName(s)
-                                               bouquets.append((str, s))
-               cnt = len(bouquets)
+               bouquets = self.csel.getBouquetList()
+               if bouquets is None:
+                       cnt = 0
+               else:
+                       cnt = len(bouquets)
                if cnt > 1: # show bouquet list
                if cnt > 1: # show bouquet list
-                       self.session.open(BouquetSelector, bouquets, self)
+                       self.session.open(BouquetSelector, bouquets, self.addCurrentServiceToBouquet)
                elif cnt == 1: # add to only one existing bouquet
                elif cnt == 1: # add to only one existing bouquet
-                       self.addCurrentServiceToBouquet(bouquet[0][1])
+                       self.addCurrentServiceToBouquet(bouquets[0][1])
                else: #no bouquets in root.. so assume only one favourite list is used
                        self.addCurrentServiceToBouquet(self.csel.bouquet_root)
 
                else: #no bouquets in root.. so assume only one favourite list is used
                        self.addCurrentServiceToBouquet(self.csel.bouquet_root)
 
@@ -100,111 +106,82 @@ class ChannelContextMenu(FixedMenu):
        def bouquetMarkAbort(self):
                self.csel.endMarkedEdit(abort=True)
                self.close()
        def bouquetMarkAbort(self):
                self.csel.endMarkedEdit(abort=True)
                self.close()
-class ChannelSelection(Screen):
-       def lastService(self):
-               self.lastServiceTimer.stop()
-               #zap to last running tv service
-               self.setRoot(eServiceReference(config.tv.lastroot.value))
-               self.session.nav.playService(eServiceReference(config.tv.lastservice.value))
-       
-       def __init__(self, session):
-               Screen.__init__(self, session)
 
 
-               #config for lastservice
-               config.tv = ConfigSubsection();
-               config.tv.lastservice = configElement("config.tv.lastservice", configText, "", 0);
-               config.tv.lastroot = configElement("config.tv.lastroot", configText, "", 0);
+class ChannelSelectionEPG:
+       def __init__(self):
+               self["ChannelSelectEPGActions"] = ActionMap(["ChannelSelectEPGActions"],
+                       {
+                               "showEPGList": self.showEPGList,
+                       })
+
+       def showEPGList(self):
+               ref=self.getCurrentSelection()
+               ptr=eEPGCache.getInstance()
+               if ptr.startTimeQuery(ref) != -1:
+                       self.session.open(EPGSelection, ref)
+               else:
+                       print 'no epg for service', ref.toString()
 
 
+class ChannelSelectionEdit:
+       def __init__(self):
                self.entry_marked = False
                self.movemode = False
                self.bouquet_mark_edit = False
                self.entry_marked = False
                self.movemode = False
                self.bouquet_mark_edit = False
-               self.bouquet_root = eServiceReference('1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET "userbouquet.favourites.tv" ORDER BY bouquet')
                self.mutableList = None
                self.mutableList = None
-
                self.__marked = [ ]
                self.__marked = [ ]
+               self.saved_title = None
+               self.saved_root = None
 
 
-               self["key_red"] = Button("All")
-               self["key_green"] = Button("Provider")
-               self["key_yellow"] = Button("Satellite")
-               self["key_blue"] = Button("Favourites")
-               
-               self["list"] = ServiceList()
-
-               if config.tv.lastroot.value == "":
-                       self["list"].setRoot(eServiceReference("""1:0:1:0:0:0:0:0:0:0:(type == 1)"""))
-               #self["okbutton"] = Button("ok", [self.channelSelected])
-
-               self.lastServiceTimer = eTimer()
-               self.lastServiceTimer.timeout.get().append(self.lastService)
-               self.lastServiceTimer.start(100)
-
-               class ChannelActionMap(ActionMap):
+               class ChannelSelectionEditActionMap(ActionMap):
+                       def __init__(self, csel, contexts = [ ], actions = { }, prio=0):
+                               ActionMap.__init__(self, contexts, actions, prio)
+                               self.csel = csel
                        def action(self, contexts, action):
                        def action(self, contexts, action):
-                               if action[:7] == "bouquet":
-                                       l = self.csel
-                                       list = l["list"]
-                                       if action.find("FROM BOUQUET") != -1:
-                                               l.setRoot(eServiceReference("1:7:1:0:0:0:0:0:0:0:" + action[8:]))
-                                       else:
-                                               l.setRoot(eServiceReference("1:0:1:0:0:0:0:0:0:0:" + action[8:]))
+                               if action == "cancel":
+                                       self.csel.handleEditCancel()
+                               elif action == "ok":
+                                       pass # avoid typo warning...
                                else:
                                else:
-                                       if action == "cancel":
-                                               l = self.csel
-                                               if l.movemode: #movemode active?
-                                                       l.channelSelected() # unmark
-                                                       l.toggleMoveMode() # disable move mode
-                                               elif l.bouquet_mark_edit:
-                                                       l.endMarkedEdit(True) # abort edit mode
                                        ActionMap.action(self, contexts, action)
                                        ActionMap.action(self, contexts, action)
-
-               self["actions"] = ChannelActionMap(["ChannelSelectActions", "OkCancelActions", "ContextMenuActions"], 
+               self["ChannelSelectEditActions"] = ChannelSelectionEditActionMap(self, ["ChannelSelectEditActions", "OkCancelActions"],
                        {
                        {
-                               "cancel": self.close,
-                               "ok": self.channelSelected,
-                               "mark": self.doMark,
                                "contextMenu": self.doContext,
                                "contextMenu": self.doContext,
-                               "showFavourites": self.showFavourites,
-                   "showEPGList": self.showEPGList
                        })
                        })
-               self["actions"].csel = self
-
-       def showEPGList(self):
-               ref=self["list"].getCurrent()
-               ptr=eEPGCache.getInstance()
-               if ptr.startTimeQuery(ref) != -1:
-                       self.session.open(EPGSelection, ref)
-               else:
-                       print 'no epg for service', ref.toString()
 
        def getMutableList(self, root=eServiceReference()):
                if not self.mutableList is None:
                        return self.mutableList
                serviceHandler = eServiceCenter.getInstance()
                if not root.valid():
 
        def getMutableList(self, root=eServiceReference()):
                if not self.mutableList is None:
                        return self.mutableList
                serviceHandler = eServiceCenter.getInstance()
                if not root.valid():
-                       root=self["list"].getRoot()
+                       root=self.getRoot()
                list = serviceHandler.list(root)
                list = serviceHandler.list(root)
-               mutableList = None
                if list is not None:
                if list is not None:
-                       mutableList = list.startEdit()
-               return mutableList
+                       return list.startEdit()
+               return None
 
 #  multiple marked entry stuff ( edit mode, later multiepg selection )
        def startMarkedEdit(self):
                self.mutableList = self.getMutableList()
 
 #  multiple marked entry stuff ( edit mode, later multiepg selection )
        def startMarkedEdit(self):
                self.mutableList = self.getMutableList()
-               l = self["list"]
                # add all services from the current list to internal marked set in listboxservicecontent
                # add all services from the current list to internal marked set in listboxservicecontent
-               self.bouquetRoot = l.getRoot()
+               self.bouquetRoot = self.getRoot()
                self.clearMarks() # this clears the internal marked set in the listboxservicecontent
                self.clearMarks() # this clears the internal marked set in the listboxservicecontent
+               self.saved_title = self.instance.getTitle()
+               new_title = self.saved_title
+               if self.bouquet_root.getPath().find('FROM BOUQUET "bouquets.') != -1:
+                       new_title += ' ' + _("[bouquet edit]")
+               else:
+                       new_title += ' ' + _("[favourite edit]")
+               self.instance.setTitle(new_title)
                self.bouquet_mark_edit = True
                self.bouquet_mark_edit = True
-               self.__marked = l.getRootServices()
+               self.__marked = self.servicelist.getRootServices()
                for x in self.__marked:
                for x in self.__marked:
-                       l.addMarked(eServiceReference(x))
+                       self.servicelist.addMarked(eServiceReference(x))
+               self.saved_root = self.getRoot()
+               self.showAllServices()
 
        def endMarkedEdit(self, abort):
 
        def endMarkedEdit(self, abort):
-               l = self["list"]
                if not abort and self.mutableList is not None:
                if not abort and self.mutableList is not None:
-                       new_marked = set(l.getMarked())
+                       new_marked = set(self.servicelist.getMarked())
                        old_marked = set(self.__marked)
                        removed = old_marked - new_marked
                        added = new_marked - old_marked
                        old_marked = set(self.__marked)
                        removed = old_marked - new_marked
                        added = new_marked - old_marked
@@ -217,109 +194,659 @@ class ChannelSelection(Screen):
                                self.mutableList.addService(eServiceReference(x))
                        if changed:
                                self.mutableList.flushChanges()
                                self.mutableList.addService(eServiceReference(x))
                        if changed:
                                self.mutableList.flushChanges()
-                               self.setRoot(self.bouquetRoot)
-                               #self.showFavourites()
                self.__marked = []
                self.clearMarks()
                self.bouquet_mark_edit = False
                self.bouquetRoot = None
                self.mutableList = None
                self.__marked = []
                self.clearMarks()
                self.bouquet_mark_edit = False
                self.bouquetRoot = None
                self.mutableList = None
+               self.instance.setTitle(self.saved_title)
+               self.saved_title = None
+               self.setRoot(self.saved_root)
 
        def clearMarks(self):
 
        def clearMarks(self):
-               self["list"].clearMarks()
+               self.servicelist.clearMarks()
 
        def doMark(self):
 
        def doMark(self):
-               ref = self["list"].getCurrent()
-               if self["list"].isMarked(ref):
-                       self["list"].removeMarked(ref)
+               ref = self.servicelist.getCurrent()
+               if self.servicelist.isMarked(ref):
+                       self.servicelist.removeMarked(ref)
                else:
                else:
-                       self["list"].addMarked(ref)
+                       self.servicelist.addMarked(ref)
 
        def removeCurrentService(self):
 
        def removeCurrentService(self):
-               l = self["list"]
-               ref = l.getCurrent()
+               ref = self.servicelist.getCurrent()
                mutableList = self.getMutableList()
                if ref.valid() and mutableList is not None:
                mutableList = self.getMutableList()
                if ref.valid() and mutableList is not None:
-                       if mutableList.removeService(ref) == 0:
+                       if not mutableList.removeService(ref):
+                               currentIndex = self.servicelist.getCurrentIndex()
+                               self.servicelist.moveDown()
+                               if self.servicelist.getCurrentIndex() == currentIndex:
+                                       currentIndex -= 1
                                mutableList.flushChanges() #FIXME dont flush on each single removed service
                                mutableList.flushChanges() #FIXME dont flush on each single removed service
-                               self.setRoot(l.getRoot())
+                               self.setRoot(self.getRoot())
+                               self.servicelist.moveToIndex(currentIndex)
 
        def addCurrentServiceToBouquet(self, dest):
                mutableList = self.getMutableList(dest)
                if not mutableList is None:
 
        def addCurrentServiceToBouquet(self, dest):
                mutableList = self.getMutableList(dest)
                if not mutableList is None:
-                       if mutableList.addService(self["list"].getCurrent()) == 0:
+                       if not mutableList.addService(self.servicelist.getCurrent()):
                                mutableList.flushChanges()
                self.close()
 
                                mutableList.flushChanges()
                self.close()
 
-       def setRoot(self, root):
-               if not self.movemode: # dont change root when movemode is enabled
-                       list = self["list"]
-
-                       #HACK
-                       inBouquetRootList = root.toString().find('FROM BOUQUET "bouquets.') != -1
-
-                       if not inBouquetRootList and ((root.flags & eServiceReference.flagDirectory) == eServiceReference.flagDirectory):
-                               list.setMode(list.MODE_FAVOURITES)
-                       else:
-                               list.setMode(list.MODE_NORMAL)
-                       list.setRoot(root)
-
-       def channelSelected(self):
-               ref = self["list"].getCurrent()
+       def toggleMoveMode(self):
                if self.movemode:
                        if self.entry_marked:
                if self.movemode:
                        if self.entry_marked:
-                               self["list"].setCurrentMarked(False)
-                               self.entry_marked = False
-                       else:
-                               self["list"].setCurrentMarked(True)
-                               self.entry_marked = True
-               elif (ref.flags & 7) == 7:
-                       self.setRoot(ref)
+                               self.toggleMoveMarked() # unmark current entry
+                       self.movemode = False
+                       self.pathChangedDisabled = True # re-enable path change
+                       self.mutableList.flushChanges() # FIXME add check if changes was made
+                       self.mutableList = None
+                       self.instance.setTitle(self.saved_title)
+                       self.saved_title = None
+               else:
+                       self.mutableList = self.getMutableList()
+                       self.movemode = True
+                       self.pathChangedDisabled = True # no path change allowed in movemode
+                       self.saved_title = self.instance.getTitle()
+                       new_title = self.saved_title
+                       new_title += ' ' + _("[move mode]");
+                       self.instance.setTitle(new_title);
+
+       def handleEditCancel(self):
+               if self.movemode: #movemode active?
+                       self.channelSelected() # unmark
+                       self.toggleMoveMode() # disable move mode
                elif self.bouquet_mark_edit:
                elif self.bouquet_mark_edit:
-                       self.doMark()
+                       self.endMarkedEdit(True) # abort edit mode
+
+       def toggleMoveMarked(self):
+               if self.entry_marked:
+                       self.servicelist.setCurrentMarked(False)
+                       self.entry_marked = False
                else:
                else:
-                       self.session.nav.playService(ref)
-                       self.saveChannel()
-                       self.close()
+                       self.servicelist.setCurrentMarked(True)
+                       self.entry_marked = True
 
 
-       #called from infoBar
-       def zap(self):
-               self.session.nav.playService(self["list"].getCurrent())
-               self.saveChannel()
+       def doContext(self):
+               self.session.open(ChannelContextMenu, self)
+
+MODE_TV = 0
+MODE_RADIO = 1
+
+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)'
+               self.service_types_radio = '1:7:1: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_blue"] = Button(_("Favourites"))
+
+               self["list"] = ServiceList()
+               self.servicelist = self["list"]
+
+               self.numericalTextInput = NumericalTextInput()
+
+               self.servicePathTV = [ ]
+               self.servicePathRadio = [ ]
+
+               self.pathChangedDisabled = False
+
+               self["ChannelSelectBaseActions"] = NumberActionMap(["ChannelSelectBaseActions", "NumberActions"],
+                       {
+                               "showFavourites": self.showFavourites,
+                               "showAllServices": self.showAllServices,
+                               "showProviders": self.showProviders,
+                               "showSatellites": self.showSatellites,
+                               "1": self.keyNumberGlobal,
+                               "2": self.keyNumberGlobal,
+                               "3": self.keyNumberGlobal,
+                               "4": self.keyNumberGlobal,
+                               "5": self.keyNumberGlobal,
+                               "6": self.keyNumberGlobal,
+                               "7": self.keyNumberGlobal,
+                               "8": self.keyNumberGlobal,
+                               "9": self.keyNumberGlobal,
+                               "0": self.keyNumberGlobal
+                       })
+
+       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):
+               bouquet = self.appendDVBTypes(bouquet)
+               if self.bouquet_root.getPath().find('FROM BOUQUET "bouquets.') == -1: #FIXME HACK
+                       return 0
+               offsetCount = 0
+               serviceHandler = eServiceCenter.getInstance()
+               bouquetlist = serviceHandler.list(self.bouquet_root)
+               if not bouquetlist is None:
+                       while True:
+                               bouquetIterator = self.appendDVBTypes(bouquetlist.getNext())
+                               if not bouquetIterator.valid() or bouquetIterator == bouquet: #end of list or bouquet found
+                                       break
+                               if ((bouquetIterator.flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory):
+                                       continue
+                               servicelist = serviceHandler.list(bouquetIterator)
+                               if not servicelist is None:
+                                       while True:
+                                               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 offsetCount
+
+       def recallBouquetMode(self):
+               if self.mode == MODE_TV:
+                       self.service_types = self.service_types_tv
+                       if currentConfigSelectionElement(config.usage.multibouquet) == "yes":
+                               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.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_root = eServiceReference(self.bouquet_rootstr)
+
+       def setTvMode(self):
+               title = self.instance.getTitle()
+               pos = title.find(" (")
+               if pos != -1:
+                       title = title[:pos]
+               title += " (TV)"
+               self.instance.setTitle(title)
+               self.mode = MODE_TV
+               self.recallBouquetMode()
+
+       def setRadioMode(self):
+               title = self.instance.getTitle()
+               pos = title.find(" (")
+               if pos != -1:
+                       title = title[:pos]
+               title += " (Radio)"
+               self.instance.setTitle(title)
+               self.mode = MODE_RADIO
+               self.recallBouquetMode()
+
+       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
+               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)
 
        def moveUp(self):
 
        def moveUp(self):
-               self["list"].moveUp()
+               self.servicelist.moveUp()
 
        def moveDown(self):
 
        def moveDown(self):
-               self["list"].moveDown()
+               self.servicelist.moveDown()
 
 
-       def doContext(self):
-               self.session.open(ChannelContextMenu, self)
+       def clearPath(self):
+               if self.mode == MODE_RADIO:
+                       self.servicePathRadio = [ ]
+               else:
+                       self.servicePathTV = [ ]
 
 
-       def toggleMoveMode(self):
-               if self.movemode:
-                       if self.entry_marked:
-                               self.channelSelected() # unmark current entry
-                       self.movemode = False
-                       self.mutableList.flushChanges() # FIXME add check if changes was made
-                       self.mutableList = None
+       def enterPath(self, ref, justSet=False):
+               if self.mode == MODE_RADIO:
+                       self.servicePathRadio.append(ref)
                else:
                else:
-                       self.mutableList = self.getMutableList()
-                       self.movemode = True
+                       self.servicePathTV.append(ref)
+               self.setRoot(ref, justSet)
+
+       def pathUp(self, justSet=False):
+               if self.mode == MODE_TV:
+                       print "MODE_TV"
+                       prev = self.servicePathTV.pop()
+                       print "prev", prev.toString()
+                       length = len(self.servicePathTV)
+                       print "length", length
+                       if length:
+                               current = self.servicePathTV[length-1]
+                               print "current", current.toString()
+               else:
+                       prev = self.servicePathRadio.pop()
+                       length = len(self.servicePathRadio)
+                       if length:
+                               current = self.servicePathRadio[length-1]
+               self.setRoot(current, justSet)
+               if not justSet:
+                       print "setCurrentSelection prev"
+                       self.setCurrentSelection(prev)
+               return prev
+
+       def isBasePathEqual(self, ref):
+               if self.mode == MODE_RADIO and len(self.servicePathRadio) > 1 and self.servicePathRadio[0] == ref:
+                       return True
+               elif self.mode == MODE_TV and len(self.servicePathTV) > 1 and self.servicePathTV[0] == ref:
+                       return True
+               return False
+
+       def isPrevPathEqual(self, ref):
+               path = self.servicePathRadio
+               if self.mode == MODE_TV:
+                       path = self.servicePathTV
+               length = len(path)
+               if length > 1 and path[length-2] == ref:
+                       return True
+               return False
+
+       def preEnterPath(self, refstr):
+               return False
+
+       def showAllServices(self):
+               if not self.pathChangedDisabled:
+                       refstr = '%s ORDER BY name'%(self.service_types)
+                       if not self.preEnterPath(refstr):
+                               ref = eServiceReference(refstr)
+                               currentRoot = self.getRoot()
+                               if currentRoot is None or currentRoot != ref:
+                                       self.clearPath()
+                                       self.enterPath(ref)
+
+       def showSatellites(self):
+               if not self.pathChangedDisabled:
+                       refstr = '%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types)
+                       if not self.preEnterPath(refstr):
+                               ref = eServiceReference(refstr)
+                               justSet=False
+                               prev = None
+
+                               if self.isBasePathEqual(ref):
+                                       if self.isPrevPathEqual(ref):
+                                               justSet=True
+                                       prev = self.pathUp(justSet)
+                               else:
+                                       currentRoot = self.getRoot()
+                                       if currentRoot is None or currentRoot != ref:
+                                               justSet=True
+                                               self.clearPath()
+                                               self.enterPath(ref, True)
+                               if justSet:
+                                       serviceHandler = eServiceCenter.getInstance()
+                                       servicelist = serviceHandler.list(ref)
+                                       if not servicelist is None:
+                                               while True:
+                                                       service = servicelist.getNext()
+                                                       if not service.valid(): #check if end of list
+                                                               break
+                                                       orbpos = service.getData(4) >> 16
+                                                       if service.getPath().find("FROM PROVIDER") != -1:
+                                                               service_name = _("Providers")
+                                                       else:
+                                                               service_name = _("Services")
+                                                       try:
+                                                               service_name += str(' - %s'%(nimmanager.getSatDescription(orbpos)))
+                                                               service.setName(service_name) # why we need this cast?
+                                                       except:
+                                                               if orbpos > 1800: # west
+                                                                       service.setName("%s (%3.1f" + _("W") + ")" %(str, (0 - (orbpos - 3600)) / 10.0))
+                                                               else:
+                                                                       service.setName("%s (%3.1f" + _("E") + ")" % (str, orbpos / 10.0))
+                                                       self.servicelist.addService(service)
+                                                       self.servicelist.finishFill()
+                                                       if prev is not None:
+                                                               self.setCurrentSelection(prev)
+
+       def showProviders(self):
+               if not self.pathChangedDisabled:
+                       refstr = '%s FROM PROVIDERS ORDER BY name'%(self.service_types)
+                       if not self.preEnterPath(refstr):
+                               ref = eServiceReference(refstr)
+                               if self.isBasePathEqual(ref):
+                                       self.pathUp()
+                               else:
+                                       currentRoot = self.getRoot()
+                                       if currentRoot is None or currentRoot != ref:
+                                               self.clearPath()
+                                               self.enterPath(ref)
 
        def showFavourites(self):
 
        def showFavourites(self):
-               self.setRoot(self.bouquet_root)
+               if not self.pathChangedDisabled:
+                       if not self.preEnterPath(self.bouquet_rootstr):
+                               if self.isBasePathEqual(self.bouquet_root):
+                                       print "basepath equal"
+                                       self.pathUp()
+                               else:
+                                       print "basepath not equal"
+                                       currentRoot = self.getRoot()
+                                       if currentRoot is None or currentRoot != self.bouquet_root:
+                                               self.clearPath()
+                                               self.enterPath(self.bouquet_root)
+
+       def keyNumberGlobal(self, number):
+               char = self.numericalTextInput.getKey(number)
+               print "You pressed number " + str(number)
+               print "You would go to character " + str(char)
+               self.servicelist.moveToChar(char)
+
+       def getRoot(self):
+               return self.servicelist.getRoot()
+
+       def getCurrentSelection(self):
+               return self.servicelist.getCurrent()
+
+       def setCurrentSelection(self, service):
+               servicepath = service.getPath()
+               pos = servicepath.find(" FROM BOUQUET")
+               if pos != -1:
+                       if self.mode == MODE_TV:
+                               servicepath = '(type == 1)' + servicepath[pos:]
+                       else:
+                               servicepath = '(type == 2)' + servicepath[pos:]
+                       service.setPath(servicepath)
+               self.servicelist.setCurrent(service)
+
+       def getBouquetList(self):
+               serviceCount=0
+               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))
+                       return bouquets
+               return None
+
+class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG):
+       def __init__(self, session):
+               ChannelSelectionBase.__init__(self,session)
+               ChannelSelectionEdit.__init__(self)
+               ChannelSelectionEPG.__init__(self)
+
+               #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.prevservice = configElement("config.tv.prevservice", configText, "", 0);
+               config.tv.prevroot = configElement("config.tv.prevroot", configText, "", 0);
+
+               self["actions"] = ActionMap(["OkCancelActions"],
+                       {
+                               "cancel": self.cancel,
+                               "ok": self.channelSelected,
+                       })
+               self.onShown.append(self.onShow)
+
+               self.lastChannelRootTimer = eTimer()
+               self.lastChannelRootTimer.timeout.get().append(self.onCreate)
+               self.lastChannelRootTimer.start(100,True)
+
+       def onCreate(self):
+               self.setTvMode()
+               self.servicePathTV = [ ]
+               self.restoreRoot()
+               lastservice=eServiceReference(config.tv.lastservice.value)
+               if lastservice.valid():
+                       self.setCurrentSelection(lastservice)
+                       self.session.nav.playService(lastservice)
+
+       def onShow(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 saveRoot(self, root):
-               if root is not None:
-                       config.tv.lastroot.value = root.toString()
+       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)
+
+       #called from infoBar and channelSelected
+       def zap(self):
+               ref = self.session.nav.getCurrentlyPlayingServiceReference()
+               if ref is None or ref != self.getCurrentSelection():
+                       self.session.nav.playService(self.getCurrentSelection())
+               self.saveRoot()
+               self.saveChannel()
+
+       def saveRoot(self):
+               path = ''
+               for i in self.servicePathTV:
+                       path += i.toString()
+                       path += ';'
+               if config.tv.prevroot.value != config.tv.lastroot.value:
+                       config.tv.prevroot.value = config.tv.lastroot.value
+                       config.tv.prevroot.save()
+               if len(path) and path != config.tv.lastroot.value:
+                       config.tv.lastroot.value = path
                        config.tv.lastroot.save()
 
                        config.tv.lastroot.save()
 
+       def restoreRoot(self):
+               self.servicePathTV = [ ]
+               re = compile('.+?;')
+               tmp = re.findall(config.tv.lastroot.value)
+               cnt = 0
+               for i in tmp:
+                       self.servicePathTV.append(eServiceReference(i[:len(i)-1]))
+                       cnt += 1
+               if cnt:
+                       path = self.servicePathTV.pop()
+                       self.enterPath(path)
+               else:
+                       self.showFavourites()
+                       self.saveRoot()
+
+       def preEnterPath(self, refstr):
+               if len(self.servicePathTV) and self.servicePathTV[0] != eServiceReference(refstr):
+                       pathstr = config.tv.lastroot.value
+                       if pathstr is not None and pathstr.find(refstr) == 0:
+                               self.restoreRoot()
+                               lastservice=eServiceReference(config.tv.lastservice.value)
+                               if lastservice is not None:
+                                       self.setCurrentSelection(lastservice)
+                               return True
+               return False
+
        def saveChannel(self):
                ref = self.session.nav.getCurrentlyPlayingServiceReference()
                if ref is not None:
                        refstr = ref.toString()
                else:
                        refstr = ""
        def saveChannel(self):
                ref = self.session.nav.getCurrentlyPlayingServiceReference()
                if ref is not None:
                        refstr = ref.toString()
                else:
                        refstr = ""
-               config.tv.lastservice.value = refstr
-               config.tv.lastservice.save()
+               if refstr != config.tv.lastservice.value:
+                       config.tv.prevservice.value = config.tv.lastservice.value
+                       config.tv.prevservice.save()
+                       config.tv.lastservice.value = refstr
+                       config.tv.lastservice.save()
+
+       def recallPrevService(self):
+               if len(config.tv.prevservice.value) and len(config.tv.prevroot.value):
+                       if config.tv.lastroot.value != config.tv.prevroot.value:
+                               tmp = config.tv.lastroot.value
+                               config.tv.lastroot.value = config.tv.prevroot.value
+                               config.tv.lastroot.save()
+                               config.tv.prevroot.value = tmp
+                               config.tv.prevroot.save()
+                               self.restoreRoot()
+                       if config.tv.lastservice.value != config.tv.prevservice.value:
+                               tmp = config.tv.lastservice.value
+                               config.tv.lastservice.value = config.tv.prevservice.value
+                               config.tv.lastservice.save()
+                               config.tv.prevservice.value = tmp
+                               config.tv.prevservice.save()
+                               lastservice=eServiceReference(config.tv.lastservice.value)
+                               self.session.nav.playService(lastservice)
+                               self.setCurrentSelection(lastservice)
+
+       def cancel(self):
+               self.close(None)
+               self.restoreRoot()
+               lastservice=eServiceReference(config.tv.lastservice.value)
+               if lastservice.valid() and self.getCurrentSelection() != lastservice:
+                       self.setCurrentSelection(lastservice)
+
+from Screens.InfoBarGenerics import InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord
+
+class RadioInfoBar(Screen, InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord):
+       def __init__(self, session):
+               Screen.__init__(self, session)
+               InfoBarEvent.__init__(self)
+               InfoBarServiceName.__init__(self)
+               InfoBarInstantRecord.__init__(self)
+               self["Clock"] = Clock()
+
+class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG):
+       def __init__(self, session):
+               ChannelSelectionBase.__init__(self, session)
+               ChannelSelectionEdit.__init__(self)
+               ChannelSelectionEPG.__init__(self)
+
+               config.radio = ConfigSubsection();
+               config.radio.lastservice = configElement("config.radio.lastservice", configText, "", 0);
+               config.radio.lastroot = configElement("config.radio.lastroot", configText, "", 0);
+               self.onLayoutFinish.append(self.onCreate)
+
+               self.info = session.instantiateDialog(RadioInfoBar)
+
+               self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
+                       {
+                               "keyTV": self.closeRadio,
+                               "keyRadio": self.closeRadio,
+                               "cancel": self.closeRadio,
+                               "ok": self.channelSelected,
+                       })
+
+       def saveRoot(self):
+               path = ''
+               for i in self.servicePathRadio:
+                       path += i.toString()
+                       path += ';'
+               if len(path) and path != config.radio.lastroot.value:
+                       config.radio.lastroot.value = path
+                       config.radio.lastroot.save()
+
+       def restoreRoot(self):
+               self.servicePathRadio = [ ]
+               re = compile('.+?;')
+               tmp = re.findall(config.radio.lastroot.value)
+               cnt = 0
+               for i in tmp:
+                       self.servicePathRadio.append(eServiceReference(i[:len(i)-1]))
+                       cnt += 1
+               if cnt:
+                       path = self.servicePathRadio.pop()
+                       self.enterPath(path)
+               else:
+                       self.showFavourites()
+                       self.saveRoot()
+
+       def preEnterPath(self, refstr):
+               if len(self.servicePathRadio) and self.servicePathRadio[0] != eServiceReference(refstr):
+                       pathstr = config.radio.lastroot.value
+                       if pathstr is not None and pathstr.find(refstr) == 0:
+                               self.restoreRoot()
+                               lastservice=eServiceReference(config.radio.lastservice.value)
+                               if lastservice is not None:
+                                       self.setCurrentSelection(lastservice)
+                               return True
+               return False
+
+       def onCreate(self):
+               self.setRadioMode()
+               self.restoreRoot()
+               lastservice=eServiceReference(config.radio.lastservice.value)
+               if lastservice.valid():
+                       self.servicelist.setCurrent(lastservice)
+                       self.session.nav.playService(lastservice)
+                       self.servicelist.setPlayableIgnoreService(lastservice)
+               self.info.instance.show()
+
+       def channelSelected(self): # just return selected service
+               ref = self.getCurrentSelection()
+               if self.movemode:
+                       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()
+
+       def closeRadio(self):
+               self.info.instance.hide()
+               #set previous tv service
+               lastservice=eServiceReference(config.tv.lastservice.value)
+               self.session.nav.playService(lastservice)
+               self.close(None)
+
+class SimpleChannelSelection(ChannelSelectionBase):
+       def __init__(self, session, title):
+               ChannelSelectionBase.__init__(self, session)
+               self.title = title
+               self.onShown.append(self.onExecCallback)
+
+               self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
+                       {
+                               "cancel": self.cancel,
+                               "ok": self.channelSelected,
+                               "keyRadio": self.setModeRadio,
+                               "keyTV": self.setModeTv,
+                       })
+
+       def onExecCallback(self):
+               self.session.currentDialog.instance.setTitle(self.title)
+               self.setModeTv()
+
+       def channelSelected(self): # just return selected service
+               ref = self.getCurrentSelection()
+               if (ref.flags & 7) == 7:
+                       self.enterPath(ref)
+               else:
+                       ref = self.getCurrentSelection()
+                       self.close(ref)
+
+       def setModeTv(self):
+               self.setTvMode()
+               self.showFavourites()
+
+       def setModeRadio(self):
+               self.setRadioMode()
+               self.showFavourites()