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 EpgSelection import EPGSelection
7 from enigma import eServiceReference, eEPGCache, eServiceCenter, eServiceCenterPtr, iMutableServiceListPtr, iStaticServiceInformationPtr, eTimer, eDVBDB
8 from Components.config import config, ConfigSubsection, ConfigText
9 from Screens.FixedMenu import FixedMenu
10 from Tools.NumericalTextInput import NumericalTextInput
11 from Components.NimManager import nimmanager
12 from Components.Sources.Clock import Clock
13 from Components.Input import Input
14 from Components.ParentalControl import parentalControl
15 from Screens.InputBox import InputBox, PinInput
16 from Screens.MessageBox import MessageBox
17 from ServiceReference import ServiceReference
18 from Tools.BoundFunction import boundFunction
22 FLAG_SERVICE_NEW_FOUND = 64 #define in lib/dvb/idvb.h as dxNewFound = 64
24 import xml.dom.minidom
26 class BouquetSelector(Screen):
27 def __init__(self, session, bouquets, selectedFunc, enableWrapAround=False):
28 Screen.__init__(self, session)
30 self.selectedFunc=selectedFunc
32 self["actions"] = ActionMap(["OkCancelActions"],
34 "ok": self.okbuttonClick,
35 "cancel": self.cancelClick
39 entrys.append((x[0], x[1]))
40 self["menu"] = MenuList(entrys, enableWrapAround)
43 cur = self["menu"].getCurrent()
46 def okbuttonClick(self):
47 self.selectedFunc(self.getCurrent())
55 def cancelClick(self):
58 class ChannelContextMenu(Screen):
59 def __init__(self, session, csel):
60 Screen.__init__(self, session)
64 self["actions"] = ActionMap(["OkCancelActions"],
66 "ok": self.okbuttonClick,
67 "cancel": self.cancelClick
71 current_root = csel.getRoot()
72 current_sel_path = csel.getCurrentSelection().getPath()
73 current_sel_flags = csel.getCurrentSelection().flags
74 inBouquetRootList = current_root and current_root.getPath().find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
75 inBouquet = csel.getMutableList() is not None
76 haveBouquets = config.usage.multibouquet.value
78 if not csel.bouquet_mark_edit and not csel.movemode:
79 if not inBouquetRootList:
80 if (csel.getCurrentSelection().flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory:
81 if config.ParentalControl.configured.value:
82 if parentalControl.getProtectionLevel(csel.getCurrentSelection().toCompareString()) == -1:
83 menu.append((_("add to parental protection"), boundFunction(self.addParentalProtection, csel.getCurrentSelection())))
85 menu.append((_("remove from parental protection"), boundFunction(self.removeParentalProtection, csel.getCurrentSelection())))
87 menu.append((_("add service to bouquet"), self.addServiceToBouquetSelected))
89 menu.append((_("add service to favourites"), self.addServiceToBouquetSelected))
92 if not inBouquet and current_sel_path.find("PROVIDERS") == -1:
93 menu.append((_("copy to bouquets"), self.copyCurrentToBouquetList))
94 if current_sel_path.find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
95 menu.append((_("remove all new found flags"), self.removeAllNewFoundFlags))
97 menu.append((_("remove entry"), self.removeCurrentService))
98 if current_root is not None and current_root.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
99 menu.append((_("remove new found flag"), self.removeNewFoundFlag))
101 menu.append((_("add bouquet"), self.showBouquetInputBox))
102 menu.append((_("remove entry"), self.removeBouquet))
104 if inBouquet: # current list is editable?
105 if not csel.bouquet_mark_edit:
106 if not csel.movemode:
107 menu.append((_("add marker"), self.showMarkerInputBox))
108 menu.append((_("enable move mode"), self.toggleMoveMode))
109 if not inBouquetRootList:
111 menu.append((_("enable bouquet edit"), self.bouquetMarkStart))
113 menu.append((_("enable favourite edit"), self.bouquetMarkStart))
115 menu.append((_("disable move mode"), self.toggleMoveMode))
116 elif not inBouquetRootList:
118 menu.append((_("end bouquet edit"), self.bouquetMarkEnd))
119 menu.append((_("abort bouquet edit"), self.bouquetMarkAbort))
121 menu.append((_("end favourites edit"), self.bouquetMarkEnd))
122 menu.append((_("abort favourites edit"), self.bouquetMarkAbort))
124 menu.append((_("back"), self.cancelClick))
125 self["menu"] = MenuList(menu)
127 def okbuttonClick(self):
128 self["menu"].getCurrent()[1]()
130 def cancelClick(self):
133 def showBouquetInputBox(self):
134 self.session.openWithCallback(self.bouquetInputCallback, InputBox, title=_("Please enter a name for the new bouquet"), text="bouquetname", maxSize=False, type=Input.TEXT)
136 def bouquetInputCallback(self, bouquet):
137 if bouquet is not None:
138 self.csel.addBouquet(bouquet, None)
141 def addParentalProtection(self, service):
142 parentalControl.protectService(service.toCompareString())
145 def removeParentalProtection(self, service):
146 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"))
148 def pinEntered(self, service, result):
150 parentalControl.unProtectService(service)
153 self.session.openWithCallback(self.close, MessageBox, _("The pin code you entered is wrong."), MessageBox.TYPE_ERROR)
155 def addServiceToBouquetSelected(self):
156 bouquets = self.csel.getBouquetList()
161 if cnt > 1: # show bouquet list
162 self.bsel = self.session.openWithCallback(self.bouquetSelClosed, BouquetSelector, bouquets, self.addCurrentServiceToBouquet)
163 elif cnt == 1: # add to only one existing bouquet
164 self.addCurrentServiceToBouquet(bouquets[0][1])
166 def bouquetSelClosed(self, recursive):
171 def copyCurrentToBouquetList(self):
172 self.csel.copyCurrentToBouquetList()
175 def removeBouquet(self):
176 self.csel.removeBouquet()
179 def showMarkerInputBox(self):
180 self.session.openWithCallback(self.markerInputCallback, InputBox, title=_("Please enter a name for the new marker"), text="markername", maxSize=False, type=Input.TEXT)
182 def markerInputCallback(self, marker):
183 if marker is not None:
184 self.csel.addMarker(marker)
187 def addCurrentServiceToBouquet(self, dest):
188 self.csel.addServiceToBouquet(dest)
189 if self.bsel is not None:
190 self.bsel.close(True)
192 self.close(True) # close bouquet selection
194 def removeCurrentService(self):
195 self.csel.removeCurrentService()
198 def toggleMoveMode(self):
199 self.csel.toggleMoveMode()
202 def bouquetMarkStart(self):
203 self.csel.startMarkedEdit()
206 def bouquetMarkEnd(self):
207 self.csel.endMarkedEdit(abort=False)
210 def bouquetMarkAbort(self):
211 self.csel.endMarkedEdit(abort=True)
214 def removeNewFoundFlag(self):
215 eDVBDB.getInstance().removeFlag(self.csel.getCurrentSelection(), FLAG_SERVICE_NEW_FOUND)
218 def removeAllNewFoundFlags(self):
219 curpath = self.csel.getCurrentSelection().getPath()
220 idx = curpath.find("satellitePosition == ")
222 tmp = curpath[idx+21:]
225 satpos = int(tmp[:idx])
226 eDVBDB.getInstance().removeFlags(FLAG_SERVICE_NEW_FOUND, -1, -1, -1, satpos)
229 class ChannelSelectionEPG:
231 self["ChannelSelectEPGActions"] = ActionMap(["ChannelSelectEPGActions"],
233 "showEPGList": self.showEPGList,
236 def showEPGList(self):
237 ref=self.getCurrentSelection()
238 ptr=eEPGCache.getInstance()
239 if ptr.startTimeQuery(ref) != -1:
240 self.session.open(EPGSelection, ref)
242 print 'no epg for service', ref.toString()
244 class ChannelSelectionEdit:
246 self.entry_marked = False
247 self.movemode = False
248 self.bouquet_mark_edit = False
249 self.mutableList = None
251 self.saved_title = None
252 self.saved_root = None
254 class ChannelSelectionEditActionMap(ActionMap):
255 def __init__(self, csel, contexts = [ ], actions = { }, prio=0):
256 ActionMap.__init__(self, contexts, actions, prio)
259 def action(self, contexts, action):
260 if action == "cancel":
261 self.csel.handleEditCancel()
262 return 0 # fall-trough
264 return 0 # fall-trough
266 return ActionMap.action(self, contexts, action)
268 self["ChannelSelectEditActions"] = ChannelSelectionEditActionMap(self, ["ChannelSelectEditActions", "OkCancelActions"],
270 "contextMenu": self.doContext,
273 def getMutableList(self, root=eServiceReference()):
274 if not self.mutableList is None:
275 return self.mutableList
276 serviceHandler = eServiceCenter.getInstance()
279 list = root and serviceHandler.list(root)
281 return list.startEdit()
284 def buildBouquetID(self, str):
288 if (c >= 'a' and c <= 'z') or (c >= '0' and c <= '9'):
294 def addMarker(self, name):
295 current = self.servicelist.getCurrent()
296 mutableList = self.getMutableList()
299 str = '1:64:%d:0:0:0:0:0:0:0::%s'%(cnt, name)
300 ref = eServiceReference(str)
301 if current and current.valid():
302 if not mutableList.addService(ref, current):
303 self.servicelist.addService(ref, True)
304 mutableList.flushChanges()
306 elif not mutableList.addService(ref):
307 self.servicelist.addService(ref, True)
308 mutableList.flushChanges()
312 def addBouquet(self, bName, services):
313 serviceHandler = eServiceCenter.getInstance()
314 mutableBouquetList = serviceHandler.list(self.bouquet_root).startEdit()
315 if mutableBouquetList:
316 if self.mode == MODE_TV:
318 str = '1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET \"userbouquet.%s.tv\" ORDER BY bouquet'%(self.buildBouquetID(bName))
321 str = '1:7:2:0:0:0:0:0:0:0:(type == 2) FROM BOUQUET \"userbouquet.%s.radio\" ORDER BY bouquet'%(self.buildBouquetID(bName))
322 new_bouquet_ref = eServiceReference(str)
323 if not mutableBouquetList.addService(new_bouquet_ref):
324 mutableBouquetList.flushChanges()
325 eDVBDB.getInstance().reloadBouquets()
326 mutableBouquet = serviceHandler.list(new_bouquet_ref).startEdit()
328 mutableBouquet.setListName(bName)
329 if services is not None:
330 for service in services:
331 if mutableBouquet.addService(service):
332 print "add", service.toString(), "to new bouquet failed"
333 mutableBouquet.flushChanges()
335 print "get mutable list for new created bouquet failed"
336 # do some voodoo to check if current_root is equal to bouquet_root
337 cur_root = self.getRoot();
338 str1 = cur_root.toString()
339 pos1 = str1.find("FROM BOUQUET")
340 pos2 = self.bouquet_rootstr.find("FROM BOUQUET")
341 if pos1 != -1 and pos2 != -1 and str1[pos1:] == self.bouquet_rootstr[pos2:]:
342 self.servicelist.addService(new_bouquet_ref)
344 print "add", str, "to bouquets failed"
346 print "bouquetlist is not editable"
348 def copyCurrentToBouquetList(self):
349 provider = ServiceReference(self.getCurrentSelection())
350 providerName = provider.getServiceName()
351 serviceHandler = eServiceCenter.getInstance()
352 services = serviceHandler.list(provider.ref)
353 self.addBouquet(providerName, services and services.getContent('R', True))
355 def removeBouquet(self):
356 refstr = self.getCurrentSelection().toString()
357 self.bouquetNumOffsetCache = { }
358 pos = refstr.find('FROM BOUQUET "')
361 refstr = refstr[pos+14:]
362 pos = refstr.find('"')
364 filename = '/etc/enigma2/' + refstr[:pos] # FIXMEEE !!! HARDCODED /etc/enigma2
365 self.removeCurrentService()
367 if filename is not None:
370 print "error during remove of", filename
372 # multiple marked entry stuff ( edit mode, later multiepg selection )
373 def startMarkedEdit(self):
374 self.mutableList = self.getMutableList()
375 # add all services from the current list to internal marked set in listboxservicecontent
376 self.clearMarks() # this clears the internal marked set in the listboxservicecontent
377 self.saved_title = self.instance.getTitle()
378 pos = self.saved_title.find(')')
379 new_title = self.saved_title[:pos+1]
380 if config.usage.multibouquet.value:
381 new_title += ' ' + _("[bouquet edit]")
383 new_title += ' ' + _("[favourite edit]")
384 self.setTitle(new_title)
385 self.bouquet_mark_edit = True
386 self.__marked = self.servicelist.getRootServices()
387 for x in self.__marked:
388 self.servicelist.addMarked(eServiceReference(x))
389 self.savedPath = self.servicePath[:]
390 self.showAllServices()
392 def endMarkedEdit(self, abort):
393 if not abort and self.mutableList is not None:
394 self.bouquetNumOffsetCache = { }
395 new_marked = set(self.servicelist.getMarked())
396 old_marked = set(self.__marked)
397 removed = old_marked - new_marked
398 added = new_marked - old_marked
402 self.mutableList.removeService(eServiceReference(x))
405 self.mutableList.addService(eServiceReference(x))
407 self.mutableList.flushChanges()
410 self.bouquet_mark_edit = False
411 self.mutableList = None
412 self.setTitle(self.saved_title)
413 self.saved_title = None
414 # self.servicePath is just a reference to servicePathTv or Radio...
415 # so we never ever do use the asignment operator in self.servicePath
416 del self.servicePath[:] # remove all elements
417 self.servicePath += self.savedPath # add saved elements
419 self.setRoot(self.servicePath[len(self.servicePath)-1])
421 def clearMarks(self):
422 self.servicelist.clearMarks()
425 ref = self.servicelist.getCurrent()
426 if self.servicelist.isMarked(ref):
427 self.servicelist.removeMarked(ref)
429 self.servicelist.addMarked(ref)
431 def removeCurrentService(self):
432 ref = self.servicelist.getCurrent()
433 mutableList = self.getMutableList()
434 if ref.valid() and mutableList is not None:
435 if not mutableList.removeService(ref):
436 self.bouquetNumOffsetCache = { }
437 mutableList.flushChanges() #FIXME dont flush on each single removed service
438 self.servicelist.removeCurrent()
440 def addServiceToBouquet(self, dest, service=None):
441 mutableList = self.getMutableList(dest)
442 if not mutableList is None:
443 if service is None: #use current selected service
444 service = self.servicelist.getCurrent()
445 if not mutableList.addService(service):
446 self.bouquetNumOffsetCache = { }
447 mutableList.flushChanges()
448 # do some voodoo to check if current_root is equal to dest
449 cur_root = self.getRoot();
450 str1 = cur_root.toString()
451 str2 = dest.toString()
452 pos1 = str1.find("FROM BOUQUET")
453 pos2 = str2.find("FROM BOUQUET")
454 if pos1 != -1 and pos2 != -1 and str1[pos1:] == str2[pos2:]:
455 self.servicelist.addService(service)
457 def toggleMoveMode(self):
459 if self.entry_marked:
460 self.toggleMoveMarked() # unmark current entry
461 self.movemode = False
462 self.pathChangedDisabled = False # re-enable path change
463 self.mutableList.flushChanges() # FIXME add check if changes was made
464 self.mutableList = None
465 self.setTitle(self.saved_title)
466 self.saved_title = None
467 if self.getRoot() == self.bouquet_root:
468 self.bouquetNumOffsetCache = { }
470 self.mutableList = self.getMutableList()
472 self.pathChangedDisabled = True # no path change allowed in movemode
473 self.saved_title = self.instance.getTitle()
474 new_title = self.saved_title
475 pos = self.saved_title.find(')')
476 new_title = self.saved_title[:pos+1] + ' ' + _("[move mode]") + self.saved_title[pos+1:]
477 self.setTitle(new_title);
479 def handleEditCancel(self):
480 if self.movemode: #movemode active?
481 self.channelSelected() # unmark
482 self.toggleMoveMode() # disable move mode
483 elif self.bouquet_mark_edit:
484 self.endMarkedEdit(True) # abort edit mode
486 def toggleMoveMarked(self):
487 if self.entry_marked:
488 self.servicelist.setCurrentMarked(False)
489 self.entry_marked = False
491 self.servicelist.setCurrentMarked(True)
492 self.entry_marked = True
495 self.session.open(ChannelContextMenu, self)
500 # this makes it much simple to implement a selectable radio or tv mode :)
501 service_types_tv = '1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17) || (type == 195) || (type == 25)'
502 service_types_radio = '1:7:2:0:0:0:0:0:0:0:(type == 2)'
504 class ChannelSelectionBase(Screen):
505 def __init__(self, session):
506 Screen.__init__(self, session)
508 self["key_red"] = Button(_("All"))
509 self["key_green"] = Button(_("Satellites"))
510 self["key_yellow"] = Button(_("Provider"))
511 self["key_blue"] = Button(_("Favourites"))
513 self["list"] = ServiceList()
514 self.servicelist = self["list"]
516 self.numericalTextInput = NumericalTextInput()
517 self.numericalTextInput.setUseableChars(u'1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ')
519 self.servicePathTV = [ ]
520 self.servicePathRadio = [ ]
521 self.servicePath = [ ]
525 self.pathChangedDisabled = False
527 self.bouquetNumOffsetCache = { }
529 self["ChannelSelectBaseActions"] = NumberActionMap(["ChannelSelectBaseActions", "NumberActions"],
531 "showFavourites": self.showFavourites,
532 "showAllServices": self.showAllServices,
533 "showProviders": self.showProviders,
534 "showSatellites": self.showSatellites,
535 "nextBouquet": self.nextBouquet,
536 "prevBouquet": self.prevBouquet,
537 "nextMarker": self.nextMarker,
538 "prevMarker": self.prevMarker,
539 "1": self.keyNumberGlobal,
540 "2": self.keyNumberGlobal,
541 "3": self.keyNumberGlobal,
542 "4": self.keyNumberGlobal,
543 "5": self.keyNumberGlobal,
544 "6": self.keyNumberGlobal,
545 "7": self.keyNumberGlobal,
546 "8": self.keyNumberGlobal,
547 "9": self.keyNumberGlobal,
550 self.recallBouquetMode()
552 def appendDVBTypes(self, ref):
554 pos = path.find(' FROM BOUQUET')
556 return eServiceReference(self.service_types + path[pos:])
559 def getBouquetNumOffset(self, bouquet):
560 if not config.usage.multibouquet.value:
562 bouquet = self.appendDVBTypes(bouquet)
563 str = bouquet.toString()
565 if not self.bouquetNumOffsetCache.has_key(str):
566 serviceHandler = eServiceCenter.getInstance()
567 bouquetlist = serviceHandler.list(self.bouquet_root)
568 if not bouquetlist is None:
570 bouquetIterator = self.appendDVBTypes(bouquetlist.getNext())
571 if not bouquetIterator.valid(): #end of list
573 self.bouquetNumOffsetCache[bouquetIterator.toString()]=offsetCount
574 if ((bouquetIterator.flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory):
576 servicelist = serviceHandler.list(bouquetIterator)
577 if not servicelist is None:
579 serviceIterator = servicelist.getNext()
580 if not serviceIterator.valid(): #check if end of list
582 if serviceIterator.flags: #playable services have no flags
585 return self.bouquetNumOffsetCache.get(str, offsetCount)
587 def recallBouquetMode(self):
588 if self.mode == MODE_TV:
589 self.service_types = service_types_tv
590 if config.usage.multibouquet.value:
591 self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET "bouquets.tv" ORDER BY bouquet'
593 self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.tv" ORDER BY bouquet'%(self.service_types)
595 self.service_types = service_types_radio
596 if config.usage.multibouquet.value:
597 self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET "bouquets.radio" ORDER BY bouquet'
599 self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.radio" ORDER BY bouquet'%(self.service_types)
600 self.bouquet_root = eServiceReference(self.bouquet_rootstr)
604 self.servicePath = self.servicePathTV
605 self.recallBouquetMode()
606 title = self.instance.getTitle()
607 pos = title.find(" (")
613 def setRadioMode(self):
614 self.mode = MODE_RADIO
615 self.servicePath = self.servicePathRadio
616 self.recallBouquetMode()
617 title = self.instance.getTitle()
618 pos = title.find(" (")
624 def setRoot(self, root, justSet=False):
625 path = root.getPath()
626 inBouquetRootList = path.find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
627 pos = path.find(' FROM BOUQUET')
628 isBouquet = pos != -1
629 if not inBouquetRootList and isBouquet:
630 self.servicelist.setMode(ServiceList.MODE_FAVOURITES)
631 self.servicelist.setNumberOffset(self.getBouquetNumOffset(root))
632 refstr = self.service_types + path[pos:]
633 root = eServiceReference(refstr)
635 self.servicelist.setMode(ServiceList.MODE_NORMAL)
636 self.servicelist.setRoot(root, justSet)
637 self.buildTitleString()
639 def removeModeStr(self, str):
640 if self.mode == MODE_TV:
641 pos = str.find(' (TV)')
643 pos = str.find(' (Radio)')
648 def getServiceName(self, ref):
649 str = self.removeModeStr(ServiceReference(ref).getServiceName())
651 pathstr = ref.getPath()
652 if pathstr.find('FROM PROVIDERS') != -1:
654 if pathstr.find('FROM SATELLITES') != -1:
655 return _("Satellites")
656 if pathstr.find(') ORDER BY name') != -1:
660 def buildTitleString(self):
661 titleStr = self.instance.getTitle()
662 pos = titleStr.find(']')
664 pos = titleStr.find(')')
666 titleStr = titleStr[:pos+1]
667 Len = len(self.servicePath)
669 base_ref = self.servicePath[0]
671 end_ref = self.servicePath[Len-1]
674 nameStr = self.getServiceName(base_ref)
675 titleStr += ' ' + nameStr
676 if end_ref is not None:
681 nameStr = self.getServiceName(end_ref)
683 self.setTitle(titleStr)
686 self.servicelist.moveUp()
689 self.servicelist.moveDown()
692 del self.servicePath[:]
694 def enterPath(self, ref, justSet=False):
695 self.servicePath.append(ref)
696 self.setRoot(ref, justSet)
698 def pathUp(self, justSet=False):
699 prev = self.servicePath.pop()
700 length = len(self.servicePath)
702 current = self.servicePath[length-1]
703 self.setRoot(current, justSet)
705 self.setCurrentSelection(prev)
708 def isBasePathEqual(self, ref):
709 if len(self.servicePath) > 1 and self.servicePath[0] == ref:
713 def isPrevPathEqual(self, ref):
714 length = len(self.servicePath)
715 if length > 1 and self.servicePath[length-2] == ref:
719 def preEnterPath(self, refstr):
722 def showAllServices(self):
723 if not self.pathChangedDisabled:
724 refstr = '%s ORDER BY name'%(self.service_types)
725 if not self.preEnterPath(refstr):
726 ref = eServiceReference(refstr)
727 currentRoot = self.getRoot()
728 if currentRoot is None or currentRoot != ref:
732 def showSatellites(self):
733 if not self.pathChangedDisabled:
734 refstr = '%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types)
735 if not self.preEnterPath(refstr):
736 ref = eServiceReference(refstr)
740 if self.isBasePathEqual(ref):
741 if self.isPrevPathEqual(ref):
743 prev = self.pathUp(justSet)
745 currentRoot = self.getRoot()
746 if currentRoot is None or currentRoot != ref:
749 self.enterPath(ref, True)
751 serviceHandler = eServiceCenter.getInstance()
752 servicelist = serviceHandler.list(ref)
753 if not servicelist is None:
755 service = servicelist.getNext()
756 if not service.valid(): #check if end of list
758 orbpos = service.getUnsignedData(4) >> 16
759 if service.getPath().find("FROM PROVIDER") != -1:
760 service_name = _("Providers")
761 elif service.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
762 service_name = _("New")
764 service_name = _("Services")
766 service_name += str(' - %s'%(nimmanager.getSatDescription(orbpos)))
767 service.setName(service_name) # why we need this cast?
769 if orbpos == 0xFFFF: #Cable
770 n = ("%s (%s)") % (service_name, _("Cable"))
771 elif orbpos == 0xEEEE: #Terrestrial
772 n = ("%s (%s)") % (service_name, _("Terrestrial"))
774 if orbpos > 1800: # west
775 orbpos = 3600 - orbpos
779 n = ("%s (%d.%d" + h + ")") % (service_name, orbpos / 10, orbpos % 10)
781 self.servicelist.addService(service)
782 self.servicelist.finishFill()
784 self.setCurrentSelection(prev)
786 def showProviders(self):
787 if not self.pathChangedDisabled:
788 refstr = '%s FROM PROVIDERS ORDER BY name'%(self.service_types)
789 if not self.preEnterPath(refstr):
790 ref = eServiceReference(refstr)
791 if self.isBasePathEqual(ref):
794 currentRoot = self.getRoot()
795 if currentRoot is None or currentRoot != ref:
799 def changeBouquet(self, direction):
800 if not self.pathChangedDisabled:
801 if self.isBasePathEqual(self.bouquet_root):
807 ref = self.getCurrentSelection()
811 return self.isBasePathEqual(self.bouquet_root)
814 return self.servicelist.atBegin()
817 return self.servicelist.atEnd()
819 def nextBouquet(self):
820 self.changeBouquet(+1)
822 def prevBouquet(self):
823 self.changeBouquet(-1)
825 def showFavourites(self):
826 if not self.pathChangedDisabled:
827 if not self.preEnterPath(self.bouquet_rootstr):
828 if self.isBasePathEqual(self.bouquet_root):
831 currentRoot = self.getRoot()
832 if currentRoot is None or currentRoot != self.bouquet_root:
834 self.enterPath(self.bouquet_root)
836 def keyNumberGlobal(self, number):
837 unichar = self.numericalTextInput.getKey(number)
838 charstr = unichar.encode("utf-8")
839 if len(charstr) == 1:
840 self.servicelist.moveToChar(charstr[0])
843 return self.servicelist.getRoot()
845 def getCurrentSelection(self):
846 return self.servicelist.getCurrent()
848 def setCurrentSelection(self, service):
849 servicepath = service.getPath()
850 pos = servicepath.find(" FROM BOUQUET")
852 if self.mode == MODE_TV:
853 servicepath = '(type == 1)' + servicepath[pos:]
855 servicepath = '(type == 2)' + servicepath[pos:]
856 service.setPath(servicepath)
857 self.servicelist.setCurrent(service)
859 def getBouquetList(self):
861 serviceHandler = eServiceCenter.getInstance()
862 if config.usage.multibouquet.value:
863 list = serviceHandler.list(self.bouquet_root)
869 if ((s.flags & eServiceReference.flagDirectory) == eServiceReference.flagDirectory):
870 info = serviceHandler.info(s)
872 bouquets.append((info.getName(s), s))
875 info = serviceHandler.info(self.bouquet_root)
877 bouquets.append((info.getName(self.bouquet_root), self.bouquet_root))
881 def keyNumber0(self, num):
882 if len(self.servicePath) > 1:
885 self.keyNumberGlobal(num)
888 if len(self.servicePath) > 1:
889 if self.isBasePathEqual(self.bouquet_root):
890 self.showFavourites()
892 ref = eServiceReference('%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types))
893 if self.isBasePathEqual(ref):
894 self.showSatellites()
896 ref = eServiceReference('%s FROM PROVIDERS ORDER BY name'%(self.service_types))
897 if self.isBasePathEqual(ref):
900 self.showAllServices()
902 def nextMarker(self):
903 self.servicelist.moveToNextMarker()
905 def prevMarker(self):
906 self.servicelist.moveToPrevMarker()
910 #config for lastservice
911 config.tv = ConfigSubsection()
912 config.tv.lastservice = ConfigText()
913 config.tv.lastroot = ConfigText()
914 config.radio = ConfigSubsection()
915 config.radio.lastservice = ConfigText()
916 config.radio.lastroot = ConfigText()
917 config.servicelist = ConfigSubsection()
918 config.servicelist.lastmode = ConfigText(default = "tv")
920 class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG):
921 def __init__(self, session):
922 ChannelSelectionBase.__init__(self,session)
923 ChannelSelectionEdit.__init__(self)
924 ChannelSelectionEPG.__init__(self)
926 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
928 "cancel": self.cancel,
929 "ok": self.channelSelected,
930 "keyRadio": self.setModeRadio,
931 "keyTV": self.setModeTv,
934 self.onShown.append(self.__onShown)
936 self.lastChannelRootTimer = eTimer()
937 self.lastChannelRootTimer.timeout.get().append(self.__onCreate)
938 self.lastChannelRootTimer.start(100,True)
940 self.history_tv = [ ]
941 self.history_radio = [ ]
942 self.history = self.history_tv
945 self.lastservice = config.tv.lastservice
946 self.lastroot = config.tv.lastroot
947 self.revertMode = None
951 lastservice=eServiceReference(self.lastservice.value)
952 if lastservice.valid():
953 self.setCurrentSelection(lastservice)
956 if self.revertMode is None and config.servicelist.lastmode.value == "radio":
957 self.revertMode = MODE_RADIO
958 self.history = self.history_tv
959 self.lastservice = config.tv.lastservice
960 self.lastroot = config.tv.lastroot
961 config.servicelist.lastmode.value = "tv"
965 def setModeRadio(self):
966 if self.revertMode is None and config.servicelist.lastmode.value == "tv":
967 self.revertMode = MODE_TV
968 if config.usage.e1like_radio_mode.value:
969 self.history = self.history_radio
970 self.lastservice = config.radio.lastservice
971 self.lastroot = config.radio.lastroot
972 config.servicelist.lastmode.value = "radio"
976 def __onCreate(self):
977 if config.usage.e1like_radio_mode.value:
978 if config.servicelist.lastmode.value == "tv":
984 lastservice=eServiceReference(self.lastservice.value)
985 if lastservice.valid():
989 self.recallBouquetMode()
990 ref = self.session.nav.getCurrentlyPlayingServiceReference()
991 if ref is not None and ref.valid() and ref.getPath() == "":
992 self.servicelist.setPlayableIgnoreService(ref)
994 self.servicelist.setPlayableIgnoreService(eServiceReference())
996 def channelSelected(self):
997 ref = self.getCurrentSelection()
999 self.toggleMoveMarked()
1000 elif (ref.flags & 7) == 7:
1002 elif self.bouquet_mark_edit:
1004 elif not (ref.flags & 64): # no marker
1008 #called from infoBar and channelSelected
1010 self.revertMode=None
1011 ref = self.session.nav.getCurrentlyPlayingServiceReference()
1012 nref = self.getCurrentSelection()
1013 if ref is None or ref != nref:
1014 self.session.nav.playService(nref)
1017 config.servicelist.lastmode.save()
1018 self.addToHistory(nref)
1020 def addToHistory(self, ref):
1021 if self.servicePath is not None:
1022 tmp=self.servicePath[:]
1025 del self.history[self.history_pos+1:]
1028 self.history.append(tmp)
1029 hlen = len(self.history)
1030 if hlen > HISTORYSIZE:
1033 self.history_pos = hlen-1
1035 def historyBack(self):
1036 hlen = len(self.history)
1037 if hlen > 1 and self.history_pos > 0:
1038 self.history_pos -= 1
1039 self.setHistoryPath()
1041 def historyNext(self):
1042 hlen = len(self.history)
1043 if hlen > 1 and self.history_pos < (hlen-1):
1044 self.history_pos += 1
1045 self.setHistoryPath()
1047 def setHistoryPath(self):
1048 path = self.history[self.history_pos][:]
1050 del self.servicePath[:]
1051 self.servicePath += path
1055 if self.getRoot() != root:
1057 self.session.nav.playService(ref)
1058 self.setCurrentSelection(ref)
1063 for i in self.servicePath:
1064 path += i.toString()
1066 if len(path) and path != self.lastroot.value:
1067 self.lastroot.value = path
1068 self.lastroot.save()
1070 def restoreRoot(self):
1072 re = compile('.+?;')
1073 tmp = re.findall(self.lastroot.value)
1076 self.servicePath.append(eServiceReference(i[:len(i)-1]))
1079 path = self.servicePath.pop()
1080 self.enterPath(path)
1082 self.showFavourites()
1085 def preEnterPath(self, refstr):
1086 if len(self.servicePath) and self.servicePath[0] != eServiceReference(refstr):
1087 pathstr = self.lastroot.value
1088 if pathstr is not None and pathstr.find(refstr) == 0:
1090 lastservice=eServiceReference(self.lastservice.value)
1091 if lastservice.valid():
1092 self.setCurrentSelection(lastservice)
1096 def saveChannel(self):
1097 ref = self.session.nav.getCurrentlyPlayingServiceReference()
1099 refstr = ref.toString()
1102 if refstr != self.lastservice.value:
1103 self.lastservice.value = refstr
1104 self.lastservice.save()
1106 def setCurrentServicePath(self, path):
1107 hlen = len(self.history)
1109 self.history[self.history_pos] = path
1111 self.history.append(path)
1112 self.setHistoryPath()
1114 def getCurrentServicePath(self):
1115 hlen = len(self.history)
1117 return self.history[self.history_pos]
1120 def recallPrevService(self):
1121 hlen = len(self.history)
1123 if self.history_pos == hlen-1:
1124 tmp = self.history[self.history_pos]
1125 self.history[self.history_pos] = self.history[self.history_pos-1]
1126 self.history[self.history_pos-1] = tmp
1128 tmp = self.history[self.history_pos+1]
1129 self.history[self.history_pos+1] = self.history[self.history_pos]
1130 self.history[self.history_pos] = tmp
1131 self.setHistoryPath()
1134 if self.revertMode is None:
1136 lastservice=eServiceReference(self.lastservice.value)
1137 if lastservice.valid() and self.getCurrentSelection() != lastservice:
1138 self.setCurrentSelection(lastservice)
1139 elif self.revertMode == MODE_TV:
1141 elif self.revertMode == MODE_RADIO:
1143 self.revertMode = None
1146 from Screens.InfoBarGenerics import InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord, InfoBarRadioText
1148 class RadioInfoBar(Screen, InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord):
1149 def __init__(self, session):
1150 Screen.__init__(self, session)
1151 InfoBarEvent.__init__(self)
1152 InfoBarServiceName.__init__(self)
1153 InfoBarInstantRecord.__init__(self)
1154 self["CurrentTime"] = Clock()
1156 class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG, InfoBarRadioText):
1158 ALLOW_SUSPEND = True
1160 def __init__(self, session):
1161 ChannelSelectionBase.__init__(self, session)
1162 ChannelSelectionEdit.__init__(self)
1163 ChannelSelectionEPG.__init__(self)
1164 InfoBarRadioText.__init__(self)
1166 config.radio = ConfigSubsection();
1167 config.radio.lastservice = ConfigText()
1168 config.radio.lastroot = ConfigText()
1169 self.onLayoutFinish.append(self.onCreate)
1171 self.info = session.instantiateDialog(RadioInfoBar)
1173 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1175 "keyTV": self.closeRadio,
1176 "keyRadio": self.closeRadio,
1177 "cancel": self.closeRadio,
1178 "ok": self.channelSelected,
1183 for i in self.servicePathRadio:
1184 path += i.toString()
1186 if len(path) and path != config.radio.lastroot.value:
1187 config.radio.lastroot.value = path
1188 config.radio.lastroot.save()
1190 def restoreRoot(self):
1192 re = compile('.+?;')
1193 tmp = re.findall(config.radio.lastroot.value)
1196 self.servicePathRadio.append(eServiceReference(i[:len(i)-1]))
1199 path = self.servicePathRadio.pop()
1200 self.enterPath(path)
1202 self.showFavourites()
1205 def preEnterPath(self, refstr):
1206 if len(self.servicePathRadio) and self.servicePathRadio[0] != eServiceReference(refstr):
1207 pathstr = config.radio.lastroot.value
1208 if pathstr is not None and pathstr.find(refstr) == 0:
1210 lastservice=eServiceReference(config.radio.lastservice.value)
1211 if lastservice.valid():
1212 self.setCurrentSelection(lastservice)
1219 lastservice=eServiceReference(config.radio.lastservice.value)
1220 if lastservice.valid():
1221 self.servicelist.setCurrent(lastservice)
1222 self.session.nav.playService(lastservice)
1223 self.servicelist.setPlayableIgnoreService(lastservice)
1226 def channelSelected(self): # just return selected service
1227 ref = self.getCurrentSelection()
1229 self.toggleMoveMarked()
1230 elif (ref.flags & 7) == 7:
1232 elif self.bouquet_mark_edit:
1234 elif not (ref.flags & 64): # no marker
1235 playingref = self.session.nav.getCurrentlyPlayingServiceReference()
1236 if playingref is None or playingref != ref:
1237 self.session.nav.playService(ref)
1238 self.servicelist.setPlayableIgnoreService(ref)
1239 config.radio.lastservice.value = ref.toString()
1240 config.radio.lastservice.save()
1243 def closeRadio(self):
1245 #set previous tv service
1246 lastservice=eServiceReference(config.tv.lastservice.value)
1247 self.session.nav.playService(lastservice)
1250 class SimpleChannelSelection(ChannelSelectionBase):
1251 def __init__(self, session, title):
1252 ChannelSelectionBase.__init__(self, session)
1254 self.onShown.append(self.__onExecCallback)
1256 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1258 "cancel": self.close,
1259 "ok": self.channelSelected,
1260 "keyRadio": self.setModeRadio,
1261 "keyTV": self.setModeTv,
1264 def __onExecCallback(self):
1265 self.setTitle(self.title)
1268 def channelSelected(self): # just return selected service
1269 ref = self.getCurrentSelection()
1270 if (ref.flags & 7) == 7:
1272 elif not (ref.flags & 64):
1273 ref = self.getCurrentSelection()
1276 def setModeTv(self):
1278 self.showFavourites()
1280 def setModeRadio(self):
1282 self.showFavourites()