X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/52ef2f890b4cf1087cabac94eb88643d06f7a2c1..29f1104e0e69589c5d78e3bdf4811fa6362fb4aa:/lib/python/Screens/ChannelSelection.py diff --git a/lib/python/Screens/ChannelSelection.py b/lib/python/Screens/ChannelSelection.py index c7c1b968..bbd4fd3f 100644 --- a/lib/python/Screens/ChannelSelection.py +++ b/lib/python/Screens/ChannelSelection.py @@ -12,14 +12,18 @@ from Components.NimManager import nimmanager from Components.ServiceName import ServiceName from Components.Clock import Clock from Components.EventInfo import EventInfo +from Components.Input import Input +from Screens.InputBox import InputBox 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 @@ -32,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) @@ -44,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"], { @@ -52,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 @@ -63,18 +81,24 @@ 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"), csel.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"), csel.removeBouquet)) + menu.append((_("remove bouquet"), self.removeBouquet)) if inBouquet: # current list is editable? if not csel.bouquet_mark_edit: if not csel.movemode: menu.append((_("enable move mode"), self.toggleMoveMode)) + menu.append((_("add bouquet..."), self.showBouquetInputBox)) if not inBouquetRootList: if haveBouquets: menu.append((_("enable bouquet edit"), self.bouquetMarkStart)) @@ -98,6 +122,13 @@ class ChannelContextMenu(Screen): def cancelClick(self): self.close(False) + + def showBouquetInputBox(self): + self.session.openWithCallback(self.bouquetInputCallback, InputBox, title=_("Please enter a name for the new bouquet"), text="bouquetname", maxSize=False, type=Input.TEXT) + + def bouquetInputCallback(self, bouquet): + if bouquet is not None: + self.csel.addBouquet(bouquet, True) def addServiceToBouquetSelected(self): bouquets = self.csel.getBouquetList() @@ -106,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) @@ -126,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() @@ -148,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"], @@ -177,13 +227,16 @@ class ChannelSelectionEdit: def __init__(self, csel, contexts = [ ], actions = { }, prio=0): ActionMap.__init__(self, contexts, actions, prio) self.csel = csel + def action(self, contexts, action): if action == "cancel": self.csel.handleEditCancel() + return 0 # fall-trough elif action == "ok": - pass # avoid typo warning... + return 0 # fall-trough else: - ActionMap.action(self, contexts, action) + return ActionMap.action(self, contexts, action) + self["ChannelSelectEditActions"] = ChannelSelectionEditActionMap(self, ["ChannelSelectEditActions", "OkCancelActions"], { "contextMenu": self.doContext, @@ -195,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 @@ -210,16 +263,16 @@ class ChannelSelectionEdit: name += '_' return name - def copyCurrentToBouquetList(self): - provider = ServiceReference(self.getCurrentSelection()) + def addBouquet(self, bName, services, refresh=False): 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)) + 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: - 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 = { } @@ -227,19 +280,14 @@ class ChannelSelectionEdit: 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" + 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() + if refresh: + self.setRoot(self.getRoot()) else: print "get mutable list for new created bouquet failed" else: @@ -247,6 +295,13 @@ class ChannelSelectionEdit: else: print "bouquetlist is not editable" + def copyCurrentToBouquetList(self): + provider = ServiceReference(self.getCurrentSelection()) + providerName = provider.getServiceName() + serviceHandler = eServiceCenter.getInstance() + services = serviceHandler.list(provider.ref) + self.addBouquet(providerName, services and services.getContent('R', True)) + def removeBouquet(self): refstr = self.getCurrentSelection().toString() self.bouquetNumOffsetCache = { } @@ -257,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 ) @@ -272,7 +330,7 @@ class ChannelSelectionEdit: new_title += ' ' + _("[bouquet edit]") else: new_title += ' ' + _("[favourite edit]") - self.instance.setTitle(new_title) + self.setTitle(new_title) self.bouquet_mark_edit = True self.__marked = self.servicelist.getRootServices() for x in self.__marked: @@ -300,9 +358,12 @@ class ChannelSelectionEdit: self.clearMarks() self.bouquet_mark_edit = False self.mutableList = None - self.instance.setTitle(self.saved_title) + self.setTitle(self.saved_title) self.saved_title = None - self.servicePath = self.savedPath[:] + # self.servicePath is just a reference to servicePathTv or Radio... + # so we never ever do use the asignment operator in self.servicePath + del self.servicePath[:] # remove all elements + self.servicePath += self.savedPath # add saved elements del self.savedPath self.setRoot(self.servicePath[len(self.servicePath)-1]) @@ -322,13 +383,8 @@ class ChannelSelectionEdit: if ref.valid() and mutableList is not None: if not mutableList.removeService(ref): self.bouquetNumOffsetCache = { } - currentIndex = self.servicelist.getCurrentIndex() - self.servicelist.moveDown() - if self.servicelist.getCurrentIndex() == currentIndex: - currentIndex -= 1 mutableList.flushChanges() #FIXME dont flush on each single removed service self.setRoot(self.getRoot()) - self.servicelist.moveToIndex(currentIndex) def addCurrentServiceToBouquet(self, dest): mutableList = self.getMutableList(dest) @@ -336,7 +392,6 @@ class ChannelSelectionEdit: if not mutableList.addService(self.servicelist.getCurrent()): self.bouquetNumOffsetCache = { } mutableList.flushChanges() - self.close() def toggleMoveMode(self): if self.movemode: @@ -346,7 +401,7 @@ class ChannelSelectionEdit: self.pathChangedDisabled = False # re-enable path change self.mutableList.flushChanges() # FIXME add check if changes was made self.mutableList = None - self.instance.setTitle(self.saved_title) + self.setTitle(self.saved_title) self.saved_title = None if self.getRoot() == self.bouquet_root: self.bouquetNumOffsetCache = { } @@ -358,7 +413,7 @@ class ChannelSelectionEdit: new_title = self.saved_title pos = self.saved_title.find(')') new_title = self.saved_title[:pos+1] + ' ' + _("[move mode]") + self.saved_title[pos+1:] - self.instance.setTitle(new_title); + self.setTitle(new_title); def handleEditCancel(self): if self.movemode: #movemode active? @@ -386,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")) @@ -401,7 +456,9 @@ class ChannelSelectionBase(Screen): self.servicePathTV = [ ] self.servicePathRadio = [ ] - self.servicePath = None + self.servicePath = [ ] + + self.mode = MODE_TV self.pathChangedDisabled = False @@ -424,7 +481,7 @@ class ChannelSelectionBase(Screen): "7": self.keyNumberGlobal, "8": self.keyNumberGlobal, "9": self.keyNumberGlobal, - "0": self.keyNumberGlobal + "0": self.keyNumber0 }) def appendDVBTypes(self, ref): @@ -487,7 +544,7 @@ class ChannelSelectionBase(Screen): if pos != -1: title = title[:pos] title += " (TV)" - self.instance.setTitle(title) + self.setTitle(title) def setRadioMode(self): self.mode = MODE_RADIO @@ -498,7 +555,7 @@ class ChannelSelectionBase(Screen): if pos != -1: title = title[:pos] title += " (Radio)" - self.instance.setTitle(title) + self.setTitle(title) def setRoot(self, root, justSet=False): path = root.getPath() @@ -559,7 +616,7 @@ class ChannelSelectionBase(Screen): titleStr += '/' nameStr = self.getServiceName(end_ref) titleStr += nameStr - self.instance.setTitle(titleStr) + self.setTitle(titleStr) def moveUp(self): self.servicelist.moveUp() @@ -579,9 +636,9 @@ class ChannelSelectionBase(Screen): length = len(self.servicePath) if length: current = self.servicePath[length-1] - self.setRoot(current, justSet) - if not justSet: - self.setCurrentSelection(prev) + self.setRoot(current, justSet) + if not justSet: + self.setCurrentSelection(prev) return prev def isBasePathEqual(self, ref): @@ -634,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() @@ -749,6 +813,27 @@ class ChannelSelectionBase(Screen): return bouquets return None + def keyNumber0(self, num): + if len(self.servicePath) > 1: + self.keyGoUp() + else: + self.keyNumberGlobal(num) + + def keyGoUp(self): + if len(self.servicePath) > 1: + if self.isBasePathEqual(self.bouquet_root): + self.showFavourites() + else: + ref = eServiceReference('%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types)) + if self.isBasePathEqual(ref): + self.showSatellites() + else: + ref = eServiceReference('%s FROM PROVIDERS ORDER BY name'%(self.service_types)) + if self.isBasePathEqual(ref): + self.showProviders() + else: + self.showAllServices() + HISTORYSIZE = 20 class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG): @@ -761,8 +846,6 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect 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"], { @@ -814,18 +897,22 @@ 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 + self.addToHistory(nref) + + def addToHistory(self, ref): + if self.servicePath is not None: + tmp=self.servicePath[:] + tmp.append(ref) + 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) @@ -842,7 +929,8 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect def setHistoryPath(self): path = self.history[self.history_pos][:] ref = path.pop() - self.servicePath = path + del self.servicePath[:] + self.servicePath += path self.saveRoot() plen = len(path) root = path[plen-1] @@ -857,9 +945,6 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect 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() @@ -897,29 +982,21 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect else: refstr = "" 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) + hlen = len(self.history) + if hlen > 1: + if self.history_pos == hlen-1: + tmp = self.history[self.history_pos] + self.history[self.history_pos] = self.history[self.history_pos-1] + self.history[self.history_pos-1] = tmp + else: + tmp = self.history[self.history_pos+1] + self.history[self.history_pos+1] = self.history[self.history_pos] + self.history[self.history_pos] = tmp + self.setHistoryPath() def cancel(self): self.close(None) @@ -1043,7 +1120,7 @@ class SimpleChannelSelection(ChannelSelectionBase): }) def __onExecCallback(self): - self.session.currentDialog.instance.setTitle(self.title) + self.setTitle(self.title) self.setModeTv() def channelSelected(self): # just return selected service