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.addCurrentServiceToBouquet(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 self.bouquetNumOffsetCache = { }
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"
335 current = self.servicelist.getCurrent()
336 if current and current.toString() == self.bouquet_rootstr:
337 self.servicelist.addService(service, True)
338 mutableBouquet.flushChanges()
340 print "get mutable list for new created bouquet failed"
341 # do some voodoo to check if current_root is equal to bouquet_root
342 cur_root = self.getRoot();
343 str1 = cur_root.toString()
344 pos1 = str1.find("FROM BOUQUET")
345 pos2 = self.bouquet_rootstr.find("FROM BOUQUET")
346 if pos1 != -1 and pos2 != -1 and str1[pos1:] == self.bouquet_rootstr[pos2:]:
347 self.setMode() #reload
349 print "add", str, "to bouquets failed"
351 print "bouquetlist is not editable"
353 def copyCurrentToBouquetList(self):
354 provider = ServiceReference(self.getCurrentSelection())
355 providerName = provider.getServiceName()
356 serviceHandler = eServiceCenter.getInstance()
357 services = serviceHandler.list(provider.ref)
358 self.addBouquet(providerName, services and services.getContent('R', True))
360 def removeBouquet(self):
361 refstr = self.getCurrentSelection().toString()
362 self.bouquetNumOffsetCache = { }
363 pos = refstr.find('FROM BOUQUET "')
365 refstr = refstr[pos+14:]
366 pos = refstr.find('"')
368 filename = '/etc/enigma2/' + refstr[:pos] # FIXMEEE !!! HARDCODED /etc/enigma2
369 self.removeCurrentService()
373 print "error during remove of", filename
375 # multiple marked entry stuff ( edit mode, later multiepg selection )
376 def startMarkedEdit(self):
377 self.mutableList = self.getMutableList()
378 # add all services from the current list to internal marked set in listboxservicecontent
379 self.clearMarks() # this clears the internal marked set in the listboxservicecontent
380 self.saved_title = self.instance.getTitle()
381 pos = self.saved_title.find(')')
382 new_title = self.saved_title[:pos+1]
383 if config.usage.multibouquet.value:
384 new_title += ' ' + _("[bouquet edit]")
386 new_title += ' ' + _("[favourite edit]")
387 self.setTitle(new_title)
388 self.bouquet_mark_edit = True
389 self.__marked = self.servicelist.getRootServices()
390 for x in self.__marked:
391 self.servicelist.addMarked(eServiceReference(x))
392 self.savedPath = self.servicePath[:]
393 self.showAllServices()
395 def endMarkedEdit(self, abort):
396 if not abort and self.mutableList is not None:
397 self.bouquetNumOffsetCache = { }
398 new_marked = set(self.servicelist.getMarked())
399 old_marked = set(self.__marked)
400 removed = old_marked - new_marked
401 added = new_marked - old_marked
405 self.mutableList.removeService(eServiceReference(x))
408 self.mutableList.addService(eServiceReference(x))
410 self.mutableList.flushChanges()
413 self.bouquet_mark_edit = False
414 self.mutableList = None
415 self.setTitle(self.saved_title)
416 self.saved_title = None
417 # self.servicePath is just a reference to servicePathTv or Radio...
418 # so we never ever do use the asignment operator in self.servicePath
419 del self.servicePath[:] # remove all elements
420 self.servicePath += self.savedPath # add saved elements
422 self.setRoot(self.servicePath[len(self.servicePath)-1])
424 def clearMarks(self):
425 self.servicelist.clearMarks()
428 ref = self.servicelist.getCurrent()
429 if self.servicelist.isMarked(ref):
430 self.servicelist.removeMarked(ref)
432 self.servicelist.addMarked(ref)
434 def removeCurrentService(self):
435 ref = self.servicelist.getCurrent()
436 mutableList = self.getMutableList()
437 if ref.valid() and mutableList is not None:
438 if not mutableList.removeService(ref):
439 self.bouquetNumOffsetCache = { }
440 mutableList.flushChanges() #FIXME dont flush on each single removed service
441 self.servicelist.removeCurrent()
443 def addCurrentServiceToBouquet(self, dest):
444 mutableList = self.getMutableList(dest)
445 if not mutableList is None:
446 if not mutableList.addService(self.servicelist.getCurrent()):
447 self.bouquetNumOffsetCache = { }
448 mutableList.flushChanges()
450 def toggleMoveMode(self):
452 if self.entry_marked:
453 self.toggleMoveMarked() # unmark current entry
454 self.movemode = False
455 self.pathChangedDisabled = False # re-enable path change
456 self.mutableList.flushChanges() # FIXME add check if changes was made
457 self.mutableList = None
458 self.setTitle(self.saved_title)
459 self.saved_title = None
460 if self.getRoot() == self.bouquet_root:
461 self.bouquetNumOffsetCache = { }
463 self.mutableList = self.getMutableList()
465 self.pathChangedDisabled = True # no path change allowed in movemode
466 self.saved_title = self.instance.getTitle()
467 new_title = self.saved_title
468 pos = self.saved_title.find(')')
469 new_title = self.saved_title[:pos+1] + ' ' + _("[move mode]") + self.saved_title[pos+1:]
470 self.setTitle(new_title);
472 def handleEditCancel(self):
473 if self.movemode: #movemode active?
474 self.channelSelected() # unmark
475 self.toggleMoveMode() # disable move mode
476 elif self.bouquet_mark_edit:
477 self.endMarkedEdit(True) # abort edit mode
479 def toggleMoveMarked(self):
480 if self.entry_marked:
481 self.servicelist.setCurrentMarked(False)
482 self.entry_marked = False
484 self.servicelist.setCurrentMarked(True)
485 self.entry_marked = True
488 self.session.open(ChannelContextMenu, self)
493 # this makes it much simple to implement a selectable radio or tv mode :)
494 service_types_tv = '1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17) || (type == 195) || (type == 25)'
495 service_types_radio = '1:7:2:0:0:0:0:0:0:0:(type == 2)'
497 class ChannelSelectionBase(Screen):
498 def __init__(self, session):
499 Screen.__init__(self, session)
501 self["key_red"] = Button(_("All"))
502 self["key_green"] = Button(_("Satellites"))
503 self["key_yellow"] = Button(_("Provider"))
504 self["key_blue"] = Button(_("Favourites"))
506 self["list"] = ServiceList()
507 self.servicelist = self["list"]
509 self.numericalTextInput = NumericalTextInput()
510 self.numericalTextInput.setUseableChars(u'1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ')
512 self.servicePathTV = [ ]
513 self.servicePathRadio = [ ]
514 self.servicePath = [ ]
518 self.pathChangedDisabled = False
520 self.bouquetNumOffsetCache = { }
522 self["ChannelSelectBaseActions"] = NumberActionMap(["ChannelSelectBaseActions", "NumberActions"],
524 "showFavourites": self.showFavourites,
525 "showAllServices": self.showAllServices,
526 "showProviders": self.showProviders,
527 "showSatellites": self.showSatellites,
528 "nextBouquet": self.nextBouquet,
529 "prevBouquet": self.prevBouquet,
530 "nextMarker": self.nextMarker,
531 "prevMarker": self.prevMarker,
532 "1": self.keyNumberGlobal,
533 "2": self.keyNumberGlobal,
534 "3": self.keyNumberGlobal,
535 "4": self.keyNumberGlobal,
536 "5": self.keyNumberGlobal,
537 "6": self.keyNumberGlobal,
538 "7": self.keyNumberGlobal,
539 "8": self.keyNumberGlobal,
540 "9": self.keyNumberGlobal,
543 self.recallBouquetMode()
545 def appendDVBTypes(self, ref):
547 pos = path.find(' FROM BOUQUET')
549 return eServiceReference(self.service_types + path[pos:])
552 def getBouquetNumOffset(self, bouquet):
553 if config.usage.multibouquet.value:
555 bouquet = self.appendDVBTypes(bouquet)
557 return self.bouquetNumOffsetCache[bouquet.toString()]
560 serviceHandler = eServiceCenter.getInstance()
561 bouquetlist = serviceHandler.list(self.bouquet_root)
562 if not bouquetlist is None:
564 bouquetIterator = self.appendDVBTypes(bouquetlist.getNext())
565 if not bouquetIterator.valid(): #end of list
567 self.bouquetNumOffsetCache[bouquetIterator.toString()]=offsetCount
568 if ((bouquetIterator.flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory):
570 servicelist = serviceHandler.list(bouquetIterator)
571 if not servicelist is None:
573 serviceIterator = servicelist.getNext()
574 if not serviceIterator.valid(): #check if end of list
576 if serviceIterator.flags: #playable services have no flags
579 return self.bouquetNumOffsetCache.get(bouquet.toString(), offsetCount)
581 def recallBouquetMode(self):
582 if self.mode == MODE_TV:
583 self.service_types = service_types_tv
584 if config.usage.multibouquet.value:
585 self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET "bouquets.tv" ORDER BY bouquet'
587 self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.tv" ORDER BY bouquet'%(self.service_types)
589 self.service_types = service_types_radio
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.radio" ORDER BY bouquet'
593 self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.radio" ORDER BY bouquet'%(self.service_types)
594 self.bouquet_root = eServiceReference(self.bouquet_rootstr)
598 self.servicePath = self.servicePathTV
599 self.recallBouquetMode()
600 title = self.instance.getTitle()
601 pos = title.find(" (")
607 def setRadioMode(self):
608 self.mode = MODE_RADIO
609 self.servicePath = self.servicePathRadio
610 self.recallBouquetMode()
611 title = self.instance.getTitle()
612 pos = title.find(" (")
618 def setRoot(self, root, justSet=False):
619 path = root.getPath()
620 inBouquetRootList = path.find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
621 pos = path.find(' FROM BOUQUET')
622 isBouquet = pos != -1
623 if not inBouquetRootList and isBouquet:
624 self.servicelist.setMode(ServiceList.MODE_FAVOURITES)
625 self.servicelist.setNumberOffset(self.getBouquetNumOffset(root))
626 refstr = self.service_types + path[pos:]
627 root = eServiceReference(refstr)
629 self.servicelist.setMode(ServiceList.MODE_NORMAL)
630 self.servicelist.setRoot(root, justSet)
631 self.buildTitleString()
633 def removeModeStr(self, str):
634 if self.mode == MODE_TV:
635 pos = str.find(' (TV)')
637 pos = str.find(' (Radio)')
642 def getServiceName(self, ref):
643 str = self.removeModeStr(ServiceReference(ref).getServiceName())
645 pathstr = ref.getPath()
646 if pathstr.find('FROM PROVIDERS') != -1:
648 if pathstr.find('FROM SATELLITES') != -1:
649 return _("Satellites")
650 if pathstr.find(') ORDER BY name') != -1:
654 def buildTitleString(self):
655 titleStr = self.instance.getTitle()
656 pos = titleStr.find(']')
658 pos = titleStr.find(')')
660 titleStr = titleStr[:pos+1]
661 Len = len(self.servicePath)
663 base_ref = self.servicePath[0]
665 end_ref = self.servicePath[Len-1]
668 nameStr = self.getServiceName(base_ref)
669 titleStr += ' ' + nameStr
670 if end_ref is not None:
675 nameStr = self.getServiceName(end_ref)
677 self.setTitle(titleStr)
680 self.servicelist.moveUp()
683 self.servicelist.moveDown()
686 del self.servicePath[:]
688 def enterPath(self, ref, justSet=False):
689 self.servicePath.append(ref)
690 self.setRoot(ref, justSet)
692 def pathUp(self, justSet=False):
693 prev = self.servicePath.pop()
694 length = len(self.servicePath)
696 current = self.servicePath[length-1]
697 self.setRoot(current, justSet)
699 self.setCurrentSelection(prev)
702 def isBasePathEqual(self, ref):
703 if len(self.servicePath) > 1 and self.servicePath[0] == ref:
707 def isPrevPathEqual(self, ref):
708 length = len(self.servicePath)
709 if length > 1 and self.servicePath[length-2] == ref:
713 def preEnterPath(self, refstr):
716 def showAllServices(self):
717 if not self.pathChangedDisabled:
718 refstr = '%s ORDER BY name'%(self.service_types)
719 if not self.preEnterPath(refstr):
720 ref = eServiceReference(refstr)
721 currentRoot = self.getRoot()
722 if currentRoot is None or currentRoot != ref:
726 def showSatellites(self):
727 if not self.pathChangedDisabled:
728 refstr = '%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types)
729 if not self.preEnterPath(refstr):
730 ref = eServiceReference(refstr)
734 if self.isBasePathEqual(ref):
735 if self.isPrevPathEqual(ref):
737 prev = self.pathUp(justSet)
739 currentRoot = self.getRoot()
740 if currentRoot is None or currentRoot != ref:
743 self.enterPath(ref, True)
745 serviceHandler = eServiceCenter.getInstance()
746 servicelist = serviceHandler.list(ref)
747 if not servicelist is None:
749 service = servicelist.getNext()
750 if not service.valid(): #check if end of list
752 orbpos = service.getUnsignedData(4) >> 16
753 if service.getPath().find("FROM PROVIDER") != -1:
754 service_name = _("Providers")
755 elif service.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
756 service_name = _("New")
758 service_name = _("Services")
760 service_name += str(' - %s'%(nimmanager.getSatDescription(orbpos)))
761 service.setName(service_name) # why we need this cast?
763 if orbpos == 0xFFFF: #Cable
764 n = ("%s (%s)") % (service_name, _("Cable"))
765 elif orbpos == 0xEEEE: #Terrestrial
766 n = ("%s (%s)") % (service_name, _("Terrestrial"))
768 if orbpos > 1800: # west
769 orbpos = 3600 - orbpos
773 n = ("%s (%d.%d" + h + ")") % (service_name, orbpos / 10, orbpos % 10)
775 self.servicelist.addService(service)
776 self.servicelist.finishFill()
778 self.setCurrentSelection(prev)
780 def showProviders(self):
781 if not self.pathChangedDisabled:
782 refstr = '%s FROM PROVIDERS ORDER BY name'%(self.service_types)
783 if not self.preEnterPath(refstr):
784 ref = eServiceReference(refstr)
785 if self.isBasePathEqual(ref):
788 currentRoot = self.getRoot()
789 if currentRoot is None or currentRoot != ref:
793 def changeBouquet(self, direction):
794 if not self.pathChangedDisabled:
795 if self.isBasePathEqual(self.bouquet_root):
801 ref = self.getCurrentSelection()
805 return self.isBasePathEqual(self.bouquet_root)
808 return self.servicelist.atBegin()
811 return self.servicelist.atEnd()
813 def nextBouquet(self):
814 self.changeBouquet(+1)
816 def prevBouquet(self):
817 self.changeBouquet(-1)
819 def showFavourites(self):
820 if not self.pathChangedDisabled:
821 if not self.preEnterPath(self.bouquet_rootstr):
822 if self.isBasePathEqual(self.bouquet_root):
825 currentRoot = self.getRoot()
826 if currentRoot is None or currentRoot != self.bouquet_root:
828 self.enterPath(self.bouquet_root)
830 def keyNumberGlobal(self, number):
831 unichar = self.numericalTextInput.getKey(number)
832 charstr = unichar.encode("utf-8")
833 if len(charstr) == 1:
834 self.servicelist.moveToChar(charstr[0])
837 return self.servicelist.getRoot()
839 def getCurrentSelection(self):
840 return self.servicelist.getCurrent()
842 def setCurrentSelection(self, service):
843 servicepath = service.getPath()
844 pos = servicepath.find(" FROM BOUQUET")
846 if self.mode == MODE_TV:
847 servicepath = '(type == 1)' + servicepath[pos:]
849 servicepath = '(type == 2)' + servicepath[pos:]
850 service.setPath(servicepath)
851 self.servicelist.setCurrent(service)
853 def getBouquetList(self):
855 serviceHandler = eServiceCenter.getInstance()
856 if config.usage.multibouquet.value:
857 list = serviceHandler.list(self.bouquet_root)
863 if ((s.flags & eServiceReference.flagDirectory) == eServiceReference.flagDirectory):
864 info = serviceHandler.info(s)
866 bouquets.append((info.getName(s), s))
869 info = serviceHandler.info(self.bouquet_root)
871 bouquets.append((info.getName(self.bouquet_root), self.bouquet_root))
875 def keyNumber0(self, num):
876 if len(self.servicePath) > 1:
879 self.keyNumberGlobal(num)
882 if len(self.servicePath) > 1:
883 if self.isBasePathEqual(self.bouquet_root):
884 self.showFavourites()
886 ref = eServiceReference('%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types))
887 if self.isBasePathEqual(ref):
888 self.showSatellites()
890 ref = eServiceReference('%s FROM PROVIDERS ORDER BY name'%(self.service_types))
891 if self.isBasePathEqual(ref):
894 self.showAllServices()
896 def nextMarker(self):
897 self.servicelist.moveToNextMarker()
899 def prevMarker(self):
900 self.servicelist.moveToPrevMarker()
904 #config for lastservice
905 config.tv = ConfigSubsection()
906 config.tv.lastservice = ConfigText()
907 config.tv.lastroot = ConfigText()
908 config.radio = ConfigSubsection()
909 config.radio.lastservice = ConfigText()
910 config.radio.lastroot = ConfigText()
911 config.servicelist = ConfigSubsection()
912 config.servicelist.lastmode = ConfigText(default = "tv")
914 class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG):
915 def __init__(self, session):
916 ChannelSelectionBase.__init__(self,session)
917 ChannelSelectionEdit.__init__(self)
918 ChannelSelectionEPG.__init__(self)
920 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
922 "cancel": self.cancel,
923 "ok": self.channelSelected,
924 "keyRadio": self.setModeRadio,
925 "keyTV": self.setModeTv,
928 self.onShown.append(self.__onShown)
930 self.lastChannelRootTimer = eTimer()
931 self.lastChannelRootTimer.timeout.get().append(self.__onCreate)
932 self.lastChannelRootTimer.start(100,True)
934 self.history_tv = [ ]
935 self.history_radio = [ ]
936 self.history = self.history_tv
939 self.lastservice = config.tv.lastservice
940 self.lastroot = config.tv.lastroot
941 self.revertMode = None
945 lastservice=eServiceReference(self.lastservice.value)
946 if lastservice.valid():
947 self.setCurrentSelection(lastservice)
950 if self.revertMode is None and config.servicelist.lastmode.value == "radio":
951 self.revertMode = MODE_RADIO
952 self.history = self.history_tv
953 self.lastservice = config.tv.lastservice
954 self.lastroot = config.tv.lastroot
955 config.servicelist.lastmode.value = "tv"
959 def setModeRadio(self):
960 if self.revertMode is None and config.servicelist.lastmode.value == "tv":
961 self.revertMode = MODE_TV
962 if config.usage.e1like_radio_mode.value:
963 self.history = self.history_radio
964 self.lastservice = config.radio.lastservice
965 self.lastroot = config.radio.lastroot
966 config.servicelist.lastmode.value = "radio"
970 def __onCreate(self):
971 if config.usage.e1like_radio_mode.value:
972 if config.servicelist.lastmode.value == "tv":
978 lastservice=eServiceReference(self.lastservice.value)
979 if lastservice.valid():
983 self.recallBouquetMode()
984 ref = self.session.nav.getCurrentlyPlayingServiceReference()
985 if ref is not None and ref.valid() and ref.getPath() == "":
986 self.servicelist.setPlayableIgnoreService(ref)
988 self.servicelist.setPlayableIgnoreService(eServiceReference())
990 def channelSelected(self):
991 ref = self.getCurrentSelection()
993 self.toggleMoveMarked()
994 elif (ref.flags & 7) == 7:
996 elif self.bouquet_mark_edit:
998 elif not (ref.flags & 64): # no marker
1002 #called from infoBar and channelSelected
1004 self.revertMode=None
1005 ref = self.session.nav.getCurrentlyPlayingServiceReference()
1006 nref = self.getCurrentSelection()
1007 if ref is None or ref != nref:
1008 self.session.nav.playService(nref)
1011 config.servicelist.lastmode.save()
1012 self.addToHistory(nref)
1014 def addToHistory(self, ref):
1015 if self.servicePath is not None:
1016 tmp=self.servicePath[:]
1019 del self.history[self.history_pos+1:]
1022 self.history.append(tmp)
1023 hlen = len(self.history)
1024 if hlen > HISTORYSIZE:
1027 self.history_pos = hlen-1
1029 def historyBack(self):
1030 hlen = len(self.history)
1031 if hlen > 1 and self.history_pos > 0:
1032 self.history_pos -= 1
1033 self.setHistoryPath()
1035 def historyNext(self):
1036 hlen = len(self.history)
1037 if hlen > 1 and self.history_pos < (hlen-1):
1038 self.history_pos += 1
1039 self.setHistoryPath()
1041 def setHistoryPath(self):
1042 path = self.history[self.history_pos][:]
1044 del self.servicePath[:]
1045 self.servicePath += path
1049 if self.getRoot() != root:
1051 self.session.nav.playService(ref)
1052 self.setCurrentSelection(ref)
1057 for i in self.servicePath:
1058 path += i.toString()
1060 if len(path) and path != self.lastroot.value:
1061 self.lastroot.value = path
1062 self.lastroot.save()
1064 def restoreRoot(self):
1066 re = compile('.+?;')
1067 tmp = re.findall(self.lastroot.value)
1070 self.servicePath.append(eServiceReference(i[:len(i)-1]))
1073 path = self.servicePath.pop()
1074 self.enterPath(path)
1076 self.showFavourites()
1079 def preEnterPath(self, refstr):
1080 if len(self.servicePath) and self.servicePath[0] != eServiceReference(refstr):
1081 pathstr = self.lastroot.value
1082 if pathstr is not None and pathstr.find(refstr) == 0:
1084 lastservice=eServiceReference(self.lastservice.value)
1085 if lastservice.valid():
1086 self.setCurrentSelection(lastservice)
1090 def saveChannel(self):
1091 ref = self.session.nav.getCurrentlyPlayingServiceReference()
1093 refstr = ref.toString()
1096 if refstr != self.lastservice.value:
1097 self.lastservice.value = refstr
1098 self.lastservice.save()
1100 def setCurrentServicePath(self, path):
1101 hlen = len(self.history)
1103 self.history[self.history_pos] = path
1105 self.history.append(path)
1106 self.setHistoryPath()
1108 def getCurrentServicePath(self):
1109 hlen = len(self.history)
1111 return self.history[self.history_pos]
1114 def recallPrevService(self):
1115 hlen = len(self.history)
1117 if self.history_pos == hlen-1:
1118 tmp = self.history[self.history_pos]
1119 self.history[self.history_pos] = self.history[self.history_pos-1]
1120 self.history[self.history_pos-1] = tmp
1122 tmp = self.history[self.history_pos+1]
1123 self.history[self.history_pos+1] = self.history[self.history_pos]
1124 self.history[self.history_pos] = tmp
1125 self.setHistoryPath()
1128 if self.revertMode is None:
1130 lastservice=eServiceReference(self.lastservice.value)
1131 if lastservice.valid() and self.getCurrentSelection() != lastservice:
1132 self.setCurrentSelection(lastservice)
1133 elif self.revertMode == MODE_TV:
1135 elif self.revertMode == MODE_RADIO:
1137 self.revertMode = None
1140 from Screens.InfoBarGenerics import InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord, InfoBarRadioText
1142 class RadioInfoBar(Screen, InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord):
1143 def __init__(self, session):
1144 Screen.__init__(self, session)
1145 InfoBarEvent.__init__(self)
1146 InfoBarServiceName.__init__(self)
1147 InfoBarInstantRecord.__init__(self)
1148 self["CurrentTime"] = Clock()
1150 class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG, InfoBarRadioText):
1152 ALLOW_SUSPEND = True
1154 def __init__(self, session):
1155 ChannelSelectionBase.__init__(self, session)
1156 ChannelSelectionEdit.__init__(self)
1157 ChannelSelectionEPG.__init__(self)
1158 InfoBarRadioText.__init__(self)
1160 config.radio = ConfigSubsection();
1161 config.radio.lastservice = ConfigText()
1162 config.radio.lastroot = ConfigText()
1163 self.onLayoutFinish.append(self.onCreate)
1165 self.info = session.instantiateDialog(RadioInfoBar)
1167 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1169 "keyTV": self.closeRadio,
1170 "keyRadio": self.closeRadio,
1171 "cancel": self.closeRadio,
1172 "ok": self.channelSelected,
1177 for i in self.servicePathRadio:
1178 path += i.toString()
1180 if len(path) and path != config.radio.lastroot.value:
1181 config.radio.lastroot.value = path
1182 config.radio.lastroot.save()
1184 def restoreRoot(self):
1186 re = compile('.+?;')
1187 tmp = re.findall(config.radio.lastroot.value)
1190 self.servicePathRadio.append(eServiceReference(i[:len(i)-1]))
1193 path = self.servicePathRadio.pop()
1194 self.enterPath(path)
1196 self.showFavourites()
1199 def preEnterPath(self, refstr):
1200 if len(self.servicePathRadio) and self.servicePathRadio[0] != eServiceReference(refstr):
1201 pathstr = config.radio.lastroot.value
1202 if pathstr is not None and pathstr.find(refstr) == 0:
1204 lastservice=eServiceReference(config.radio.lastservice.value)
1205 if lastservice.valid():
1206 self.setCurrentSelection(lastservice)
1213 lastservice=eServiceReference(config.radio.lastservice.value)
1214 if lastservice.valid():
1215 self.servicelist.setCurrent(lastservice)
1216 self.session.nav.playService(lastservice)
1217 self.servicelist.setPlayableIgnoreService(lastservice)
1220 def channelSelected(self): # just return selected service
1221 ref = self.getCurrentSelection()
1223 self.toggleMoveMarked()
1224 elif (ref.flags & 7) == 7:
1226 elif self.bouquet_mark_edit:
1228 elif not (ref.flags & 64): # no marker
1229 playingref = self.session.nav.getCurrentlyPlayingServiceReference()
1230 if playingref is None or playingref != ref:
1231 self.session.nav.playService(ref)
1232 self.servicelist.setPlayableIgnoreService(ref)
1233 config.radio.lastservice.value = ref.toString()
1234 config.radio.lastservice.save()
1237 def closeRadio(self):
1239 #set previous tv service
1240 lastservice=eServiceReference(config.tv.lastservice.value)
1241 self.session.nav.playService(lastservice)
1244 class SimpleChannelSelection(ChannelSelectionBase):
1245 def __init__(self, session, title):
1246 ChannelSelectionBase.__init__(self, session)
1248 self.onShown.append(self.__onExecCallback)
1250 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1252 "cancel": self.close,
1253 "ok": self.channelSelected,
1254 "keyRadio": self.setModeRadio,
1255 "keyTV": self.setModeTv,
1258 def __onExecCallback(self):
1259 self.setTitle(self.title)
1262 def channelSelected(self): # just return selected service
1263 ref = self.getCurrentSelection()
1264 if (ref.flags & 7) == 7:
1266 elif not (ref.flags & 64):
1267 ref = self.getCurrentSelection()
1270 def setModeTv(self):
1272 self.showFavourites()
1274 def setModeRadio(self):
1276 self.showFavourites()