X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/d2bea1918fa33f5e92ed75f3f744c119439924bc..b58a0fa7cab89937586e2d08d79274fab3f14edc:/lib/python/Screens/ChannelSelection.py diff --git a/lib/python/Screens/ChannelSelection.py b/lib/python/Screens/ChannelSelection.py index c75c421a..e2dbd6b5 100644 --- a/lib/python/Screens/ChannelSelection.py +++ b/lib/python/Screens/ChannelSelection.py @@ -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, eTimer, eDVBDB, iPlayableService, iServiceInformation from Components.config import config, ConfigSubsection, ConfigText from Screens.FixedMenu import FixedMenu from Tools.NumericalTextInput import NumericalTextInput @@ -14,6 +15,7 @@ from Components.Input import Input from Components.ParentalControl import parentalControl from Screens.InputBox import InputBox, PinInput from Screens.MessageBox import MessageBox +from Screens.ServiceInfo import ServiceInfo from ServiceReference import ServiceReference from Tools.BoundFunction import boundFunction from re import * @@ -55,6 +57,11 @@ class BouquetSelector(Screen): def cancelClick(self): self.close(False) +# csel.bouquet_mark_edit values +OFF = 0 +EDIT_BOUQUET = 1 +EDIT_ALTERNATIVES = 2 + class ChannelContextMenu(Screen): def __init__(self, session, csel): Screen.__init__(self, session) @@ -75,9 +82,12 @@ class ChannelContextMenu(Screen): inBouquet = csel.getMutableList() is not None haveBouquets = config.usage.multibouquet.value - if not csel.bouquet_mark_edit and not csel.movemode: + if not (len(current_sel_path) or current_sel_flags & eServiceReference.isDirectory): + menu.append((_("show transponder info"), self.showServiceInformations)) + if csel.bouquet_mark_edit == OFF and not csel.movemode: if not inBouquetRootList: - if (csel.getCurrentSelection().flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory: + isPlayable = not (current_sel_flags & (eServiceReference.isMarker|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()))) @@ -95,31 +105,41 @@ class ChannelContextMenu(Screen): menu.append((_("remove all new found flags"), self.removeAllNewFoundFlags)) if inBouquet: menu.append((_("remove entry"), self.removeCurrentService)) - if current_root is not None and current_root.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1: + if current_root and current_root.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1: menu.append((_("remove new found flag"), self.removeNewFoundFlag)) else: menu.append((_("add bouquet"), self.showBouquetInputBox)) menu.append((_("remove entry"), self.removeBouquet)) if inBouquet: # current list is editable? - if not csel.bouquet_mark_edit: + if csel.bouquet_mark_edit == OFF: if not csel.movemode: - menu.append((_("add marker"), self.showMarkerInputBox)) menu.append((_("enable move mode"), self.toggleMoveMode)) - if not inBouquetRootList: + if not inBouquetRootList and current_root and not (current_root.flags & eServiceReference.isGroup): + menu.append((_("add marker"), self.showMarkerInputBox)) if haveBouquets: menu.append((_("enable bouquet edit"), self.bouquetMarkStart)) else: menu.append((_("enable favourite edit"), self.bouquetMarkStart)) + if current_sel_flags & eServiceReference.isGroup: + menu.append((_("edit alternatives"), self.editAlternativeServices)) + menu.append((_("show alternatives"), self.showAlternativeServices)) + menu.append((_("remove all alternatives"), self.removeAlternativeServices)) + else: + menu.append((_("add alternatives"), self.addAlternativeServices)) else: 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: + if csel.bouquet_mark_edit == EDIT_BOUQUET: + 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)) else: - menu.append((_("end favourites edit"), self.bouquetMarkEnd)) - menu.append((_("abort favourites edit"), self.bouquetMarkAbort)) + menu.append((_("end alternatives edit"), self.bouquetMarkEnd)) + menu.append((_("abort alternatives edit"), self.bouquetMarkAbort)) menu.append((_("back"), self.cancelClick)) self["menu"] = MenuList(menu) @@ -129,7 +149,10 @@ class ChannelContextMenu(Screen): def cancelClick(self): self.close(False) - + + def showServiceInformations(self): + self.session.open( ServiceInfo, self.csel.getCurrentSelection() ) + 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) @@ -200,7 +223,7 @@ class ChannelContextMenu(Screen): self.close() def bouquetMarkStart(self): - self.csel.startMarkedEdit() + self.csel.startMarkedEdit(EDIT_BOUQUET) self.close() def bouquetMarkEnd(self): @@ -226,6 +249,23 @@ class ChannelContextMenu(Screen): eDVBDB.getInstance().removeFlags(FLAG_SERVICE_NEW_FOUND, -1, -1, -1, satpos) self.close() + def editAlternativeServices(self): + self.csel.startMarkedEdit(EDIT_ALTERNATIVES) + self.close() + + def showAlternativeServices(self): + self.csel.enterPath(self.csel.getCurrentSelection()) + self.close() + + def removeAlternativeServices(self): + self.csel.removeAlternativeServices() + self.close() + + def addAlternativeServices(self): + self.csel.addAlternativeServices() + self.csel.startMarkedEdit(EDIT_ALTERNATIVES) + self.close() + class ChannelSelectionEPG: def __init__(self): self["ChannelSelectEPGActions"] = ActionMap(["ChannelSelectEPGActions"], @@ -245,7 +285,7 @@ class ChannelSelectionEdit: def __init__(self): self.entry_marked = False self.movemode = False - self.bouquet_mark_edit = False + self.bouquet_mark_edit = OFF self.mutableList = None self.__marked = [ ] self.saved_title = None @@ -309,6 +349,39 @@ class ChannelSelectionEdit: break cnt+=1 + def addAlternativeServices(self): + cur_service = ServiceReference(self.getCurrentSelection()) + root = self.getRoot() + cur_root = root and ServiceReference(root) + mutableBouquet = cur_root.list().startEdit() + if mutableBouquet: + name = cur_service.getServiceName() + print "NAME", name + if self.mode == MODE_TV: + str = '1:134:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET \"alternatives.%s.tv\" ORDER BY bouquet'%(self.buildBouquetID(name)) + else: + str = '1:134:2:0:0:0:0:0:0:0:(type == 2) FROM BOUQUET \"alternatives.%s.radio\" ORDER BY bouquet'%(self.buildBouquetID(name)) + new_ref = ServiceReference(str) + if not mutableBouquet.addService(new_ref.ref, cur_service.ref): + mutableBouquet.removeService(cur_service.ref) + mutableBouquet.flushChanges() + eDVBDB.getInstance().reloadBouquets() + mutableAlternatives = new_ref.list().startEdit() + if mutableAlternatives: + mutableAlternatives.setListName(name) + if mutableAlternatives.addService(cur_service.ref): + print "add", cur_service.toString(), "to new alternatives failed" + mutableAlternatives.flushChanges() + self.servicelist.addService(new_ref.ref, True) + self.servicelist.removeCurrent() + self.servicelist.moveUp() + else: + print "get mutable list for new created alternatives failed" + else: + print "add", str, "to", cur_root.getServiceName(), "failed" + else: + print "bouquetlist is not editable" + def addBouquet(self, bName, services): serviceHandler = eServiceCenter.getInstance() mutableBouquetList = serviceHandler.list(self.bouquet_root).startEdit() @@ -335,8 +408,8 @@ class ChannelSelectionEdit: print "get mutable list for new created bouquet failed" # do some voodoo to check if current_root is equal to bouquet_root cur_root = self.getRoot(); - str1 = cur_root.toString() - pos1 = str1.find("FROM BOUQUET") + str1 = cur_root and cur_root.toString() + pos1 = str1 and str1.find("FROM BOUQUET") or -1 pos2 = self.bouquet_rootstr.find("FROM BOUQUET") if pos1 != -1 and pos2 != -1 and str1[pos1:] == self.bouquet_rootstr[pos2:]: self.servicelist.addService(new_bouquet_ref) @@ -352,8 +425,29 @@ class ChannelSelectionEdit: services = serviceHandler.list(provider.ref) self.addBouquet(providerName, services and services.getContent('R', True)) + def removeAlternativeServices(self): + cur_service = ServiceReference(self.getCurrentSelection()) + root = self.getRoot() + cur_root = root and ServiceReference(root) + list = cur_service.list() + first_in_alternative = list and list.getNext() + if first_in_alternative: + edit_root = cur_root and cur_root.list().startEdit() + if edit_root: + if not edit_root.addService(first_in_alternative, cur_service.ref): + self.servicelist.addService(first_in_alternative, True) + else: + print "couldn't add first alternative service to current root" + else: + print "couldn't edit current root!!" + else: + print "remove empty alternative list !!" + self.removeBouquet() + self.servicelist.moveUp() + def removeBouquet(self): refstr = self.getCurrentSelection().toString() + print "removeBouquet", refstr self.bouquetNumOffsetCache = { } pos = refstr.find('FROM BOUQUET "') filename = None @@ -370,23 +464,29 @@ class ChannelSelectionEdit: print "error during remove of", filename # multiple marked entry stuff ( edit mode, later multiepg selection ) - def startMarkedEdit(self): + def startMarkedEdit(self, type): + self.savedPath = self.servicePath[:] + if type == EDIT_ALTERNATIVES: + self.enterPath(self.getCurrentSelection()) 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() pos = self.saved_title.find(')') new_title = self.saved_title[:pos+1] - if config.usage.multibouquet.value: - new_title += ' ' + _("[bouquet edit]") + if type == EDIT_ALTERNATIVES: + self.bouquet_mark_edit = EDIT_ALTERNATIVES + new_title += ' ' + _("[alternative edit]") else: - new_title += ' ' + _("[favourite edit]") + self.bouquet_mark_edit = EDIT_BOUQUET + if config.usage.multibouquet.value: + new_title += ' ' + _("[bouquet edit]") + else: + new_title += ' ' + _("[favourite edit]") self.setTitle(new_title) - self.bouquet_mark_edit = True self.__marked = self.servicelist.getRootServices() for x in self.__marked: self.servicelist.addMarked(eServiceReference(x)) - self.savedPath = self.servicePath[:] self.showAllServices() def endMarkedEdit(self, abort): @@ -407,7 +507,7 @@ class ChannelSelectionEdit: self.mutableList.flushChanges() self.__marked = [] self.clearMarks() - self.bouquet_mark_edit = False + self.bouquet_mark_edit = OFF self.mutableList = None self.setTitle(self.saved_title) self.saved_title = None @@ -447,7 +547,7 @@ class ChannelSelectionEdit: mutableList.flushChanges() # do some voodoo to check if current_root is equal to dest cur_root = self.getRoot(); - str1 = cur_root.toString() + str1 = cur_root and cur_root.toString() or -1 str2 = dest.toString() pos1 = str1.find("FROM BOUQUET") pos2 = str2.find("FROM BOUQUET") @@ -464,7 +564,8 @@ class ChannelSelectionEdit: self.mutableList = None self.setTitle(self.saved_title) self.saved_title = None - if self.getRoot() == self.bouquet_root: + cur_root = self.getRoot() + if cur_root and cur_root == self.bouquet_root: self.bouquetNumOffsetCache = { } else: self.mutableList = self.getMutableList() @@ -480,7 +581,7 @@ class ChannelSelectionEdit: if self.movemode: #movemode active? self.channelSelected() # unmark self.toggleMoveMode() # disable move mode - elif self.bouquet_mark_edit: + elif self.bouquet_mark_edit != OFF: self.endMarkedEdit(True) # abort edit mode def toggleMoveMarked(self): @@ -571,7 +672,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: @@ -579,9 +680,9 @@ class ChannelSelectionBase(Screen): serviceIterator = servicelist.getNext() if not serviceIterator.valid(): #check if end of list break - if serviceIterator.flags: #playable services have no flags - continue - offsetCount += 1 + playable = not (serviceIterator.flags & (eServiceReference.isDirectory|eServiceReference.isMarker)) + if playable: + offsetCount += 1 return self.bouquetNumOffsetCache.get(str, offsetCount) def recallBouquetMode(self): @@ -625,7 +726,7 @@ class ChannelSelectionBase(Screen): path = root.getPath() inBouquetRootList = path.find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK pos = path.find(' FROM BOUQUET') - isBouquet = pos != -1 + isBouquet = (pos != -1) and (root.flags & eServiceReference.isDirectory) if not inBouquetRootList and isBouquet: self.servicelist.setMode(ServiceList.MODE_FAVOURITES) self.servicelist.setNumberOffset(self.getBouquetNumOffset(root)) @@ -866,19 +967,19 @@ 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 @@ -936,7 +1037,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) @@ -950,6 +1055,21 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect self.lastservice = config.tv.lastservice self.lastroot = config.tv.lastroot self.revertMode = None + config.usage.multibouquet.addNotifier(self.multibouquet_config_changed) + + def multibouquet_config_changed(self, val): + self.recallBouquetMode() + + 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() @@ -990,25 +1110,20 @@ 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: self.toggleMoveMarked() elif (ref.flags & 7) == 7: self.enterPath(ref) - elif self.bouquet_mark_edit: - self.doMark() - elif not (ref.flags & 64): # no marker - self.zap() - self.close(ref) + elif self.bouquet_mark_edit != OFF: + if not (self.bouquet_mark_edit == EDIT_ALTERNATIVES and ref.flags & eServiceReference.isGroup): + self.doMark() + elif not (ref.flags & eServiceReference.isMarker): # no marker + root = self.getRoot() + if not root or not (root.flags & eServiceReference.isGroup): + self.zap() + self.close(ref) #called from infoBar and channelSelected def zap(self): @@ -1018,7 +1133,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) @@ -1057,11 +1172,12 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect self.saveRoot() plen = len(path) root = path[plen-1] - if self.getRoot() != root: + cur_root = self.getRoot() + if cur_root and cur_root != root: self.setRoot(root) self.session.nav.playService(ref) self.setCurrentSelection(ref) - self.saveChannel() + self.saveChannel(ref) def saveRoot(self): path = '' @@ -1098,8 +1214,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: @@ -1183,6 +1298,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: @@ -1225,7 +1357,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 @@ -1234,16 +1365,18 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS self.toggleMoveMarked() elif (ref.flags & 7) == 7: self.enterPath(ref) - elif self.bouquet_mark_edit: - self.doMark() - elif not (ref.flags & 64): # no marker - 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() + elif self.bouquet_mark_edit != OFF: + if not (self.bouquet_mark_edit == EDIT_ALTERNATIVES and ref.flags & eServiceReference.isGroup): + self.doMark() + elif not (ref.flags & eServiceReference.isMarker): # no marker + cur_root = self.getRoot() + if not cur_root or not (cur_root.flags & eServiceReference.isGroup): + playingref = self.session.nav.getCurrentlyPlayingServiceReference() + if playingref is None or playingref != ref: + self.session.nav.playService(ref) + config.radio.lastservice.value = ref.toString() + config.radio.lastservice.save() + self.saveRoot() def closeRadio(self): self.info.hide() @@ -1274,7 +1407,7 @@ class SimpleChannelSelection(ChannelSelectionBase): ref = self.getCurrentSelection() if (ref.flags & 7) == 7: self.enterPath(ref) - elif not (ref.flags & 64): + elif not (ref.flags & eServiceReference.isMarker): ref = self.getCurrentSelection() self.close(ref)