more changes for service groups (replacement for zapping alternatives
[vuplus_dvbapp] / lib / python / Screens / ChannelSelection.py
index c376d4f..6a5605c 100644 (file)
@@ -3,8 +3,9 @@ from Components.Button import Button
 from Components.ServiceList import ServiceList
 from Components.ActionMap import NumberActionMap, ActionMap
 from Components.MenuList import MenuList
+from Components.ServiceEventTracker import ServiceEventTracker
 from EpgSelection import EPGSelection
-from enigma import eServiceReference, eEPGCache, eServiceCenter, eServiceCenterPtr, iMutableServiceListPtr, iStaticServiceInformationPtr, eTimer, eDVBDB
+from enigma import eServiceReference, eEPGCache, eServiceCenter, eServiceCenterPtr, iMutableServiceListPtr, iStaticServiceInformationPtr, eTimer, eDVBDB, iPlayableService, iServiceInformation
 from Components.config import config, ConfigSubsection, ConfigText
 from Screens.FixedMenu import FixedMenu
 from Tools.NumericalTextInput import NumericalTextInput
@@ -77,7 +78,9 @@ class ChannelContextMenu(Screen):
 
                if not csel.bouquet_mark_edit and not csel.movemode:
                        if not inBouquetRootList:
-                               if (csel.getCurrentSelection().flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory:
+                               flags = csel.getCurrentSelection().flags
+                               isPlayable = not ((flags & eServiceReference.isMarker) or (flags & 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())))
@@ -185,7 +188,7 @@ class ChannelContextMenu(Screen):
                self.close()
 
        def addCurrentServiceToBouquet(self, dest):
-               self.csel.addCurrentServiceToBouquet(dest)
+               self.csel.addServiceToBouquet(dest)
                if self.bsel is not None:
                        self.bsel.close(True)
                else:
@@ -321,7 +324,6 @@ class ChannelSelectionEdit:
                                str = '1:7:2:0:0:0:0:0:0:0:(type == 2) FROM BOUQUET \"userbouquet.%s.radio\" ORDER BY bouquet'%(self.buildBouquetID(bName))
                        new_bouquet_ref = eServiceReference(str)
                        if not mutableBouquetList.addService(new_bouquet_ref):
-                               self.bouquetNumOffsetCache = { }
                                mutableBouquetList.flushChanges()
                                eDVBDB.getInstance().reloadBouquets()
                                mutableBouquet = serviceHandler.list(new_bouquet_ref).startEdit()
@@ -331,10 +333,6 @@ class ChannelSelectionEdit:
                                                for service in services:
                                                        if mutableBouquet.addService(service):
                                                                print "add", service.toString(), "to new bouquet failed"
-                                                       else:
-                                                               current = self.servicelist.getCurrent()
-                                                               if current and current.toString() == self.bouquet_rootstr:
-                                                                       self.servicelist.addService(service, True)
                                        mutableBouquet.flushChanges()
                                else:
                                        print "get mutable list for new created bouquet failed"
@@ -344,7 +342,7 @@ class ChannelSelectionEdit:
                                pos1 = str1.find("FROM BOUQUET")
                                pos2 = self.bouquet_rootstr.find("FROM BOUQUET")
                                if pos1 != -1 and pos2 != -1 and str1[pos1:] == self.bouquet_rootstr[pos2:]:
-                                       self.setMode() #reload
+                                       self.servicelist.addService(new_bouquet_ref)
                        else:
                                print "add", str, "to bouquets failed"
                else:
@@ -442,19 +440,29 @@ class ChannelSelectionEdit:
                                mutableList.flushChanges() #FIXME dont flush on each single removed service
                                self.servicelist.removeCurrent()
 
-       def addCurrentServiceToBouquet(self, dest):
+       def addServiceToBouquet(self, dest, service=None):
                mutableList = self.getMutableList(dest)
                if not mutableList is None:
-                       if not mutableList.addService(self.servicelist.getCurrent()):
+                       if service is None: #use current selected service
+                               service = self.servicelist.getCurrent()
+                       if not mutableList.addService(service):
                                self.bouquetNumOffsetCache = { }
                                mutableList.flushChanges()
+                               # do some voodoo to check if current_root is equal to dest
+                               cur_root = self.getRoot();
+                               str1 = cur_root.toString()
+                               str2 = dest.toString()
+                               pos1 = str1.find("FROM BOUQUET")
+                               pos2 = str2.find("FROM BOUQUET")
+                               if pos1 != -1 and pos2 != -1 and str1[pos1:] == str2[pos2:]:
+                                       self.servicelist.addService(service)
 
        def toggleMoveMode(self):
                if self.movemode:
                        if self.entry_marked:
                                self.toggleMoveMarked() # unmark current entry
                        self.movemode = False
-                       self.pathChangedDisabled = False # re-enable path change
+                       self.pathChangeDisabled = False # re-enable path change
                        self.mutableList.flushChanges() # FIXME add check if changes was made
                        self.mutableList = None
                        self.setTitle(self.saved_title)
@@ -464,7 +472,7 @@ class ChannelSelectionEdit:
                else:
                        self.mutableList = self.getMutableList()
                        self.movemode = True
-                       self.pathChangedDisabled = True # no path change allowed in movemode
+                       self.pathChangeDisabled = True # no path change allowed in movemode
                        self.saved_title = self.instance.getTitle()
                        new_title = self.saved_title
                        pos = self.saved_title.find(')')
@@ -517,7 +525,7 @@ class ChannelSelectionBase(Screen):
 
                self.mode = MODE_TV
 
-               self.pathChangedDisabled = False
+               self.pathChangeDisabled = False
 
                self.bouquetNumOffsetCache = { }
 
@@ -552,13 +560,12 @@ class ChannelSelectionBase(Screen):
                return ref
 
        def getBouquetNumOffset(self, bouquet):
-               if config.usage.multibouquet.value:
+               if not config.usage.multibouquet.value:
                        return 0
                bouquet = self.appendDVBTypes(bouquet)
-               try:
-                       return self.bouquetNumOffsetCache[bouquet.toString()]
-               except:
-                       offsetCount = 0
+               str = bouquet.toString()
+               offsetCount = 0
+               if not self.bouquetNumOffsetCache.has_key(str):
                        serviceHandler = eServiceCenter.getInstance()
                        bouquetlist = serviceHandler.list(self.bouquet_root)
                        if not bouquetlist is None:
@@ -567,7 +574,7 @@ class ChannelSelectionBase(Screen):
                                        if not bouquetIterator.valid(): #end of list
                                                break
                                        self.bouquetNumOffsetCache[bouquetIterator.toString()]=offsetCount
-                                       if ((bouquetIterator.flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory):
+                                       if not (bouquetIterator.flags & eServiceReference.isDirectory):
                                                continue
                                        servicelist = serviceHandler.list(bouquetIterator)
                                        if not servicelist is None:
@@ -578,7 +585,7 @@ class ChannelSelectionBase(Screen):
                                                        if serviceIterator.flags: #playable services have no flags
                                                                continue
                                                        offsetCount += 1
-               return self.bouquetNumOffsetCache.get(bouquet.toString(), offsetCount)
+               return self.bouquetNumOffsetCache.get(str, offsetCount)
 
        def recallBouquetMode(self):
                if self.mode == MODE_TV:
@@ -716,7 +723,7 @@ class ChannelSelectionBase(Screen):
                return False
 
        def showAllServices(self):
-               if not self.pathChangedDisabled:
+               if not self.pathChangeDisabled:
                        refstr = '%s ORDER BY name'%(self.service_types)
                        if not self.preEnterPath(refstr):
                                ref = eServiceReference(refstr)
@@ -726,7 +733,7 @@ class ChannelSelectionBase(Screen):
                                        self.enterPath(ref)
 
        def showSatellites(self):
-               if not self.pathChangedDisabled:
+               if not self.pathChangeDisabled:
                        refstr = '%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types)
                        if not self.preEnterPath(refstr):
                                ref = eServiceReference(refstr)
@@ -780,7 +787,7 @@ class ChannelSelectionBase(Screen):
                                                        self.setCurrentSelection(prev)
 
        def showProviders(self):
-               if not self.pathChangedDisabled:
+               if not self.pathChangeDisabled:
                        refstr = '%s FROM PROVIDERS ORDER BY name'%(self.service_types)
                        if not self.preEnterPath(refstr):
                                ref = eServiceReference(refstr)
@@ -793,9 +800,14 @@ class ChannelSelectionBase(Screen):
                                                self.enterPath(ref)
 
        def changeBouquet(self, direction):
-               if not self.pathChangedDisabled:
-                       if self.isBasePathEqual(self.bouquet_root):
-                               self.pathUp()
+               if not self.pathChangeDisabled:
+                       if len(self.servicePath) > 1:
+                               #when enter satellite root list we must do some magic stuff..
+                               ref = eServiceReference('%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types))
+                               if self.isBasePathEqual(ref):
+                                       self.showSatellites()
+                               else:
+                                       self.pathUp()
                                if direction < 0:
                                        self.moveUp()
                                else:
@@ -819,7 +831,7 @@ class ChannelSelectionBase(Screen):
                self.changeBouquet(-1)
 
        def showFavourites(self):
-               if not self.pathChangedDisabled:
+               if not self.pathChangeDisabled:
                        if not self.preEnterPath(self.bouquet_rootstr):
                                if self.isBasePathEqual(self.bouquet_root):
                                        self.pathUp()
@@ -857,23 +869,38 @@ class ChannelSelectionBase(Screen):
                serviceHandler = eServiceCenter.getInstance()
                if config.usage.multibouquet.value:
                        list = serviceHandler.list(self.bouquet_root)
-                       if not list is None:
+                       if list:
                                while True:
                                        s = list.getNext()
                                        if not s.valid():
                                                break
-                                       if ((s.flags & eServiceReference.flagDirectory) == eServiceReference.flagDirectory):
+                                       if s.flags & eServiceReference.isDirectory:
                                                info = serviceHandler.info(s)
-                                               if not info is None:
+                                               if info:
                                                        bouquets.append((info.getName(s), s))
                                return bouquets
                else:
                        info = serviceHandler.info(self.bouquet_root)
-                       if not info is None:
+                       if info:
                                bouquets.append((info.getName(self.bouquet_root), self.bouquet_root))
                        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()
@@ -927,7 +954,11 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                                "keyTV": self.setModeTv,
                        })
 
-               self.onShown.append(self.__onShown)
+               self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
+                       {
+                               iPlayableService.evStart: self.__evServiceStart,
+                               iPlayableService.evEnd: self.__evServiceEnd
+                       })
 
                self.lastChannelRootTimer = eTimer()
                self.lastChannelRootTimer.timeout.get().append(self.__onCreate)
