fix "Clearall before scan" handling
[enigma2.git] / lib / python / Screens / ChannelSelection.py
index d8aa39d45e3f2c456d6661a84b3be46c3a6f87b3..47a9d9e66aef0dfd1637d352759e91cf8ef4a03c 100644 (file)
@@ -18,10 +18,12 @@ from ServiceReference import ServiceReference
 from re import *
 from os import remove
 
+FLAG_SERVICE_NEW_FOUND = 64 #define in lib/dvb/idvb.h as dxNewFound = 64
+
 import xml.dom.minidom
 
 class BouquetSelector(Screen):
-       def __init__(self, session, bouquets, selectedFunc):
+       def __init__(self, session, bouquets, selectedFunc, enableWrapAround=False):
                Screen.__init__(self, session)
 
                self.selectedFunc=selectedFunc
@@ -34,10 +36,20 @@ class BouquetSelector(Screen):
                entrys = [ ]
                for x in bouquets:
                        entrys.append((x[0], x[1]))
-               self["menu"] = MenuList(entrys)
+               self["menu"] = MenuList(entrys, enableWrapAround)
+
+       def getCurrent(self):
+               cur = self["menu"].getCurrent()
+               return cur and cur[1]
 
        def okbuttonClick(self):
-               self.selectedFunc(self["menu"].getCurrent()[1])
+               self.selectedFunc(self.getCurrent())
+
+       def up(self):
+               self["menu"].up()
+
+       def down(self):
+               self["menu"].down()
 
        def cancelClick(self):
                self.close(False)
@@ -46,6 +58,7 @@ class ChannelContextMenu(Screen):
        def __init__(self, session, csel):
                Screen.__init__(self, session)
                self.csel = csel
+               self.bsel = None
 
                self["actions"] = ActionMap(["OkCancelActions"],
                        {
@@ -54,7 +67,10 @@ class ChannelContextMenu(Screen):
                        })
                menu = [ ]
 
-               inBouquetRootList = csel.getRoot().getPath().find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
+               current_root = csel.getRoot()
+               current_sel_path = csel.getCurrentSelection().getPath()
+               current_sel_flags = csel.getCurrentSelection().flags
+               inBouquetRootList = current_root and current_root.getPath().find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
                inBouquet = csel.getMutableList() is not None
                haveBouquets = csel.bouquet_root.getPath().find('FROM BOUQUET "bouquets.') != -1
 
@@ -65,11 +81,16 @@ class ChannelContextMenu(Screen):
                                                menu.append((_("add service to bouquet"), self.addServiceToBouquetSelected))
                                        else:
                                                menu.append((_("add service to favourites"), self.addServiceToBouquetSelected))
-                               elif haveBouquets:
-                                       if not inBouquet and csel.getCurrentSelection().getPath().find("PROVIDERS") == -1:
-                                               menu.append((_("copy to favourites"), self.copyCurrentToBouquetList))
+                               else:
+                                       if haveBouquets:
+                                               if not inBouquet and current_sel_path.find("PROVIDERS") == -1:
+                                                       menu.append((_("copy to favourites"), self.copyCurrentToBouquetList))
+                                       if current_sel_path.find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
+                                               menu.append((_("remove all new found flags"), self.removeAllNewFoundFlags))
                                if inBouquet:
                                        menu.append((_("remove service"), self.removeCurrentService))
+                               if current_root.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
+                                       menu.append((_("remove new found flag"), self.removeNewFoundFlag))
                        elif haveBouquets:
                                menu.append((_("remove bouquet"), self.removeBouquet))
 
@@ -107,7 +128,7 @@ class ChannelContextMenu(Screen):
 
        def bouquetInputCallback(self, bouquet):
                if bouquet is not None:
-                       self.csel.addBouquet(bouquet)
+                       self.csel.addBouquet(bouquet, True)
 
        def addServiceToBouquetSelected(self):
                bouquets = self.csel.getBouquetList()
@@ -116,13 +137,14 @@ class ChannelContextMenu(Screen):
                else:
                        cnt = len(bouquets)
                if cnt > 1: # show bouquet list
-                       self.session.openWithCallback(self.bouquetSelClosed, BouquetSelector, bouquets, self.addCurrentServiceToBouquet)
+                       self.bsel = self.session.openWithCallback(self.bouquetSelClosed, BouquetSelector, bouquets, self.addCurrentServiceToBouquet)
                elif cnt == 1: # add to only one existing bouquet
                        self.addCurrentServiceToBouquet(bouquets[0][1])
                else: #no bouquets in root.. so assume only one favourite list is used
                        self.addCurrentServiceToBouquet(self.csel.bouquet_root)
 
        def bouquetSelClosed(self, recursive):
