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 ServiceReference import ServiceReference
19 from Tools.BoundFunction import boundFunction
23 FLAG_SERVICE_NEW_FOUND = 64 #define in lib/dvb/idvb.h as dxNewFound = 64
25 import xml.dom.minidom
27 class BouquetSelector(Screen):
28 def __init__(self, session, bouquets, selectedFunc, enableWrapAround=False):
29 Screen.__init__(self, session)
31 self.selectedFunc=selectedFunc
33 self["actions"] = ActionMap(["OkCancelActions"],
35 "ok": self.okbuttonClick,
36 "cancel": self.cancelClick
40 entrys.append((x[0], x[1]))
41 self["menu"] = MenuList(entrys, enableWrapAround)
44 cur = self["menu"].getCurrent()
47 def okbuttonClick(self):
48 self.selectedFunc(self.getCurrent())
56 def cancelClick(self):
59 # csel.bouquet_mark_edit values
64 class ChannelContextMenu(Screen):
65 def __init__(self, session, csel):
66 Screen.__init__(self, session)
70 self["actions"] = ActionMap(["OkCancelActions"],
72 "ok": self.okbuttonClick,
73 "cancel": self.cancelClick
77 current_root = csel.getRoot()
78 current_sel_path = csel.getCurrentSelection().getPath()
79 current_sel_flags = csel.getCurrentSelection().flags
80 inBouquetRootList = current_root and current_root.getPath().find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
81 inBouquet = csel.getMutableList() is not None
82 haveBouquets = config.usage.multibouquet.value
84 if csel.bouquet_mark_edit == OFF and not csel.movemode:
85 if not inBouquetRootList:
86 isPlayable = not (current_sel_flags & (eServiceReference.isMarker|eServiceReference.isDirectory))
88 if config.ParentalControl.configured.value:
89 if parentalControl.getProtectionLevel(csel.getCurrentSelection().toCompareString()) == -1:
90 menu.append((_("add to parental protection"), boundFunction(self.addParentalProtection, csel.getCurrentSelection())))
92 menu.append((_("remove from parental protection"), boundFunction(self.removeParentalProtection, csel.getCurrentSelection())))
94 menu.append((_("add service to bouquet"), self.addServiceToBouquetSelected))
96 menu.append((_("add service to favourites"), self.addServiceToBouquetSelected))
99 if not inBouquet and current_sel_path.find("PROVIDERS") == -1:
100 menu.append((_("copy to bouquets"), self.copyCurrentToBouquetList))
101 if current_sel_path.find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
102 menu.append((_("remove all new found flags"), self.removeAllNewFoundFlags))
104 menu.append((_("remove entry"), self.removeCurrentService))
105 if current_root is not None and current_root.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
106 menu.append((_("remove new found flag"), self.removeNewFoundFlag))
108 menu.append((_("add bouquet"), self.showBouquetInputBox))
109 menu.append((_("remove entry"), self.removeBouquet))
111 if inBouquet: # current list is editable?
112 if csel.bouquet_mark_edit == OFF:
113 if not csel.movemode:
114 menu.append((_("enable move mode"), self.toggleMoveMode))
115 if not inBouquetRootList and not current_root.flags & eServiceReference.isGroup:
116 menu.append((_("add marker"), self.showMarkerInputBox))
118 menu.append((_("enable bouquet edit"), self.bouquetMarkStart))
120 menu.append((_("enable favourite edit"), self.bouquetMarkStart))
121 if current_sel_flags & eServiceReference.isGroup:
122 menu.append((_("edit alternatives"), self.editAlternativeServices))
123 menu.append((_("show alternatives"), self.showAlternativeServices))
124 menu.append((_("remove all alternatives"), self.removeAlternativeServices))
126 menu.append((_("add alternatives"), self.addAlternativeServices))
128 menu.append((_("disable move mode"), self.toggleMoveMode))
130 if csel.bouquet_mark_edit == EDIT_BOUQUET:
132 menu.append((_("end bouquet edit"), self.bouquetMarkEnd))
133 menu.append((_("abort bouquet edit"), self.bouquetMarkAbort))
135 menu.append((_("end favourites edit"), self.bouquetMarkEnd))
136 menu.append((_("abort favourites edit"), self.bouquetMarkAbort))
138 menu.append((_("end alternatives edit"), self.bouquetMarkEnd))
139 menu.append((_("abort alternatives edit"), self.bouquetMarkAbort))
141 menu.append((_("back"), self.cancelClick))
142 self["menu"] = MenuList(menu)
144 def okbuttonClick(self):
145 self["menu"].getCurrent()[1]()
147 def cancelClick(self):
150 def showBouquetInputBox(self):
151 self.session.openWithCallback(self.bouquetInputCallback, InputBox, title=_("Please enter a name for the new bouquet"), text="bouquetname", maxSize=False, type=Input.TEXT)
153 def bouquetInputCallback(self, bouquet):
154 if bouquet is not None:
155 self.csel.addBouquet(bouquet, None)
158 def addParentalProtection(self, service):
159 parentalControl.protectService(service.toCompareString())
162 def removeParentalProtection(self, service):
163 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"))
165 def pinEntered(self, service, result):
167 parentalControl.unProtectService(service)
170 self.session.openWithCallback(self.close, MessageBox, _("The pin code you entered is wrong."), MessageBox.TYPE_ERROR)
172 def addServiceToBouquetSelected(self):
173 bouquets = self.csel.getBouquetList()
178 if cnt > 1: # show bouquet list
179 self.bsel = self.session.openWithCallback(self.bouquetSelClosed, BouquetSelector, bouquets, self.addCurrentServiceToBouquet)
180 elif cnt == 1: # add to only one existing bouquet
181 self.addCurrentServiceToBouquet(bouquets[0][1])
183 def bouquetSelClosed(self, recursive):
188 def copyCurrentToBouquetList(self):
189 self.csel.copyCurrentToBouquetList()
192 def removeBouquet(self):
193 self.csel.removeBouquet()
196 def showMarkerInputBox(self):
197 self.session.openWithCallback(self.markerInputCallback, InputBox, title=_("Please enter a name for the new marker"), text="markername", maxSize=False, type=Input.TEXT)
199 def markerInputCallback(self, marker):
200 if marker is not None:
201 self.csel.addMarker(marker)
204 def addCurrentServiceToBouquet(self, dest):
205 self.csel.addServiceToBouquet(dest)
206 if self.bsel is not None:
207 self.bsel.close(True)
209 self.close(True) # close bouquet selection
211 def removeCurrentService(self):
212 self.csel.removeCurrentService()
215 def toggleMoveMode(self):
216 self.csel.toggleMoveMode()
219 def bouquetMarkStart(self):
220 self.csel.startMarkedEdit(EDIT_BOUQUET)
223 def bouquetMarkEnd(self):
224 self.csel.endMarkedEdit(abort=False)
227 def bouquetMarkAbort(self):
228 self.csel.endMarkedEdit(abort=True)
231 def removeNewFoundFlag(self):
232 eDVBDB.getInstance().removeFlag(self.csel.getCurrentSelection(), FLAG_SERVICE_NEW_FOUND)
235 def removeAllNewFoundFlags(self):
236 curpath = self.csel.getCurrentSelection().getPath()
237 idx = curpath.find("satellitePosition == ")
239 tmp = curpath[idx+21:]
242 satpos = int(tmp[:idx])
243 eDVBDB.getInstance().removeFlags(FLAG_SERVICE_NEW_FOUND, -1, -1, -1, satpos)
246 def editAlternativeServices(self):
247 self.csel.startMarkedEdit(EDIT_ALTERNATIVES)
250 def showAlternativeServices(self):
251 self.csel.enterPath(self.csel.getCurrentSelection())
254 def removeAlternativeServices(self):
255 self.csel.removeAlternativeServices()
258 def addAlternativeServices(self):
259 self.csel.addAlternativeServices()
260 self.csel.startMarkedEdit(EDIT_ALTERNATIVES)
263 class ChannelSelectionEPG:
265 self["ChannelSelectEPGActions"] = ActionMap(["ChannelSelectEPGActions"],
267 "showEPGList": self.showEPGList,
270 def showEPGList(self):
271 ref=self.getCurrentSelection()
272 ptr=eEPGCache.getInstance()
273 if ptr.startTimeQuery(ref) != -1:
274 self.session.open(EPGSelection, ref)
276 print 'no epg for service', ref.toString()
278 class ChannelSelectionEdit:
280 self.entry_marked = False
281 self.movemode = False
282 self.bouquet_mark_edit = OFF
283 self.mutableList = None
285 self.saved_title = None
286 self.saved_root = None
288 class ChannelSelectionEditActionMap(ActionMap):
289 def __init__(self, csel, contexts = [ ], actions = { }, prio=0):
290 ActionMap.__init__(self, contexts, actions, prio)
293 def action(self, contexts, action):
294 if action == "cancel":
295 self.csel.handleEditCancel()
296 return 0 # fall-trough
298 return 0 # fall-trough
300 return ActionMap.action(self, contexts, action)
302 self["ChannelSelectEditActions"] = ChannelSelectionEditActionMap(self, ["ChannelSelectEditActions", "OkCancelActions"],
304 "contextMenu": self.doContext,
307 def getMutableList(self, root=eServiceReference()):
308 if not self.mutableList is None:
309 return self.mutableList
310 serviceHandler = eServiceCenter.getInstance()
313 list = root and serviceHandler.list(root)
315 return list.startEdit()
318 def buildBouquetID(self, str):
322 if (c >= 'a' and c <= 'z') or (c >= '0' and c <= '9'):
328 def addMarker(self, name):
329 current = self.servicelist.getCurrent()
330 mutableList = self.getMutableList()
333 str = '1:64:%d:0:0:0:0:0:0:0::%s'%(cnt, name)
334 ref = eServiceReference(str)
335 if current and current.valid():
336 if not mutableList.addService(ref, current):
337 self.servicelist.addService(ref, True)
338 mutableList.flushChanges()
340 elif not mutableList.addService(ref):
341 self.servicelist.addService(ref, True)
342 mutableList.flushChanges()
346 def addAlternativeServices(self):
347 cur_service = ServiceReference(self.getCurrentSelection())
348 cur_root = ServiceReference(self.getRoot())
349 mutableBouquet = cur_root.list().startEdit()
351 name = cur_service.getServiceName()
353 if self.mode == MODE_TV:
354 str = '1:134:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET \"alternatives.%s.tv\" ORDER BY bouquet'%(self.buildBouquetID(name))
356 str = '1:134:2:0:0:0:0:0:0:0:(type == 2) FROM BOUQUET \"alternatives.%s.radio\" ORDER BY bouquet'%(self.buildBouquetID(name))
357 new_ref = ServiceReference(str)
358 if not mutableBouquet.addService(new_ref.ref, cur_service.ref):
359 mutableBouquet.removeService(cur_service.ref)
360 mutableBouquet.flushChanges()
361 eDVBDB.getInstance().reloadBouquets()
362 mutableAlternatives = new_ref.list().startEdit()
363 if mutableAlternatives:
364 mutableAlternatives.setListName(name)
365 if mutableAlternatives.addService(cur_service.ref):
366 print "add", cur_service.toString(), "to new alternatives failed"
367 mutableAlternatives.flushChanges()
368 self.servicelist.addService(new_ref.ref, True)
369 self.servicelist.removeCurrent()
370 self.servicelist.moveUp()
372 print "get mutable list for new created alternatives failed"
374 print "add", str, "to", cur_root.getServiceName(), "failed"
376 print "bouquetlist is not editable"
378 def addBouquet(self, bName, services):
379 serviceHandler = eServiceCenter.getInstance()
380 mutableBouquetList = serviceHandler.list(self.bouquet_root).startEdit()
381 if mutableBouquetList:
382 if self.mode == MODE_TV:
384 str = '1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET \"userbouquet.%s.tv\" ORDER BY bouquet'%(self.buildBouquetID(bName))
387 str = '1:7:2:0:0:0:0:0:0:0:(type == 2) FROM BOUQUET \"userbouquet.%s.radio\" ORDER BY bouquet'%(self.buildBouquetID(bName))
388 new_bouquet_ref = eServiceReference(str)
389 if not mutableBouquetList.addService(new_bouquet_ref):
390 mutableBouquetList.flushChanges()
391 eDVBDB.getInstance().reloadBouquets()
392 mutableBouquet = serviceHandler.list(new_bouquet_ref).startEdit()
394 mutableBouquet.setListName(bName)
395 if services is not None:
396 for service in services:
397 if mutableBouquet.addService(service):
398 print "add", service.toString(), "to new bouquet failed"
399 mutableBouquet.flushChanges()
401 print "get mutable list for new created bouquet failed"
402 # do some voodoo to check if current_root is equal to bouquet_root
403 cur_root = self.getRoot();
404 str1 = cur_root.toString()
405 pos1 = str1.find("FROM BOUQUET")
406 pos2 = self.bouquet_rootstr.find("FROM BOUQUET")
407 if pos1 != -1 and pos2 != -1 and str1[pos1:] == self.bouquet_rootstr[pos2:]:
408 self.servicelist.addService(new_bouquet_ref)
410 print "add", str, "to bouquets failed"
412 print "bouquetlist is not editable"
414 def copyCurrentToBouquetList(self):
415 provider = ServiceReference(self.getCurrentSelection())
416 providerName = provider.getServiceName()
417 serviceHandler = eServiceCenter.getInstance()
418 services = serviceHandler.list(provider.ref)
419 self.addBouquet(providerName, services and services.getContent('R', True))
421 def removeAlternativeServices(self):
422 cur_service = ServiceReference(self.getCurrentSelection())
423 cur_root = ServiceReference(self.getRoot())
424 list = cur_service.list()
425 first_in_alternative = list and list.getNext()
426 if first_in_alternative:
427 edit_root = cur_root.list().startEdit()
429 if not edit_root.addService(first_in_alternative, cur_service.ref):
430 self.servicelist.addService(first_in_alternative, True)
432 print "couldn't add first alternative service to current root"
434 print "couldn't edit current root!!"
436 print "remove empty alternative list !!"
438 self.servicelist.moveUp()
440 def removeBouquet(self):
441 refstr = self.getCurrentSelection().toString()
442 print "removeBouquet", refstr
443 self.bouquetNumOffsetCache = { }
444 pos = refstr.find('FROM BOUQUET "')
447 refstr = refstr[pos+14:]
448 pos = refstr.find('"')
450 filename = '/etc/enigma2/' + refstr[:pos] # FIXMEEE !!! HARDCODED /etc/enigma2
451 self.removeCurrentService()
453 if filename is not None:
456 print "error during remove of", filename
458 # multiple marked entry stuff ( edit mode, later multiepg selection )
459 def startMarkedEdit(self, type):
460 self.savedPath = self.servicePath[:]
461 if type == EDIT_ALTERNATIVES:
462 self.enterPath(self.getCurrentSelection())
463 self.mutableList = self.getMutableList()
464 # add all services from the current list to internal marked set in listboxservicecontent
465 self.clearMarks() # this clears the internal marked set in the listboxservicecontent
466 self.saved_title = self.instance.getTitle()
467 pos = self.saved_title.find(')')
468 new_title = self.saved_title[:pos+1]
469 if type == EDIT_ALTERNATIVES:
470 self.bouquet_mark_edit = EDIT_ALTERNATIVES
471 new_title += ' ' + _("[alternative edit]")
473 self.bouquet_mark_edit = EDIT_BOUQUET
474 if config.usage.multibouquet.value:
475 new_title += ' ' + _("[bouquet edit]")
477 new_title += ' ' + _("[favourite edit]")
478 self.setTitle(new_title)
479 self.__marked = self.servicelist.getRootServices()
480 for x in self.__marked:
481 self.servicelist.addMarked(eServiceReference(x))
482 self.showAllServices()
484 def endMarkedEdit(self, abort):
485 if not abort and self.mutableList is not None:
486 self.bouquetNumOffsetCache = { }
487 new_marked = set(self.servicelist.getMarked())
488 old_marked = set(self.__marked)
489 removed = old_marked - new_marked
490 added = new_marked - old_marked
494 self.mutableList.removeService(eServiceReference(x))
497 self.mutableList.addService(eServiceReference(x))
499 self.mutableList.flushChanges()
502 self.bouquet_mark_edit = OFF
503 self.mutableList = None
504 self.setTitle(self.saved_title)
505 self.saved_title = None
506 # self.servicePath is just a reference to servicePathTv or Radio...
507 # so we never ever do use the asignment operator in self.servicePath
508 del self.servicePath[:] # remove all elements
509 self.servicePath += self.savedPath # add saved elements
511 self.setRoot(self.servicePath[len(self.servicePath)-1])
513 def clearMarks(self):
514 self.servicelist.clearMarks()
517 ref = self.servicelist.getCurrent()
518 if self.servicelist.isMarked(ref):
519 self.servicelist.removeMarked(ref)
521 self.servicelist.addMarked(ref)
523 def removeCurrentService(self):
524 ref = self.servicelist.getCurrent()
525 mutableList = self.getMutableList()
526 if ref.valid() and mutableList is not None:
527 if not mutableList.removeService(ref):
528 self.bouquetNumOffsetCache = { }
529 mutableList.flushChanges() #FIXME dont flush on each single removed service
530 self.servicelist.removeCurrent()
532 def addServiceToBouquet(self, dest, service=None):
533 mutableList = self.getMutableList(dest)
534 if not mutableList is None:
535 if service is None: #use current selected service
536 service = self.servicelist.getCurrent()
537 if not mutableList.addService(service):
538 self.bouquetNumOffsetCache = { }
539 mutableList.flushChanges()
540 # do some voodoo to check if current_root is equal to dest
541 cur_root = self.getRoot();
542 str1 = cur_root.toString()
543 str2 = dest.toString()
544 pos1 = str1.find("FROM BOUQUET")
545 pos2 = str2.find("FROM BOUQUET")
546 if pos1 != -1 and pos2 != -1 and str1[pos1:] == str2[pos2:]:
547 self.servicelist.addService(service)
549 def toggleMoveMode(self):
551 if self.entry_marked:
552 self.toggleMoveMarked() # unmark current entry
553 self.movemode = False
554 self.pathChangeDisabled = False # re-enable path change
555 self.mutableList.flushChanges() # FIXME add check if changes was made
556 self.mutableList = None
557 self.setTitle(self.saved_title)
558 self.saved_title = None
559 if self.getRoot() == self.bouquet_root:
560 self.bouquetNumOffsetCache = { }
562 self.mutableList = self.getMutableList()
564 self.pathChangeDisabled = True # no path change allowed in movemode
565 self.saved_title = self.instance.getTitle()
566 new_title = self.saved_title
567 pos = self.saved_title.find(')')
568 new_title = self.saved_title[:pos+1] + ' ' + _("[move mode]") + self.saved_title[pos+1:]
569 self.setTitle(new_title);
571 def handleEditCancel(self):
572 if self.movemode: #movemode active?
573 self.channelSelected() # unmark
574 self.toggleMoveMode() # disable move mode
575 elif self.bouquet_mark_edit != OFF:
576 self.endMarkedEdit(True) # abort edit mode
578 def toggleMoveMarked(self):
579 if self.entry_marked:
580 self.servicelist.setCurrentMarked(False)
581 self.entry_marked = False
583 self.servicelist.setCurrentMarked(True)
584 self.entry_marked = True
587 self.session.open(ChannelContextMenu, self)
592 # this makes it much simple to implement a selectable radio or tv mode :)
593 service_types_tv = '1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17) || (type == 195) || (type == 25)'
594 service_types_radio = '1:7:2:0:0:0:0:0:0:0:(type == 2)'
596 class ChannelSelectionBase(Screen):
597 def __init__(self, session):
598 Screen.__init__(self, session)
600 self["key_red"] = Button(_("All"))
601 self["key_green"] = Button(_("Satellites"))
602 self["key_yellow"] = Button(_("Provider"))
603 self["key_blue"] = Button(_("Favourites"))
605 self["list"] = ServiceList()
606 self.servicelist = self["list"]
608 self.numericalTextInput = NumericalTextInput()
609 self.numericalTextInput.setUseableChars(u'1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ')
611 self.servicePathTV = [ ]
612 self.servicePathRadio = [ ]
613 self.servicePath = [ ]
617 self.pathChangeDisabled = False
619 self.bouquetNumOffsetCache = { }
621 self["ChannelSelectBaseActions"] = NumberActionMap(["ChannelSelectBaseActions", "NumberActions"],
623 "showFavourites": self.showFavourites,
624 "showAllServices": self.showAllServices,
625 "showProviders": self.showProviders,
626 "showSatellites": self.showSatellites,
627 "nextBouquet": self.nextBouquet,
628 "prevBouquet": self.prevBouquet,
629 "nextMarker": self.nextMarker,
630 "prevMarker": self.prevMarker,
631 "1": self.keyNumberGlobal,
632 "2": self.keyNumberGlobal,
633 "3": self.keyNumberGlobal,
634 "4": self.keyNumberGlobal,
635 "5": self.keyNumberGlobal,
636 "6": self.keyNumberGlobal,
637 "7": self.keyNumberGlobal,
638 "8": self.keyNumberGlobal,
639 "9": self.keyNumberGlobal,
642 self.recallBouquetMode()
644 def appendDVBTypes(self, ref):
646 pos = path.find(' FROM BOUQUET')
648 return eServiceReference(self.service_types + path[pos:])
651 def getBouquetNumOffset(self, bouquet):
652 if not config.usage.multibouquet.value:
654 bouquet = self.appendDVBTypes(bouquet)
655 str = bouquet.toString()
657 if not self.bouquetNumOffsetCache.has_key(str):
658 serviceHandler = eServiceCenter.getInstance()
659 bouquetlist = serviceHandler.list(self.bouquet_root)
660 if not bouquetlist is None:
662 bouquetIterator = self.appendDVBTypes(bouquetlist.getNext())
663 if not bouquetIterator.valid(): #end of list
665 self.bouquetNumOffsetCache[bouquetIterator.toString()]=offsetCount
666 if not (bouquetIterator.flags & eServiceReference.isDirectory):
668 servicelist = serviceHandler.list(bouquetIterator)
669 if not servicelist is None:
671 serviceIterator = servicelist.getNext()
672 if not serviceIterator.valid(): #check if end of list
674 playable = not (serviceIterator.flags & (eServiceReference.isDirectory|eServiceReference.isMarker))
677 return self.bouquetNumOffsetCache.get(str, offsetCount)
679 def recallBouquetMode(self):
680 if self.mode == MODE_TV:
681 self.service_types = service_types_tv
682 if config.usage.multibouquet.value:
683 self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET "bouquets.tv" ORDER BY bouquet'
685 self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.tv" ORDER BY bouquet'%(self.service_types)
687 self.service_types = service_types_radio
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.radio" ORDER BY bouquet'
691 self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.radio" ORDER BY bouquet'%(self.service_types)
692 self.bouquet_root = eServiceReference(self.bouquet_rootstr)
696 self.servicePath = self.servicePathTV
697 self.recallBouquetMode()
698 title = self.instance.getTitle()
699 pos = title.find(" (")
705 def setRadioMode(self):
706 self.mode = MODE_RADIO
707 self.servicePath = self.servicePathRadio
708 self.recallBouquetMode()
709 title = self.instance.getTitle()
710 pos = title.find(" (")
716 def setRoot(self, root, justSet=False):
717 path = root.getPath()
718 inBouquetRootList = path.find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
719 pos = path.find(' FROM BOUQUET')
720 isBouquet = (pos != -1) and (root.flags & eServiceReference.isDirectory)
721 if not inBouquetRootList and isBouquet:
722 self.servicelist.setMode(ServiceList.MODE_FAVOURITES)
723 self.servicelist.setNumberOffset(self.getBouquetNumOffset(root))
724 refstr = self.service_types + path[pos:]
725 root = eServiceReference(refstr)
727 self.servicelist.setMode(ServiceList.MODE_NORMAL)
728 self.servicelist.setRoot(root, justSet)
729 self.buildTitleString()
731 def removeModeStr(self, str):
732 if self.mode == MODE_TV:
733 pos = str.find(' (TV)')
735 pos = str.find(' (Radio)')
740 def getServiceName(self, ref):
741 str = self.removeModeStr(ServiceReference(ref).getServiceName())
743 pathstr = ref.getPath()
744 if pathstr.find('FROM PROVIDERS') != -1:
746 if pathstr.find('FROM SATELLITES') != -1:
747 return _("Satellites")
748 if pathstr.find(') ORDER BY name') != -1:
752 def buildTitleString(self):
753 titleStr = self.instance.getTitle()
754 pos = titleStr.find(']')
756 pos = titleStr.find(')')
758 titleStr = titleStr[:pos+1]
759 Len = len(self.servicePath)
761 base_ref = self.servicePath[0]
763 end_ref = self.servicePath[Len-1]
766 nameStr = self.getServiceName(base_ref)
767 titleStr += ' ' + nameStr
768 if end_ref is not None:
773 nameStr = self.getServiceName(end_ref)
775 self.setTitle(titleStr)
778 self.servicelist.moveUp()
781 self.servicelist.moveDown()
784 del self.servicePath[:]
786 def enterPath(self, ref, justSet=False):
787 self.servicePath.append(ref)
788 self.setRoot(ref, justSet)
790 def pathUp(self, justSet=False):
791 prev = self.servicePath.pop()
792 length = len(self.servicePath)
794 current = self.servicePath[length-1]
795 self.setRoot(current, justSet)
797 self.setCurrentSelection(prev)
800 def isBasePathEqual(self, ref):
801 if len(self.servicePath) > 1 and self.servicePath[0] == ref:
805 def isPrevPathEqual(self, ref):
806 length = len(self.servicePath)
807 if length > 1 and self.servicePath[length-2] == ref:
811 def preEnterPath(self, refstr):
814 def showAllServices(self):
815 if not self.pathChangeDisabled:
816 refstr = '%s ORDER BY name'%(self.service_types)
817 if not self.preEnterPath(refstr):
818 ref = eServiceReference(refstr)
819 currentRoot = self.getRoot()
820 if currentRoot is None or currentRoot != ref:
824 def showSatellites(self):
825 if not self.pathChangeDisabled:
826 refstr = '%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types)
827 if not self.preEnterPath(refstr):
828 ref = eServiceReference(refstr)
832 if self.isBasePathEqual(ref):
833 if self.isPrevPathEqual(ref):
835 prev = self.pathUp(justSet)
837 currentRoot = self.getRoot()
838 if currentRoot is None or currentRoot != ref:
841 self.enterPath(ref, True)
843 serviceHandler = eServiceCenter.getInstance()
844 servicelist = serviceHandler.list(ref)
845 if not servicelist is None:
847 service = servicelist.getNext()
848 if not service.valid(): #check if end of list
850 orbpos = service.getUnsignedData(4) >> 16
851 if service.getPath().find("FROM PROVIDER") != -1:
852 service_name = _("Providers")
853 elif service.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
854 service_name = _("New")
856 service_name = _("Services")
858 service_name += str(' - %s'%(nimmanager.getSatDescription(orbpos)))
859 service.setName(service_name) # why we need this cast?
861 if orbpos == 0xFFFF: #Cable
862 n = ("%s (%s)") % (service_name, _("Cable"))
863 elif orbpos == 0xEEEE: #Terrestrial
864 n = ("%s (%s)") % (service_name, _("Terrestrial"))
866 if orbpos > 1800: # west
867 orbpos = 3600 - orbpos
871 n = ("%s (%d.%d" + h + ")") % (service_name, orbpos / 10, orbpos % 10)
873 self.servicelist.addService(service)
874 self.servicelist.finishFill()
876 self.setCurrentSelection(prev)
878 def showProviders(self):
879 if not self.pathChangeDisabled:
880 refstr = '%s FROM PROVIDERS ORDER BY name'%(self.service_types)
881 if not self.preEnterPath(refstr):
882 ref = eServiceReference(refstr)
883 if self.isBasePathEqual(ref):
886 currentRoot = self.getRoot()
887 if currentRoot is None or currentRoot != ref:
891 def changeBouquet(self, direction):
892 if not self.pathChangeDisabled:
893 if len(self.servicePath) > 1:
894 #when enter satellite root list we must do some magic stuff..
895 ref = eServiceReference('%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types))
896 if self.isBasePathEqual(ref):
897 self.showSatellites()
904 ref = self.getCurrentSelection()
908 return self.isBasePathEqual(self.bouquet_root)
911 return self.servicelist.atBegin()
914 return self.servicelist.atEnd()
916 def nextBouquet(self):
917 self.changeBouquet(+1)
919 def prevBouquet(self):
920 self.changeBouquet(-1)
922 def showFavourites(self):
923 if not self.pathChangeDisabled:
924 if not self.preEnterPath(self.bouquet_rootstr):
925 if self.isBasePathEqual(self.bouquet_root):
928 currentRoot = self.getRoot()
929 if currentRoot is None or currentRoot != self.bouquet_root:
931 self.enterPath(self.bouquet_root)
933 def keyNumberGlobal(self, number):
934 unichar = self.numericalTextInput.getKey(number)
935 charstr = unichar.encode("utf-8")
936 if len(charstr) == 1:
937 self.servicelist.moveToChar(charstr[0])
940 return self.servicelist.getRoot()
942 def getCurrentSelection(self):
943 return self.servicelist.getCurrent()
945 def setCurrentSelection(self, service):
946 servicepath = service.getPath()
947 pos = servicepath.find(" FROM BOUQUET")
949 if self.mode == MODE_TV:
950 servicepath = '(type == 1)' + servicepath[pos:]
952 servicepath = '(type == 2)' + servicepath[pos:]
953 service.setPath(servicepath)
954 self.servicelist.setCurrent(service)
956 def getBouquetList(self):
958 serviceHandler = eServiceCenter.getInstance()
959 if config.usage.multibouquet.value:
960 list = serviceHandler.list(self.bouquet_root)
966 if s.flags & eServiceReference.isDirectory:
967 info = serviceHandler.info(s)
969 bouquets.append((info.getName(s), s))
972 info = serviceHandler.info(self.bouquet_root)
974 bouquets.append((info.getName(self.bouquet_root), self.bouquet_root))
978 def keyNumber0(self, num):
979 if len(self.servicePath) > 1:
982 self.keyNumberGlobal(num)
985 if len(self.servicePath) > 1:
986 if self.isBasePathEqual(self.bouquet_root):
987 self.showFavourites()
989 ref = eServiceReference('%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types))
990 if self.isBasePathEqual(ref):
991 self.showSatellites()
993 ref = eServiceReference('%s FROM PROVIDERS ORDER BY name'%(self.service_types))
994 if self.isBasePathEqual(ref):
997 self.showAllServices()
999 def nextMarker(self):
1000 self.servicelist.moveToNextMarker()
1002 def prevMarker(self):
1003 self.servicelist.moveToPrevMarker()
1007 #config for lastservice
1008 config.tv = ConfigSubsection()
1009 config.tv.lastservice = ConfigText()
1010 config.tv.lastroot = ConfigText()
1011 config.radio = ConfigSubsection()
1012 config.radio.lastservice = ConfigText()
1013 config.radio.lastroot = ConfigText()
1014 config.servicelist = ConfigSubsection()
1015 config.servicelist.lastmode = ConfigText(default = "tv")
1017 class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG):
1018 def __init__(self, session):
1019 ChannelSelectionBase.__init__(self,session)
1020 ChannelSelectionEdit.__init__(self)
1021 ChannelSelectionEPG.__init__(self)
1023 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1025 "cancel": self.cancel,
1026 "ok": self.channelSelected,
1027 "keyRadio": self.setModeRadio,
1028 "keyTV": self.setModeTv,
1031 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
1033 iPlayableService.evStart: self.__evServiceStart,
1034 iPlayableService.evEnd: self.__evServiceEnd
1037 self.lastChannelRootTimer = eTimer()
1038 self.lastChannelRootTimer.timeout.get().append(self.__onCreate)
1039 self.lastChannelRootTimer.start(100,True)
1041 self.history_tv = [ ]
1042 self.history_radio = [ ]
1043 self.history = self.history_tv
1044 self.history_pos = 0
1046 self.lastservice = config.tv.lastservice
1047 self.lastroot = config.tv.lastroot
1048 self.revertMode = None
1049 config.usage.multibouquet.addNotifier(self.multibouquet_config_changed)
1051 def multibouquet_config_changed(self, val):
1052 self.recallBouquetMode()
1054 def __evServiceStart(self):
1055 service = self.session.nav.getCurrentService()
1057 info = service.info()
1059 refstr = info.getInfoString(iServiceInformation.sServiceref)
1060 self.servicelist.setPlayableIgnoreService(eServiceReference(refstr))
1062 def __evServiceEnd(self):
1063 self.servicelist.setPlayableIgnoreService(eServiceReference())
1067 lastservice=eServiceReference(self.lastservice.value)
1068 if lastservice.valid():
1069 self.setCurrentSelection(lastservice)
1071 def setModeTv(self):
1072 if self.revertMode is None and config.servicelist.lastmode.value == "radio":
1073 self.revertMode = MODE_RADIO
1074 self.history = self.history_tv
1075 self.lastservice = config.tv.lastservice
1076 self.lastroot = config.tv.lastroot
1077 config.servicelist.lastmode.value = "tv"
1081 def setModeRadio(self):
1082 if self.revertMode is None and config.servicelist.lastmode.value == "tv":
1083 self.revertMode = MODE_TV
1084 if config.usage.e1like_radio_mode.value:
1085 self.history = self.history_radio
1086 self.lastservice = config.radio.lastservice
1087 self.lastroot = config.radio.lastroot
1088 config.servicelist.lastmode.value = "radio"
1092 def __onCreate(self):
1093 if config.usage.e1like_radio_mode.value:
1094 if config.servicelist.lastmode.value == "tv":
1100 lastservice=eServiceReference(self.lastservice.value)
1101 if lastservice.valid():
1104 def channelSelected(self):
1105 ref = self.getCurrentSelection()
1107 self.toggleMoveMarked()
1108 elif (ref.flags & 7) == 7:
1110 elif self.bouquet_mark_edit != OFF:
1111 if not (self.bouquet_mark_edit == EDIT_ALTERNATIVES and ref.flags & eServiceReference.isGroup):
1113 elif not (ref.flags & eServiceReference.isMarker): # no marker
1114 if not (self.getRoot().flags & eServiceReference.isGroup):
1118 #called from infoBar and channelSelected
1120 self.revertMode=None
1121 ref = self.session.nav.getCurrentlyPlayingServiceReference()
1122 nref = self.getCurrentSelection()
1123 if ref is None or ref != nref:
1124 self.session.nav.playService(nref)
1126 self.saveChannel(nref)
1127 config.servicelist.lastmode.save()
1128 self.addToHistory(nref)
1130 def addToHistory(self, ref):
1131 if self.servicePath is not None:
1132 tmp=self.servicePath[:]
1135 del self.history[self.history_pos+1:]
1138 self.history.append(tmp)
1139 hlen = len(self.history)
1140 if hlen > HISTORYSIZE:
1143 self.history_pos = hlen-1
1145 def historyBack(self):
1146 hlen = len(self.history)
1147 if hlen > 1 and self.history_pos > 0:
1148 self.history_pos -= 1
1149 self.setHistoryPath()
1151 def historyNext(self):
1152 hlen = len(self.history)
1153 if hlen > 1 and self.history_pos < (hlen-1):
1154 self.history_pos += 1
1155 self.setHistoryPath()
1157 def setHistoryPath(self):
1158 path = self.history[self.history_pos][:]
1160 del self.servicePath[:]
1161 self.servicePath += path
1165 if self.getRoot() != root:
1167 self.session.nav.playService(ref)
1168 self.setCurrentSelection(ref)
1169 self.saveChannel(ref)
1173 for i in self.servicePath:
1174 path += i.toString()
1176 if len(path) and path != self.lastroot.value:
1177 self.lastroot.value = path
1178 self.lastroot.save()
1180 def restoreRoot(self):
1182 re = compile('.+?;')
1183 tmp = re.findall(self.lastroot.value)
1186 self.servicePath.append(eServiceReference(i[:len(i)-1]))
1189 path = self.servicePath.pop()
1190 self.enterPath(path)
1192 self.showFavourites()
1195 def preEnterPath(self, refstr):
1196 if len(self.servicePath) and self.servicePath[0] != eServiceReference(refstr):
1197 pathstr = self.lastroot.value
1198 if pathstr is not None and pathstr.find(refstr) == 0:
1200 lastservice=eServiceReference(self.lastservice.value)
1201 if lastservice.valid():
1202 self.setCurrentSelection(lastservice)
1206 def saveChannel(self, ref):
1208 refstr = ref.toString()
1211 if refstr != self.lastservice.value:
1212 self.lastservice.value = refstr
1213 self.lastservice.save()
1215 def setCurrentServicePath(self, path):
1216 hlen = len(self.history)
1218 self.history[self.history_pos] = path
1220 self.history.append(path)
1221 self.setHistoryPath()
1223 def getCurrentServicePath(self):
1224 hlen = len(self.history)
1226 return self.history[self.history_pos]
1229 def recallPrevService(self):
1230 hlen = len(self.history)
1232 if self.history_pos == hlen-1:
1233 tmp = self.history[self.history_pos]
1234 self.history[self.history_pos] = self.history[self.history_pos-1]
1235 self.history[self.history_pos-1] = tmp
1237 tmp = self.history[self.history_pos+1]
1238 self.history[self.history_pos+1] = self.history[self.history_pos]
1239 self.history[self.history_pos] = tmp
1240 self.setHistoryPath()
1243 if self.revertMode is None:
1245 lastservice=eServiceReference(self.lastservice.value)
1246 if lastservice.valid() and self.getCurrentSelection() != lastservice:
1247 self.setCurrentSelection(lastservice)
1248 elif self.revertMode == MODE_TV:
1250 elif self.revertMode == MODE_RADIO:
1252 self.revertMode = None
1255 from Screens.InfoBarGenerics import InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord, InfoBarRadioText
1257 class RadioInfoBar(Screen, InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord):
1258 def __init__(self, session):
1259 Screen.__init__(self, session)
1260 InfoBarEvent.__init__(self)
1261 InfoBarServiceName.__init__(self)
1262 InfoBarInstantRecord.__init__(self)
1263 self["CurrentTime"] = Clock()
1265 class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG, InfoBarRadioText):
1267 ALLOW_SUSPEND = True
1269 def __init__(self, session):
1270 ChannelSelectionBase.__init__(self, session)
1271 ChannelSelectionEdit.__init__(self)
1272 ChannelSelectionEPG.__init__(self)
1273 InfoBarRadioText.__init__(self)
1275 config.radio = ConfigSubsection();
1276 config.radio.lastservice = ConfigText()
1277 config.radio.lastroot = ConfigText()
1278 self.onLayoutFinish.append(self.onCreate)
1280 self.info = session.instantiateDialog(RadioInfoBar)
1282 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1284 "keyTV": self.closeRadio,
1285 "keyRadio": self.closeRadio,
1286 "cancel": self.closeRadio,
1287 "ok": self.channelSelected,
1290 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
1292 iPlayableService.evStart: self.__evServiceStart,
1293 iPlayableService.evEnd: self.__evServiceEnd
1296 def __evServiceStart(self):
1297 service = self.session.nav.getCurrentService()
1299 info = service.info()
1301 refstr = info.getInfoString(iServiceInformation.sServiceref)
1302 self.servicelist.setPlayableIgnoreService(eServiceReference(refstr))
1304 def __evServiceEnd(self):
1305 self.servicelist.setPlayableIgnoreService(eServiceReference())
1309 for i in self.servicePathRadio:
1310 path += i.toString()
1312 if len(path) and path != config.radio.lastroot.value:
1313 config.radio.lastroot.value = path
1314 config.radio.lastroot.save()
1316 def restoreRoot(self):
1318 re = compile('.+?;')
1319 tmp = re.findall(config.radio.lastroot.value)
1322 self.servicePathRadio.append(eServiceReference(i[:len(i)-1]))
1325 path = self.servicePathRadio.pop()
1326 self.enterPath(path)
1328 self.showFavourites()
1331 def preEnterPath(self, refstr):
1332 if len(self.servicePathRadio) and self.servicePathRadio[0] != eServiceReference(refstr):
1333 pathstr = config.radio.lastroot.value
1334 if pathstr is not None and pathstr.find(refstr) == 0:
1336 lastservice=eServiceReference(config.radio.lastservice.value)
1337 if lastservice.valid():
1338 self.setCurrentSelection(lastservice)
1345 lastservice=eServiceReference(config.radio.lastservice.value)
1346 if lastservice.valid():
1347 self.servicelist.setCurrent(lastservice)
1348 self.session.nav.playService(lastservice)
1351 def channelSelected(self): # just return selected service
1352 ref = self.getCurrentSelection()
1354 self.toggleMoveMarked()
1355 elif (ref.flags & 7) == 7:
1357 elif self.bouquet_mark_edit != OFF:
1358 if not (self.bouquet_mark_edit == EDIT_ALTERNATIVES and ref.flags & eServiceReference.isGroup):
1360 elif not (ref.flags & eServiceReference.isMarker): # no marker
1361 if not (self.getRoot().flags & eServiceReference.isGroup):
1362 playingref = self.session.nav.getCurrentlyPlayingServiceReference()
1363 if playingref is None or playingref != ref:
1364 self.session.nav.playService(ref)
1365 config.radio.lastservice.value = ref.toString()
1366 config.radio.lastservice.save()
1369 def closeRadio(self):
1371 #set previous tv service
1372 lastservice=eServiceReference(config.tv.lastservice.value)
1373 self.session.nav.playService(lastservice)
1376 class SimpleChannelSelection(ChannelSelectionBase):
1377 def __init__(self, session, title):
1378 ChannelSelectionBase.__init__(self, session)
1380 self.onShown.append(self.__onExecCallback)
1382 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1384 "cancel": self.close,
1385 "ok": self.channelSelected,
1386 "keyRadio": self.setModeRadio,
1387 "keyTV": self.setModeTv,
1390 def __onExecCallback(self):
1391 self.setTitle(self.title)
1394 def channelSelected(self): # just return selected service
1395 ref = self.getCurrentSelection()
1396 if (ref.flags & 7) == 7:
1398 elif not (ref.flags & eServiceReference.isMarker):
1399 ref = self.getCurrentSelection()
1402 def setModeTv(self):
1404 self.showFavourites()
1406 def setModeRadio(self):
1408 self.showFavourites()