1 from Screen import Screen
2 from Components.Button import Button
3 from Components.ServiceList import ServiceList
4 from Components.ActionMap import NumberActionMap, ActionMap, HelpableActionMap
5 from Components.MenuList import MenuList
6 from Components.ServiceEventTracker import ServiceEventTracker
7 from EpgSelection import EPGSelection
8 from enigma import eServiceReference, eEPGCache, eServiceCenter, eTimer, eDVBDB, iPlayableService, iServiceInformation
9 from Components.config import config, ConfigSubsection, ConfigText
10 from Screens.FixedMenu import FixedMenu
11 from Tools.NumericalTextInput import NumericalTextInput
12 from Components.NimManager import nimmanager
13 from Components.Sources.Clock import Clock
14 from Components.Sources.RdsDecoder import RdsDecoder
15 from Components.Input import Input
16 from Components.ParentalControl import parentalControl
17 from Components.Pixmap import Pixmap
18 from Screens.InputBox import InputBox, PinInput
19 from Screens.MessageBox import MessageBox
20 from Screens.ServiceInfo import ServiceInfo
21 from Screens.RdsDisplay import RassInteractive
22 from ServiceReference import ServiceReference
23 from Tools.BoundFunction import boundFunction
27 FLAG_SERVICE_NEW_FOUND = 64 #define in lib/dvb/idvb.h as dxNewFound = 64
29 import xml.dom.minidom
31 class BouquetSelector(Screen):
32 def __init__(self, session, bouquets, selectedFunc, enableWrapAround=False):
33 Screen.__init__(self, session)
35 self.selectedFunc=selectedFunc
37 self["actions"] = ActionMap(["OkCancelActions"],
39 "ok": self.okbuttonClick,
40 "cancel": self.cancelClick
42 entrys = [ (x[0], x[1]) for x in bouquets ]
43 self["menu"] = MenuList(entrys, enableWrapAround)
46 cur = self["menu"].getCurrent()
49 def okbuttonClick(self):
50 self.selectedFunc(self.getCurrent())
58 def cancelClick(self):
61 # csel.bouquet_mark_edit values
66 def apend_when_current_valid(current, menu, args):
67 if current and current.valid():
70 class ChannelContextMenu(Screen):
71 def __init__(self, session, csel):
72 Screen.__init__(self, session)
76 self["actions"] = ActionMap(["OkCancelActions"],
78 "ok": self.okbuttonClick,
79 "cancel": self.cancelClick
83 current = csel.getCurrentSelection()
84 current_root = csel.getRoot()
85 current_sel_path = current.getPath()
86 current_sel_flags = current.flags
87 inBouquetRootList = current_root and current_root.getPath().find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
88 inBouquet = csel.getMutableList() is not None
89 haveBouquets = config.usage.multibouquet.value
91 if not (len(current_sel_path) or current_sel_flags & (eServiceReference.isDirectory|eServiceReference.isMarker)):
92 apend_when_current_valid(current, menu, (_("show transponder info"), self.showServiceInformations))
93 if csel.bouquet_mark_edit == OFF and not csel.movemode:
94 if not inBouquetRootList:
95 isPlayable = not (current_sel_flags & (eServiceReference.isMarker|eServiceReference.isDirectory))
97 if config.ParentalControl.configured.value:
98 if parentalControl.getProtectionLevel(csel.getCurrentSelection().toCompareString()) == -1:
99 apend_when_current_valid(current, menu, (_("add to parental protection"), boundFunction(self.addParentalProtection, csel.getCurrentSelection())))
101 apend_when_current_valid(current, menu, (_("remove from parental protection"), boundFunction(self.removeParentalProtection, csel.getCurrentSelection())))
103 apend_when_current_valid(current, menu, (_("add service to bouquet"), self.addServiceToBouquetSelected))
105 apend_when_current_valid(current, menu, (_("add service to favourites"), self.addServiceToBouquetSelected))
108 if not inBouquet and current_sel_path.find("PROVIDERS") == -1:
109 apend_when_current_valid(current, menu, (_("copy to bouquets"), self.copyCurrentToBouquetList))
110 if current_sel_path.find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
111 apend_when_current_valid(current, menu, (_("remove all new found flags"), self.removeAllNewFoundFlags))
113 apend_when_current_valid(current, menu, (_("remove entry"), self.removeCurrentService))
114 if current_root and current_root.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
115 apend_when_current_valid(current, menu, (_("remove new found flag"), self.removeNewFoundFlag))
117 menu.append((_("add bouquet"), self.showBouquetInputBox))
118 apend_when_current_valid(current, menu, (_("remove entry"), self.removeBouquet))
120 if inBouquet: # current list is editable?
121 if csel.bouquet_mark_edit == OFF:
122 if not csel.movemode:
123 apend_when_current_valid(current, menu, (_("enable move mode"), self.toggleMoveMode))
124 if not inBouquetRootList and current_root and not (current_root.flags & eServiceReference.isGroup):
125 menu.append((_("add marker"), self.showMarkerInputBox))
127 apend_when_current_valid(current, menu, (_("enable bouquet edit"), self.bouquetMarkStart))
129 apend_when_current_valid(current, menu, (_("enable favourite edit"), self.bouquetMarkStart))
130 if current_sel_flags & eServiceReference.isGroup:
131 apend_when_current_valid(current, menu, (_("edit alternatives"), self.editAlternativeServices))
132 apend_when_current_valid(current, menu, (_("show alternatives"), self.showAlternativeServices))
133 apend_when_current_valid(current, menu, (_("remove all alternatives"), self.removeAlternativeServices))
134 elif not current_sel_flags & eServiceReference.isMarker:
135 apend_when_current_valid(current, menu, (_("add alternatives"), self.addAlternativeServices))
137 apend_when_current_valid(current, menu, (_("disable move mode"), self.toggleMoveMode))
139 if csel.bouquet_mark_edit == EDIT_BOUQUET:
141 apend_when_current_valid(current, menu, (_("end bouquet edit"), self.bouquetMarkEnd))
142 apend_when_current_valid(current, menu, (_("abort bouquet edit"), self.bouquetMarkAbort))
144 apend_when_current_valid(current, menu, (_("end favourites edit"), self.bouquetMarkEnd))
145 apend_when_current_valid(current, menu, (_("abort favourites edit"), self.bouquetMarkAbort))
147 apend_when_current_valid(current, menu, (_("end alternatives edit"), self.bouquetMarkEnd))
148 apend_when_current_valid(current, menu, (_("abort alternatives edit"), self.bouquetMarkAbort))
150 menu.append((_("back"), self.cancelClick))
151 self["menu"] = MenuList(menu)
153 def okbuttonClick(self):
154 self["menu"].getCurrent()[1]()
156 def cancelClick(self):
159 def showServiceInformations(self):
160 self.session.open( ServiceInfo, self.csel.getCurrentSelection() )
162 def showBouquetInputBox(self):
163 self.session.openWithCallback(self.bouquetInputCallback, InputBox, title=_("Please enter a name for the new bouquet"), text="bouquetname", maxSize=False, type=Input.TEXT)
165 def bouquetInputCallback(self, bouquet):
166 if bouquet is not None:
167 self.csel.addBouquet(bouquet, None)
170 def addParentalProtection(self, service):
171 parentalControl.protectService(service.toCompareString())
174 def removeParentalProtection(self, service):
175 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"))
177 def pinEntered(self, service, result):
179 parentalControl.unProtectService(service)
182 self.session.openWithCallback(self.close, MessageBox, _("The pin code you entered is wrong."), MessageBox.TYPE_ERROR)
184 def addServiceToBouquetSelected(self):
185 bouquets = self.csel.getBouquetList()
190 if cnt > 1: # show bouquet list
191 self.bsel = self.session.openWithCallback(self.bouquetSelClosed, BouquetSelector, bouquets, self.addCurrentServiceToBouquet)
192 elif cnt == 1: # add to only one existing bouquet
193 self.addCurrentServiceToBouquet(bouquets[0][1])
195 def bouquetSelClosed(self, recursive):
200 def copyCurrentToBouquetList(self):
201 self.csel.copyCurrentToBouquetList()
204 def removeBouquet(self):
205 self.csel.removeBouquet()
208 def showMarkerInputBox(self):
209 self.session.openWithCallback(self.markerInputCallback, InputBox, title=_("Please enter a name for the new marker"), text="markername", maxSize=False, type=Input.TEXT)
211 def markerInputCallback(self, marker):
212 if marker is not None:
213 self.csel.addMarker(marker)
216 def addCurrentServiceToBouquet(self, dest):
217 self.csel.addServiceToBouquet(dest)
218 if self.bsel is not None:
219 self.bsel.close(True)
221 self.close(True) # close bouquet selection
223 def removeCurrentService(self):
224 self.csel.removeCurrentService()
227 def toggleMoveMode(self):
228 self.csel.toggleMoveMode()
231 def bouquetMarkStart(self):
232 self.csel.startMarkedEdit(EDIT_BOUQUET)
235 def bouquetMarkEnd(self):
236 self.csel.endMarkedEdit(abort=False)
239 def bouquetMarkAbort(self):
240 self.csel.endMarkedEdit(abort=True)
243 def removeNewFoundFlag(self):
244 eDVBDB.getInstance().removeFlag(self.csel.getCurrentSelection(), FLAG_SERVICE_NEW_FOUND)
247 def removeAllNewFoundFlags(self):
248 curpath = self.csel.getCurrentSelection().getPath()
249 idx = curpath.find("satellitePosition == ")
251 tmp = curpath[idx+21:]
254 satpos = int(tmp[:idx])
255 eDVBDB.getInstance().removeFlags(FLAG_SERVICE_NEW_FOUND, -1, -1, -1, satpos)
258 def editAlternativeServices(self):
259 self.csel.startMarkedEdit(EDIT_ALTERNATIVES)
262 def showAlternativeServices(self):
263 self.csel.enterPath(self.csel.getCurrentSelection())
266 def removeAlternativeServices(self):
267 self.csel.removeAlternativeServices()
270 def addAlternativeServices(self):
271 self.csel.addAlternativeServices()
272 self.csel.startMarkedEdit(EDIT_ALTERNATIVES)
275 class ChannelSelectionEPG:
277 self["ChannelSelectEPGActions"] = ActionMap(["ChannelSelectEPGActions"],
279 "showEPGList": self.showEPGList,
282 def showEPGList(self):
283 ref=self.getCurrentSelection()
284 ptr=eEPGCache.getInstance()
285 if ptr.startTimeQuery(ref) != -1:
286 self.session.open(EPGSelection, ref)
288 print 'no epg for service', ref.toString()
290 class ChannelSelectionEdit:
292 self.entry_marked = False
293 self.movemode = False
294 self.bouquet_mark_edit = OFF
295 self.mutableList = None
297 self.saved_title = None
298 self.saved_root = None
300 class ChannelSelectionEditActionMap(ActionMap):
301 def __init__(self, csel, contexts = [ ], actions = { }, prio=0):
302 ActionMap.__init__(self, contexts, actions, prio)
305 def action(self, contexts, action):
306 if action == "cancel":
307 self.csel.handleEditCancel()
308 return 0 # fall-trough
310 return 0 # fall-trough
312 return ActionMap.action(self, contexts, action)
314 self["ChannelSelectEditActions"] = ChannelSelectionEditActionMap(self, ["ChannelSelectEditActions", "OkCancelActions"],
316 "contextMenu": self.doContext,
319 def getMutableList(self, root=eServiceReference()):
320 if not self.mutableList is None:
321 return self.mutableList
322 serviceHandler = eServiceCenter.getInstance()
325 list = root and serviceHandler.list(root)
327 return list.startEdit()
330 def buildBouquetID(self, str):
334 if (c >= 'a' and c <= 'z') or (c >= '0' and c <= '9'):
340 def addMarker(self, name):
341 current = self.servicelist.getCurrent()
342 mutableList = self.getMutableList()
345 str = '1:64:%d:0:0:0:0:0:0:0::%s'%(cnt, name)
346 ref = eServiceReference(str)
347 if current and current.valid():
348 if not mutableList.addService(ref, current):
349 self.servicelist.addService(ref, True)
350 mutableList.flushChanges()
352 elif not mutableList.addService(ref):
353 self.servicelist.addService(ref, True)
354 mutableList.flushChanges()
358 def addAlternativeServices(self):
359 cur_service = ServiceReference(self.getCurrentSelection())
360 root = self.getRoot()
361 cur_root = root and ServiceReference(root)
362 mutableBouquet = cur_root.list().startEdit()
364 name = cur_service.getServiceName()
366 if self.mode == MODE_TV:
367 str = '1:134:1:0:0:0:0:0:0:0:FROM BOUQUET \"alternatives.%s.tv\" ORDER BY bouquet'%(self.buildBouquetID(name))
369 str = '1:134:2:0:0:0:0:0:0:0:FROM BOUQUET \"alternatives.%s.radio\" ORDER BY bouquet'%(self.buildBouquetID(name))
370 new_ref = ServiceReference(str)
371 if not mutableBouquet.addService(new_ref.ref, cur_service.ref):
372 mutableBouquet.removeService(cur_service.ref)
373 mutableBouquet.flushChanges()
374 eDVBDB.getInstance().reloadBouquets()
375 mutableAlternatives = new_ref.list().startEdit()
376 if mutableAlternatives:
377 mutableAlternatives.setListName(name)
378 if mutableAlternatives.addService(cur_service.ref):
379 print "add", cur_service.toString(), "to new alternatives failed"
380 mutableAlternatives.flushChanges()
381 self.servicelist.addService(new_ref.ref, True)
382 self.servicelist.removeCurrent()
383 self.servicelist.moveUp()
385 print "get mutable list for new created alternatives failed"
387 print "add", str, "to", cur_root.getServiceName(), "failed"
389 print "bouquetlist is not editable"
391 def addBouquet(self, bName, services):
392 serviceHandler = eServiceCenter.getInstance()
393 mutableBouquetList = serviceHandler.list(self.bouquet_root).startEdit()
394 if mutableBouquetList:
395 if self.mode == MODE_TV:
397 str = '1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET \"userbouquet.%s.tv\" ORDER BY bouquet'%(self.buildBouquetID(bName))
400 str = '1:7:2:0:0:0:0:0:0:0:(type == 2) FROM BOUQUET \"userbouquet.%s.radio\" ORDER BY bouquet'%(self.buildBouquetID(bName))
401 new_bouquet_ref = eServiceReference(str)
402 if not mutableBouquetList.addService(new_bouquet_ref):
403 mutableBouquetList.flushChanges()
404 eDVBDB.getInstance().reloadBouquets()
405 mutableBouquet = serviceHandler.list(new_bouquet_ref).startEdit()
407 mutableBouquet.setListName(bName)
408 if services is not None:
409 for service in services:
410 if mutableBouquet.addService(service):
411 print "add", service.toString(), "to new bouquet failed"
412 mutableBouquet.flushChanges()
414 print "get mutable list for new created bouquet failed"
415 # do some voodoo to check if current_root is equal to bouquet_root
416 cur_root = self.getRoot();
417 str1 = cur_root and cur_root.toString()
418 pos1 = str1 and str1.find("FROM BOUQUET") or -1
419 pos2 = self.bouquet_rootstr.find("FROM BOUQUET")
420 if pos1 != -1 and pos2 != -1 and str1[pos1:] == self.bouquet_rootstr[pos2:]:
421 self.servicelist.addService(new_bouquet_ref)
423 print "add", str, "to bouquets failed"
425 print "bouquetlist is not editable"
427 def copyCurrentToBouquetList(self):
428 provider = ServiceReference(self.getCurrentSelection())
429 providerName = provider.getServiceName()
430 serviceHandler = eServiceCenter.getInstance()
431 services = serviceHandler.list(provider.ref)
432 self.addBouquet(providerName, services and services.getContent('R', True))
434 def removeAlternativeServices(self):
435 cur_service = ServiceReference(self.getCurrentSelection())
436 root = self.getRoot()
437 cur_root = root and ServiceReference(root)
438 list = cur_service.list()
439 first_in_alternative = list and list.getNext()
440 if first_in_alternative:
441 edit_root = cur_root and cur_root.list().startEdit()
443 if not edit_root.addService(first_in_alternative, cur_service.ref):
444 self.servicelist.addService(first_in_alternative, True)
446 print "couldn't add first alternative service to current root"
448 print "couldn't edit current root!!"
450 print "remove empty alternative list !!"
452 self.servicelist.moveUp()
454 def removeBouquet(self):
455 refstr = self.getCurrentSelection().toString()
456 print "removeBouquet", refstr
457 self.bouquetNumOffsetCache = { }
458 pos = refstr.find('FROM BOUQUET "')
461 refstr = refstr[pos+14:]
462 pos = refstr.find('"')
464 filename = '/etc/enigma2/' + refstr[:pos] # FIXMEEE !!! HARDCODED /etc/enigma2
465 self.removeCurrentService()
467 if filename is not None:
470 print "error during remove of", filename
472 # multiple marked entry stuff ( edit mode, later multiepg selection )
473 def startMarkedEdit(self, type):
474 self.savedPath = self.servicePath[:]
475 if type == EDIT_ALTERNATIVES:
476 self.enterPath(self.getCurrentSelection())
477 self.mutableList = self.getMutableList()
478 # add all services from the current list to internal marked set in listboxservicecontent
479 self.clearMarks() # this clears the internal marked set in the listboxservicecontent
480 self.saved_title = self.instance.getTitle()
481 pos = self.saved_title.find(')')
482 new_title = self.saved_title[:pos+1]
483 if type == EDIT_ALTERNATIVES:
484 self.bouquet_mark_edit = EDIT_ALTERNATIVES
485 new_title += ' ' + _("[alternative edit]")
487 self.bouquet_mark_edit = EDIT_BOUQUET
488 if config.usage.multibouquet.value:
489 new_title += ' ' + _("[bouquet edit]")
491 new_title += ' ' + _("[favourite edit]")
492 self.setTitle(new_title)
493 self.__marked = self.servicelist.getRootServices()
494 for x in self.__marked:
495 self.servicelist.addMarked(eServiceReference(x))
496 self.showAllServices()
498 def endMarkedEdit(self, abort):
499 if not abort and self.mutableList is not None:
500 self.bouquetNumOffsetCache = { }
501 new_marked = set(self.servicelist.getMarked())
502 old_marked = set(self.__marked)
503 removed = old_marked - new_marked
504 added = new_marked - old_marked
508 self.mutableList.removeService(eServiceReference(x))
511 self.mutableList.addService(eServiceReference(x))
513 self.mutableList.flushChanges()
516 self.bouquet_mark_edit = OFF
517 self.mutableList = None
518 self.setTitle(self.saved_title)
519 self.saved_title = None
520 # self.servicePath is just a reference to servicePathTv or Radio...
521 # so we never ever do use the asignment operator in self.servicePath
522 del self.servicePath[:] # remove all elements
523 self.servicePath += self.savedPath # add saved elements
525 self.setRoot(self.servicePath[len(self.servicePath)-1])
527 def clearMarks(self):
528 self.servicelist.clearMarks()
531 ref = self.servicelist.getCurrent()
532 if self.servicelist.isMarked(ref):
533 self.servicelist.removeMarked(ref)
535 self.servicelist.addMarked(ref)
537 def removeCurrentService(self):
538 ref = self.servicelist.getCurrent()
539 mutableList = self.getMutableList()
540 if ref.valid() and mutableList is not None:
541 if not mutableList.removeService(ref):
542 self.bouquetNumOffsetCache = { }
543 mutableList.flushChanges() #FIXME dont flush on each single removed service
544 self.servicelist.removeCurrent()
546 def addServiceToBouquet(self, dest, service=None):
547 mutableList = self.getMutableList(dest)
548 if not mutableList is None:
549 if service is None: #use current selected service
550 service = self.servicelist.getCurrent()
551 if not mutableList.addService(service):
552 self.bouquetNumOffsetCache = { }
553 mutableList.flushChanges()
554 # do some voodoo to check if current_root is equal to dest
555 cur_root = self.getRoot();
556 str1 = cur_root and cur_root.toString() or -1
557 str2 = dest.toString()
558 pos1 = str1.find("FROM BOUQUET")
559 pos2 = str2.find("FROM BOUQUET")
560 if pos1 != -1 and pos2 != -1 and str1[pos1:] == str2[pos2:]:
561 self.servicelist.addService(service)
563 def toggleMoveMode(self):
565 if self.entry_marked:
566 self.toggleMoveMarked() # unmark current entry
567 self.movemode = False
568 self.pathChangeDisabled = False # re-enable path change
569 self.mutableList.flushChanges() # FIXME add check if changes was made
570 self.mutableList = None
571 self.setTitle(self.saved_title)
572 self.saved_title = None
573 cur_root = self.getRoot()
574 if cur_root and cur_root == self.bouquet_root:
575 self.bouquetNumOffsetCache = { }
577 self.mutableList = self.getMutableList()
579 self.pathChangeDisabled = True # no path change allowed in movemode
580 self.saved_title = self.instance.getTitle()
581 new_title = self.saved_title
582 pos = self.saved_title.find(')')
583 new_title = self.saved_title[:pos+1] + ' ' + _("[move mode]") + self.saved_title[pos+1:]
584 self.setTitle(new_title);
586 def handleEditCancel(self):
587 if self.movemode: #movemode active?
588 self.channelSelected() # unmark
589 self.toggleMoveMode() # disable move mode
590 elif self.bouquet_mark_edit != OFF:
591 self.endMarkedEdit(True) # abort edit mode
593 def toggleMoveMarked(self):
594 if self.entry_marked:
595 self.servicelist.setCurrentMarked(False)
596 self.entry_marked = False
598 self.servicelist.setCurrentMarked(True)
599 self.entry_marked = True
602 self.session.open(ChannelContextMenu, self)
607 # this makes it much simple to implement a selectable radio or tv mode :)
608 service_types_tv = '1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17) || (type == 195) || (type == 25)'
609 service_types_radio = '1:7:2:0:0:0:0:0:0:0:(type == 2)'
611 class ChannelSelectionBase(Screen):
612 def __init__(self, session):
613 Screen.__init__(self, session)
615 self["key_red"] = Button(_("All"))
616 self["key_green"] = Button(_("Satellites"))
617 self["key_yellow"] = Button(_("Provider"))
618 self["key_blue"] = Button(_("Favourites"))
620 self["list"] = ServiceList()
621 self.servicelist = self["list"]
623 self.numericalTextInput = NumericalTextInput()
624 self.numericalTextInput.setUseableChars(u'1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ')
626 self.servicePathTV = [ ]
627 self.servicePathRadio = [ ]
628 self.servicePath = [ ]
632 self.pathChangeDisabled = False
634 self.bouquetNumOffsetCache = { }
636 self["ChannelSelectBaseActions"] = NumberActionMap(["ChannelSelectBaseActions", "NumberActions"],
638 "showFavourites": self.showFavourites,
639 "showAllServices": self.showAllServices,
640 "showProviders": self.showProviders,
641 "showSatellites": self.showSatellites,
642 "nextBouquet": self.nextBouquet,
643 "prevBouquet": self.prevBouquet,
644 "nextMarker": self.nextMarker,
645 "prevMarker": self.prevMarker,
646 "1": self.keyNumberGlobal,
647 "2": self.keyNumberGlobal,
648 "3": self.keyNumberGlobal,
649 "4": self.keyNumberGlobal,
650 "5": self.keyNumberGlobal,
651 "6": self.keyNumberGlobal,
652 "7": self.keyNumberGlobal,
653 "8": self.keyNumberGlobal,
654 "9": self.keyNumberGlobal,
657 self.recallBouquetMode()
659 def getBouquetNumOffset(self, bouquet):
660 if not config.usage.multibouquet.value:
662 str = bouquet.toString()
664 if not self.bouquetNumOffsetCache.has_key(str):
665 serviceHandler = eServiceCenter.getInstance()
666 bouquetlist = serviceHandler.list(self.bouquet_root)
667 if not bouquetlist is None:
669 bouquetIterator = bouquetlist.getNext()
670 if not bouquetIterator.valid(): #end of list
672 self.bouquetNumOffsetCache[bouquetIterator.toString()]=offsetCount
673 if not (bouquetIterator.flags & eServiceReference.isDirectory):
675 servicelist = serviceHandler.list(bouquetIterator)
676 if not servicelist is None:
678 serviceIterator = servicelist.getNext()
679 if not serviceIterator.valid(): #check if end of list
681 playable = not (serviceIterator.flags & (eServiceReference.isDirectory|eServiceReference.isMarker))
684 return self.bouquetNumOffsetCache.get(str, offsetCount)
686 def recallBouquetMode(self):
687 if self.mode == MODE_TV:
688 self.service_types = service_types_tv
689 if config.usage.multibouquet.value:
690 self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "bouquets.tv" ORDER BY bouquet'
692 self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.tv" ORDER BY bouquet'%(self.service_types)
694 self.service_types = service_types_radio
695 if config.usage.multibouquet.value:
696 self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "bouquets.radio" ORDER BY bouquet'
698 self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.radio" ORDER BY bouquet'%(self.service_types)
699 self.bouquet_root = eServiceReference(self.bouquet_rootstr)
703 self.servicePath = self.servicePathTV
704 self.recallBouquetMode()
705 title = self.instance.getTitle()
706 pos = title.find(" (")
712 def setRadioMode(self):
713 self.mode = MODE_RADIO
714 self.servicePath = self.servicePathRadio
715 self.recallBouquetMode()
716 title = self.instance.getTitle()
717 pos = title.find(" (")
723 def setRoot(self, root, justSet=False):
724 path = root.getPath()
725 inBouquetRootList = path.find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
726 pos = path.find('FROM BOUQUET')
727 isBouquet = (pos != -1) and (root.flags & eServiceReference.isDirectory)
728 if not inBouquetRootList and isBouquet:
729 self.servicelist.setMode(ServiceList.MODE_FAVOURITES)
730 self.servicelist.setNumberOffset(self.getBouquetNumOffset(root))
732 self.servicelist.setMode(ServiceList.MODE_NORMAL)
733 self.servicelist.setRoot(root, justSet)
734 self.buildTitleString()
736 def removeModeStr(self, str):
737 if self.mode == MODE_TV:
738 pos = str.find(' (TV)')
740 pos = str.find(' (Radio)')
745 def getServiceName(self, ref):
746 str = self.removeModeStr(ServiceReference(ref).getServiceName())
748 pathstr = ref.getPath()
749 if pathstr.find('FROM PROVIDERS') != -1:
751 if pathstr.find('FROM SATELLITES') != -1:
752 return _("Satellites")
753 if pathstr.find(') ORDER BY name') != -1:
757 def buildTitleString(self):
758 titleStr = self.instance.getTitle()
759 pos = titleStr.find(']')
761 pos = titleStr.find(')')
763 titleStr = titleStr[:pos+1]
764 Len = len(self.servicePath)
766 base_ref = self.servicePath[0]
768 end_ref = self.servicePath[Len-1]
771 nameStr = self.getServiceName(base_ref)
772 titleStr += ' ' + nameStr
773 if end_ref is not None:
778 nameStr = self.getServiceName(end_ref)
780 self.setTitle(titleStr)
783 self.servicelist.moveUp()
786 self.servicelist.moveDown()
789 del self.servicePath[:]
791 def enterPath(self, ref, justSet=False):
792 self.servicePath.append(ref)
793 self.setRoot(ref, justSet)
795 def pathUp(self, justSet=False):
796 prev = self.servicePath.pop()
797 length = len(self.servicePath)
799 current = self.servicePath[length-1]
800 self.setRoot(current, justSet)
802 self.setCurrentSelection(prev)
805 def isBasePathEqual(self, ref):
806 if len(self.servicePath) > 1 and self.servicePath[0] == ref:
810 def isPrevPathEqual(self, ref):
811 length = len(self.servicePath)
812 if length > 1 and self.servicePath[length-2] == ref:
816 def preEnterPath(self, refstr):
819 def showAllServices(self):
820 if not self.pathChangeDisabled:
821 refstr = '%s ORDER BY name'%(self.service_types)
822 if not self.preEnterPath(refstr):
823 ref = eServiceReference(refstr)
824 currentRoot = self.getRoot()
825 if currentRoot is None or currentRoot != ref:
829 def showSatellites(self):
830 if not self.pathChangeDisabled:
831 refstr = '%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types)
832 if not self.preEnterPath(refstr):
833 ref = eServiceReference(refstr)
837 if self.isBasePathEqual(ref):
838 if self.isPrevPathEqual(ref):
840 prev = self.pathUp(justSet)
842 currentRoot = self.getRoot()
843 if currentRoot is None or currentRoot != ref:
846 self.enterPath(ref, True)
848 serviceHandler = eServiceCenter.getInstance()
849 servicelist = serviceHandler.list(ref)
850 if not servicelist is None:
852 service = servicelist.getNext()
853 if not service.valid(): #check if end of list
855 orbpos = service.getUnsignedData(4) >> 16
856 if service.getPath().find("FROM PROVIDER") != -1:
857 service_type = _("Providers")
858 elif service.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
859 service_type = _("New")
861 service_type = _("Services")
863 # why we need this cast?
864 service_name = str(nimmanager.getSatDescription(orbpos))
866 if orbpos == 0xFFFF: #Cable
867 service_name = _("Cable")
868 elif orbpos == 0xEEEE: #Terrestrial
869 service_name = _("Terrestrial")
871 if orbpos > 1800: # west
872 orbpos = 3600 - orbpos
876 service_name = ("%d.%d" + h) % (orbpos / 10, orbpos % 10)
877 service.setName("%s - %s" % (service_name, service_type))
878 self.servicelist.addService(service)
879 self.servicelist.finishFill()
881 self.setCurrentSelection(prev)
883 def showProviders(self):
884 if not self.pathChangeDisabled:
885 refstr = '%s FROM PROVIDERS ORDER BY name'%(self.service_types)
886 if not self.preEnterPath(refstr):
887 ref = eServiceReference(refstr)
888 if self.isBasePathEqual(ref):
891 currentRoot = self.getRoot()
892 if currentRoot is None or currentRoot != ref:
896 def changeBouquet(self, direction):
897 if not self.pathChangeDisabled:
898 if len(self.servicePath) > 1:
899 #when enter satellite root list we must do some magic stuff..
900 ref = eServiceReference('%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types))
901 if self.isBasePathEqual(ref):
902 self.showSatellites()
909 ref = self.getCurrentSelection()
913 if len(self.servicePath) > 0 and self.servicePath[0] == self.bouquet_root:
918 return self.servicelist.atBegin()
921 return self.servicelist.atEnd()
923 def nextBouquet(self):
924 self.changeBouquet(+1)
926 def prevBouquet(self):
927 self.changeBouquet(-1)
929 def showFavourites(self):
930 if not self.pathChangeDisabled:
931 if not self.preEnterPath(self.bouquet_rootstr):
932 if self.isBasePathEqual(self.bouquet_root):
935 currentRoot = self.getRoot()
936 if currentRoot is None or currentRoot != self.bouquet_root:
938 self.enterPath(self.bouquet_root)
940 def keyNumberGlobal(self, number):
941 unichar = self.numericalTextInput.getKey(number)
942 charstr = unichar.encode("utf-8")
943 if len(charstr) == 1:
944 self.servicelist.moveToChar(charstr[0])
947 return self.servicelist.getRoot()
949 def getCurrentSelection(self):
950 return self.servicelist.getCurrent()
952 def setCurrentSelection(self, service):
953 servicepath = service.getPath()
954 pos = servicepath.find(" FROM BOUQUET")
956 if self.mode == MODE_TV:
957 servicepath = '(type == 1)' + servicepath[pos:]
959 servicepath = '(type == 2)' + servicepath[pos:]
960 service.setPath(servicepath)
961 self.servicelist.setCurrent(service)
963 def getBouquetList(self):
965 serviceHandler = eServiceCenter.getInstance()
966 if config.usage.multibouquet.value:
967 list = serviceHandler.list(self.bouquet_root)
973 if s.flags & eServiceReference.isDirectory:
974 info = serviceHandler.info(s)
976 bouquets.append((info.getName(s), s))
979 info = serviceHandler.info(self.bouquet_root)
981 bouquets.append((info.getName(self.bouquet_root), self.bouquet_root))
985 def keyNumber0(self, num):
986 if len(self.servicePath) > 1:
989 self.keyNumberGlobal(num)
992 if len(self.servicePath) > 1:
993 if self.isBasePathEqual(self.bouquet_root):
994 self.showFavourites()
996 ref = eServiceReference('%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types))
997 if self.isBasePathEqual(ref):
998 self.showSatellites()
1000 ref = eServiceReference('%s FROM PROVIDERS ORDER BY name'%(self.service_types))
1001 if self.isBasePathEqual(ref):
1002 self.showProviders()
1004 self.showAllServices()
1006 def nextMarker(self):
1007 self.servicelist.moveToNextMarker()
1009 def prevMarker(self):
1010 self.servicelist.moveToPrevMarker()
1014 #config for lastservice
1015 config.tv = ConfigSubsection()
1016 config.tv.lastservice = ConfigText()
1017 config.tv.lastroot = ConfigText()
1018 config.radio = ConfigSubsection()
1019 config.radio.lastservice = ConfigText()
1020 config.radio.lastroot = ConfigText()
1021 config.servicelist = ConfigSubsection()
1022 config.servicelist.lastmode = ConfigText(default = "tv")
1024 class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG):
1025 def __init__(self, session):
1026 ChannelSelectionBase.__init__(self,session)
1027 ChannelSelectionEdit.__init__(self)
1028 ChannelSelectionEPG.__init__(self)
1030 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1032 "cancel": self.cancel,
1033 "ok": self.channelSelected,
1034 "keyRadio": self.setModeRadio,
1035 "keyTV": self.setModeTv,
1038 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
1040 iPlayableService.evStart: self.__evServiceStart,
1041 iPlayableService.evEnd: self.__evServiceEnd
1044 self.lastChannelRootTimer = eTimer()
1045 self.lastChannelRootTimer.timeout.get().append(self.__onCreate)
1046 self.lastChannelRootTimer.start(100,True)
1048 self.history_tv = [ ]
1049 self.history_radio = [ ]
1050 self.history = self.history_tv
1051 self.history_pos = 0
1053 self.lastservice = config.tv.lastservice
1054 self.lastroot = config.tv.lastroot
1055 self.revertMode = None
1056 config.usage.multibouquet.addNotifier(self.multibouquet_config_changed)
1058 def multibouquet_config_changed(self, val):
1059 self.recallBouquetMode()
1061 def __evServiceStart(self):
1062 service = self.session.nav.getCurrentService()
1064 info = service.info()
1066 refstr = info.getInfoString(iServiceInformation.sServiceref)
1067 self.servicelist.setPlayableIgnoreService(eServiceReference(refstr))
1069 def __evServiceEnd(self):
1070 self.servicelist.setPlayableIgnoreService(eServiceReference())
1074 lastservice=eServiceReference(self.lastservice.value)
1075 if lastservice.valid():
1076 self.setCurrentSelection(lastservice)
1078 def setModeTv(self):
1079 if self.revertMode is None and config.servicelist.lastmode.value == "radio":
1080 self.revertMode = MODE_RADIO
1081 self.history = self.history_tv
1082 self.lastservice = config.tv.lastservice
1083 self.lastroot = config.tv.lastroot
1084 config.servicelist.lastmode.value = "tv"
1088 def setModeRadio(self):
1089 if self.revertMode is None and config.servicelist.lastmode.value == "tv":
1090 self.revertMode = MODE_TV
1091 if config.usage.e1like_radio_mode.value:
1092 self.history = self.history_radio
1093 self.lastservice = config.radio.lastservice
1094 self.lastroot = config.radio.lastroot
1095 config.servicelist.lastmode.value = "radio"
1099 def __onCreate(self):
1100 if config.usage.e1like_radio_mode.value:
1101 if config.servicelist.lastmode.value == "tv":
1107 lastservice=eServiceReference(self.lastservice.value)
1108 if lastservice.valid():
1111 def channelSelected(self):
1112 ref = self.getCurrentSelection()
1114 self.toggleMoveMarked()
1115 elif (ref.flags & 7) == 7:
1117 elif self.bouquet_mark_edit != OFF:
1118 if not (self.bouquet_mark_edit == EDIT_ALTERNATIVES and ref.flags & eServiceReference.isGroup):
1120 elif not (ref.flags & eServiceReference.isMarker): # no marker
1121 root = self.getRoot()
1122 if not root or not (root.flags & eServiceReference.isGroup):
1126 #called from infoBar and channelSelected
1128 self.revertMode=None
1129 ref = self.session.nav.getCurrentlyPlayingServiceReference()
1130 nref = self.getCurrentSelection()
1131 if ref is None or ref != nref:
1132 self.session.nav.playService(nref)
1134 self.saveChannel(nref)
1135 config.servicelist.lastmode.save()
1136 self.addToHistory(nref)
1138 def addToHistory(self, ref):
1139 if self.servicePath is not None:
1140 tmp=self.servicePath[:]
1143 del self.history[self.history_pos+1:]
1146 self.history.append(tmp)
1147 hlen = len(self.history)
1148 if hlen > HISTORYSIZE:
1151 self.history_pos = hlen-1
1153 def historyBack(self):
1154 hlen = len(self.history)
1155 if hlen > 1 and self.history_pos > 0:
1156 self.history_pos -= 1
1157 self.setHistoryPath()
1159 def historyNext(self):
1160 hlen = len(self.history)
1161 if hlen > 1 and self.history_pos < (hlen-1):
1162 self.history_pos += 1
1163 self.setHistoryPath()
1165 def setHistoryPath(self):
1166 path = self.history[self.history_pos][:]
1168 del self.servicePath[:]
1169 self.servicePath += path
1173 cur_root = self.getRoot()
1174 if cur_root and cur_root != root:
1176 self.session.nav.playService(ref)
1177 self.setCurrentSelection(ref)
1178 self.saveChannel(ref)
1182 for i in self.servicePath:
1183 path += i.toString()
1185 if len(path) and path != self.lastroot.value:
1186 self.lastroot.value = path
1187 self.lastroot.save()
1189 def restoreRoot(self):
1191 re = compile('.+?;')
1192 tmp = re.findall(self.lastroot.value)
1195 self.servicePath.append(eServiceReference(i[:len(i)-1]))
1198 path = self.servicePath.pop()
1199 self.enterPath(path)
1201 self.showFavourites()
1204 def preEnterPath(self, refstr):
1205 if len(self.servicePath) and self.servicePath[0] != eServiceReference(refstr):
1206 pathstr = self.lastroot.value
1207 if pathstr is not None and pathstr.find(refstr) == 0:
1209 lastservice=eServiceReference(self.lastservice.value)
1210 if lastservice.valid():
1211 self.setCurrentSelection(lastservice)
1215 def saveChannel(self, ref):
1217 refstr = ref.toString()
1220 if refstr != self.lastservice.value:
1221 self.lastservice.value = refstr
1222 self.lastservice.save()
1224 def setCurrentServicePath(self, path):
1225 hlen = len(self.history)
1227 self.history[self.history_pos] = path
1229 self.history.append(path)
1230 self.setHistoryPath()
1232 def getCurrentServicePath(self):
1233 hlen = len(self.history)
1235 return self.history[self.history_pos]
1238 def recallPrevService(self):
1239 hlen = len(self.history)
1241 if self.history_pos == hlen-1:
1242 tmp = self.history[self.history_pos]
1243 self.history[self.history_pos] = self.history[self.history_pos-1]
1244 self.history[self.history_pos-1] = tmp
1246 tmp = self.history[self.history_pos+1]
1247 self.history[self.history_pos+1] = self.history[self.history_pos]
1248 self.history[self.history_pos] = tmp
1249 self.setHistoryPath()
1252 if self.revertMode is None:
1254 lastservice=eServiceReference(self.lastservice.value)
1255 if lastservice.valid() and self.getCurrentSelection() != lastservice:
1256 self.setCurrentSelection(lastservice)
1257 elif self.revertMode == MODE_TV:
1259 elif self.revertMode == MODE_RADIO:
1261 self.revertMode = None
1264 from Screens.InfoBarGenerics import InfoBarEvent, InfoBarServiceName
1266 class RadioInfoBar(Screen, InfoBarEvent, InfoBarServiceName):
1267 def __init__(self, session):
1268 Screen.__init__(self, session)
1269 InfoBarEvent.__init__(self)
1270 InfoBarServiceName.__init__(self)
1271 self["CurrentTime"] = Clock()
1272 self["RdsDecoder"] = RdsDecoder(self.session.nav)
1273 self["BlinkingPoint"] = Pixmap()
1274 self["BlinkingPoint"].hide()
1276 class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG):
1277 ALLOW_SUSPEND = True
1279 def __init__(self, session, infobar):
1280 ChannelSelectionBase.__init__(self, session)
1281 ChannelSelectionEdit.__init__(self)
1282 ChannelSelectionEPG.__init__(self)
1283 self.infobar = infobar
1284 config.radio = ConfigSubsection();
1285 config.radio.lastservice = ConfigText()
1286 config.radio.lastroot = ConfigText()
1287 self.onLayoutFinish.append(self.onCreate)
1289 self.info = session.instantiateDialog(RadioInfoBar) # our simple infobar
1291 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1293 "keyTV": self.closeRadio,
1294 "keyRadio": self.closeRadio,
1295 "cancel": self.closeRadio,
1296 "ok": self.channelSelected,
1299 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
1301 iPlayableService.evStart: self.__evServiceStart,
1302 iPlayableService.evEnd: self.__evServiceEnd
1305 ########## RDS Radiotext / Rass Support BEGIN
1306 self.infobar = infobar # reference to real infobar (the one and only)
1307 self["RdsDecoder"] = self.info["RdsDecoder"]
1308 self["RdsActions"] = HelpableActionMap(self, "InfobarRdsActions",
1310 "startRassInteractive": (self.startRassInteractive, _("View Rass interactive..."))
1312 self["RdsActions"].setEnabled(False)
1313 infobar.rds_display.onRassInteractivePossibilityChanged.append(self.RassInteractivePossibilityChanged)
1315 def startRassInteractive(self):
1317 self.infobar.rass_interactive = self.session.openWithCallback(self.RassInteractiveClosed, RassInteractive)
1319 def RassInteractiveClosed(self):
1321 self.infobar.rass_interactive = None
1322 self.infobar.RassSlidePicChanged()
1324 def RassInteractivePossibilityChanged(self, state):
1325 self["RdsActions"].setEnabled(state)
1326 ########## RDS Radiotext / Rass Support END
1328 def closeRadio(self):
1329 self.infobar.rds_display.onRassInteractivePossibilityChanged.remove(self.RassInteractivePossibilityChanged)
1331 #set previous tv service
1332 lastservice=eServiceReference(config.tv.lastservice.value)
1333 self.session.nav.playService(lastservice)
1336 def __evServiceStart(self):
1337 service = self.session.nav.getCurrentService()
1339 info = service.info()
1341 refstr = info.getInfoString(iServiceInformation.sServiceref)
1342 self.servicelist.setPlayableIgnoreService(eServiceReference(refstr))
1344 def __evServiceEnd(self):
1345 self.servicelist.setPlayableIgnoreService(eServiceReference())
1349 for i in self.servicePathRadio:
1350 path += i.toString()
1352 if len(path) and path != config.radio.lastroot.value:
1353 config.radio.lastroot.value = path
1354 config.radio.lastroot.save()
1356 def restoreRoot(self):
1358 re = compile('.+?;')
1359 tmp = re.findall(config.radio.lastroot.value)
1362 self.servicePathRadio.append(eServiceReference(i[:len(i)-1]))
1365 path = self.servicePathRadio.pop()
1366 self.enterPath(path)
1368 self.showFavourites()
1371 def preEnterPath(self, refstr):
1372 if len(self.servicePathRadio) and self.servicePathRadio[0] != eServiceReference(refstr):
1373 pathstr = config.radio.lastroot.value
1374 if pathstr is not None and pathstr.find(refstr) == 0:
1376 lastservice=eServiceReference(config.radio.lastservice.value)
1377 if lastservice.valid():
1378 self.setCurrentSelection(lastservice)
1385 lastservice=eServiceReference(config.radio.lastservice.value)
1386 if lastservice.valid():
1387 self.servicelist.setCurrent(lastservice)
1388 self.session.nav.playService(lastservice)
1391 def channelSelected(self): # just return selected service
1392 ref = self.getCurrentSelection()
1394 self.toggleMoveMarked()
1395 elif (ref.flags & 7) == 7:
1397 elif self.bouquet_mark_edit != OFF:
1398 if not (self.bouquet_mark_edit == EDIT_ALTERNATIVES and ref.flags & eServiceReference.isGroup):
1400 elif not (ref.flags & eServiceReference.isMarker): # no marker
1401 cur_root = self.getRoot()
1402 if not cur_root or not (cur_root.flags & eServiceReference.isGroup):
1403 playingref = self.session.nav.getCurrentlyPlayingServiceReference()
1404 if playingref is None or playingref != ref:
1405 self.session.nav.playService(ref)
1406 config.radio.lastservice.value = ref.toString()
1407 config.radio.lastservice.save()
1410 class SimpleChannelSelection(ChannelSelectionBase):
1411 def __init__(self, session, title):
1412 ChannelSelectionBase.__init__(self, session)
1414 self.onShown.append(self.__onExecCallback)
1416 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1418 "cancel": self.close,
1419 "ok": self.channelSelected,
1420 "keyRadio": self.setModeRadio,
1421 "keyTV": self.setModeTv,
1424 def __onExecCallback(self):
1425 self.setTitle(self.title)
1428 def channelSelected(self): # just return selected service
1429 ref = self.getCurrentSelection()
1430 if (ref.flags & 7) == 7:
1432 elif not (ref.flags & eServiceReference.isMarker):
1433 ref = self.getCurrentSelection()
1436 def setModeTv(self):
1438 self.showFavourites()
1440 def setModeRadio(self):
1442 self.showFavourites()