+               self.bsel = None
                if recursive:
                        self.close(False)
 
@@ -136,7 +158,10 @@ class ChannelContextMenu(Screen):
 
        def addCurrentServiceToBouquet(self, dest):
                self.csel.addCurrentServiceToBouquet(dest)
-               self.close(True) # close bouquet selection
+               if self.bsel is not None:
+                       self.bsel.close(True)
+               else:
+                       self.close(True) # close bouquet selection
 
        def removeCurrentService(self):
                self.csel.removeCurrentService()
@@ -158,6 +183,21 @@ class ChannelContextMenu(Screen):
                self.csel.endMarkedEdit(abort=True)
                self.close()
 
+       def removeNewFoundFlag(self):
+               eDVBDB.getInstance().removeFlag(self.csel.getCurrentSelection(), FLAG_SERVICE_NEW_FOUND)
+               self.close()
+
+       def removeAllNewFoundFlags(self):
+               curpath = self.csel.getCurrentSelection().getPath()
+               idx = curpath.find("satellitePosition == ")
+               if idx != -1:
+                       tmp = curpath[idx+21:]
+                       idx = tmp.find(')')
+                       if idx != -1:
+                               satpos = int(tmp[:idx])
+                               eDVBDB.getInstance().removeFlags(FLAG_SERVICE_NEW_FOUND, -1, -1, -1, satpos)
+               self.close()
+
 class ChannelSelectionEPG:
        def __init__(self):
                self["ChannelSelectEPGActions"] = ActionMap(["ChannelSelectEPGActions"],
@@ -208,7 +248,7 @@ class ChannelSelectionEdit:
                serviceHandler = eServiceCenter.getInstance()
                if not root.valid():
                        root=self.getRoot()
-               list = serviceHandler.list(root)
+               list = root and serviceHandler.list(root)
                if list is not None:
                        return list.startEdit()
                return None
@@ -222,17 +262,17 @@ class ChannelSelectionEdit:
                        else:
                                name += '_'
                return name
-       
-       def addBouquet(self, providerName):
+
+       def addBouquet(self, bName, services, refresh=False):
                serviceHandler = eServiceCenter.getInstance()
                mutableBouquetList = serviceHandler.list(self.bouquet_root).startEdit()
                if mutableBouquetList:
                        if self.mode == MODE_TV:
-                               providerName += " (TV)"
-                               str = '1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET \"userbouquet.%s.tv\" ORDER BY bouquet'%(self.buildBouquetID(providerName))
+                               bName += " (TV)"
+                               str = '1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET \"userbouquet.%s.tv\" ORDER BY bouquet'%(self.buildBouquetID(bName))
                        else:
-                               providerName += " (Radio)"
-                               str = '1:7:2:0:0:0:0:0:0:0:(type == 2) FROM BOUQUET \"userbouquet.%s.radio\" ORDER BY bouquet'%(self.buildBouquetID(providerName))
+                               bName += " (Radio)"
+                               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 = { }
@@ -240,9 +280,14 @@ class ChannelSelectionEdit:
                                eDVBDB.getInstance().reloadBouquets()
                                mutableBouquet = serviceHandler.list(new_bouquet_ref).startEdit()
                                if mutableBouquet:
-                                       mutableBouquet.setListName(providerName)
+                                       mutableBouquet.setListName(bName)
+                                       if services is not None:
+                                               for service in services:
+                                                       if mutableBouquet.addService(service):
+                                                               print "add", service.toString(), "to new bouquet failed"
                                        mutableBouquet.flushChanges()
-                                       self.setRoot(self.getRoot())
+                                       if refresh:
+                                               self.setRoot(self.getRoot())
                                else:
                                        print "get mutable list for new created bouquet failed"
                        else:
@@ -252,40 +297,10 @@ class ChannelSelectionEdit:
 
        def copyCurrentToBouquetList(self):
                provider = ServiceReference(self.getCurrentSelection())
+               providerName = provider.getServiceName()
                serviceHandler = eServiceCenter.getInstance()
-               mutableBouquetList = serviceHandler.list(self.bouquet_root).startEdit()
-               if mutableBouquetList:
-                       providerName = provider.getServiceName()
-                       if self.mode == MODE_TV:
-                               str = '1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET \"userbouquet.%s.tv\" ORDER BY bouquet'%(self.buildBouquetID(providerName))
-                       else:
-                               str = '1:7:2:0:0:0:0:0:0:0:(type == 2) FROM BOUQUET \"userbouquet.%s.radio\" ORDER BY bouquet'%(self.buildBouquetID(providerName))
-                       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()
-                               if mutableBouquet:
-                                       mutableBouquet.setListName(providerName)
-                                       list = [ ]
-                                       services = serviceHandler.list(provider.ref)
-                                       if not services is None:
-                                               if not services.getContent(list, True):
-                                                       for service in list:
-                                                               if mutableBouquet.addService(service):
-                                                                       print "add", service.toString(), "to new bouquet failed"
-                                                       mutableBouquet.flushChanges()
-                                               else:
-                                                       print "getContent failed"
-                                       else:
-                                               print "list provider", providerName, "failed"
-                               else:
-                                       print "get mutable list for new created bouquet failed"
-                       else:
-                               print "add", str, "to bouquets failed"
-               else:
-                       print "bouquetlist is not editable"
+               services = serviceHandler.list(provider.ref)
+               self.addBouquet(providerName, services and services.getContent('R', True))
 
        def removeBouquet(self):
                refstr = self.getCurrentSelection().toString()
@@ -297,7 +312,10 @@ class ChannelSelectionEdit:
                        if pos != -1:
                                filename = '/etc/enigma2/' + refstr[:pos] # FIXMEEE !!! HARDCODED /etc/enigma2
                self.removeCurrentService()
-               remove(filename)
+               try:
+                       remove(filename)
+               except OSError:
+                       print "error during remove of", filename
                eDVBDB.getInstance().reloadBouquets()
 
 #  multiple marked entry stuff ( edit mode, later multiepg selection )
@@ -374,7 +392,6 @@ class ChannelSelectionEdit:
                        if not mutableList.addService(self.servicelist.getCurrent()):
                                self.bouquetNumOffsetCache = { }
                                mutableList.flushChanges()
-               self.close()
 
        def toggleMoveMode(self):
                if self.movemode:
@@ -424,7 +441,7 @@ class ChannelSelectionBase(Screen):
                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_tv = '1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17) || (type == 195)'
                self.service_types_radio = '1:7:2:0:0:0:0:0:0:0:(type == 2)'
 
                self["key_red"] = Button(_("All"))
@@ -439,8 +456,8 @@ class ChannelSelectionBase(Screen):
 
                self.servicePathTV = [ ]
                self.servicePathRadio = [ ]
-               self.servicePath = None
-               
+               self.servicePath = [ ]
+
                self.mode = MODE_TV
 
                self.pathChangedDisabled = False
@@ -674,21 +691,28 @@ class ChannelSelectionBase(Screen):
                                                        service = servicelist.getNext()
                                                        if not service.valid(): #check if end of list
                                                                break
-                                                       orbpos = service.getData(4) >> 16
+                                                       orbpos = service.getUnsignedData(4) >> 16
                                                        if service.getPath().find("FROM PROVIDER") != -1:
                                                                service_name = _("Providers")
+                                                       elif service.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
+                                                               service_name = _("New")
                                                        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
-                                                                       orbpos = 3600 - orbpos
-                                                                       h = _("W")
+                                                               if orbpos == 0xFFFF: #Cable
+                                                                       n = ("%s (%s)") % (service_name, _("Cable"))
+                                                               elif orbpos == 0xEEEE: #Terrestrial
+                                                                       n = ("%s (%s)") % (service_name, _("Terrestrial"))
                                                                else:
-                                                                       h = _("E")
-                                                               n = ("%s (%d.%d" + h + ")") % (service_name, orbpos / 10, orbpos % 10)
+                                                                       if orbpos > 1800: # west
+                                                                               orbpos = 3600 - orbpos
+                                                                               h = _("W")
+                                                                       else:
+                                                                               h = _("E")
+                                                                       n = ("%s (%d.%d" + h + ")") % (service_name, orbpos / 10, orbpos % 10)
                                                                service.setName(n)
                                                        self.servicelist.addService(service)
                                                        self.servicelist.finishFill()
@@ -873,18 +897,19 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                        self.session.nav.playService(nref)
                self.saveRoot()
                self.saveChannel()
-               tmp=self.servicePath[:]
-               tmp.append(nref)
-               try:
-                       del self.history[self.history_pos+1:]
-               except:
-                       pass
-               self.history.append(tmp)
-               hlen = len(self.history)
-               if hlen > HISTORYSIZE:
-                       del self.history[0]
-                       hlen -= 1
-               self.history_pos = hlen-1
+               if self.servicePath is not None:
+                       tmp=self.servicePath[:]
+                       tmp.append(nref)
+                       try:
+                               del self.history[self.history_pos+1:]
+                       except:
+                               pass
+                       self.history.append(tmp)
+                       hlen = len(self.history)
+                       if hlen > HISTORYSIZE:
+                               del self.history[0]
+                               hlen -= 1
+                       self.history_pos = hlen-1
 
        def historyBack(self):
                hlen = len(self.history)