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 if (csel.getCurrentSelection().flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory:
82 if config.ParentalControl.configured.value:
83 if parentalControl.getProtectionLevel(csel.getCurrentSelection().toCompareString()) == -1:
84 menu.append((_("add to parental protection"), boundFunction(self.addParentalProtection, csel.getCurrentSelection())))
86 menu.append((_("remove from parental protection"), boundFunction(self.removeParentalProtection, csel.getCurrentSelection())))
88 menu.append((_("add service to bouquet"), self.addServiceToBouquetSelected))
90 menu.append((_("add service to favourites"), self.addServiceToBouquetSelected))
93 if not inBouquet and current_sel_path.find("PROVIDERS") == -1:
94 menu.append((_("copy to bouquets"), self.copyCurrentToBouquetList))
95 if current_sel_path.find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
96 menu.append((_("remove all new found flags"), self.removeAllNewFoundFlags))
98 menu.append((_("remove entry"), self.removeCurrentService))
99 if current_root is not None and current_root.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
100 menu.append((_("remove new found flag"), self.removeNewFoundFlag))
102 menu.append((_("add bouquet"), self.showBouquetInputBox))
103 menu.append((_("remove entry"), self.removeBouquet))
105 if inBouquet: # current list is editable?
106 if not csel.bouquet_mark_edit:
107 if not csel.movemode:
108 menu.append((_("add marker"), self.showMarkerInputBox))
109 menu.append((_("enable move mode"), self.toggleMoveMode))
110 if not inBouquetRootList:
112 menu.append((_("enable bouquet edit"), self.bouquetMarkStart))
114 menu.append((_("enable favourite edit"), self.bouquetMarkStart))
116 menu.append((_("disable move mode"), self.toggleMoveMode))
117 elif not inBouquetRootList:
119 menu.append((_("end bouquet edit"), self.bouquetMarkEnd))
120 menu.append((_("abort bouquet edit"), self.bouquetMarkAbort))
122 menu.append((_("end favourites edit"), self.bouquetMarkEnd))
123 menu.append((_("abort favourites edit"), self.bouquetMarkAbort))
125 menu.append((_("back"), self.cancelClick))
126 self["menu"] = MenuList(menu)
128 def okbuttonClick(self):
129 self["menu"].getCurrent()[1]()
131 def cancelClick(self):
134 def showBouquetInputBox(self):
135 self.session.openWithCallback(self.bouquetInputCallback, InputBox, title=_("Please enter a name for the new bouquet"), text="bouquetname", maxSize=False, type=Input.TEXT)
137 def bouquetInputCallback(self, bouquet):
138 if bouquet is not None:
139 self.csel.addBouquet(bouquet, None)
142 def addParentalProtection(self, service):
143 parentalControl.protectService(service.toCompareString())
146 def removeParentalProtection(self, service):
147 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"))
149 def pinEntered(self, service, result):
151 parentalControl.unProtectService(service)
154 self.session.openWithCallback(self.close, MessageBox, _("The pin code you entered is wrong."), MessageBox.TYPE_ERROR)
156 def addServiceToBouquetSelected(self):
157 bouquets = self.csel.getBouquetList()
162 if cnt > 1: # show bouquet list
163 self.bsel = self.session.openWithCallback(self.bouquetSelClosed, BouquetSelector, bouquets, self.addCurrentServiceToBouquet)
164 elif cnt == 1: # add to only one existing bouquet
165 self.addCurrentServiceToBouquet(bouquets[0][1])
167 def bouquetSelClosed(self, recursive):
172 def copyCurrentToBouquetList(self):
173 self.csel.copyCurrentToBouquetList()
176 def removeBouquet(self):
177 self.csel.removeBouquet()
180 def showMarkerInputBox(self):
181 self.session.openWithCallback(self.markerInputCallback, InputBox, title=_("Please enter a name for the new marker"), text="markername", maxSize=False, type=Input.TEXT)
183 def markerInputCallback(self, marker):
184 if marker is not None:
185 self.csel.addMarker(marker)
188 def addCurrentServiceToBouquet(self, dest):
189 self.csel.addServiceToBouquet(dest)
190 if self.bsel is not None:
191 self.bsel.close(True)
193 self.close(True) # close bouquet selection
195 def removeCurrentService(self):
196 self.csel.removeCurrentService()
199 def toggleMoveMode(self):
200 self.csel.toggleMoveMode()
203 def bouquetMarkStart(self):
204 self.csel.startMarkedEdit()
207 def bouquetMarkEnd(self):
208 self.csel.endMarkedEdit(abort=False)
211 def bouquetMarkAbort(self):
212 self.csel.endMarkedEdit(abort=True)
215 def removeNewFoundFlag(self):
216 eDVBDB.getInstance().removeFlag(self.csel.getCurrentSelection(), FLAG_SERVICE_NEW_FOUND)
219 def removeAllNewFoundFlags(self):
220 curpath = self.csel.getCurrentSelection().getPath()
221 idx = curpath.find("satellitePosition == ")
223 tmp = curpath[idx+21:]
226 satpos = int(tmp[:idx])
227 eDVBDB.getInstance().removeFlags(FLAG_SERVICE_NEW_FOUND, -1, -1, -1, satpos)
230 class ChannelSelectionEPG:
232 self["ChannelSelectEPGActions"] = ActionMap(["ChannelSelectEPGActions"],
234 "showEPGList": self.showEPGList,
237 def showEPGList(self):
238 ref=self.getCurrentSelection()
239 ptr=eEPGCache.getInstance()
240 if ptr.startTimeQuery(ref) != -1:
241 self.session.open(EPGSelection, ref)
243 print 'no epg for service', ref.toString()
245 class ChannelSelectionEdit:
247 self.entry_marked = False
248 self.movemode = False
249 self.bouquet_mark_edit = False
250 self.mutableList = None
252 self.saved_title = None
253 self.saved_root = None
255 class ChannelSelectionEditActionMap(ActionMap):
256 def __init__(self, csel, contexts = [ ], actions = { }, prio=0):
257 ActionMap.__init__(self, contexts, actions, prio)
260 def action(self, contexts, action):
261 if action == "cancel":
262 self.csel.handleEditCancel()
263 return 0 # fall-trough
265 return 0 # fall-trough
267 return ActionMap.action(self, contexts, action)
269 self["ChannelSelectEditActions"] = ChannelSelectionEditActionMap(self, ["ChannelSelectEditActions", "OkCancelActions"],
271 "contextMenu": self.doContext,
274 def getMutableList(self, root=eServiceReference()):
275 if not self.mutableList is None:
276 return self.mutableList
277 serviceHandler = eServiceCenter.getInstance()
280 list = root and serviceHandler.list(root)
282 return list.startEdit()
285 def buildBouquetID(self, str):
289 if (c >= 'a' and c <= 'z') or (c >= '0' and c <= '9'):
295 def addMarker(self, name):
296 current = self.servicelist.getCurrent()
297 mutableList = self.getMutableList()
300 str = '1:64:%d:0:0:0:0:0:0:0::%s'%(cnt, name)
301 ref = eServiceReference(str)
302 if current and current.valid():
303 if not mutableList.addService(ref, current):
304 self.servicelist.addService(ref, True)
305 mutableList.flushChanges()
307 elif not mutableList.addService(ref):
308 self.servicelist.addService(ref, True)
309 mutableList.flushChanges()
313 def addBouquet(self, bName, services):
314 serviceHandler = eServiceCenter.getInstance()
315 mutableBouquetList = serviceHandler.list(self.bouquet_root).startEdit()
316 if mutableBouquetList:
317 if self.mode == MODE_TV:
319 str = '1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET \"userbouquet.%s.tv\" ORDER BY bouquet'%(self.buildBouquetID(bName))
322 str = '1:7:2:0:0:0:0:0:0:0:(type == 2) FROM BOUQUET \"userbouquet.%s.radio\" ORDER BY bouquet'%(self.buildBouquetID(bName))
323 new_bouquet_ref = eServiceReference(str)
324 if not mutableBouquetList.addService(new_bouquet_ref):
325 mutableBouquetList.flushChanges()
326 eDVBDB.getInstance().reloadBouquets()
327 mutableBouquet = serviceHandler.list(new_bouquet_ref).startEdit()
329 mutableBouquet.setListName(bName)
330 if services is not None:
331 for service in services:
332 if mutableBouquet.addService(service):
333 print "add", service.toString(), "to new bouquet failed"
334 mutableBouquet.flushChanges()
336 print "get mutable list for new created bouquet failed"
337 # do some voodoo to check if current_root is equal to bouquet_root
338 cur_root = self.getRoot();
339 str1 = cur_root.toString()
340 pos1 = str1.find("FROM BOUQUET")
341 pos2 = self.bouquet_rootstr.find("FROM BOUQUET")
342 if pos1 != -1 and pos2 != -1 and str1[pos1:] == self.bouquet_rootstr[pos2:]:
343 self.servicelist.addService(new_bouquet_ref)
345 print "add", str, "to bouquets failed"
347 print "bouquetlist is not editable"
349 def copyCurrentToBouquetList(self):
350 provider = ServiceReference(self.getCurrentSelection())
351 providerName = provider.getServiceName()
352 serviceHandler = eServiceCenter.getInstance()
353 services = serviceHandler.list(provider.ref)
354 self.addBouquet(providerName, services and services.getContent('R', True))
356 def removeBouquet(self):
357 refstr = self.getCurrentSelection().toString()
358 self.bouquetNumOffsetCache = { }
359 pos = refstr.find('FROM BOUQUET "')
362 refstr = refstr[pos+14:]
363 pos = refstr.find('"')
365 filename = '/etc/enigma2/' + refstr[:pos] # FIXMEEE !!! HARDCODED /etc/enigma2
366 self.removeCurrentService()
368 if filename is not None:
371 print "error during remove of", filename
373 # multiple marked entry stuff ( edit mode, later multiepg selection )
374 def startMarkedEdit(self):
375 self.mutableList = self.getMutableList()
376 # add all services from the current list to internal marked set in listboxservicecontent
377 self.clearMarks() # this clears the internal marked set in the listboxservicecontent
378 self.saved_title = self.instance.getTitle()
379 pos = self.saved_title.find(')')
380 new_title = self.saved_title[:pos+1]
381 if config.usage.multibouquet.value:
382 new_title += ' ' + _("[bouquet edit]")
384 new_title += ' ' + _("[favourite edit]")
385 self.setTitle(new_title)
386 self.bouquet_mark_edit = True
387 self.__marked = self.servicelist.getRootServices()
388 for x in self.__marked:
389 self.servicelist.addMarked(eServiceReference(x))
390 self.savedPath = self.servicePath[:]
391 self.showAllServices()
393 def endMarkedEdit(self, abort):
394 if not abort and self.mutableList is not None:
395 self.bouquetNumOffsetCache = { }
396 new_marked = set(self.servicelist.getMarked())
397 old_marked = set(self.__marked)
398 removed = old_marked - new_marked
399 added = new_marked - old_marked
403 self.mutableList.removeService(eServiceReference(x))
406 self.mutableList.addService(eServiceReference(x))
408 self.mutableList.flushChanges()
411 self.bouquet_mark_edit = False
412 self.mutableList = None
413 self.setTitle(self.saved_title)
414 self.saved_title = None
415 # self.servicePath is just a reference to servicePathTv or Radio...
416 # so we never ever do use the asignment operator in self.servicePath
417 del self.servicePath[:] # remove all elements
418 self.servicePath += self.savedPath # add saved elements
420 self.setRoot(self.servicePath[len(self.servicePath)-1])
422 def clearMarks(self):
423 self.servicelist.clearMarks()
426 ref = self.servicelist.getCurrent()
427 if self.servicelist.isMarked(ref):
428 self.servicelist.removeMarked(ref)
430 self.servicelist.addMarked(ref)
432 def removeCurrentService(self):
433 ref = self.servicelist.getCurrent()
434 mutableList = self.getMutableList()
435 if ref.valid() and mutableList is not None:
436 if not mutableList.removeService(ref):
437 self.bouquetNumOffsetCache = { }
438 mutableList.flushChanges() #FIXME dont flush on each single removed service
439 self.servicelist.removeCurrent()
441 def addServiceToBouquet(self, dest, service=None):
442 mutableList = self.getMutableList(dest)
443 if not mutableList is None:
444 if service is None: #use current selected service
445 service = self.servicelist.getCurrent()
446 if not mutableList.addService(service):
447 self.bouquetNumOffsetCache = { }
448 mutableList.flushChanges()
449 # do some voodoo to check if current_root is equal to dest
450 cur_root = self.getRoot();
451 str1 = cur_root.toString()
452 str2 = dest.toString()
453 pos1 = str1.find("FROM BOUQUET")
454 pos2 = str2.find("FROM BOUQUET")
455 if pos1 != -1 and pos2 != -1 and str1[pos1:] == str2[pos2:]:
456 self.servicelist.addService(service)
458 def toggleMoveMode(self):
460 if self.entry_marked:
461 self.toggleMoveMarked() # unmark current entry
462 self.movemode = False
463 self.pathChangeDisabled = False # re-enable path change
464 self.mutableList.flushChanges() # FIXME add check if changes was made
465 self.mutableList = None
466 self.setTitle(self.saved_title)
467 self.saved_title = None
468 if self.getRoot() == self.bouquet_root:
469 self.bouquetNumOffsetCache = { }
471 self.mutableList = self.getMutableList()
473 self.pathChangeDisabled = True # no path change allowed in movemode
474 self.saved_title = self.instance.getTitle()
475 new_title = self.saved_title
476 pos = self.saved_title.find(')')
477 new_title = self.saved_title[:pos+1] + ' ' + _("[move mode]") + self.saved_title[pos+1:]
478 self.setTitle(new_title);
480 def handleEditCancel(self):
481 if self.movemode: #movemode active?
482 self.channelSelected() # unmark
483 self.toggleMoveMode() # disable move mode
484 elif self.bouquet_mark_edit:
485 self.endMarkedEdit(True) # abort edit mode
487 def toggleMoveMarked(self):
488 if self.entry_marked:
489 self.servicelist.setCurrentMarked(False)
490 self.entry_marked = False
492 self.servicelist.setCurrentMarked(True)
493 self.entry_marked = True
496 self.session.open(ChannelContextMenu, self)
501 # this makes it much simple to implement a selectable radio or tv mode :)
502 service_types_tv = '1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17) || (type == 195) || (type == 25)'
503 service_types_radio = '1:7:2:0:0:0:0:0:0:0:(type == 2)'
505 class ChannelSelectionBase(Screen):
506 def __init__(self, session):
507 Screen.__init__(self, session)
509 self["key_red"] = Button(_("All"))
510 self["key_green"] = Button(_("Satellites"))
511 self["key_yellow"] = Button(_("Provider"))
512 self["key_blue"] = Button(_("Favourites"))
514 self["list"] = ServiceList()
515 self.servicelist = self["list"]
517 self.numericalTextInput = NumericalTextInput()
518 self.numericalTextInput.setUseableChars(u'1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ')
520 self.servicePathTV = [ ]
521 self.servicePathRadio = [ ]
522 self.servicePath = [ ]
526 self.pathChangeDisabled = False
528 self.bouquetNumOffsetCache = { }
530 self["ChannelSelectBaseActions"] = NumberActionMap(["ChannelSelectBaseActions", "NumberActions"],
532 "showFavourites": self.showFavourites,
533 "showAllServices": self.showAllServices,
534 "showProviders": self.showProviders,
535 "showSatellites": self.showSatellites,
536 "nextBouquet": self.nextBouquet,
537 "prevBouquet": self.prevBouquet,
538 "nextMarker": self.nextMarker,
539 "prevMarker": self.prevMarker,
540 "1": self.keyNumberGlobal,
541 "2": self.keyNumberGlobal,
542 "3": self.keyNumberGlobal,
543 "4": self.keyNumberGlobal,
544 "5": self.keyNumberGlobal,
545 "6": self.keyNumberGlobal,
546 "7": self.keyNumberGlobal,
547 "8": self.keyNumberGlobal,
548 "9": self.keyNumberGlobal,
551 self.recallBouquetMode()
553 def appendDVBTypes(self, ref):
555 pos = path.find(' FROM BOUQUET')
557 return eServiceReference(self.service_types + path[pos:])
560 def getBouquetNumOffset(self, bouquet):
561 if not config.usage.multibouquet.value:
563 bouquet = self.appendDVBTypes(bouquet)
564 str = bouquet.toString()
566 if not self.bouquetNumOffsetCache.has_key(str):
567 serviceHandler = eServiceCenter.getInstance()
568 bouquetlist = serviceHandler.list(self.bouquet_root)
569 if not bouquetlist is None:
571 bouquetIterator = self.appendDVBTypes(bouquetlist.getNext())
572 if not bouquetIterator.valid(): #end of list
574 self.bouquetNumOffsetCache[bouquetIterator.toString()]=offsetCount
575 if ((bouquetIterator.flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory):
577 servicelist = serviceHandler.list(bouquetIterator)
578 if not servicelist is None:
580 serviceIterator = servicelist.getNext()
581 if not serviceIterator.valid(): #check if end of list
583 if serviceIterator.flags: #playable services have no flags
586 return self.bouquetNumOffsetCache.get(str, offsetCount)
588 def recallBouquetMode(self):
589 if self.mode == MODE_TV:
590 self.service_types = service_types_tv
591 if config.usage.multibouquet.value:
592 self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET "bouquets.tv" ORDER BY bouquet'
594 self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.tv" ORDER BY bouquet'%(self.service_types)
596 self.service_types = service_types_radio
597 if config.usage.multibouquet.value:
598 self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET "bouquets.radio" ORDER BY bouquet'
600 self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.radio" ORDER BY bouquet'%(self.service_types)
601 self.bouquet_root = eServiceReference(self.bouquet_rootstr)
605 self.servicePath = self.servicePathTV
606 self.recallBouquetMode()
607 title = self.instance.getTitle()
608 pos = title.find(" (")
614 def setRadioMode(self):
615 self.mode = MODE_RADIO
616 self.servicePath = self.servicePathRadio
617 self.recallBouquetMode()
618 title = self.instance.getTitle()
619 pos = title.find(" (")
625 def setRoot(self, root, justSet=False):
626 path = root.getPath()
627 inBouquetRootList = path.find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
628 pos = path.find(' FROM BOUQUET')
629 isBouquet = pos != -1
630 if not inBouquetRootList and isBouquet:
631 self.servicelist.setMode(ServiceList.MODE_FAVOURITES)
632 self.servicelist.setNumberOffset(self.getBouquetNumOffset(root))
633 refstr = self.service_types + path[pos:]
634 root = eServiceReference(refstr)
636 self.servicelist.setMode(ServiceList.MODE_NORMAL)
637 self.servicelist.setRoot(root, justSet)
638 self.buildTitleString()
640 def removeModeStr(self, str):
641 if self.mode == MODE_TV:
642 pos = str.find(' (TV)')
644 pos = str.find(' (Radio)')
649 def getServiceName(self, ref):
650 str = self.removeModeStr(ServiceReference(ref).getServiceName())
652 pathstr = ref.getPath()
653 if pathstr.find('FROM PROVIDERS') != -1:
655 if pathstr.find('FROM SATELLITES') != -1:
656 return _("Satellites")
657 if pathstr.find(') ORDER BY name') != -1:
661 def buildTitleString(self):
662 titleStr = self.instance.getTitle()
663 pos = titleStr.find(']')
665 pos = titleStr.find(')')
667 titleStr = titleStr[:pos+1]
668 Len = len(self.servicePath)
670 base_ref = self.servicePath[0]
672 end_ref = self.servicePath[Len-1]
675 nameStr = self.getServiceName(base_ref)
676 titleStr += ' ' + nameStr
677 if end_ref is not None:
682 nameStr = self.getServiceName(end_ref)
684 self.setTitle(titleStr)
687 self.servicelist.moveUp()
690 self.servicelist.moveDown()
693 del self.servicePath[:]
695 def enterPath(self, ref, justSet=False):
696 self.servicePath.append(ref)
697 self.setRoot(ref, justSet)
699 def pathUp(self, justSet=False):
700 prev = self.servicePath.pop()
701 length = len(self.servicePath)
703 current = self.servicePath[length-1]
704 self.setRoot(current, justSet)
706 self.setCurrentSelection(prev)
709 def isBasePathEqual(self, ref):
710 if len(self.servicePath) > 1 and self.servicePath[0] == ref:
714 def isPrevPathEqual(self, ref):
715 length = len(self.servicePath)
716 if length > 1 and self.servicePath[length-2] == ref:
720 def preEnterPath(self, refstr):
723 def showAllServices(self):
724 if not self.pathChangeDisabled:
725 refstr = '%s ORDER BY name'%(self.service_types)
726 if not self.preEnterPath(refstr):
727 ref = eServiceReference(refstr)
728 currentRoot = self.getRoot()
729 if currentRoot is None or currentRoot != ref:
733 def showSatellites(self):
734 if not self.pathChangeDisabled:
735 refstr = '%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types)
736 if not self.preEnterPath(refstr):
737 ref = eServiceReference(refstr)
741 if self.isBasePathEqual(ref):
742 if self.isPrevPathEqual(ref):
744 prev = self.pathUp(justSet)
746 currentRoot = self.getRoot()
747 if currentRoot is None or currentRoot != ref:
750 self.enterPath(ref, True)
752 serviceHandler = eServiceCenter.getInstance()
753 servicelist = serviceHandler.list(ref)
754 if not servicelist is None:
756 service = servicelist.getNext()
757 if not service.valid(): #check if end of list
759 orbpos = service.getUnsignedData(4) >> 16
760 if service.getPath().find("FROM PROVIDER") != -1:
761 service_name = _("Providers")
762 elif service.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
763 service_name = _("New")
765 service_name = _("Services")
767 service_name += str(' - %s'%(nimmanager.getSatDescription(orbpos)))
768 service.setName(service_name) # why we need this cast?
770 if orbpos == 0xFFFF: #Cable
771 n = ("%s (%s)") % (service_name, _("Cable"))
772 elif orbpos == 0xEEEE: #Terrestrial
773 n = ("%s (%s)") % (service_name, _("Terrestrial"))
775 if orbpos > 1800: # west
776 orbpos = 3600 - orbpos
780 n = ("%s (%d.%d" + h + ")") % (service_name, orbpos / 10, orbpos % 10)
782 self.servicelist.addService(service)
783 self.servicelist.finishFill()
785 self.setCurrentSelection(prev)
787 def showProviders(self):
788 if not self.pathChangeDisabled:
789 refstr = '%s FROM PROVIDERS ORDER BY name'%(self.service_types)
790 if not self.preEnterPath(refstr):
791 ref = eServiceReference(refstr)
792 if self.isBasePathEqual(ref):
795 currentRoot = self.getRoot()
796 if currentRoot is None or currentRoot != ref:
800 def changeBouquet(self, direction):
801 if not self.pathChangeDisabled:
802 if len(self.servicePath) > 1:
803 #when enter satellite root list we must do some magic stuff..
804 ref = eServiceReference('%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types))
805 if self.isBasePathEqual(ref):
806 self.showSatellites()
813 ref = self.getCurrentSelection()
817 return self.isBasePathEqual(self.bouquet_root)
820 return self.servicelist.atBegin()
823 return self.servicelist.atEnd()
825 def nextBouquet(self):
826 self.changeBouquet(+1)
828 def prevBouquet(self):
829 self.changeBouquet(-1)
831 def showFavourites(self):
832 if not self.pathChangeDisabled:
833 if not self.preEnterPath(self.bouquet_rootstr):
834 if self.isBasePathEqual(self.bouquet_root):
837 currentRoot = self.getRoot()
838 if currentRoot is None or currentRoot != self.bouquet_root:
840 self.enterPath(self.bouquet_root)
842 def keyNumberGlobal(self, number):
843 unichar = self.numericalTextInput.getKey(number)
844 charstr = unichar.encode("utf-8")
845 if len(charstr) == 1:
846 self.servicelist.moveToChar(charstr[0])
849 return self.servicelist.getRoot()
851 def getCurrentSelection(self):
852 return self.servicelist.getCurrent()
854 def setCurrentSelection(self, service):
855 servicepath = service.getPath()
856 pos = servicepath.find(" FROM BOUQUET")
858 if self.mode == MODE_TV:
859 servicepath = '(type == 1)' + servicepath[pos:]
861 servicepath = '(type == 2)' + servicepath[pos:]
862 service.setPath(servicepath)
863 self.servicelist.setCurrent(service)
865 def getBouquetList(self):
867 serviceHandler = eServiceCenter.getInstance()
868 if config.usage.multibouquet.value:
869 list = serviceHandler.list(self.bouquet_root)
875 if (s.flags & eServiceReference.isGroup):
877 if (s.flags & eServiceReference.flagDirectory) == eServiceReference.flagDirectory:
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.flagDirectory) == eServiceReference.flagDirectory:
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)
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)
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):
1127 ref = self.session.nav.getCurrentlyPlayingServiceReference()
1129 refstr = ref.toString()
1132 if refstr != self.lastservice.value:
1133 self.lastservice.value = refstr
1134 self.lastservice.save()
1136 def setCurrentServicePath(self, path):
1137 hlen = len(self.history)
1139 self.history[self.history_pos] = path
1141 self.history.append(path)
1142 self.setHistoryPath()
1144 def getCurrentServicePath(self):
1145 hlen = len(self.history)
1147 return self.history[self.history_pos]
1150 def recallPrevService(self):
1151 hlen = len(self.history)
1153 if self.history_pos == hlen-1:
1154 tmp = self.history[self.history_pos]
1155 self.history[self.history_pos] = self.history[self.history_pos-1]
1156 self.history[self.history_pos-1] = tmp
1158 tmp = self.history[self.history_pos+1]
1159 self.history[self.history_pos+1] = self.history[self.history_pos]
1160 self.history[self.history_pos] = tmp
1161 self.setHistoryPath()
1164 if self.revertMode is None:
1166 lastservice=eServiceReference(self.lastservice.value)
1167 if lastservice.valid() and self.getCurrentSelection() != lastservice:
1168 self.setCurrentSelection(lastservice)
1169 elif self.revertMode == MODE_TV:
1171 elif self.revertMode == MODE_RADIO:
1173 self.revertMode = None
1176 from Screens.InfoBarGenerics import InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord, InfoBarRadioText
1178 class RadioInfoBar(Screen, InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord):
1179 def __init__(self, session):
1180 Screen.__init__(self, session)
1181 InfoBarEvent.__init__(self)
1182 InfoBarServiceName.__init__(self)
1183 InfoBarInstantRecord.__init__(self)
1184 self["CurrentTime"] = Clock()
1186 class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG, InfoBarRadioText):
1188 ALLOW_SUSPEND = True
1190 def __init__(self, session):
1191 ChannelSelectionBase.__init__(self, session)
1192 ChannelSelectionEdit.__init__(self)
1193 ChannelSelectionEPG.__init__(self)
1194 InfoBarRadioText.__init__(self)
1196 config.radio = ConfigSubsection();
1197 config.radio.lastservice = ConfigText()
1198 config.radio.lastroot = ConfigText()
1199 self.onLayoutFinish.append(self.onCreate)
1201 self.info = session.instantiateDialog(RadioInfoBar)
1203 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1205 "keyTV": self.closeRadio,
1206 "keyRadio": self.closeRadio,
1207 "cancel": self.closeRadio,
1208 "ok": self.channelSelected,
1211 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
1213 iPlayableService.evStart: self.__evServiceStart,
1214 iPlayableService.evEnd: self.__evServiceEnd
1217 def __evServiceStart(self):
1218 service = self.session.nav.getCurrentService()
1220 info = service.info()
1222 refstr = info.getInfoString(iServiceInformation.sServiceref)
1223 self.servicelist.setPlayableIgnoreService(eServiceReference(refstr))
1225 def __evServiceEnd(self):
1226 self.servicelist.setPlayableIgnoreService(eServiceReference())
1230 for i in self.servicePathRadio:
1231 path += i.toString()
1233 if len(path) and path != config.radio.lastroot.value:
1234 config.radio.lastroot.value = path
1235 config.radio.lastroot.save()
1237 def restoreRoot(self):
1239 re = compile('.+?;')
1240 tmp = re.findall(config.radio.lastroot.value)
1243 self.servicePathRadio.append(eServiceReference(i[:len(i)-1]))
1246 path = self.servicePathRadio.pop()
1247 self.enterPath(path)
1249 self.showFavourites()
1252 def preEnterPath(self, refstr):
1253 if len(self.servicePathRadio) and self.servicePathRadio[0] != eServiceReference(refstr):
1254 pathstr = config.radio.lastroot.value
1255 if pathstr is not None and pathstr.find(refstr) == 0:
1257 lastservice=eServiceReference(config.radio.lastservice.value)
1258 if lastservice.valid():
1259 self.setCurrentSelection(lastservice)
1266 lastservice=eServiceReference(config.radio.lastservice.value)
1267 if lastservice.valid():
1268 self.servicelist.setCurrent(lastservice)
1269 self.session.nav.playService(lastservice)
1272 def channelSelected(self): # just return selected service
1273 ref = self.getCurrentSelection()
1275 self.toggleMoveMarked()
1276 elif (ref.flags & 7) == 7:
1278 elif self.bouquet_mark_edit:
1280 elif not (ref.flags & 64): # no marker
1281 playingref = self.session.nav.getCurrentlyPlayingServiceReference()
1282 if playingref is None or playingref != ref:
1283 self.session.nav.playService(ref)
1284 config.radio.lastservice.value = ref.toString()
1285 config.radio.lastservice.save()
1288 def closeRadio(self):
1290 #set previous tv service
1291 lastservice=eServiceReference(config.tv.lastservice.value)
1292 self.session.nav.playService(lastservice)
1295 class SimpleChannelSelection(ChannelSelectionBase):
1296 def __init__(self, session, title):
1297 ChannelSelectionBase.__init__(self, session)
1299 self.onShown.append(self.__onExecCallback)
1301 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1303 "cancel": self.close,
1304 "ok": self.channelSelected,
1305 "keyRadio": self.setModeRadio,
1306 "keyTV": self.setModeTv,
1309 def __onExecCallback(self):
1310 self.setTitle(self.title)
1313 def channelSelected(self): # just return selected service
1314 ref = self.getCurrentSelection()
1315 if (ref.flags & 7) == 7:
1317 elif not (ref.flags & 64):
1318 ref = self.getCurrentSelection()
1321 def setModeTv(self):
1323 self.showFavourites()
1325 def setModeRadio(self):
1327 self.showFavourites()