X-Git-Url: http://code.vuplus.com/gitweb/?p=vuplus_dvbapp;a=blobdiff_plain;f=lib%2Fpython%2FScreens%2FChannelSelection.py;h=34316f01b0b085dc5379b14c44a09b51771c19f2;hp=755d37fca0eb39e0f5be290537e7a88be95eaf24;hb=3c14624fb6631feb91ac28c102027fb9bbc79b7a;hpb=efc5aca651306518e6f21a6bd7cbfa1928821b60 diff --git a/lib/python/Screens/ChannelSelection.py b/lib/python/Screens/ChannelSelection.py index 755d37f..34316f0 100644 --- a/lib/python/Screens/ChannelSelection.py +++ b/lib/python/Screens/ChannelSelection.py @@ -5,7 +5,7 @@ from Components.Button import Button from Components.ServiceList import ServiceList from Components.ActionMap import NumberActionMap, ActionMap, HelpableActionMap from Components.MenuList import MenuList -from Components.ServiceEventTracker import ServiceEventTracker +from Components.ServiceEventTracker import ServiceEventTracker, InfoBarBase profile("ChannelSelection.py 1") from EpgSelection import EPGSelection from enigma import eServiceReference, eEPGCache, eServiceCenter, eRCInput, eTimer, eDVBDB, iPlayableService, iServiceInformation, getPrevAsciiCode @@ -20,16 +20,16 @@ from Components.Sources.ServiceEvent import ServiceEvent profile("ChannelSelection.py 2.3") from Components.Input import Input profile("ChannelSelection.py 3") -from Components.ParentalControl import parentalControl -from Components.Pixmap import Pixmap +from Components.ChoiceList import ChoiceList, ChoiceEntryComponent +from Components.SystemInfo import SystemInfo from Screens.InputBox import InputBox, PinInput from Screens.MessageBox import MessageBox from Screens.ServiceInfo import ServiceInfo profile("ChannelSelection.py 4") +from Screens.PictureInPicture import PictureInPicture from Screens.RdsDisplay import RassInteractive from ServiceReference import ServiceReference from Tools.BoundFunction import boundFunction -from re import compile from os import remove profile("ChannelSelection.py after imports") @@ -70,24 +70,27 @@ OFF = 0 EDIT_BOUQUET = 1 EDIT_ALTERNATIVES = 2 -def append_when_current_valid(current, menu, args, level = 0): +def append_when_current_valid(current, menu, args, level = 0, key = ""): if current and current.valid() and level <= config.usage.setup_level.index: - menu.append(args) + menu.append(ChoiceEntryComponent(key, args)) class ChannelContextMenu(Screen): def __init__(self, session, csel): + Screen.__init__(self, session) - #raise "we need a better summary screen here" + #raise Exception("we need a better summary screen here") self.csel = csel self.bsel = None - self["actions"] = ActionMap(["OkCancelActions"], + self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "NumberActions"], { "ok": self.okbuttonClick, - "cancel": self.cancelClick + "cancel": self.cancelClick, + "blue": self.showServiceInPiP }) menu = [ ] + self.pipAvailable = False current = csel.getCurrentSelection() current_root = csel.getRoot() current_sel_path = current.getPath() @@ -96,22 +99,32 @@ class ChannelContextMenu(Screen): inBouquet = csel.getMutableList() is not None haveBouquets = config.usage.multibouquet.value - if not (len(current_sel_path) or current_sel_flags & (eServiceReference.isDirectory|eServiceReference.isMarker)): + if not (current_sel_path or current_sel_flags & (eServiceReference.isDirectory|eServiceReference.isMarker)): append_when_current_valid(current, menu, (_("show transponder info"), self.showServiceInformations), level = 2) if csel.bouquet_mark_edit == OFF and not csel.movemode: if not inBouquetRootList: isPlayable = not (current_sel_flags & (eServiceReference.isMarker|eServiceReference.isDirectory)) if isPlayable: if config.ParentalControl.configured.value: + from Components.ParentalControl import parentalControl if parentalControl.getProtectionLevel(csel.getCurrentSelection().toCompareString()) == -1: append_when_current_valid(current, menu, (_("add to parental protection"), boundFunction(self.addParentalProtection, csel.getCurrentSelection())), level = 0) else: append_when_current_valid(current, menu, (_("remove from parental protection"), boundFunction(self.removeParentalProtection, csel.getCurrentSelection())), level = 0) if haveBouquets: - append_when_current_valid(current, menu, (_("add service to bouquet"), self.addServiceToBouquetSelected), level = 0) + bouquets = self.csel.getBouquetList() + if bouquets is None: + bouquetCnt = 0 + else: + bouquetCnt = len(bouquets) + if not inBouquet or bouquetCnt > 1: + append_when_current_valid(current, menu, (_("add service to bouquet"), self.addServiceToBouquetSelected), level = 0) else: - append_when_current_valid(current, menu, (_("add service to favourites"), self.addServiceToBouquetSelected), level = 0) + if not inBouquet: + append_when_current_valid(current, menu, (_("add service to favourites"), self.addServiceToBouquetSelected), level = 0) else: + if current_root.getPath().find('FROM SATELLITES') != -1: + append_when_current_valid(current, menu, (_("remove selected satellite"), self.removeSatelliteServices), level = 0) if haveBouquets: if not inBouquet and current_sel_path.find("PROVIDERS") == -1: append_when_current_valid(current, menu, (_("copy to bouquets"), self.copyCurrentToBouquetList), level = 0) @@ -121,8 +134,11 @@ class ChannelContextMenu(Screen): append_when_current_valid(current, menu, (_("remove entry"), self.removeCurrentService), level = 0) if current_root and current_root.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1: append_when_current_valid(current, menu, (_("remove new found flag"), self.removeNewFoundFlag), level = 0) + if isPlayable and SystemInfo.get("NumVideoDecoders", 1) > 1: + append_when_current_valid(current, menu, (_("Activate Picture in Picture"), self.showServiceInPiP), level = 0, key = "blue") + self.pipAvailable = True else: - menu.append((_("add bouquet"), self.showBouquetInputBox)) + menu.append(ChoiceEntryComponent(text = (_("add bouquet"), self.showBouquetInputBox))) append_when_current_valid(current, menu, (_("remove entry"), self.removeBouquet), level = 0) if inBouquet: # current list is editable? @@ -130,7 +146,7 @@ class ChannelContextMenu(Screen): if not csel.movemode: append_when_current_valid(current, menu, (_("enable move mode"), self.toggleMoveMode), level = 1) if not inBouquetRootList and current_root and not (current_root.flags & eServiceReference.isGroup): - menu.append((_("add marker"), self.showMarkerInputBox)) + menu.append(ChoiceEntryComponent(text = (_("add marker"), self.showMarkerInputBox))) if haveBouquets: append_when_current_valid(current, menu, (_("enable bouquet edit"), self.bouquetMarkStart), level = 0) else: @@ -155,11 +171,11 @@ class ChannelContextMenu(Screen): append_when_current_valid(current, menu, (_("end alternatives edit"), self.bouquetMarkEnd), level = 0) append_when_current_valid(current, menu, (_("abort alternatives edit"), self.bouquetMarkAbort), level = 0) - menu.append((_("back"), self.cancelClick)) - self["menu"] = MenuList(menu) + menu.append(ChoiceEntryComponent(text = (_("back"), self.cancelClick))) + self["menu"] = ChoiceList(menu) def okbuttonClick(self): - self["menu"].getCurrent()[1]() + self["menu"].getCurrent()[0][1]() def cancelClick(self): self.close(False) @@ -176,6 +192,7 @@ class ChannelContextMenu(Screen): self.close() def addParentalProtection(self, service): + from Components.ParentalControl import parentalControl parentalControl.protectService(service.toCompareString()) self.close() @@ -184,10 +201,28 @@ class ChannelContextMenu(Screen): def pinEntered(self, service, result): if result: + from Components.ParentalControl import parentalControl parentalControl.unProtectService(service) self.close() else: self.session.openWithCallback(self.close, MessageBox, _("The pin code you entered is wrong."), MessageBox.TYPE_ERROR) + + def showServiceInPiP(self): + if not self.pipAvailable: + return + if self.session.pipshown: + del self.session.pip + self.session.pip = self.session.instantiateDialog(PictureInPicture) + self.session.pip.show() + newservice = self.csel.servicelist.getCurrent() + if self.session.pip.playService(newservice): + self.session.pipshown = True + self.session.pip.servicePath = self.csel.getCurrentServicePath() + self.close(True) + else: + self.session.pipshown = False + del self.session.pip + self.session.openWithCallback(self.close, MessageBox, _("Could not open Picture in Picture"), MessageBox.TYPE_ERROR) def addServiceToBouquetSelected(self): bouquets = self.csel.getBouquetList() @@ -198,13 +233,24 @@ class ChannelContextMenu(Screen): if cnt > 1: # show bouquet list 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]) + self.addCurrentServiceToBouquet(bouquets[0][1], closeBouquetSelection = False) def bouquetSelClosed(self, recursive): self.bsel = None if recursive: self.close(False) + def removeSatelliteServices(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().removeServices(-1, -1, -1, satpos) + self.close() + def copyCurrentToBouquetList(self): self.csel.copyCurrentToBouquetList() self.close() @@ -221,12 +267,12 @@ class ChannelContextMenu(Screen): self.csel.addMarker(marker) self.close() - def addCurrentServiceToBouquet(self, dest): + def addCurrentServiceToBouquet(self, dest, closeBouquetSelection = True): self.csel.addServiceToBouquet(dest) if self.bsel is not None: self.bsel.close(True) else: - self.close(True) # close bouquet selection + self.close(closeBouquetSelection) # close bouquet selection def removeCurrentService(self): self.csel.removeCurrentService() @@ -305,11 +351,24 @@ class ChannelSelectionEPG: 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() + if ref: + self.savedService = ref + self.session.openWithCallback(self.SingleServiceEPGClosed, EPGSelection, ref, serviceChangeCB=self.changeServiceCB) + + def SingleServiceEPGClosed(self, ret=False): + self.setCurrentSelection(self.savedService) + + def changeServiceCB(self, direction, epg): + beg = self.getCurrentSelection() + while True: + if direction > 0: + self.moveDown() + else: + self.moveUp() + cur = self.getCurrentSelection() + if cur == beg or not (cur.flags & eServiceReference.isMarker): + break + epg.setService(ServiceReference(self.getCurrentSelection())) class ChannelSelectionEdit: def __init__(self): @@ -400,7 +459,7 @@ class ChannelSelectionEdit: if mutableAlternatives: mutableAlternatives.setListName(name) if mutableAlternatives.addService(cur_service.ref): - print "add", cur_service.toString(), "to new alternatives failed" + print "add", cur_service.ref.toString(), "to new alternatives failed" mutableAlternatives.flushChanges() self.servicelist.addService(new_ref.ref, True) self.servicelist.removeCurrent() @@ -501,7 +560,7 @@ class ChannelSelectionEdit: self.mutableList = self.getMutableList() # add all services from the current list to internal marked set in listboxservicecontent self.clearMarks() # this clears the internal marked set in the listboxservicecontent - self.saved_title = self.instance.getTitle() + self.saved_title = self.getTitle() pos = self.saved_title.find(')') new_title = self.saved_title[:pos+1] if type == EDIT_ALTERNATIVES: @@ -546,7 +605,7 @@ class ChannelSelectionEdit: del self.servicePath[:] # remove all elements self.servicePath += self.savedPath # add saved elements del self.savedPath - self.setRoot(self.servicePath[len(self.servicePath)-1]) + self.setRoot(self.servicePath[-1]) def clearMarks(self): self.servicelist.clearMarks() @@ -601,7 +660,7 @@ class ChannelSelectionEdit: self.mutableList = self.getMutableList() self.movemode = True self.pathChangeDisabled = True # no path change allowed in movemode - self.saved_title = self.instance.getTitle() + self.saved_title = self.getTitle() new_title = self.saved_title pos = self.saved_title.find(')') new_title = self.saved_title[:pos+1] + ' ' + _("[move mode]") + self.saved_title[pos+1:] @@ -623,14 +682,27 @@ class ChannelSelectionEdit: self.entry_marked = True def doContext(self): - self.session.open(ChannelContextMenu, self) + self.session.openWithCallback(self.exitContext, ChannelContextMenu, self) + + def exitContext(self, close = False): + if close: + self.cancel() MODE_TV = 0 MODE_RADIO = 1 -# this makes it much simple to implement a selectable radio or tv mode :) -service_types_tv = '1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17) || (type == 195) || (type == 25) || (type == 134)' -service_types_radio = '1:7:2:0:0:0:0:0:0:0:(type == 2)' +# type 1 = digital television service +# type 4 = nvod reference service (NYI) +# type 17 = MPEG-2 HD digital television service +# type 22 = advanced codec SD digital television +# type 24 = advanced codec SD NVOD reference service (NYI) +# type 25 = advanced codec HD digital television +# type 27 = advanced codec HD NVOD reference service (NYI) +# type 2 = digital radio sound service +# type 10 = advanced codec digital radio sound service + +service_types_tv = '1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17) || (type == 22) || (type == 25) || (type == 134) || (type == 195)' +service_types_radio = '1:7:2:0:0:0:0:0:0:0:(type == 2) || (type == 10)' class ChannelSelectionBase(Screen): def __init__(self, session): @@ -650,6 +722,7 @@ class ChannelSelectionBase(Screen): self.servicePathTV = [ ] self.servicePathRadio = [ ] self.servicePath = [ ] + self.rootChanged = False self.mode = MODE_TV @@ -727,7 +800,7 @@ class ChannelSelectionBase(Screen): self.mode = MODE_TV self.servicePath = self.servicePathTV self.recallBouquetMode() - title = self.instance.getTitle() + title = self.getTitle() pos = title.find(" (") if pos != -1: title = title[:pos] @@ -738,7 +811,7 @@ class ChannelSelectionBase(Screen): self.mode = MODE_RADIO self.servicePath = self.servicePathRadio self.recallBouquetMode() - title = self.instance.getTitle() + title = self.getTitle() pos = title.find(" (") if pos != -1: title = title[:pos] @@ -756,6 +829,7 @@ class ChannelSelectionBase(Screen): else: self.servicelist.setMode(ServiceList.MODE_NORMAL) self.servicelist.setRoot(root, justSet) + self.rootChanged = True self.buildTitleString() def removeModeStr(self, str): @@ -769,18 +843,18 @@ class ChannelSelectionBase(Screen): def getServiceName(self, ref): str = self.removeModeStr(ServiceReference(ref).getServiceName()) - if not len(str): + if not str: pathstr = ref.getPath() - if pathstr.find('FROM PROVIDERS') != -1: + if 'FROM PROVIDERS' in pathstr: return _("Provider") - if pathstr.find('FROM SATELLITES') != -1: + if 'FROM SATELLITES' in pathstr: return _("Satellites") - if pathstr.find(') ORDER BY name') != -1: + if ') ORDER BY name' in pathstr: return _("All") return str def buildTitleString(self): - titleStr = self.instance.getTitle() + titleStr = self.getTitle() pos = titleStr.find(']') if pos == -1: pos = titleStr.find(')') @@ -819,9 +893,8 @@ class ChannelSelectionBase(Screen): def pathUp(self, justSet=False): prev = self.servicePath.pop() - length = len(self.servicePath) - if length: - current = self.servicePath[length-1] + if self.servicePath: + current = self.servicePath[-1] self.setRoot(current, justSet) if not justSet: self.setCurrentSelection(prev) @@ -949,7 +1022,7 @@ class ChannelSelectionBase(Screen): self.enterPath(ref) def inBouquet(self): - if len(self.servicePath) > 0 and self.servicePath[0] == self.bouquet_root: + if self.servicePath and self.servicePath[0] == self.bouquet_root: return True return False @@ -1118,6 +1191,7 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect self.servicelist.setPlayableIgnoreService(eServiceReference()) def setMode(self): + self.rootChanged = True self.restoreRoot() lastservice=eServiceReference(self.lastservice.value) if lastservice.valid(): @@ -1223,8 +1297,7 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect del self.servicePath[:] self.servicePath += path self.saveRoot() - plen = len(path) - root = path[plen-1] + root = path[-1] cur_root = self.getRoot() if cur_root and cur_root != root: self.setRoot(root) @@ -1237,27 +1310,29 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect for i in self.servicePath: path += i.toString() path += ';' - if len(path) and path != self.lastroot.value: + if path and path != self.lastroot.value: self.lastroot.value = path self.lastroot.save() def restoreRoot(self): - self.clearPath() - re = compile('.+?;') - tmp = re.findall(self.lastroot.value) - cnt = 0 - for i in tmp: - self.servicePath.append(eServiceReference(i[:len(i)-1])) - cnt += 1 - if cnt: - path = self.servicePath.pop() - self.enterPath(path) - else: - self.showFavourites() - self.saveRoot() + tmp = [x for x in self.lastroot.value.split(';') if x != ''] + current = [x.toString() for x in self.servicePath] + if tmp != current or self.rootChanged: + self.clearPath() + cnt = 0 + for i in tmp: + self.servicePath.append(eServiceReference(i)) + cnt += 1 + if cnt: + path = self.servicePath.pop() + self.enterPath(path) + else: + self.showFavourites() + self.saveRoot() + self.rootChanged = False def preEnterPath(self, refstr): - if len(self.servicePath) and self.servicePath[0] != eServiceReference(refstr): + if self.servicePath and self.servicePath[0] != eServiceReference(refstr): pathstr = self.lastroot.value if pathstr is not None and pathstr.find(refstr) == 0: self.restoreRoot() @@ -1277,16 +1352,14 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect self.lastservice.save() def setCurrentServicePath(self, path): - hlen = len(self.history) - if hlen > 0: + if self.history: self.history[self.history_pos] = path else: self.history.append(path) self.setHistoryPath() def getCurrentServicePath(self): - hlen = len(self.history) - if hlen > 0: + if self.history: return self.history[self.history_pos] return None @@ -1320,18 +1393,16 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect class RadioInfoBar(Screen): def __init__(self, session): Screen.__init__(self, session) - InfoBarEvent.__init__(self) self["RdsDecoder"] = RdsDecoder(self.session.nav) - self["BlinkingPoint"] = Pixmap() - self["BlinkingPoint"].hide() -class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG): +class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG, InfoBarBase): ALLOW_SUSPEND = True def __init__(self, session, infobar): ChannelSelectionBase.__init__(self, session) ChannelSelectionEdit.__init__(self) ChannelSelectionEPG.__init__(self) + InfoBarBase.__init__(self) self.infobar = infobar self.onLayoutFinish.append(self.onCreate) @@ -1339,9 +1410,9 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"], { - "keyTV": self.closeRadio, - "keyRadio": self.closeRadio, - "cancel": self.closeRadio, + "keyTV": self.cancel, + "keyRadio": self.cancel, + "cancel": self.cancel, "ok": self.channelSelected, }) @@ -1360,6 +1431,11 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS },-1) self["RdsActions"].setEnabled(False) infobar.rds_display.onRassInteractivePossibilityChanged.append(self.RassInteractivePossibilityChanged) + self.onClose.append(self.__onClose) + + def __onClose(self): + lastservice=eServiceReference(config.tv.lastservice.value) + self.session.nav.playService(lastservice) def startRassInteractive(self): self.info.hide(); @@ -1374,12 +1450,10 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS self["RdsActions"].setEnabled(state) ########## RDS Radiotext / Rass Support END - def closeRadio(self): + def cancel(self): self.infobar.rds_display.onRassInteractivePossibilityChanged.remove(self.RassInteractivePossibilityChanged) self.info.hide() #set previous tv service - lastservice=eServiceReference(config.tv.lastservice.value) - self.session.nav.playService(lastservice) self.close(None) def __evServiceStart(self): @@ -1398,27 +1472,28 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS for i in self.servicePathRadio: path += i.toString() path += ';' - if len(path) and path != config.radio.lastroot.value: + if path and path != config.radio.lastroot.value: config.radio.lastroot.value = path config.radio.lastroot.save() def restoreRoot(self): - self.clearPath() - 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() + tmp = [x for x in config.radio.lastroot.value.split(';') if x != ''] + current = [x.toString() for x in self.servicePath] + if tmp != current or self.rootChanged: + cnt = 0 + for i in tmp: + self.servicePathRadio.append(eServiceReference(i)) + cnt += 1 + if cnt: + path = self.servicePathRadio.pop() + self.enterPath(path) + else: + self.showFavourites() + self.saveRoot() + self.rootChanged = False def preEnterPath(self, refstr): - if len(self.servicePathRadio) and self.servicePathRadio[0] != eServiceReference(refstr): + if 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() @@ -1461,9 +1536,6 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS 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.close, @@ -1471,9 +1543,10 @@ class SimpleChannelSelection(ChannelSelectionBase): "keyRadio": self.setModeRadio, "keyTV": self.setModeTv, }) + self.title = title + self.onLayoutFinish.append(self.layoutFinished) - def __onExecCallback(self): - self.setTitle(self.title) + def layoutFinished(self): self.setModeTv() def channelSelected(self): # just return selected service