@@ -942,6 +973,17 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                self.lastroot = config.tv.lastroot
                self.revertMode = None
 
+       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()
                lastservice=eServiceReference(self.lastservice.value)
@@ -981,14 +1023,6 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                if lastservice.valid():
                        self.zap()
 
-       def __onShown(self):
-               self.recallBouquetMode()
-               ref = self.session.nav.getCurrentlyPlayingServiceReference()
-               if ref is not None and ref.valid() and ref.getPath() == "":
-                       self.servicelist.setPlayableIgnoreService(ref)
-               else:
-                       self.servicelist.setPlayableIgnoreService(eServiceReference())
-
        def channelSelected(self):
                ref = self.getCurrentSelection()
                if self.movemode:
@@ -1009,7 +1043,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)
 
@@ -1052,7 +1086,7 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                        self.setRoot(root)
                self.session.nav.playService(ref)
                self.setCurrentSelection(ref)
-               self.saveChannel()
+               self.saveChannel(ref)
 
        def saveRoot(self):
                path = ''
@@ -1089,8 +1123,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:
@@ -1174,6 +1207,23 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS
                                "ok": self.channelSelected,
                        })
 
+               self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
+                       {
+                               iPlayableService.evStart: self.__evServiceStart,
+                               iPlayableService.evEnd: self.__evServiceEnd
+                       })
+
+       def __evServiceStart(self):
+               service = self.session.nav.getCurrentService()
+               if service:
+                       info = service.info()
+                       if info:
+                               refstr = info.getInfoString(iServiceInformation.sServiceref)
+                               self.servicelist.setPlayableIgnoreService(eServiceReference(refstr))
+
+       def __evServiceEnd(self):
+               self.servicelist.setPlayableIgnoreService(eServiceReference())
+
        def saveRoot(self):
                path = ''
                for i in self.servicePathRadio:
@@ -1216,7 +1266,6 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS
                if lastservice.valid():
                        self.servicelist.setCurrent(lastservice)
                        self.session.nav.playService(lastservice)
-                       self.servicelist.setPlayableIgnoreService(lastservice)
                self.info.show()
 
        def channelSelected(self): # just return selected service
@@ -1231,7 +1280,6 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS
                        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()