1 from Screen import Screen
2 from Components.Button import Button
3 from Components.ServiceList import ServiceList
4 from Components.ActionMap import NumberActionMap, ActionMap
5 from Components.MenuList import MenuList
6 from Components.ServiceEventTracker import ServiceEventTracker
7 from EpgSelection import EPGSelection
8 from enigma import eServiceReference, eEPGCache, eServiceCenter, eServiceCenterPtr, iMutableServiceListPtr, iStaticServiceInformationPtr, eTimer, eDVBDB, iPlayableService, iServiceInformation
9 from Components.config import config, ConfigSubsection, ConfigText
10 from Screens.FixedMenu import FixedMenu
11 from Tools.NumericalTextInput import NumericalTextInput
12 from Components.NimManager import nimmanager
13 from Components.Sources.Clock import Clock
14 from Components.Input import Input
15 from Components.ParentalControl import parentalControl
16 from Screens.InputBox import InputBox, PinInput
17 from Screens.MessageBox import MessageBox
18 from ServiceReference import ServiceReference
19 from Tools.BoundFunction import boundFunction
23 FLAG_SERVICE_NEW_FOUND = 64 #define in lib/dvb/idvb.h as dxNewFound = 64
25 import xml.dom.minidom
27 class BouquetSelector(Screen):
28 def __init__(self, session, bouquets, selectedFunc, enableWrapAround=False):
29 Screen.__init__(self, session)
31 self.selectedFunc=selectedFunc
33 self["actions"] = ActionMap(["OkCancelActions"],
35 "ok": self.okbuttonClick,
36 "cancel": self.cancelClick
40 entrys.append((x[0], x[1]))
41 self["menu"] = MenuList(entrys, enableWrapAround)
44 cur = self["menu"].getCurrent()
47 def okbuttonClick(self):
48 self.selectedFunc(self.getCurrent())
56 def cancelClick(self):
59 class ChannelContextMenu(Screen):
60 def __init__(self, session, csel):
61 Screen.__init__(self, session)
65 self["actions"] = ActionMap(["OkCancelActions"],
67 "ok": self.okbuttonClick,
68 "cancel": self.cancelClick
72 current_root = csel.getRoot()
73 current_sel_path = csel.getCurrentSelection().getPath()
74 current_sel_flags = csel.getCurrentSelection().flags
75 inBouquetRootList = current_root and current_root.getPath().find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
76 inBouquet = csel.getMutableList() is not None
77 haveBouquets = config.usage.multibouquet.value
79 if not csel.bouquet_mark_edit and not csel.movemode:
80 if not inBouquetRootList:
81 flags = csel.getCurrentSelection().flags
82 isPlayable = not ((flags & eServiceReference.isMarker) or (flags & eServiceReference.isDirectory))
84 if config.ParentalControl.configured.value:
85 if parentalControl.getProtectionLevel(csel.getCurrentSelection().toCompareString()) == -1:
86 menu.append((_("add to parental protection"), boundFunction(self.addParentalProtection, csel.getCurrentSelection())))
88 menu.append((_("remove from parental protection"), boundFunction(self.removeParentalProtection, csel.getCurrentSelection())))
90 menu.append((_("add service to bouquet"), self.addServiceToBouquetSelected))
92 menu.append((_("add service to favourites"), self.addServiceToBouquetSelected))
95 if not inBouquet and current_sel_path.find("PROVIDERS") == -1:
96 menu.append((_("copy to bouquets"), self.copyCurrentToBouquetList))
97 if current_sel_path.find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
98 menu.append((_("remove all new found flags"), self.removeAllNewFoundFlags))
100 menu.append((_("remove entry"), self.removeCurrentService))
101 if current_root is not None and current_root.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
102 menu.append((_("remove new found flag"), self.removeNewFoundFlag))
104 menu.append((_("add bouquet"), self.showBouquetInputBox))
105 menu.append((_("remove entry"), self.removeBouquet))
107 if inBouquet: # current list is editable?
108 if not csel.bouquet_mark_edit:
109 if not csel.movemode:
110 menu.append((_("add marker"), self.showMarkerInputBox))
111 menu.append((_("enable move mode"), self.toggleMoveMode))
112 if not inBouquetRootList:
114 menu.append((_("enable bouquet edit"), self.bouquetMarkStart))
116 menu.append((_("enable favourite edit"), self.bouquetMarkStart))
118 menu.append((_("disable move mode"), self.toggleMoveMode))
119 elif not inBouquetRootList:
121 menu.append((_("end bouquet edit"), self.bouquetMarkEnd))
122 menu.append((_("abort bouquet edit"), self.bouquetMarkAbort))
124 menu.append((_("end favourites edit"), self.bouquetMarkEnd))
125 menu.append((_("abort favourites edit"), self.bouquetMarkAbort))
127 menu.append((_("back"), self.cancelClick))
128 self["menu"] = MenuList(menu)
130 def okbuttonClick(self):
131 self["menu"].getCurrent()[1]()
133 def cancelClick(self):
136 def showBouquetInputBox(self):
137 self.session.openWithCallback(self.bouquetInputCallback, InputBox, title=_("Please enter a name for the new bouquet"), text="bouquetname", maxSize=False, type=Input.TEXT)
139 def bouquetInputCallback(self, bouquet):
140 if bouquet is not None:
141 self.csel.addBouquet(bouquet, None)
144 def addParentalProtection(self, service):
145 parentalControl.protectService(service.toCompareString())
148 def removeParentalProtection(self, service):
149 self.session.openWithCallback(boundFunction(self.pinEntered, service.toCompareString()), PinInput, pinList = [config.ParentalControl.servicepin[0].value], triesEntry = config.ParentalControl.retries.servicepin, title = _("Enter the service pin"), windowTitle = _("Change pin code"))
151 def pinEntered(self, service, result):
153 parentalControl.unProtectService(service)
156 self.session.openWithCallback(self.close, MessageBox, _("The pin code you entered is wrong."), MessageBox.TYPE_ERROR)
158 def addServiceToBouquetSelected(self):
159 bouquets = self.csel.getBouquetList()
164 if cnt > 1: # show bouquet list
165 self.bsel = self.session.openWithCallback(self.bouquetSelClosed, BouquetSelector, bouquets, self.addCurrentServiceToBouquet)
166 elif cnt == 1: # add to only one existing bouquet
167 self.addCurrentServiceToBouquet(bouquets[0][1])
169 def bouquetSelClosed(self, recursive):
174 def copyCurrentToBouquetList(self):
175 self.csel.copyCurrentToBouquetList()
178 def removeBouquet(self):
179 self.csel.removeBouquet()
182 def showMarkerInputBox(self):
183 self.session.openWithCallback(self.markerInputCallback, InputBox, title=_("Please enter a name for the new marker"), text="markername", maxSize=False, type=Input.TEXT)
185 def markerInputCallback(self, marker):
186 if marker is not None:
187 self.csel.addMarker(marker)
190 def addCurrentServiceToBouquet(self, dest):
191 self.csel.addServiceToBouquet(dest)
192 if self.bsel is not None:
193 self.bsel.close(True)
195 self.close(True) # close bouquet selection
197 def removeCurrentService(self):
198 self.csel.removeCurrentService()
201 def toggleMoveMode(self):
202 self.csel.toggleMoveMode()
205 def bouquetMarkStart(self):
206 self.csel.startMarkedEdit()
209 def bouquetMarkEnd(self):
210 self.csel.endMarkedEdit(abort=False)
213 def bouquetMarkAbort(self):
214 self.csel.endMarkedEdit(abort=True)
217 def removeNewFoundFlag(self):
218 eDVBDB.getInstance().removeFlag(self.csel.getCurrentSelection(), FLAG_SERVICE_NEW_FOUND)
221 def removeAllNewFoundFlags(self):
222 curpath = self.csel.getCurrentSelection().getPath()
223 idx = curpath.find("satellitePosition == ")
225 tmp = curpath[idx+21:]
228 satpos = int(tmp[:idx])
229 eDVBDB.getInstance().removeFlags(FLAG_SERVICE_NEW_FOUND, -1, -1, -1, satpos)
232 class ChannelSelectionEPG:
234 self["ChannelSelectEPGActions"] = ActionMap(["ChannelSelectEPGActions"],
236 "showEPGList": self.showEPGList,
239 def showEPGList(self):
240 ref=self.getCurrentSelection()
241 ptr=eEPGCache.getInstance()
242 if ptr.startTimeQuery(ref) != -1:
243 self.session.open(EPGSelection, ref)
245 print 'no epg for service', ref.toString()
247 class ChannelSelectionEdit:
249 self.entry_marked = False
250 self.movemode = False
251 self.bouquet_mark_edit = False
252 self.mutableList = None
254 self.saved_title = None
255 self.saved_root = None
257 class ChannelSelectionEditActionMap(ActionMap):
258 def __init__(self, csel, contexts = [ ], actions = { }, prio=0):
259 ActionMap.__init__(self, contexts, actions, prio)
262 def action(self, contexts, action):
263 if action == "cancel":
264 self.csel.handleEditCancel()
265 return 0 # fall-trough
267 return 0 # fall-trough
269 return ActionMap.action(self, contexts, action)
271 self["ChannelSelectEditActions"] = ChannelSelectionEditActionMap(self, ["ChannelSelectEditActions", "OkCancelActions"],
273 "contextMenu": self.doContext,
276 def getMutableList(self, root=eServiceReference()):
277 if not self.mutableList is None:
278 return self.mutableList
279 serviceHandler = eServiceCenter.getInstance()
282 list = root and serviceHandler.list(root)
284 return list.startEdit()
287 def buildBouquetID(self, str):
291 if (c >= 'a' and c <= 'z') or (c >= '0' and c <= '9'):
297 def addMarker(self, name):
298 current = self.servicelist.getCurrent()
299 mutableList = self.getMutableList()
302 str = '1:64:%d:0:0:0:0:0:0:0::%s'%(cnt, name)
303 ref = eServiceReference(str)
304 if current and current.valid():
305 if not mutableList.addService(ref, current):
306 self.servicelist.addService(ref, True)
307 mutableList.flushChanges()
309 elif not mutableList.addService(ref):
310 self.servicelist.addService(ref, True)
311 mutableList.flushChanges()
315 def addBouquet(self, bName, services):
316 serviceHandler = eServiceCenter.getInstance()
317 mutableBouquetList = serviceHandler.list(self.bouquet_root).startEdit()
318 if mutableBouquetList:
319 if self.mode == MODE_TV:
321 str = '1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET \"userbouquet.%s.tv\" ORDER BY bouquet'%(self.buildBouquetID(bName))
324 str = '1:7:2:0:0:0:0:0:0:0:(type == 2) FROM BOUQUET \"userbouquet.%s.radio\" ORDER BY bouquet'%(self.buildBouquetID(bName))
325 new_bouquet_ref = eServiceReference(str)
326 if not mutableBouquetList.addService(new_bouquet_ref):
327 mutableBouquetList.flushChanges()
328 eDVBDB.getInstance().reloadBouquets()
329 mutableBouquet = serviceHandler.list(new_bouquet_ref).startEdit()
331 mutableBouquet.setListName(bName)
332 if services is not None:
333 for service in services:
334 if mutableBouquet.addService(service):
335 print "add", service.toString(), "to new bouquet failed"
336 mutableBouquet.flushChanges()
338 print "get mutable list for new created bouquet failed"
339 # do some voodoo to check if current_root is equal to bouquet_root
340 cur_root = self.getRoot();
341 str1 = cur_root.toString()
342 pos1 = str1.find("FROM BOUQUET")
343 pos2 = self.bouquet_rootstr.find("FROM BOUQUET")
344 if pos1 != -1 and pos2 != -1 and str1[pos1:] == self.bouquet_rootstr[pos2:]:
345 self.servicelist.addService(new_bouquet_ref)
347 print "add", str, "to bouquets failed"
349 print "bouquetlist is not editable"
351 def copyCurrentToBouquetList(self):
352 provider = ServiceReference(self.getCurrentSelection())
353 providerName = provider.getServiceName()
354 serviceHandler = eServiceCenter.getInstance()
355 services = serviceHandler.list(provider.ref)
356 self.addBouquet(providerName, services and services.getContent('R', True))
358 def removeBouquet(self):
359 refstr = self.getCurrentSelection().toString()
360 self.bouquetNumOffsetCache = { }
361 pos = refstr.find('FROM BOUQUET "')
364 refstr = refstr[pos+14:]
365 pos = refstr.find('"')
367 filename = '/etc/enigma2/' + refstr[:pos] # FIXMEEE !!! HARDCODED /etc/enigma2
368 self.removeCurrentService()
370 if filename is not None:
373 print "error during remove of", filename
375 # multiple marked entry stuff ( edit mode, later multiepg selection )
376 def startMarkedEdit(self):
377 self.mutableList = self.getMutableList()
378 # add all services from the current list to internal marked set in listboxservicecontent
379 self.clearMarks() # this clears the internal marked set in the listboxservicecontent
380 self.saved_title = self.instance.getTitle()
381 pos = self.saved_title.find(')')
382 new_title = self.saved_title[:pos+1]
383 if config.usage.multibouquet.value:
384 new_title += ' ' + _("[bouquet edit]")
386 new_title += ' ' + _("[favourite edit]")
387 self.setTitle(new_title)
388 self.bouquet_mark_edit = True
389 self.__marked = self.servicelist.getRootServices()
390 for x in self.__marked:
391 self.servicelist.addMarked(eServiceReference(x))
392 self.savedPath = self.servicePath[:]
393 self.showAllServices()
395 def endMarkedEdit(self, abort):
396 if not abort and self.mutableList is not None:
397 self.bouquetNumOffsetCache = { }
398 new_marked = set(self.servicelist.getMarked())
399 old_marked = set(self.__marked)
400 removed = old_marked - new_marked
401 added = new_marked - old_marked
405 self.mutableList.removeService(eServiceReference(x))
408 self.mutableList.addService(eServiceReference(x))
410 self.mutableList.flushChanges()
413 self.bouquet_mark_edit = False
414 self.mutableList = None
415 self.setTitle(self.saved_title)
416 self.saved_title = None
417 # self.servicePath is just a reference to servicePathTv or Radio...
418 # so we never ever do use the asignment operator in self.servicePath
419 del self.servicePath[:] # remove all elements
420 self.servicePath += self.savedPath # add saved elements
422 self.setRoot(self.servicePath[len(self.servicePath)-1])
424 def clearMarks(self):
425 self.servicelist.clearMarks()
428 ref = self.servicelist.getCurrent()
429 if self.servicelist.isMarked(ref):
430 self.servicelist.removeMarked(ref)
432 self.servicelist.addMarked(ref)
434 def removeCurrentService(self):
435 ref = self.servicelist.getCurrent()
436 mutableList = self.getMutableList()
437 if ref.valid() and mutableList is not None:
438 if not mutableList.removeService(ref):
439 self.bouquetNumOffsetCache = { }
440 mutableList.flushChanges() #FIXME dont flush on each single removed service
441 self.servicelist.removeCurrent()
443 def addServiceToBouquet(self, dest, service=None):
444 mutableList = self.getMutableList(dest)
445 if not mutableList is None:
446 if service is None: #use current selected service
447 service = self.servicelist.getCurrent()
448 if not mutableList.addService(service):
449 self.bouquetNumOffsetCache = { }
450 mutableList.flushChanges()
451 # do some voodoo to check if current_root is equal to dest
452 cur_root = self.getRoot();
453 str1 = cur_root.toString()
454 str2 = dest.toString()
455 pos1 = str1.find("FROM BOUQUET")
456 pos2 = str2.find("FROM BOUQUET")
457 if pos1 != -1 and pos2 != -1 and str1[pos1:] == str2[pos2:]:
458 self.servicelist.addService(service)
460 def toggleMoveMode(self):
462 if self.entry_marked:
463 self.toggleMoveMarked() # unmark current entry
464 self.movemode = False
465 self.pathChangeDisabled = False # re-enable path change
466 self.mutableList.flushChanges() # FIXME add check if changes was made
467 self.mutableList = None
468 self.setTitle(self.saved_title)
469 self.saved_title = None
470 if self.getRoot() == self.bouquet_root:
471 self.bouquetNumOffsetCache = { }
473 self.mutableList = self.getMutableList()
475 self.pathChangeDisabled = True # no path change allowed in movemode
476 self.saved_title = self.instance.getTitle()
477 new_title = self.saved_title
478 pos = self.saved_title.find(')')
479 new_title = self.saved_title[:pos+1] + ' ' + _("[move mode]") + self.saved_title[pos+1:]
480 self.setTitle(new_title);
482 def handleEditCancel(self):
483 if self.movemode: #movemode active?
484 self.channelSelected() # unmark
485 self.toggleMoveMode() # disable move mode
486 elif self.bouquet_mark_edit:
487 self.endMarkedEdit(True) # abort edit mode
489 def toggleMoveMarked(self):
490 if self.entry_marked:
491 self.servicelist.setCurrentMarked(False)
492 self.entry_marked = False
494 self.servicelist.setCurrentMarked(True)
495 self.entry_marked = True
498 self.session.open(ChannelContextMenu, self)
503 # this makes it much simple to implement a selectable radio or tv mode :)
504 service_types_tv = '1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17) || (type == 195) || (type == 25)'
505 service_types_radio = '1:7:2:0:0:0:0:0:0:0:(type == 2)'
507 class ChannelSelectionBase(Screen):
508 def __init__(self, session):
509 Screen.__init__(self, session)
511 self["key_red"] = Button(_("All"))
512 self["key_green"] = Button(_("Satellites"))
513 self["key_yellow"] = Button(_("Provider"))
514 self["key_blue"] = Button(_("Favourites"))
516 self["list"] = ServiceList()
517 self.servicelist = self["list"]
519 self.numericalTextInput = NumericalTextInput()
520 self.numericalTextInput.setUseableChars(u'1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ')
522 self.servicePathTV = [ ]
523 self.servicePathRadio = [ ]
524 self.servicePath = [ ]
528 self.pathChangeDisabled = False
530 self.bouquetNumOffsetCache = { }
532 self["ChannelSelectBaseActions"] = NumberActionMap(["ChannelSelectBaseActions", "NumberActions"],
534 "showFavourites": self.showFavourites,
535 "showAllServices": self.showAllServices,
536 "showProviders": self.showProviders,
537 "showSatellites": self.showSatellites,
538 "nextBouquet": self.nextBouquet,
539 "prevBouquet": self.prevBouquet,
540 "nextMarker": self.nextMarker,
541 "prevMarker": self.prevMarker,
542 "1": self.keyNumberGlobal,
543 "2": self.keyNumberGlobal,
544 "3": self.keyNumberGlobal,
545 "4": self.keyNumberGlobal,
546 "5": self.keyNumberGlobal,
547 "6": self.keyNumberGlobal,
548 "7": self.keyNumberGlobal,
549 "8": self.keyNumberGlobal,
550 "9": self.keyNumberGlobal,
553 self.recallBouquetMode()
555 def appendDVBTypes(self, ref):
557 pos = path.find(' FROM BOUQUET')
559 return eServiceReference(self.service_types + path[pos:])
562 def getBouquetNumOffset(self, bouquet):
563 if not config.usage.multibouquet.value:
565 bouquet = self.appendDVBTypes(bouquet)
566 str = bouquet.toString()
568 if not self.bouquetNumOffsetCache.has_key(str):
569 serviceHandler = eServiceCenter.getInstance()
570 bouquetlist = serviceHandler.list(self.bouquet_root)
571 if not bouquetlist is None:
573 bouquetIterator = self.appendDVBTypes(bouquetlist.getNext())
574 if not bouquetIterator.valid(): #end of list
576 self.bouquetNumOffsetCache[bouquetIterator.toString()]=offsetCount
577 if not (bouquetIterator.flags & eServiceReference.isDirectory):
579 servicelist = serviceHandler.list(bouquetIterator)
580 if not servicelist is None:
582 serviceIterator = servicelist.getNext()
583 if not serviceIterator.valid(): #check if end of list
585 if serviceIterator.flags: #playable services have no flags
588 return self.bouquetNumOffsetCache.get(str, offsetCount)
590 def recallBouquetMode(self):
591 if self.mode == MODE_TV:
592 self.service_types = service_types_tv
593 if config.usage.multibouquet.value:
594 self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET "bouquets.tv" ORDER BY bouquet'
596 self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.tv" ORDER BY bouquet'%(self.service_types)
598 self.service_types = service_types_radio
599 if config.usage.multibouquet.value:
600 self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET "bouquets.radio" ORDER BY bouquet'
602 self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.radio" ORDER BY bouquet'%(self.service_types)
603 self.bouquet_root = eServiceReference(self.bouquet_rootstr)
607 self.servicePath = self.servicePathTV
608 self.recallBouquetMode()
609 title = self.instance.getTitle()
610 pos = title.find(" (")
616 def setRadioMode(self):
617 self.mode = MODE_RADIO
618 self.servicePath = self.servicePathRadio
619 self.recallBouquetMode()
620 title = self.instance.getTitle()
621 pos = title.find(" (")
627 def setRoot(self, root, justSet=False):
628 path = root.getPath()
629 inBouquetRootList = path.find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
630 pos = path.find(' FROM BOUQUET')
631 isBouquet = pos != -1
632 if not inBouquetRootList and isBouquet:
633 self.servicelist.setMode(ServiceList.MODE_FAVOURITES)
634 self.servicelist.setNumberOffset(self.getBouquetNumOffset(root))
635 refstr = self.service_types + path[pos:]
636 root = eServiceReference(refstr)
638 self.servicelist.setMode(ServiceList.MODE_NORMAL)
639 self.servicelist.setRoot(root, justSet)
640 self.buildTitleString()
642 def removeModeStr(self, str):
643 if self.mode == MODE_TV:
644 pos = str.find(' (TV)')
646 pos = str.find(' (Radio)')
651 def getServiceName(self, ref):
652 str = self.removeModeStr(ServiceReference(ref).getServiceName())
654 pathstr = ref.getPath()
655 if pathstr.find('FROM PROVIDERS') != -1:
657 if pathstr.find('FROM SATELLITES') != -1:
658 return _("Satellites")
659 if pathstr.find(') ORDER BY name') != -1:
663 def buildTitleString(self):
664 titleStr = self.instance.getTitle()
665 pos = titleStr.find(']')
667 pos = titleStr.find(')')
669 titleStr = titleStr[:pos+1]
670 Len = len(self.servicePath)
672 base_ref = self.servicePath[0]
674 end_ref = self.servicePath[Len-1]
677 nameStr = self.getServiceName(base_ref)
678 titleStr += ' ' + nameStr
679 if end_ref is not None:
684 nameStr = self.getServiceName(end_ref)
686 self.setTitle(titleStr)
689 self.servicelist.moveUp()
692 self.servicelist.moveDown()
695 del self.servicePath[:]
697 def enterPath(self, ref, justSet=False):
698 self.servicePath.append(ref)
699 self.setRoot(ref, justSet)
701 def pathUp(self, justSet=False):
702 prev = self.servicePath.pop()
703 length = len(self.servicePath)
705 current = self.servicePath[length-1]
706 self.setRoot(current, justSet)
708 self.setCurrentSelection(prev)
711 def isBasePathEqual(self, ref):
712 if len(self.servicePath) > 1 and self.servicePath[0] == ref:
716 def isPrevPathEqual(self, ref):
717 length = len(self.servicePath)
718 if length > 1 and self.servicePath[length-2] == ref:
722 def preEnterPath(self, refstr):
725 def showAllServices(self):
726 if not self.pathChangeDisabled:
727 refstr = '%s ORDER BY name'%(self.service_types)
728 if not self.preEnterPath(refstr):
729 ref = eServiceReference(refstr)
730 currentRoot = self.getRoot()
731 if currentRoot is None or currentRoot != ref:
735 def showSatellites(self):
736 if not self.pathChangeDisabled:
737 refstr = '%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types)
738 if not self.preEnterPath(refstr):
739 ref = eServiceReference(refstr)
743 if self.isBasePathEqual(ref):
744 if self.isPrevPathEqual(ref):
746 prev = self.pathUp(justSet)
748 currentRoot = self.getRoot()
749 if currentRoot is None or currentRoot != ref:
752 self.enterPath(ref, True)
754 serviceHandler = eServiceCenter.getInstance()
755 servicelist = serviceHandler.list(ref)
756 if not servicelist is None:
758 service = servicelist.getNext()
759 if not service.valid(): #check if end of list
761 orbpos = service.getUnsignedData(4) >> 16
762 if service.getPath().find("FROM PROVIDER") != -1:
763 service_name = _("Providers")
764 elif service.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
765 service_name = _("New")
767 service_name = _("Services")
769 service_name += str(' - %s'%(nimmanager.getSatDescription(orbpos)))
770 service.setName(service_name) # why we need this cast?
772 if orbpos == 0xFFFF: #Cable
773 n = ("%s (%s)") % (service_name, _("Cable"))
774 elif orbpos == 0xEEEE: #Terrestrial
775 n = ("%s (%s)") % (service_name, _("Terrestrial"))
777 if orbpos > 1800: # west
778 orbpos = 3600 - orbpos
782 n = ("%s (%d.%d" + h + ")") % (service_name, orbpos / 10, orbpos % 10)
784 self.servicelist.addService(service)
785 self.servicelist.finishFill()
787 self.setCurrentSelection(prev)
789 def showProviders(self):
790 if not self.pathChangeDisabled:
791 refstr = '%s FROM PROVIDERS ORDER BY name'%(self.service_types)
792 if not self.preEnterPath(refstr):
793 ref = eServiceReference(refstr)
794 if self.isBasePathEqual(ref):
797 currentRoot = self.getRoot()
798 if currentRoot is None or currentRoot != ref:
802 def changeBouquet(self, direction):
803 if not self.pathChangeDisabled:
804 if len(self.servicePath) > 1:
805 #when enter satellite root list we must do some magic stuff..
806 ref = eServiceReference('%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types))
807 if self.isBasePathEqual(ref):
808 self.showSatellites()
815 ref = self.getCurrentSelection()
819 return self.isBasePathEqual(self.bouquet_root)
822 return self.servicelist.atBegin()
825 return self.servicelist.atEnd()
827 def nextBouquet(self):
828 self.changeBouquet(+1)
830 def prevBouquet(self):
831 self.changeBouquet(-1)
833 def showFavourites(self):
834 if not self.pathChangeDisabled:
835 if not self.preEnterPath(self.bouquet_rootstr):
836 if self.isBasePathEqual(self.bouquet_root):
839 currentRoot = self.getRoot()
840 if currentRoot is None or currentRoot != self.bouquet_root:
842 self.enterPath(self.bouquet_root)
844 def keyNumberGlobal(self, number):
845 unichar = self.numericalTextInput.getKey(number)
846 charstr = unichar.encode("utf-8")
847 if len(charstr) == 1:
848 self.servicelist.moveToChar(charstr[0])
851 return self.servicelist.getRoot()
853 def getCurrentSelection(self):
854 return self.servicelist.getCurrent()
856 def setCurrentSelection(self, service):
857 servicepath = service.getPath()
858 pos = servicepath.find(" FROM BOUQUET")
860 if self.mode == MODE_TV:
861 servicepath = '(type == 1)' + servicepath[pos:]
863 servicepath = '(type == 2)' + servicepath[pos:]
864 service.setPath(servicepath)
865 self.servicelist.setCurrent(service)
867 def getBouquetList(self):
869 serviceHandler = eServiceCenter.getInstance()
870 if config.usage.multibouquet.value:
871 list = serviceHandler.list(self.bouquet_root)
877 if s.flags & eServiceReference.isDirectory:
878 info = serviceHandler.info(s)
880 bouquets.append((info.getName(s), s))
883 info = serviceHandler.info(self.bouquet_root)
885 bouquets.append((info.getName(self.bouquet_root), self.bouquet_root))
889 def getGroupList(self):
891 serviceHandler = eServiceCenter.getInstance()
892 list = serviceHandler.list(self.bouquet_root)
898 if (s.flags & eServiceReference.isGroup) and (s.flags & eServiceReference.mustDescent):
899 info = serviceHandler.info(s)
901 groups.append((info.getName(s), s))
904 def keyNumber0(self, num):
905 if len(self.servicePath) > 1:
908 self.keyNumberGlobal(num)
911 if len(self.servicePath) > 1:
912 if self.isBasePathEqual(self.bouquet_root):
913 self.showFavourites()
915 ref = eServiceReference('%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types))
916 if self.isBasePathEqual(ref):
917 self.showSatellites()
919 ref = eServiceReference('%s FROM PROVIDERS ORDER BY name'%(self.service_types))
920 if self.isBasePathEqual(ref):
923 self.showAllServices()
925 def nextMarker(self):
926 self.servicelist.moveToNextMarker()
928 def prevMarker(self):
929 self.servicelist.moveToPrevMarker()
933 #config for lastservice
934 config.tv = ConfigSubsection()
935 config.tv.lastservice = ConfigText()
936 config.tv.lastroot = ConfigText()
937 config.radio = ConfigSubsection()
938 config.radio.lastservice = ConfigText()
939 config.radio.lastroot = ConfigText()
940 config.servicelist = ConfigSubsection()
941 config.servicelist.lastmode = ConfigText(default = "tv")
943 class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG):
944 def __init__(self, session):
945 ChannelSelectionBase.__init__(self,session)
946 ChannelSelectionEdit.__init__(self)
947 ChannelSelectionEPG.__init__(self)
949 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
951 "cancel": self.cancel,
952 "ok": self.channelSelected,
953 "keyRadio": self.setModeRadio,
954 "keyTV": self.setModeTv,
957 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
959 iPlayableService.evStart: self.__evServiceStart,
960 iPlayableService.evEnd: self.__evServiceEnd
963 self.lastChannelRootTimer = eTimer()
964 self.lastChannelRootTimer.timeout.get().append(self.__onCreate)
965 self.lastChannelRootTimer.start(100,True)
967 self.history_tv = [ ]
968 self.history_radio = [ ]
969 self.history = self.history_tv
972 self.lastservice = config.tv.lastservice
973 self.lastroot = config.tv.lastroot
974 self.revertMode = None
976 def __evServiceStart(self):
977 service = self.session.nav.getCurrentService()
979 info = service.info()
981 refstr = info.getInfoString(iServiceInformation.sServiceref)
982 self.servicelist.setPlayableIgnoreService(eServiceReference(refstr))
984 def __evServiceEnd(self):
985 self.servicelist.setPlayableIgnoreService(eServiceReference())
989 lastservice=eServiceReference(self.lastservice.value)
990 if lastservice.valid():
991 self.setCurrentSelection(lastservice)
994 if self.revertMode is None and config.servicelist.lastmode.value == "radio":
995 self.revertMode = MODE_RADIO
996 self.history = self.history_tv
997 self.lastservice = config.tv.lastservice
998 self.lastroot = config.tv.lastroot
999 config.servicelist.lastmode.value = "tv"
1003 def setModeRadio(self):
1004 if self.revertMode is None and config.servicelist.lastmode.value == "tv":
1005 self.revertMode = MODE_TV
1006 if config.usage.e1like_radio_mode.value:
1007 self.history = self.history_radio
1008 self.lastservice = config.radio.lastservice
1009 self.lastroot = config.radio.lastroot
1010 config.servicelist.lastmode.value = "radio"
1014 def __onCreate(self):
1015 if config.usage.e1like_radio_mode.value:
1016 if config.servicelist.lastmode.value == "tv":
1022 lastservice=eServiceReference(self.lastservice.value)
1023 if lastservice.valid():
1026 def channelSelected(self):
1027 ref = self.getCurrentSelection()
1029 self.toggleMoveMarked()
1030 elif (ref.flags & 7) == 7:
1032 elif self.bouquet_mark_edit:
1034 elif not (ref.flags & 64): # no marker
1038 #called from infoBar and channelSelected
1040 self.revertMode=None
1041 ref = self.session.nav.getCurrentlyPlayingServiceReference()
1042 nref = self.getCurrentSelection()
1043 if ref is None or ref != nref:
1044 self.session.nav.playService(nref)
1046 self.saveChannel(nref)
1047 config.servicelist.lastmode.save()
1048 self.addToHistory(nref)
1050 def addToHistory(self, ref):
1051 if self.servicePath is not None:
1052 tmp=self.servicePath[:]
1055 del self.history[self.history_pos+1:]
1058 self.history.append(tmp)
1059 hlen = len(self.history)
1060 if hlen > HISTORYSIZE:
1063 self.history_pos = hlen-1
1065 def historyBack(self):
1066 hlen = len(self.history)
1067 if hlen > 1 and self.history_pos > 0:
1068 self.history_pos -= 1
1069 self.setHistoryPath()
1071 def historyNext(self):
1072 hlen = len(self.history)
1073 if hlen > 1 and self.history_pos < (hlen-1):
1074 self.history_pos += 1
1075 self.setHistoryPath()
1077 def setHistoryPath(self):
1078 path = self.history[self.history_pos][:]
1080 del self.servicePath[:]
1081 self.servicePath += path
1085 if self.getRoot() != root:
1087 self.session.nav.playService(ref)
1088 self.setCurrentSelection(ref)
1089 self.saveChannel(ref)
1093 for i in self.servicePath:
1094 path += i.toString()
1096 if len(path) and path != self.lastroot.value:
1097 self.lastroot.value = path
1098 self.lastroot.save()
1100 def restoreRoot(self):
1102 re = compile('.+?;')
1103 tmp = re.findall(self.lastroot.value)
1106 self.servicePath.append(eServiceReference(i[:len(i)-1]))
1109 path = self.servicePath.pop()
1110 self.enterPath(path)
1112 self.showFavourites()
1115 def preEnterPath(self, refstr):
1116 if len(self.servicePath) and self.servicePath[0] != eServiceReference(refstr):
1117 pathstr = self.lastroot.value
1118 if pathstr is not None and pathstr.find(refstr) == 0:
1120 lastservice=eServiceReference(self.lastservice.value)
1121 if lastservice.valid():
1122 self.setCurrentSelection(lastservice)
1126 def saveChannel(self, ref):
1128 refstr = ref.toString()
1131 if refstr != self.lastservice.value:
1132 self.lastservice.value = refstr
1133 self.lastservice.save()
1135 def setCurrentServicePath(self, path):
1136 hlen = len(self.history)
1138 self.history[self.history_pos] = path
1140 self.history.append(path)
1141 self.setHistoryPath()
1143 def getCurrentServicePath(self):
1144 hlen = len(self.history)
1146 return self.history[self.history_pos]
1149 def recallPrevService(self):
1150 hlen = len(self.history)
1152 if self.history_pos == hlen-1:
1153 tmp = self.history[self.history_pos]
1154 self.history[self.history_pos] = self.history[self.history_pos-1]
1155 self.history[self.history_pos-1] = tmp
1157 tmp = self.history[self.history_pos+1]
1158 self.history[self.history_pos+1] = self.history[self.history_pos]
1159 self.history[self.history_pos] = tmp
1160 self.setHistoryPath()
1163 if self.revertMode is None:
1165 lastservice=eServiceReference(self.lastservice.value)
1166 if lastservice.valid() and self.getCurrentSelection() != lastservice:
1167 self.setCurrentSelection(lastservice)
1168 elif self.revertMode == MODE_TV:
1170 elif self.revertMode == MODE_RADIO:
1172 self.revertMode = None
1175 from Screens.InfoBarGenerics import InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord, InfoBarRadioText
1177 class RadioInfoBar(Screen, InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord):
1178 def __init__(self, session):
1179 Screen.__init__(self, session)
1180 InfoBarEvent.__init__(self)
1181 InfoBarServiceName.__init__(self)
1182 InfoBarInstantRecord.__init__(self)
1183 self["CurrentTime"] = Clock()
1185 class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG, InfoBarRadioText):
1187 ALLOW_SUSPEND = True
1189 def __init__(self, session):
1190 ChannelSelectionBase.__init__(self, session)
1191 ChannelSelectionEdit.__init__(self)
1192 ChannelSelectionEPG.__init__(self)
1193 InfoBarRadioText.__init__(self)
1195 config.radio = ConfigSubsection();
1196 config.radio.lastservice = ConfigText()
1197 config.radio.lastroot = ConfigText()
1198 self.onLayoutFinish.append(self.onCreate)
1200 self.info = session.instantiateDialog(RadioInfoBar)
1202 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1204 "keyTV": self.closeRadio,
1205 "keyRadio": self.closeRadio,
1206 "cancel": self.closeRadio,
1207 "ok": self.channelSelected,
1210 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
1212 iPlayableService.evStart: self.__evServiceStart,
1213 iPlayableService.evEnd: self.__evServiceEnd
1216 def __evServiceStart(self):
1217 service = self.session.nav.getCurrentService()
1219 info = service.info()
1221 refstr = info.getInfoString(iServiceInformation.sServiceref)
1222 self.servicelist.setPlayableIgnoreService(eServiceReference(refstr))
1224 def __evServiceEnd(self):
1225 self.servicelist.setPlayableIgnoreService(eServiceReference())
1229 for i in self.servicePathRadio:
1230 path += i.toString()
1232 if len(path) and path != config.radio.lastroot.value:
1233 config.radio.lastroot.value = path
1234 config.radio.lastroot.save()
1236 def restoreRoot(self):
1238 re = compile('.+?;')
1239 tmp = re.findall(config.radio.lastroot.value)
1242 self.servicePathRadio.append(eServiceReference(i[:len(i)-1]))
1245 path = self.servicePathRadio.pop()
1246 self.enterPath(path)
1248 self.showFavourites()
1251 def preEnterPath(self, refstr):
1252 if len(self.servicePathRadio) and self.servicePathRadio[0] != eServiceReference(refstr):
1253 pathstr = config.radio.lastroot.value
1254 if pathstr is not None and pathstr.find(refstr) == 0:
1256 lastservice=eServiceReference(config.radio.lastservice.value)
1257 if lastservice.valid():
1258 self.setCurrentSelection(lastservice)
1265 lastservice=eServiceReference(config.radio.lastservice.value)
1266 if lastservice.valid():
1267 self.servicelist.setCurrent(lastservice)
1268 self.session.nav.playService(lastservice)
1271 def channelSelected(self): # just return selected service
1272 ref = self.getCurrentSelection()
1274 self.toggleMoveMarked()
1275 elif (ref.flags & 7) == 7:
1277 elif self.bouquet_mark_edit:
1279 elif not (ref.flags & 64): # no marker
1280 playingref = self.session.nav.getCurrentlyPlayingServiceReference()
1281 if playingref is None or playingref != ref:
1282 self.session.nav.playService(ref)
1283 config.radio.lastservice.value = ref.toString()
1284 config.radio.lastservice.save()
1287 def closeRadio(self):
1289 #set previous tv service
1290 lastservice=eServiceReference(config.tv.lastservice.value)
1291 self.session.nav.playService(lastservice)
1294 class SimpleChannelSelection(ChannelSelectionBase):
1295 def __init__(self, session, title):
1296 ChannelSelectionBase.__init__(self, session)
1298 self.onShown.append(self.__onExecCallback)
1300 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1302 "cancel": self.close,
1303 "ok": self.channelSelected,
1304 "keyRadio": self.setModeRadio,
1305 "keyTV": self.setModeTv,
1308 def __onExecCallback(self):
1309 self.setTitle(self.title)
1312 def channelSelected(self): # just return selected service
1313 ref = self.getCurrentSelection()
1314 if (ref.flags & 7) == 7:
1316 elif not (ref.flags & 64):
1317 ref = self.getCurrentSelection()
1320 def setModeTv(self):
1322 self.showFavourites()
1324 def setModeRadio(self):
1326 self.showFavourites()