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.pathChangeDisabled = 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.pathChangeDisabled = 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.pathChangeDisabled = 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.pathChangeDisabled:
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.pathChangeDisabled:
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.pathChangeDisabled:
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.pathChangeDisabled:
801 if len(self.servicePath) > 1:
802 #when enter satellite root list we must do some magic stuff..
803 ref = eServiceReference('%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types))
804 if self.isBasePathEqual(ref):
805 self.showSatellites()
812 ref = self.getCurrentSelection()
816 return self.isBasePathEqual(self.bouquet_root)
819 return self.servicelist.atBegin()
822 return self.servicelist.atEnd()
824 def nextBouquet(self):
825 self.changeBouquet(+1)
827 def prevBouquet(self):
828 self.changeBouquet(-1)
830 def showFavourites(self):
831 if not self.pathChangeDisabled:
832 if not self.preEnterPath(self.bouquet_rootstr):
833 if self.isBasePathEqual(self.bouquet_root):
836 currentRoot = self.getRoot()
837 if currentRoot is None or currentRoot != self.bouquet_root:
839 self.enterPath(self.bouquet_root)
841 def keyNumberGlobal(self, number):
842 unichar = self.numericalTextInput.getKey(number)
843 charstr = unichar.encode("utf-8")
844 if len(charstr) == 1:
845 self.servicelist.moveToChar(charstr[0])
848 return self.servicelist.getRoot()
850 def getCurrentSelection(self):
851 return self.servicelist.getCurrent()
853 def setCurrentSelection(self, service):
854 servicepath = service.getPath()
855 pos = servicepath.find(" FROM BOUQUET")
857 if self.mode == MODE_TV:
858 servicepath = '(type == 1)' + servicepath[pos:]
860 servicepath = '(type == 2)' + servicepath[pos:]
861 service.setPath(servicepath)
862 self.servicelist.setCurrent(service)
864 def getBouquetList(self):
866 serviceHandler = eServiceCenter.getInstance()
867 if config.usage.multibouquet.value:
868 list = serviceHandler.list(self.bouquet_root)
874 if ((s.flags & eServiceReference.flagDirectory) == eServiceReference.flagDirectory):
875 info = serviceHandler.info(s)
877 bouquets.append((info.getName(s), s))
880 info = serviceHandler.info(self.bouquet_root)
882 bouquets.append((info.getName(self.bouquet_root), self.bouquet_root))
886 def keyNumber0(self, num):
887 if len(self.servicePath) > 1:
890 self.keyNumberGlobal(num)
893 if len(self.servicePath) > 1:
894 if self.isBasePathEqual(self.bouquet_root):
895 self.showFavourites()
897 ref = eServiceReference('%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types))
898 if self.isBasePathEqual(ref):
899 self.showSatellites()
901 ref = eServiceReference('%s FROM PROVIDERS ORDER BY name'%(self.service_types))
902 if self.isBasePathEqual(ref):
905 self.showAllServices()
907 def nextMarker(self):
908 self.servicelist.moveToNextMarker()
910 def prevMarker(self):
911 self.servicelist.moveToPrevMarker()
915 #config for lastservice
916 config.tv = ConfigSubsection()
917 config.tv.lastservice = ConfigText()
918 config.tv.lastroot = ConfigText()
919 config.radio = ConfigSubsection()
920 config.radio.lastservice = ConfigText()
921 config.radio.lastroot = ConfigText()
922 config.servicelist = ConfigSubsection()
923 config.servicelist.lastmode = ConfigText(default = "tv")
925 class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG):
926 def __init__(self, session):
927 ChannelSelectionBase.__init__(self,session)
928 ChannelSelectionEdit.__init__(self)
929 ChannelSelectionEPG.__init__(self)
931 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
933 "cancel": self.cancel,
934 "ok": self.channelSelected,
935 "keyRadio": self.setModeRadio,
936 "keyTV": self.setModeTv,
939 self.onShown.append(self.__onShown)
941 self.lastChannelRootTimer = eTimer()
942 self.lastChannelRootTimer.timeout.get().append(self.__onCreate)
943 self.lastChannelRootTimer.start(100,True)
945 self.history_tv = [ ]
946 self.history_radio = [ ]
947 self.history = self.history_tv
950 self.lastservice = config.tv.lastservice
951 self.lastroot = config.tv.lastroot
952 self.revertMode = None
956 lastservice=eServiceReference(self.lastservice.value)
957 if lastservice.valid():
958 self.setCurrentSelection(lastservice)
961 if self.revertMode is None and config.servicelist.lastmode.value == "radio":
962 self.revertMode = MODE_RADIO
963 self.history = self.history_tv
964 self.lastservice = config.tv.lastservice
965 self.lastroot = config.tv.lastroot
966 config.servicelist.lastmode.value = "tv"
970 def setModeRadio(self):
971 if self.revertMode is None and config.servicelist.lastmode.value == "tv":
972 self.revertMode = MODE_TV
973 if config.usage.e1like_radio_mode.value:
974 self.history = self.history_radio
975 self.lastservice = config.radio.lastservice
976 self.lastroot = config.radio.lastroot
977 config.servicelist.lastmode.value = "radio"
981 def __onCreate(self):
982 if config.usage.e1like_radio_mode.value:
983 if config.servicelist.lastmode.value == "tv":
989 lastservice=eServiceReference(self.lastservice.value)
990 if lastservice.valid():
994 self.recallBouquetMode()
995 ref = self.session.nav.getCurrentlyPlayingServiceReference()
996 if ref is not None and ref.valid() and ref.getPath() == "":
997 self.servicelist.setPlayableIgnoreService(ref)
999 self.servicelist.setPlayableIgnoreService(eServiceReference())
1001 def channelSelected(self):
1002 ref = self.getCurrentSelection()
1004 self.toggleMoveMarked()
1005 elif (ref.flags & 7) == 7:
1007 elif self.bouquet_mark_edit:
1009 elif not (ref.flags & 64): # no marker
1013 #called from infoBar and channelSelected
1015 self.revertMode=None
1016 ref = self.session.nav.getCurrentlyPlayingServiceReference()
1017 nref = self.getCurrentSelection()
1018 if ref is None or ref != nref:
1019 self.session.nav.playService(nref)
1022 config.servicelist.lastmode.save()
1023 self.addToHistory(nref)
1025 def addToHistory(self, ref):
1026 if self.servicePath is not None:
1027 tmp=self.servicePath[:]
1030 del self.history[self.history_pos+1:]
1033 self.history.append(tmp)
1034 hlen = len(self.history)
1035 if hlen > HISTORYSIZE:
1038 self.history_pos = hlen-1
1040 def historyBack(self):
1041 hlen = len(self.history)
1042 if hlen > 1 and self.history_pos > 0:
1043 self.history_pos -= 1
1044 self.setHistoryPath()
1046 def historyNext(self):
1047 hlen = len(self.history)
1048 if hlen > 1 and self.history_pos < (hlen-1):
1049 self.history_pos += 1
1050 self.setHistoryPath()
1052 def setHistoryPath(self):
1053 path = self.history[self.history_pos][:]
1055 del self.servicePath[:]
1056 self.servicePath += path
1060 if self.getRoot() != root:
1062 self.session.nav.playService(ref)
1063 self.setCurrentSelection(ref)
1068 for i in self.servicePath:
1069 path += i.toString()
1071 if len(path) and path != self.lastroot.value:
1072 self.lastroot.value = path
1073 self.lastroot.save()
1075 def restoreRoot(self):
1077 re = compile('.+?;')
1078 tmp = re.findall(self.lastroot.value)
1081 self.servicePath.append(eServiceReference(i[:len(i)-1]))
1084 path = self.servicePath.pop()
1085 self.enterPath(path)
1087 self.showFavourites()
1090 def preEnterPath(self, refstr):
1091 if len(self.servicePath) and self.servicePath[0] != eServiceReference(refstr):
1092 pathstr = self.lastroot.value
1093 if pathstr is not None and pathstr.find(refstr) == 0:
1095 lastservice=eServiceReference(self.lastservice.value)
1096 if lastservice.valid():
1097 self.setCurrentSelection(lastservice)
1101 def saveChannel(self):
1102 ref = self.session.nav.getCurrentlyPlayingServiceReference()
1104 refstr = ref.toString()
1107 if refstr != self.lastservice.value:
1108 self.lastservice.value = refstr
1109 self.lastservice.save()
1111 def setCurrentServicePath(self, path):
1112 hlen = len(self.history)
1114 self.history[self.history_pos] = path
1116 self.history.append(path)
1117 self.setHistoryPath()
1119 def getCurrentServicePath(self):
1120 hlen = len(self.history)
1122 return self.history[self.history_pos]
1125 def recallPrevService(self):
1126 hlen = len(self.history)
1128 if self.history_pos == hlen-1:
1129 tmp = self.history[self.history_pos]
1130 self.history[self.history_pos] = self.history[self.history_pos-1]
1131 self.history[self.history_pos-1] = tmp
1133 tmp = self.history[self.history_pos+1]
1134 self.history[self.history_pos+1] = self.history[self.history_pos]
1135 self.history[self.history_pos] = tmp
1136 self.setHistoryPath()
1139 if self.revertMode is None:
1141 lastservice=eServiceReference(self.lastservice.value)
1142 if lastservice.valid() and self.getCurrentSelection() != lastservice:
1143 self.setCurrentSelection(lastservice)
1144 elif self.revertMode == MODE_TV:
1146 elif self.revertMode == MODE_RADIO:
1148 self.revertMode = None
1151 from Screens.InfoBarGenerics import InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord, InfoBarRadioText
1153 class RadioInfoBar(Screen, InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord):
1154 def __init__(self, session):
1155 Screen.__init__(self, session)
1156 InfoBarEvent.__init__(self)
1157 InfoBarServiceName.__init__(self)
1158 InfoBarInstantRecord.__init__(self)
1159 self["CurrentTime"] = Clock()
1161 class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG, InfoBarRadioText):
1163 ALLOW_SUSPEND = True
1165 def __init__(self, session):
1166 ChannelSelectionBase.__init__(self, session)
1167 ChannelSelectionEdit.__init__(self)
1168 ChannelSelectionEPG.__init__(self)
1169 InfoBarRadioText.__init__(self)
1171 config.radio = ConfigSubsection();
1172 config.radio.lastservice = ConfigText()
1173 config.radio.lastroot = ConfigText()
1174 self.onLayoutFinish.append(self.onCreate)
1176 self.info = session.instantiateDialog(RadioInfoBar)
1178 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1180 "keyTV": self.closeRadio,
1181 "keyRadio": self.closeRadio,
1182 "cancel": self.closeRadio,
1183 "ok": self.channelSelected,
1188 for i in self.servicePathRadio:
1189 path += i.toString()
1191 if len(path) and path != config.radio.lastroot.value:
1192 config.radio.lastroot.value = path
1193 config.radio.lastroot.save()
1195 def restoreRoot(self):
1197 re = compile('.+?;')
1198 tmp = re.findall(config.radio.lastroot.value)
1201 self.servicePathRadio.append(eServiceReference(i[:len(i)-1]))
1204 path = self.servicePathRadio.pop()
1205 self.enterPath(path)
1207 self.showFavourites()
1210 def preEnterPath(self, refstr):
1211 if len(self.servicePathRadio) and self.servicePathRadio[0] != eServiceReference(refstr):
1212 pathstr = config.radio.lastroot.value
1213 if pathstr is not None and pathstr.find(refstr) == 0:
1215 lastservice=eServiceReference(config.radio.lastservice.value)
1216 if lastservice.valid():
1217 self.setCurrentSelection(lastservice)
1224 lastservice=eServiceReference(config.radio.lastservice.value)
1225 if lastservice.valid():
1226 self.servicelist.setCurrent(lastservice)
1227 self.session.nav.playService(lastservice)
1228 self.servicelist.setPlayableIgnoreService(lastservice)
1231 def channelSelected(self): # just return selected service
1232 ref = self.getCurrentSelection()
1234 self.toggleMoveMarked()
1235 elif (ref.flags & 7) == 7:
1237 elif self.bouquet_mark_edit:
1239 elif not (ref.flags & 64): # no marker
1240 playingref = self.session.nav.getCurrentlyPlayingServiceReference()
1241 if playingref is None or playingref != ref:
1242 self.session.nav.playService(ref)
1243 self.servicelist.setPlayableIgnoreService(ref)
1244 config.radio.lastservice.value = ref.toString()
1245 config.radio.lastservice.save()
1248 def closeRadio(self):
1250 #set previous tv service
1251 lastservice=eServiceReference(config.tv.lastservice.value)
1252 self.session.nav.playService(lastservice)
1255 class SimpleChannelSelection(ChannelSelectionBase):
1256 def __init__(self, session, title):
1257 ChannelSelectionBase.__init__(self, session)
1259 self.onShown.append(self.__onExecCallback)
1261 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1263 "cancel": self.close,
1264 "ok": self.channelSelected,
1265 "keyRadio": self.setModeRadio,
1266 "keyTV": self.setModeTv,
1269 def __onExecCallback(self):
1270 self.setTitle(self.title)
1273 def channelSelected(self): # just return selected service
1274 ref = self.getCurrentSelection()
1275 if (ref.flags & 7) == 7:
1277 elif not (ref.flags & 64):
1278 ref = self.getCurrentSelection()
1281 def setModeTv(self):
1283 self.showFavourites()
1285 def setModeRadio(self):
1287 self.showFavourites()