1 from Screen import Screen
2 from Components.Button import Button
3 from Components.ServiceList import ServiceList
4 from Components.ActionMap import NumberActionMap, ActionMap
5 from Components.MenuList import MenuList
6 from Components.ServiceEventTracker import ServiceEventTracker
7 from EpgSelection import EPGSelection
8 from enigma import eServiceReference, eEPGCache, eServiceCenter, eTimer, eDVBDB, iPlayableService, iServiceInformation
9 from Components.config import config, ConfigSubsection, ConfigText
10 from Screens.FixedMenu import FixedMenu
11 from Tools.NumericalTextInput import NumericalTextInput
12 from Components.NimManager import nimmanager
13 from Components.Sources.Clock import Clock
14 from Components.Input import Input
15 from Components.ParentalControl import parentalControl
16 from Screens.InputBox import InputBox, PinInput
17 from Screens.MessageBox import MessageBox
18 from Screens.ServiceInfo import ServiceInfo
19 from ServiceReference import ServiceReference
20 from Tools.BoundFunction import boundFunction
24 FLAG_SERVICE_NEW_FOUND = 64 #define in lib/dvb/idvb.h as dxNewFound = 64
26 import xml.dom.minidom
28 class BouquetSelector(Screen):
29 def __init__(self, session, bouquets, selectedFunc, enableWrapAround=False):
30 Screen.__init__(self, session)
32 self.selectedFunc=selectedFunc
34 self["actions"] = ActionMap(["OkCancelActions"],
36 "ok": self.okbuttonClick,
37 "cancel": self.cancelClick
41 entrys.append((x[0], x[1]))
42 self["menu"] = MenuList(entrys, enableWrapAround)
45 cur = self["menu"].getCurrent()
48 def okbuttonClick(self):
49 self.selectedFunc(self.getCurrent())
57 def cancelClick(self):
60 # csel.bouquet_mark_edit values
65 class ChannelContextMenu(Screen):
66 def __init__(self, session, csel):
67 Screen.__init__(self, session)
71 self["actions"] = ActionMap(["OkCancelActions"],
73 "ok": self.okbuttonClick,
74 "cancel": self.cancelClick
78 current_root = csel.getRoot()
79 current_sel_path = csel.getCurrentSelection().getPath()
80 current_sel_flags = csel.getCurrentSelection().flags
81 inBouquetRootList = current_root and current_root.getPath().find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
82 inBouquet = csel.getMutableList() is not None
83 haveBouquets = config.usage.multibouquet.value
85 if not (len(current_sel_path) or current_sel_flags & eServiceReference.isDirectory):
86 menu.append((_("show transponder info"), self.showServiceInformations))
87 if csel.bouquet_mark_edit == OFF and not csel.movemode:
88 if not inBouquetRootList:
89 isPlayable = not (current_sel_flags & (eServiceReference.isMarker|eServiceReference.isDirectory))
91 if config.ParentalControl.configured.value:
92 if parentalControl.getProtectionLevel(csel.getCurrentSelection().toCompareString()) == -1:
93 menu.append((_("add to parental protection"), boundFunction(self.addParentalProtection, csel.getCurrentSelection())))
95 menu.append((_("remove from parental protection"), boundFunction(self.removeParentalProtection, csel.getCurrentSelection())))
97 menu.append((_("add service to bouquet"), self.addServiceToBouquetSelected))
99 menu.append((_("add service to favourites"), self.addServiceToBouquetSelected))
102 if not inBouquet and current_sel_path.find("PROVIDERS") == -1:
103 menu.append((_("copy to bouquets"), self.copyCurrentToBouquetList))
104 if current_sel_path.find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
105 menu.append((_("remove all new found flags"), self.removeAllNewFoundFlags))
107 menu.append((_("remove entry"), self.removeCurrentService))
108 if current_root is not None and current_root.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
109 menu.append((_("remove new found flag"), self.removeNewFoundFlag))
111 menu.append((_("add bouquet"), self.showBouquetInputBox))
112 menu.append((_("remove entry"), self.removeBouquet))
114 if inBouquet: # current list is editable?
115 if csel.bouquet_mark_edit == OFF:
116 if not csel.movemode:
117 menu.append((_("enable move mode"), self.toggleMoveMode))
118 if not inBouquetRootList and not current_root.flags & eServiceReference.isGroup:
119 menu.append((_("add marker"), self.showMarkerInputBox))
121 menu.append((_("enable bouquet edit"), self.bouquetMarkStart))
123 menu.append((_("enable favourite edit"), self.bouquetMarkStart))
124 if current_sel_flags & eServiceReference.isGroup:
125 menu.append((_("edit alternatives"), self.editAlternativeServices))
126 menu.append((_("show alternatives"), self.showAlternativeServices))
127 menu.append((_("remove all alternatives"), self.removeAlternativeServices))
129 menu.append((_("add alternatives"), self.addAlternativeServices))
131 menu.append((_("disable move mode"), self.toggleMoveMode))
133 if csel.bouquet_mark_edit == EDIT_BOUQUET:
135 menu.append((_("end bouquet edit"), self.bouquetMarkEnd))
136 menu.append((_("abort bouquet edit"), self.bouquetMarkAbort))
138 menu.append((_("end favourites edit"), self.bouquetMarkEnd))
139 menu.append((_("abort favourites edit"), self.bouquetMarkAbort))
141 menu.append((_("end alternatives edit"), self.bouquetMarkEnd))
142 menu.append((_("abort alternatives edit"), self.bouquetMarkAbort))
144 menu.append((_("back"), self.cancelClick))
145 self["menu"] = MenuList(menu)
147 def okbuttonClick(self):
148 self["menu"].getCurrent()[1]()
150 def cancelClick(self):
153 def showServiceInformations(self):
154 self.session.open( ServiceInfo, self.csel.getCurrentSelection() )
156 def showBouquetInputBox(self):
157 self.session.openWithCallback(self.bouquetInputCallback, InputBox, title=_("Please enter a name for the new bouquet"), text="bouquetname", maxSize=False, type=Input.TEXT)
159 def bouquetInputCallback(self, bouquet):
160 if bouquet is not None:
161 self.csel.addBouquet(bouquet, None)
164 def addParentalProtection(self, service):
165 parentalControl.protectService(service.toCompareString())
168 def removeParentalProtection(self, service):
169 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"))
171 def pinEntered(self, service, result):
173 parentalControl.unProtectService(service)
176 self.session.openWithCallback(self.close, MessageBox, _("The pin code you entered is wrong."), MessageBox.TYPE_ERROR)
178 def addServiceToBouquetSelected(self):
179 bouquets = self.csel.getBouquetList()
184 if cnt > 1: # show bouquet list
185 self.bsel = self.session.openWithCallback(self.bouquetSelClosed, BouquetSelector, bouquets, self.addCurrentServiceToBouquet)
186 elif cnt == 1: # add to only one existing bouquet
187 self.addCurrentServiceToBouquet(bouquets[0][1])
189 def bouquetSelClosed(self, recursive):
194 def copyCurrentToBouquetList(self):
195 self.csel.copyCurrentToBouquetList()
198 def removeBouquet(self):
199 self.csel.removeBouquet()
202 def showMarkerInputBox(self):
203 self.session.openWithCallback(self.markerInputCallback, InputBox, title=_("Please enter a name for the new marker"), text="markername", maxSize=False, type=Input.TEXT)
205 def markerInputCallback(self, marker):
206 if marker is not None:
207 self.csel.addMarker(marker)
210 def addCurrentServiceToBouquet(self, dest):
211 self.csel.addServiceToBouquet(dest)
212 if self.bsel is not None:
213 self.bsel.close(True)
215 self.close(True) # close bouquet selection
217 def removeCurrentService(self):
218 self.csel.removeCurrentService()
221 def toggleMoveMode(self):
222 self.csel.toggleMoveMode()
225 def bouquetMarkStart(self):
226 self.csel.startMarkedEdit(EDIT_BOUQUET)
229 def bouquetMarkEnd(self):
230 self.csel.endMarkedEdit(abort=False)
233 def bouquetMarkAbort(self):
234 self.csel.endMarkedEdit(abort=True)
237 def removeNewFoundFlag(self):
238 eDVBDB.getInstance().removeFlag(self.csel.getCurrentSelection(), FLAG_SERVICE_NEW_FOUND)
241 def removeAllNewFoundFlags(self):
242 curpath = self.csel.getCurrentSelection().getPath()
243 idx = curpath.find("satellitePosition == ")
245 tmp = curpath[idx+21:]
248 satpos = int(tmp[:idx])
249 eDVBDB.getInstance().removeFlags(FLAG_SERVICE_NEW_FOUND, -1, -1, -1, satpos)
252 def editAlternativeServices(self):
253 self.csel.startMarkedEdit(EDIT_ALTERNATIVES)
256 def showAlternativeServices(self):
257 self.csel.enterPath(self.csel.getCurrentSelection())
260 def removeAlternativeServices(self):
261 self.csel.removeAlternativeServices()
264 def addAlternativeServices(self):
265 self.csel.addAlternativeServices()
266 self.csel.startMarkedEdit(EDIT_ALTERNATIVES)
269 class ChannelSelectionEPG:
271 self["ChannelSelectEPGActions"] = ActionMap(["ChannelSelectEPGActions"],
273 "showEPGList": self.showEPGList,
276 def showEPGList(self):
277 ref=self.getCurrentSelection()
278 ptr=eEPGCache.getInstance()
279 if ptr.startTimeQuery(ref) != -1:
280 self.session.open(EPGSelection, ref)
282 print 'no epg for service', ref.toString()
284 class ChannelSelectionEdit:
286 self.entry_marked = False
287 self.movemode = False
288 self.bouquet_mark_edit = OFF
289 self.mutableList = None
291 self.saved_title = None
292 self.saved_root = None
294 class ChannelSelectionEditActionMap(ActionMap):
295 def __init__(self, csel, contexts = [ ], actions = { }, prio=0):
296 ActionMap.__init__(self, contexts, actions, prio)
299 def action(self, contexts, action):
300 if action == "cancel":
301 self.csel.handleEditCancel()
302 return 0 # fall-trough
304 return 0 # fall-trough
306 return ActionMap.action(self, contexts, action)
308 self["ChannelSelectEditActions"] = ChannelSelectionEditActionMap(self, ["ChannelSelectEditActions", "OkCancelActions"],
310 "contextMenu": self.doContext,
313 def getMutableList(self, root=eServiceReference()):
314 if not self.mutableList is None:
315 return self.mutableList
316 serviceHandler = eServiceCenter.getInstance()
319 list = root and serviceHandler.list(root)
321 return list.startEdit()
324 def buildBouquetID(self, str):
328 if (c >= 'a' and c <= 'z') or (c >= '0' and c <= '9'):
334 def addMarker(self, name):
335 current = self.servicelist.getCurrent()
336 mutableList = self.getMutableList()
339 str = '1:64:%d:0:0:0:0:0:0:0::%s'%(cnt, name)
340 ref = eServiceReference(str)
341 if current and current.valid():
342 if not mutableList.addService(ref, current):
343 self.servicelist.addService(ref, True)
344 mutableList.flushChanges()
346 elif not mutableList.addService(ref):
347 self.servicelist.addService(ref, True)
348 mutableList.flushChanges()
352 def addAlternativeServices(self):
353 cur_service = ServiceReference(self.getCurrentSelection())
354 cur_root = ServiceReference(self.getRoot())
355 mutableBouquet = cur_root.list().startEdit()
357 name = cur_service.getServiceName()
359 if self.mode == MODE_TV:
360 str = '1:134:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET \"alternatives.%s.tv\" ORDER BY bouquet'%(self.buildBouquetID(name))
362 str = '1:134:2:0:0:0:0:0:0:0:(type == 2) FROM BOUQUET \"alternatives.%s.radio\" ORDER BY bouquet'%(self.buildBouquetID(name))
363 new_ref = ServiceReference(str)
364 if not mutableBouquet.addService(new_ref.ref, cur_service.ref):
365 mutableBouquet.removeService(cur_service.ref)
366 mutableBouquet.flushChanges()
367 eDVBDB.getInstance().reloadBouquets()
368 mutableAlternatives = new_ref.list().startEdit()
369 if mutableAlternatives:
370 mutableAlternatives.setListName(name)
371 if mutableAlternatives.addService(cur_service.ref):
372 print "add", cur_service.toString(), "to new alternatives failed"
373 mutableAlternatives.flushChanges()
374 self.servicelist.addService(new_ref.ref, True)
375 self.servicelist.removeCurrent()
376 self.servicelist.moveUp()
378 print "get mutable list for new created alternatives failed"
380 print "add", str, "to", cur_root.getServiceName(), "failed"
382 print "bouquetlist is not editable"
384 def addBouquet(self, bName, services):
385 serviceHandler = eServiceCenter.getInstance()
386 mutableBouquetList = serviceHandler.list(self.bouquet_root).startEdit()
387 if mutableBouquetList:
388 if self.mode == MODE_TV:
390 str = '1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET \"userbouquet.%s.tv\" ORDER BY bouquet'%(self.buildBouquetID(bName))
393 str = '1:7:2:0:0:0:0:0:0:0:(type == 2) FROM BOUQUET \"userbouquet.%s.radio\" ORDER BY bouquet'%(self.buildBouquetID(bName))
394 new_bouquet_ref = eServiceReference(str)
395 if not mutableBouquetList.addService(new_bouquet_ref):
396 mutableBouquetList.flushChanges()
397 eDVBDB.getInstance().reloadBouquets()
398 mutableBouquet = serviceHandler.list(new_bouquet_ref).startEdit()
400 mutableBouquet.setListName(bName)
401 if services is not None:
402 for service in services:
403 if mutableBouquet.addService(service):
404 print "add", service.toString(), "to new bouquet failed"
405 mutableBouquet.flushChanges()
407 print "get mutable list for new created bouquet failed"
408 # do some voodoo to check if current_root is equal to bouquet_root
409 cur_root = self.getRoot();
410 str1 = cur_root.toString()
411 pos1 = str1.find("FROM BOUQUET")
412 pos2 = self.bouquet_rootstr.find("FROM BOUQUET")
413 if pos1 != -1 and pos2 != -1 and str1[pos1:] == self.bouquet_rootstr[pos2:]:
414 self.servicelist.addService(new_bouquet_ref)
416 print "add", str, "to bouquets failed"
418 print "bouquetlist is not editable"
420 def copyCurrentToBouquetList(self):
421 provider = ServiceReference(self.getCurrentSelection())
422 providerName = provider.getServiceName()
423 serviceHandler = eServiceCenter.getInstance()
424 services = serviceHandler.list(provider.ref)
425 self.addBouquet(providerName, services and services.getContent('R', True))
427 def removeAlternativeServices(self):
428 cur_service = ServiceReference(self.getCurrentSelection())
429 cur_root = ServiceReference(self.getRoot())
430 list = cur_service.list()
431 first_in_alternative = list and list.getNext()
432 if first_in_alternative:
433 edit_root = cur_root.list().startEdit()
435 if not edit_root.addService(first_in_alternative, cur_service.ref):
436 self.servicelist.addService(first_in_alternative, True)
438 print "couldn't add first alternative service to current root"
440 print "couldn't edit current root!!"
442 print "remove empty alternative list !!"
444 self.servicelist.moveUp()
446 def removeBouquet(self):
447 refstr = self.getCurrentSelection().toString()
448 print "removeBouquet", refstr
449 self.bouquetNumOffsetCache = { }
450 pos = refstr.find('FROM BOUQUET "')
453 refstr = refstr[pos+14:]
454 pos = refstr.find('"')
456 filename = '/etc/enigma2/' + refstr[:pos] # FIXMEEE !!! HARDCODED /etc/enigma2
457 self.removeCurrentService()
459 if filename is not None:
462 print "error during remove of", filename
464 # multiple marked entry stuff ( edit mode, later multiepg selection )
465 def startMarkedEdit(self, type):
466 self.savedPath = self.servicePath[:]
467 if type == EDIT_ALTERNATIVES:
468 self.enterPath(self.getCurrentSelection())
469 self.mutableList = self.getMutableList()
470 # add all services from the current list to internal marked set in listboxservicecontent
471 self.clearMarks() # this clears the internal marked set in the listboxservicecontent
472 self.saved_title = self.instance.getTitle()
473 pos = self.saved_title.find(')')
474 new_title = self.saved_title[:pos+1]
475 if type == EDIT_ALTERNATIVES:
476 self.bouquet_mark_edit = EDIT_ALTERNATIVES
477 new_title += ' ' + _("[alternative edit]")
479 self.bouquet_mark_edit = EDIT_BOUQUET
480 if config.usage.multibouquet.value:
481 new_title += ' ' + _("[bouquet edit]")
483 new_title += ' ' + _("[favourite edit]")
484 self.setTitle(new_title)
485 self.__marked = self.servicelist.getRootServices()
486 for x in self.__marked:
487 self.servicelist.addMarked(eServiceReference(x))
488 self.showAllServices()
490 def endMarkedEdit(self, abort):
491 if not abort and self.mutableList is not None:
492 self.bouquetNumOffsetCache = { }
493 new_marked = set(self.servicelist.getMarked())
494 old_marked = set(self.__marked)
495 removed = old_marked - new_marked
496 added = new_marked - old_marked
500 self.mutableList.removeService(eServiceReference(x))
503 self.mutableList.addService(eServiceReference(x))
505 self.mutableList.flushChanges()
508 self.bouquet_mark_edit = OFF
509 self.mutableList = None
510 self.setTitle(self.saved_title)
511 self.saved_title = None
512 # self.servicePath is just a reference to servicePathTv or Radio...
513 # so we never ever do use the asignment operator in self.servicePath
514 del self.servicePath[:] # remove all elements
515 self.servicePath += self.savedPath # add saved elements
517 self.setRoot(self.servicePath[len(self.servicePath)-1])
519 def clearMarks(self):
520 self.servicelist.clearMarks()
523 ref = self.servicelist.getCurrent()
524 if self.servicelist.isMarked(ref):
525 self.servicelist.removeMarked(ref)
527 self.servicelist.addMarked(ref)
529 def removeCurrentService(self):
530 ref = self.servicelist.getCurrent()
531 mutableList = self.getMutableList()
532 if ref.valid() and mutableList is not None:
533 if not mutableList.removeService(ref):
534 self.bouquetNumOffsetCache = { }
535 mutableList.flushChanges() #FIXME dont flush on each single removed service
536 self.servicelist.removeCurrent()
538 def addServiceToBouquet(self, dest, service=None):
539 mutableList = self.getMutableList(dest)
540 if not mutableList is None:
541 if service is None: #use current selected service
542 service = self.servicelist.getCurrent()
543 if not mutableList.addService(service):
544 self.bouquetNumOffsetCache = { }
545 mutableList.flushChanges()
546 # do some voodoo to check if current_root is equal to dest
547 cur_root = self.getRoot();
548 str1 = cur_root.toString()
549 str2 = dest.toString()
550 pos1 = str1.find("FROM BOUQUET")
551 pos2 = str2.find("FROM BOUQUET")
552 if pos1 != -1 and pos2 != -1 and str1[pos1:] == str2[pos2:]:
553 self.servicelist.addService(service)
555 def toggleMoveMode(self):
557 if self.entry_marked:
558 self.toggleMoveMarked() # unmark current entry
559 self.movemode = False
560 self.pathChangeDisabled = False # re-enable path change
561 self.mutableList.flushChanges() # FIXME add check if changes was made
562 self.mutableList = None
563 self.setTitle(self.saved_title)
564 self.saved_title = None
565 if self.getRoot() == self.bouquet_root:
566 self.bouquetNumOffsetCache = { }
568 self.mutableList = self.getMutableList()
570 self.pathChangeDisabled = True # no path change allowed in movemode
571 self.saved_title = self.instance.getTitle()
572 new_title = self.saved_title
573 pos = self.saved_title.find(')')
574 new_title = self.saved_title[:pos+1] + ' ' + _("[move mode]") + self.saved_title[pos+1:]
575 self.setTitle(new_title);
577 def handleEditCancel(self):
578 if self.movemode: #movemode active?
579 self.channelSelected() # unmark
580 self.toggleMoveMode() # disable move mode
581 elif self.bouquet_mark_edit != OFF:
582 self.endMarkedEdit(True) # abort edit mode
584 def toggleMoveMarked(self):
585 if self.entry_marked:
586 self.servicelist.setCurrentMarked(False)
587 self.entry_marked = False
589 self.servicelist.setCurrentMarked(True)
590 self.entry_marked = True
593 self.session.open(ChannelContextMenu, self)
598 # this makes it much simple to implement a selectable radio or tv mode :)
599 service_types_tv = '1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17) || (type == 195) || (type == 25)'
600 service_types_radio = '1:7:2:0:0:0:0:0:0:0:(type == 2)'
602 class ChannelSelectionBase(Screen):
603 def __init__(self, session):
604 Screen.__init__(self, session)
606 self["key_red"] = Button(_("All"))
607 self["key_green"] = Button(_("Satellites"))
608 self["key_yellow"] = Button(_("Provider"))
609 self["key_blue"] = Button(_("Favourites"))
611 self["list"] = ServiceList()
612 self.servicelist = self["list"]
614 self.numericalTextInput = NumericalTextInput()
615 self.numericalTextInput.setUseableChars(u'1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ')
617 self.servicePathTV = [ ]
618 self.servicePathRadio = [ ]
619 self.servicePath = [ ]
623 self.pathChangeDisabled = False
625 self.bouquetNumOffsetCache = { }
627 self["ChannelSelectBaseActions"] = NumberActionMap(["ChannelSelectBaseActions", "NumberActions"],
629 "showFavourites": self.showFavourites,
630 "showAllServices": self.showAllServices,
631 "showProviders": self.showProviders,
632 "showSatellites": self.showSatellites,
633 "nextBouquet": self.nextBouquet,
634 "prevBouquet": self.prevBouquet,
635 "nextMarker": self.nextMarker,
636 "prevMarker": self.prevMarker,
637 "1": self.keyNumberGlobal,
638 "2": self.keyNumberGlobal,
639 "3": self.keyNumberGlobal,
640 "4": self.keyNumberGlobal,
641 "5": self.keyNumberGlobal,
642 "6": self.keyNumberGlobal,
643 "7": self.keyNumberGlobal,
644 "8": self.keyNumberGlobal,
645 "9": self.keyNumberGlobal,
648 self.recallBouquetMode()
650 def appendDVBTypes(self, ref):
652 pos = path.find(' FROM BOUQUET')
654 return eServiceReference(self.service_types + path[pos:])
657 def getBouquetNumOffset(self, bouquet):
658 if not config.usage.multibouquet.value:
660 bouquet = self.appendDVBTypes(bouquet)
661 str = bouquet.toString()
663 if not self.bouquetNumOffsetCache.has_key(str):
664 serviceHandler = eServiceCenter.getInstance()
665 bouquetlist = serviceHandler.list(self.bouquet_root)
666 if not bouquetlist is None:
668 bouquetIterator = self.appendDVBTypes(bouquetlist.getNext())
669 if not bouquetIterator.valid(): #end of list
671 self.bouquetNumOffsetCache[bouquetIterator.toString()]=offsetCount
672 if not (bouquetIterator.flags & eServiceReference.isDirectory):
674 servicelist = serviceHandler.list(bouquetIterator)
675 if not servicelist is None:
677 serviceIterator = servicelist.getNext()
678 if not serviceIterator.valid(): #check if end of list
680 playable = not (serviceIterator.flags & (eServiceReference.isDirectory|eServiceReference.isMarker))
683 return self.bouquetNumOffsetCache.get(str, offsetCount)
685 def recallBouquetMode(self):
686 if self.mode == MODE_TV:
687 self.service_types = service_types_tv
688 if config.usage.multibouquet.value:
689 self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET "bouquets.tv" ORDER BY bouquet'
691 self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.tv" ORDER BY bouquet'%(self.service_types)
693 self.service_types = service_types_radio
694 if config.usage.multibouquet.value:
695 self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET "bouquets.radio" ORDER BY bouquet'
697 self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.radio" ORDER BY bouquet'%(self.service_types)
698 self.bouquet_root = eServiceReference(self.bouquet_rootstr)
702 self.servicePath = self.servicePathTV
703 self.recallBouquetMode()
704 title = self.instance.getTitle()
705 pos = title.find(" (")
711 def setRadioMode(self):
712 self.mode = MODE_RADIO
713 self.servicePath = self.servicePathRadio
714 self.recallBouquetMode()
715 title = self.instance.getTitle()
716 pos = title.find(" (")
722 def setRoot(self, root, justSet=False):
723 path = root.getPath()
724 inBouquetRootList = path.find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
725 pos = path.find(' FROM BOUQUET')
726 isBouquet = (pos != -1) and (root.flags & eServiceReference.isDirectory)
727 if not inBouquetRootList and isBouquet:
728 self.servicelist.setMode(ServiceList.MODE_FAVOURITES)
729 self.servicelist.setNumberOffset(self.getBouquetNumOffset(root))
730 refstr = self.service_types + path[pos:]
731 root = eServiceReference(refstr)
733 self.servicelist.setMode(ServiceList.MODE_NORMAL)
734 self.servicelist.setRoot(root, justSet)
735 self.buildTitleString()
737 def removeModeStr(self, str):
738 if self.mode == MODE_TV:
739 pos = str.find(' (TV)')
741 pos = str.find(' (Radio)')
746 def getServiceName(self, ref):
747 str = self.removeModeStr(ServiceReference(ref).getServiceName())
749 pathstr = ref.getPath()
750 if pathstr.find('FROM PROVIDERS') != -1:
752 if pathstr.find('FROM SATELLITES') != -1:
753 return _("Satellites")
754 if pathstr.find(') ORDER BY name') != -1:
758 def buildTitleString(self):
759 titleStr = self.instance.getTitle()
760 pos = titleStr.find(']')
762 pos = titleStr.find(')')
764 titleStr = titleStr[:pos+1]
765 Len = len(self.servicePath)
767 base_ref = self.servicePath[0]
769 end_ref = self.servicePath[Len-1]
772 nameStr = self.getServiceName(base_ref)
773 titleStr += ' ' + nameStr
774 if end_ref is not None:
779 nameStr = self.getServiceName(end_ref)
781 self.setTitle(titleStr)
784 self.servicelist.moveUp()
787 self.servicelist.moveDown()
790 del self.servicePath[:]
792 def enterPath(self, ref, justSet=False):
793 self.servicePath.append(ref)
794 self.setRoot(ref, justSet)
796 def pathUp(self, justSet=False):
797 prev = self.servicePath.pop()
798 length = len(self.servicePath)
800 current = self.servicePath[length-1]
801 self.setRoot(current, justSet)
803 self.setCurrentSelection(prev)
806 def isBasePathEqual(self, ref):
807 if len(self.servicePath) > 1 and self.servicePath[0] == ref:
811 def isPrevPathEqual(self, ref):
812 length = len(self.servicePath)
813 if length > 1 and self.servicePath[length-2] == ref:
817 def preEnterPath(self, refstr):
820 def showAllServices(self):
821 if not self.pathChangeDisabled:
822 refstr = '%s ORDER BY name'%(self.service_types)
823 if not self.preEnterPath(refstr):
824 ref = eServiceReference(refstr)
825 currentRoot = self.getRoot()
826 if currentRoot is None or currentRoot != ref:
830 def showSatellites(self):
831 if not self.pathChangeDisabled:
832 refstr = '%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types)
833 if not self.preEnterPath(refstr):
834 ref = eServiceReference(refstr)
838 if self.isBasePathEqual(ref):
839 if self.isPrevPathEqual(ref):
841 prev = self.pathUp(justSet)
843 currentRoot = self.getRoot()
844 if currentRoot is None or currentRoot != ref:
847 self.enterPath(ref, True)
849 serviceHandler = eServiceCenter.getInstance()
850 servicelist = serviceHandler.list(ref)
851 if not servicelist is None:
853 service = servicelist.getNext()
854 if not service.valid(): #check if end of list
856 orbpos = service.getUnsignedData(4) >> 16
857 if service.getPath().find("FROM PROVIDER") != -1:
858 service_name = _("Providers")
859 elif service.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
860 service_name = _("New")
862 service_name = _("Services")
864 service_name += str(' - %s'%(nimmanager.getSatDescription(orbpos)))
865 service.setName(service_name) # why we need this cast?
867 if orbpos == 0xFFFF: #Cable
868 n = ("%s (%s)") % (service_name, _("Cable"))
869 elif orbpos == 0xEEEE: #Terrestrial
870 n = ("%s (%s)") % (service_name, _("Terrestrial"))
872 if orbpos > 1800: # west
873 orbpos = 3600 - orbpos
877 n = ("%s (%d.%d" + h + ")") % (service_name, orbpos / 10, orbpos % 10)
879 self.servicelist.addService(service)
880 self.servicelist.finishFill()
882 self.setCurrentSelection(prev)
884 def showProviders(self):
885 if not self.pathChangeDisabled:
886 refstr = '%s FROM PROVIDERS ORDER BY name'%(self.service_types)
887 if not self.preEnterPath(refstr):
888 ref = eServiceReference(refstr)
889 if self.isBasePathEqual(ref):
892 currentRoot = self.getRoot()
893 if currentRoot is None or currentRoot != ref:
897 def changeBouquet(self, direction):
898 if not self.pathChangeDisabled:
899 if len(self.servicePath) > 1:
900 #when enter satellite root list we must do some magic stuff..
901 ref = eServiceReference('%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types))
902 if self.isBasePathEqual(ref):
903 self.showSatellites()
910 ref = self.getCurrentSelection()
914 return self.isBasePathEqual(self.bouquet_root)
917 return self.servicelist.atBegin()
920 return self.servicelist.atEnd()
922 def nextBouquet(self):
923 self.changeBouquet(+1)
925 def prevBouquet(self):
926 self.changeBouquet(-1)
928 def showFavourites(self):
929 if not self.pathChangeDisabled:
930 if not self.preEnterPath(self.bouquet_rootstr):
931 if self.isBasePathEqual(self.bouquet_root):
934 currentRoot = self.getRoot()
935 if currentRoot is None or currentRoot != self.bouquet_root:
937 self.enterPath(self.bouquet_root)
939 def keyNumberGlobal(self, number):
940 unichar = self.numericalTextInput.getKey(number)
941 charstr = unichar.encode("utf-8")
942 if len(charstr) == 1:
943 self.servicelist.moveToChar(charstr[0])
946 return self.servicelist.getRoot()
948 def getCurrentSelection(self):
949 return self.servicelist.getCurrent()
951 def setCurrentSelection(self, service):
952 servicepath = service.getPath()
953 pos = servicepath.find(" FROM BOUQUET")
955 if self.mode == MODE_TV:
956 servicepath = '(type == 1)' + servicepath[pos:]
958 servicepath = '(type == 2)' + servicepath[pos:]
959 service.setPath(servicepath)
960 self.servicelist.setCurrent(service)
962 def getBouquetList(self):
964 serviceHandler = eServiceCenter.getInstance()
965 if config.usage.multibouquet.value:
966 list = serviceHandler.list(self.bouquet_root)
972 if s.flags & eServiceReference.isDirectory:
973 info = serviceHandler.info(s)
975 bouquets.append((info.getName(s), s))
978 info = serviceHandler.info(self.bouquet_root)
980 bouquets.append((info.getName(self.bouquet_root), self.bouquet_root))
984 def keyNumber0(self, num):
985 if len(self.servicePath) > 1:
988 self.keyNumberGlobal(num)
991 if len(self.servicePath) > 1:
992 if self.isBasePathEqual(self.bouquet_root):
993 self.showFavourites()
995 ref = eServiceReference('%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types))
996 if self.isBasePathEqual(ref):
997 self.showSatellites()
999 ref = eServiceReference('%s FROM PROVIDERS ORDER BY name'%(self.service_types))
1000 if self.isBasePathEqual(ref):
1001 self.showProviders()
1003 self.showAllServices()
1005 def nextMarker(self):
1006 self.servicelist.moveToNextMarker()
1008 def prevMarker(self):
1009 self.servicelist.moveToPrevMarker()
1013 #config for lastservice
1014 config.tv = ConfigSubsection()
1015 config.tv.lastservice = ConfigText()
1016 config.tv.lastroot = ConfigText()
1017 config.radio = ConfigSubsection()
1018 config.radio.lastservice = ConfigText()
1019 config.radio.lastroot = ConfigText()
1020 config.servicelist = ConfigSubsection()
1021 config.servicelist.lastmode = ConfigText(default = "tv")
1023 class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG):
1024 def __init__(self, session):
1025 ChannelSelectionBase.__init__(self,session)
1026 ChannelSelectionEdit.__init__(self)
1027 ChannelSelectionEPG.__init__(self)
1029 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1031 "cancel": self.cancel,
1032 "ok": self.channelSelected,
1033 "keyRadio": self.setModeRadio,
1034 "keyTV": self.setModeTv,
1037 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
1039 iPlayableService.evStart: self.__evServiceStart,
1040 iPlayableService.evEnd: self.__evServiceEnd
1043 self.lastChannelRootTimer = eTimer()
1044 self.lastChannelRootTimer.timeout.get().append(self.__onCreate)
1045 self.lastChannelRootTimer.start(100,True)
1047 self.history_tv = [ ]
1048 self.history_radio = [ ]
1049 self.history = self.history_tv
1050 self.history_pos = 0
1052 self.lastservice = config.tv.lastservice
1053 self.lastroot = config.tv.lastroot
1054 self.revertMode = None
1055 config.usage.multibouquet.addNotifier(self.multibouquet_config_changed)
1057 def multibouquet_config_changed(self, val):
1058 self.recallBouquetMode()
1060 def __evServiceStart(self):
1061 service = self.session.nav.getCurrentService()
1063 info = service.info()
1065 refstr = info.getInfoString(iServiceInformation.sServiceref)
1066 self.servicelist.setPlayableIgnoreService(eServiceReference(refstr))
1068 def __evServiceEnd(self):
1069 self.servicelist.setPlayableIgnoreService(eServiceReference())
1073 lastservice=eServiceReference(self.lastservice.value)
1074 if lastservice.valid():
1075 self.setCurrentSelection(lastservice)
1077 def setModeTv(self):
1078 if self.revertMode is None and config.servicelist.lastmode.value == "radio":
1079 self.revertMode = MODE_RADIO
1080 self.history = self.history_tv
1081 self.lastservice = config.tv.lastservice
1082 self.lastroot = config.tv.lastroot
1083 config.servicelist.lastmode.value = "tv"
1087 def setModeRadio(self):
1088 if self.revertMode is None and config.servicelist.lastmode.value == "tv":
1089 self.revertMode = MODE_TV
1090 if config.usage.e1like_radio_mode.value:
1091 self.history = self.history_radio
1092 self.lastservice = config.radio.lastservice
1093 self.lastroot = config.radio.lastroot
1094 config.servicelist.lastmode.value = "radio"
1098 def __onCreate(self):
1099 if config.usage.e1like_radio_mode.value:
1100 if config.servicelist.lastmode.value == "tv":
1106 lastservice=eServiceReference(self.lastservice.value)
1107 if lastservice.valid():
1110 def channelSelected(self):
1111 ref = self.getCurrentSelection()
1113 self.toggleMoveMarked()
1114 elif (ref.flags & 7) == 7:
1116 elif self.bouquet_mark_edit != OFF:
1117 if not (self.bouquet_mark_edit == EDIT_ALTERNATIVES and ref.flags & eServiceReference.isGroup):
1119 elif not (ref.flags & eServiceReference.isMarker): # no marker
1120 if not (self.getRoot().flags & eServiceReference.isGroup):
1124 #called from infoBar and channelSelected
1126 self.revertMode=None
1127 ref = self.session.nav.getCurrentlyPlayingServiceReference()
1128 nref = self.getCurrentSelection()
1129 if ref is None or ref != nref:
1130 self.session.nav.playService(nref)
1132 self.saveChannel(nref)
1133 config.servicelist.lastmode.save()
1134 self.addToHistory(nref)
1136 def addToHistory(self, ref):
1137 if self.servicePath is not None:
1138 tmp=self.servicePath[:]
1141 del self.history[self.history_pos+1:]
1144 self.history.append(tmp)
1145 hlen = len(self.history)
1146 if hlen > HISTORYSIZE:
1149 self.history_pos = hlen-1
1151 def historyBack(self):
1152 hlen = len(self.history)
1153 if hlen > 1 and self.history_pos > 0:
1154 self.history_pos -= 1
1155 self.setHistoryPath()
1157 def historyNext(self):
1158 hlen = len(self.history)
1159 if hlen > 1 and self.history_pos < (hlen-1):
1160 self.history_pos += 1
1161 self.setHistoryPath()
1163 def setHistoryPath(self):
1164 path = self.history[self.history_pos][:]
1166 del self.servicePath[:]
1167 self.servicePath += path
1171 if self.getRoot() != root:
1173 self.session.nav.playService(ref)
1174 self.setCurrentSelection(ref)
1175 self.saveChannel(ref)
1179 for i in self.servicePath:
1180 path += i.toString()
1182 if len(path) and path != self.lastroot.value:
1183 self.lastroot.value = path
1184 self.lastroot.save()
1186 def restoreRoot(self):
1188 re = compile('.+?;')
1189 tmp = re.findall(self.lastroot.value)
1192 self.servicePath.append(eServiceReference(i[:len(i)-1]))
1195 path = self.servicePath.pop()
1196 self.enterPath(path)
1198 self.showFavourites()
1201 def preEnterPath(self, refstr):
1202 if len(self.servicePath) and self.servicePath[0] != eServiceReference(refstr):
1203 pathstr = self.lastroot.value
1204 if pathstr is not None and pathstr.find(refstr) == 0:
1206 lastservice=eServiceReference(self.lastservice.value)
1207 if lastservice.valid():
1208 self.setCurrentSelection(lastservice)
1212 def saveChannel(self, ref):
1214 refstr = ref.toString()
1217 if refstr != self.lastservice.value:
1218 self.lastservice.value = refstr
1219 self.lastservice.save()
1221 def setCurrentServicePath(self, path):
1222 hlen = len(self.history)
1224 self.history[self.history_pos] = path
1226 self.history.append(path)
1227 self.setHistoryPath()
1229 def getCurrentServicePath(self):
1230 hlen = len(self.history)
1232 return self.history[self.history_pos]
1235 def recallPrevService(self):
1236 hlen = len(self.history)
1238 if self.history_pos == hlen-1:
1239 tmp = self.history[self.history_pos]
1240 self.history[self.history_pos] = self.history[self.history_pos-1]
1241 self.history[self.history_pos-1] = tmp
1243 tmp = self.history[self.history_pos+1]
1244 self.history[self.history_pos+1] = self.history[self.history_pos]
1245 self.history[self.history_pos] = tmp
1246 self.setHistoryPath()
1249 if self.revertMode is None:
1251 lastservice=eServiceReference(self.lastservice.value)
1252 if lastservice.valid() and self.getCurrentSelection() != lastservice:
1253 self.setCurrentSelection(lastservice)
1254 elif self.revertMode == MODE_TV:
1256 elif self.revertMode == MODE_RADIO:
1258 self.revertMode = None
1261 from Screens.InfoBarGenerics import InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord, InfoBarRadioText
1263 class RadioInfoBar(Screen, InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord):
1264 def __init__(self, session):
1265 Screen.__init__(self, session)
1266 InfoBarEvent.__init__(self)
1267 InfoBarServiceName.__init__(self)
1268 InfoBarInstantRecord.__init__(self)
1269 self["CurrentTime"] = Clock()
1271 class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG, InfoBarRadioText):
1273 ALLOW_SUSPEND = True
1275 def __init__(self, session):
1276 ChannelSelectionBase.__init__(self, session)
1277 ChannelSelectionEdit.__init__(self)
1278 ChannelSelectionEPG.__init__(self)
1279 InfoBarRadioText.__init__(self)
1281 config.radio = ConfigSubsection();
1282 config.radio.lastservice = ConfigText()
1283 config.radio.lastroot = ConfigText()
1284 self.onLayoutFinish.append(self.onCreate)
1286 self.info = session.instantiateDialog(RadioInfoBar)
1288 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1290 "keyTV": self.closeRadio,
1291 "keyRadio": self.closeRadio,
1292 "cancel": self.closeRadio,
1293 "ok": self.channelSelected,
1296 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
1298 iPlayableService.evStart: self.__evServiceStart,
1299 iPlayableService.evEnd: self.__evServiceEnd
1302 def __evServiceStart(self):
1303 service = self.session.nav.getCurrentService()
1305 info = service.info()
1307 refstr = info.getInfoString(iServiceInformation.sServiceref)
1308 self.servicelist.setPlayableIgnoreService(eServiceReference(refstr))
1310 def __evServiceEnd(self):
1311 self.servicelist.setPlayableIgnoreService(eServiceReference())
1315 for i in self.servicePathRadio:
1316 path += i.toString()
1318 if len(path) and path != config.radio.lastroot.value:
1319 config.radio.lastroot.value = path
1320 config.radio.lastroot.save()
1322 def restoreRoot(self):
1324 re = compile('.+?;')
1325 tmp = re.findall(config.radio.lastroot.value)
1328 self.servicePathRadio.append(eServiceReference(i[:len(i)-1]))
1331 path = self.servicePathRadio.pop()
1332 self.enterPath(path)
1334 self.showFavourites()
1337 def preEnterPath(self, refstr):
1338 if len(self.servicePathRadio) and self.servicePathRadio[0] != eServiceReference(refstr):
1339 pathstr = config.radio.lastroot.value
1340 if pathstr is not None and pathstr.find(refstr) == 0:
1342 lastservice=eServiceReference(config.radio.lastservice.value)
1343 if lastservice.valid():
1344 self.setCurrentSelection(lastservice)
1351 lastservice=eServiceReference(config.radio.lastservice.value)
1352 if lastservice.valid():
1353 self.servicelist.setCurrent(lastservice)
1354 self.session.nav.playService(lastservice)
1357 def channelSelected(self): # just return selected service
1358 ref = self.getCurrentSelection()
1360 self.toggleMoveMarked()
1361 elif (ref.flags & 7) == 7:
1363 elif self.bouquet_mark_edit != OFF:
1364 if not (self.bouquet_mark_edit == EDIT_ALTERNATIVES and ref.flags & eServiceReference.isGroup):
1366 elif not (ref.flags & eServiceReference.isMarker): # no marker
1367 if not (self.getRoot().flags & eServiceReference.isGroup):
1368 playingref = self.session.nav.getCurrentlyPlayingServiceReference()
1369 if playingref is None or playingref != ref:
1370 self.session.nav.playService(ref)
1371 config.radio.lastservice.value = ref.toString()
1372 config.radio.lastservice.save()
1375 def closeRadio(self):
1377 #set previous tv service
1378 lastservice=eServiceReference(config.tv.lastservice.value)
1379 self.session.nav.playService(lastservice)
1382 class SimpleChannelSelection(ChannelSelectionBase):
1383 def __init__(self, session, title):
1384 ChannelSelectionBase.__init__(self, session)
1386 self.onShown.append(self.__onExecCallback)
1388 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1390 "cancel": self.close,
1391 "ok": self.channelSelected,
1392 "keyRadio": self.setModeRadio,
1393 "keyTV": self.setModeTv,
1396 def __onExecCallback(self):
1397 self.setTitle(self.title)
1400 def channelSelected(self): # just return selected service
1401 ref = self.getCurrentSelection()
1402 if (ref.flags & 7) == 7:
1404 elif not (ref.flags & eServiceReference.isMarker):
1405 ref = self.getCurrentSelection()
1408 def setModeTv(self):
1410 self.showFavourites()
1412 def setModeRadio(self):
1414 self.showFavourites()