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 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 current_root 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 root = self.getRoot()
355 cur_root = root and ServiceReference(root)
356 mutableBouquet = cur_root.list().startEdit()
358 name = cur_service.getServiceName()
360 if self.mode == MODE_TV:
361 str = '1:134:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET \"alternatives.%s.tv\" ORDER BY bouquet'%(self.buildBouquetID(name))
363 str = '1:134:2:0:0:0:0:0:0:0:(type == 2) FROM BOUQUET \"alternatives.%s.radio\" ORDER BY bouquet'%(self.buildBouquetID(name))
364 new_ref = ServiceReference(str)
365 if not mutableBouquet.addService(new_ref.ref, cur_service.ref):
366 mutableBouquet.removeService(cur_service.ref)
367 mutableBouquet.flushChanges()
368 eDVBDB.getInstance().reloadBouquets()
369 mutableAlternatives = new_ref.list().startEdit()
370 if mutableAlternatives:
371 mutableAlternatives.setListName(name)
372 if mutableAlternatives.addService(cur_service.ref):
373 print "add", cur_service.toString(), "to new alternatives failed"
374 mutableAlternatives.flushChanges()
375 self.servicelist.addService(new_ref.ref, True)
376 self.servicelist.removeCurrent()
377 self.servicelist.moveUp()
379 print "get mutable list for new created alternatives failed"
381 print "add", str, "to", cur_root.getServiceName(), "failed"
383 print "bouquetlist is not editable"
385 def addBouquet(self, bName, services):
386 serviceHandler = eServiceCenter.getInstance()
387 mutableBouquetList = serviceHandler.list(self.bouquet_root).startEdit()
388 if mutableBouquetList:
389 if self.mode == MODE_TV:
391 str = '1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET \"userbouquet.%s.tv\" ORDER BY bouquet'%(self.buildBouquetID(bName))
394 str = '1:7:2:0:0:0:0:0:0:0:(type == 2) FROM BOUQUET \"userbouquet.%s.radio\" ORDER BY bouquet'%(self.buildBouquetID(bName))
395 new_bouquet_ref = eServiceReference(str)
396 if not mutableBouquetList.addService(new_bouquet_ref):
397 mutableBouquetList.flushChanges()
398 eDVBDB.getInstance().reloadBouquets()
399 mutableBouquet = serviceHandler.list(new_bouquet_ref).startEdit()
401 mutableBouquet.setListName(bName)
402 if services is not None:
403 for service in services:
404 if mutableBouquet.addService(service):
405 print "add", service.toString(), "to new bouquet failed"
406 mutableBouquet.flushChanges()
408 print "get mutable list for new created bouquet failed"
409 # do some voodoo to check if current_root is equal to bouquet_root
410 cur_root = self.getRoot();
411 str1 = cur_root and cur_root.toString()
412 pos1 = str1 and str1.find("FROM BOUQUET") or -1
413 pos2 = self.bouquet_rootstr.find("FROM BOUQUET")
414 if pos1 != -1 and pos2 != -1 and str1[pos1:] == self.bouquet_rootstr[pos2:]:
415 self.servicelist.addService(new_bouquet_ref)
417 print "add", str, "to bouquets failed"
419 print "bouquetlist is not editable"
421 def copyCurrentToBouquetList(self):
422 provider = ServiceReference(self.getCurrentSelection())
423 providerName = provider.getServiceName()
424 serviceHandler = eServiceCenter.getInstance()
425 services = serviceHandler.list(provider.ref)
426 self.addBouquet(providerName, services and services.getContent('R', True))
428 def removeAlternativeServices(self):
429 cur_service = ServiceReference(self.getCurrentSelection())
430 root = self.getRoot()
431 cur_root = root and ServiceReference(root)
432 list = cur_service.list()
433 first_in_alternative = list and list.getNext()
434 if first_in_alternative:
435 edit_root = cur_root and cur_root.list().startEdit()
437 if not edit_root.addService(first_in_alternative, cur_service.ref):
438 self.servicelist.addService(first_in_alternative, True)
440 print "couldn't add first alternative service to current root"
442 print "couldn't edit current root!!"
444 print "remove empty alternative list !!"
446 self.servicelist.moveUp()
448 def removeBouquet(self):
449 refstr = self.getCurrentSelection().toString()
450 print "removeBouquet", refstr
451 self.bouquetNumOffsetCache = { }
452 pos = refstr.find('FROM BOUQUET "')
455 refstr = refstr[pos+14:]
456 pos = refstr.find('"')
458 filename = '/etc/enigma2/' + refstr[:pos] # FIXMEEE !!! HARDCODED /etc/enigma2
459 self.removeCurrentService()
461 if filename is not None:
464 print "error during remove of", filename
466 # multiple marked entry stuff ( edit mode, later multiepg selection )
467 def startMarkedEdit(self, type):
468 self.savedPath = self.servicePath[:]
469 if type == EDIT_ALTERNATIVES:
470 self.enterPath(self.getCurrentSelection())
471 self.mutableList = self.getMutableList()
472 # add all services from the current list to internal marked set in listboxservicecontent
473 self.clearMarks() # this clears the internal marked set in the listboxservicecontent
474 self.saved_title = self.instance.getTitle()
475 pos = self.saved_title.find(')')
476 new_title = self.saved_title[:pos+1]
477 if type == EDIT_ALTERNATIVES:
478 self.bouquet_mark_edit = EDIT_ALTERNATIVES
479 new_title += ' ' + _("[alternative edit]")
481 self.bouquet_mark_edit = EDIT_BOUQUET
482 if config.usage.multibouquet.value:
483 new_title += ' ' + _("[bouquet edit]")
485 new_title += ' ' + _("[favourite edit]")
486 self.setTitle(new_title)
487 self.__marked = self.servicelist.getRootServices()
488 for x in self.__marked:
489 self.servicelist.addMarked(eServiceReference(x))
490 self.showAllServices()
492 def endMarkedEdit(self, abort):
493 if not abort and self.mutableList is not None:
494 self.bouquetNumOffsetCache = { }
495 new_marked = set(self.servicelist.getMarked())
496 old_marked = set(self.__marked)
497 removed = old_marked - new_marked
498 added = new_marked - old_marked
502 self.mutableList.removeService(eServiceReference(x))
505 self.mutableList.addService(eServiceReference(x))
507 self.mutableList.flushChanges()
510 self.bouquet_mark_edit = OFF
511 self.mutableList = None
512 self.setTitle(self.saved_title)
513 self.saved_title = None
514 # self.servicePath is just a reference to servicePathTv or Radio...
515 # so we never ever do use the asignment operator in self.servicePath
516 del self.servicePath[:] # remove all elements
517 self.servicePath += self.savedPath # add saved elements
519 self.setRoot(self.servicePath[len(self.servicePath)-1])
521 def clearMarks(self):
522 self.servicelist.clearMarks()
525 ref = self.servicelist.getCurrent()
526 if self.servicelist.isMarked(ref):
527 self.servicelist.removeMarked(ref)
529 self.servicelist.addMarked(ref)
531 def removeCurrentService(self):
532 ref = self.servicelist.getCurrent()
533 mutableList = self.getMutableList()
534 if ref.valid() and mutableList is not None:
535 if not mutableList.removeService(ref):
536 self.bouquetNumOffsetCache = { }
537 mutableList.flushChanges() #FIXME dont flush on each single removed service
538 self.servicelist.removeCurrent()
540 def addServiceToBouquet(self, dest, service=None):
541 mutableList = self.getMutableList(dest)
542 if not mutableList is None:
543 if service is None: #use current selected service
544 service = self.servicelist.getCurrent()
545 if not mutableList.addService(service):
546 self.bouquetNumOffsetCache = { }
547 mutableList.flushChanges()
548 # do some voodoo to check if current_root is equal to dest
549 cur_root = self.getRoot();
550 str1 = cur_root and cur_root.toString() or -1
551 str2 = dest.toString()
552 pos1 = str1.find("FROM BOUQUET")
553 pos2 = str2.find("FROM BOUQUET")
554 if pos1 != -1 and pos2 != -1 and str1[pos1:] == str2[pos2:]:
555 self.servicelist.addService(service)
557 def toggleMoveMode(self):
559 if self.entry_marked:
560 self.toggleMoveMarked() # unmark current entry
561 self.movemode = False
562 self.pathChangeDisabled = False # re-enable path change
563 self.mutableList.flushChanges() # FIXME add check if changes was made
564 self.mutableList = None
565 self.setTitle(self.saved_title)
566 self.saved_title = None
567 cur_root = self.getRoot()
568 if cur_root and cur_root == self.bouquet_root:
569 self.bouquetNumOffsetCache = { }
571 self.mutableList = self.getMutableList()
573 self.pathChangeDisabled = True # no path change allowed in movemode
574 self.saved_title = self.instance.getTitle()
575 new_title = self.saved_title
576 pos = self.saved_title.find(')')
577 new_title = self.saved_title[:pos+1] + ' ' + _("[move mode]") + self.saved_title[pos+1:]
578 self.setTitle(new_title);
580 def handleEditCancel(self):
581 if self.movemode: #movemode active?
582 self.channelSelected() # unmark
583 self.toggleMoveMode() # disable move mode
584 elif self.bouquet_mark_edit != OFF:
585 self.endMarkedEdit(True) # abort edit mode
587 def toggleMoveMarked(self):
588 if self.entry_marked:
589 self.servicelist.setCurrentMarked(False)
590 self.entry_marked = False
592 self.servicelist.setCurrentMarked(True)
593 self.entry_marked = True
596 self.session.open(ChannelContextMenu, self)
601 # this makes it much simple to implement a selectable radio or tv mode :)
602 service_types_tv = '1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17) || (type == 195) || (type == 25)'
603 service_types_radio = '1:7:2:0:0:0:0:0:0:0:(type == 2)'
605 class ChannelSelectionBase(Screen):
606 def __init__(self, session):
607 Screen.__init__(self, session)
609 self["key_red"] = Button(_("All"))
610 self["key_green"] = Button(_("Satellites"))
611 self["key_yellow"] = Button(_("Provider"))
612 self["key_blue"] = Button(_("Favourites"))
614 self["list"] = ServiceList()
615 self.servicelist = self["list"]
617 self.numericalTextInput = NumericalTextInput()
618 self.numericalTextInput.setUseableChars(u'1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ')
620 self.servicePathTV = [ ]
621 self.servicePathRadio = [ ]
622 self.servicePath = [ ]
626 self.pathChangeDisabled = False
628 self.bouquetNumOffsetCache = { }
630 self["ChannelSelectBaseActions"] = NumberActionMap(["ChannelSelectBaseActions", "NumberActions"],
632 "showFavourites": self.showFavourites,
633 "showAllServices": self.showAllServices,
634 "showProviders": self.showProviders,
635 "showSatellites": self.showSatellites,
636 "nextBouquet": self.nextBouquet,
637 "prevBouquet": self.prevBouquet,
638 "nextMarker": self.nextMarker,
639 "prevMarker": self.prevMarker,
640 "1": self.keyNumberGlobal,
641 "2": self.keyNumberGlobal,
642 "3": self.keyNumberGlobal,
643 "4": self.keyNumberGlobal,
644 "5": self.keyNumberGlobal,
645 "6": self.keyNumberGlobal,
646 "7": self.keyNumberGlobal,
647 "8": self.keyNumberGlobal,
648 "9": self.keyNumberGlobal,
651 self.recallBouquetMode()
653 def getBouquetNumOffset(self, bouquet):
654 if not config.usage.multibouquet.value:
656 str = bouquet.toString()
658 if not self.bouquetNumOffsetCache.has_key(str):
659 serviceHandler = eServiceCenter.getInstance()
660 bouquetlist = serviceHandler.list(self.bouquet_root)
661 if not bouquetlist is None:
663 bouquetIterator = bouquetlist.getNext()
664 if not bouquetIterator.valid(): #end of list
666 self.bouquetNumOffsetCache[bouquetIterator.toString()]=offsetCount
667 if not (bouquetIterator.flags & eServiceReference.isDirectory):
669 servicelist = serviceHandler.list(bouquetIterator)
670 if not servicelist is None:
672 serviceIterator = servicelist.getNext()
673 if not serviceIterator.valid(): #check if end of list
675 playable = not (serviceIterator.flags & (eServiceReference.isDirectory|eServiceReference.isMarker))
678 return self.bouquetNumOffsetCache.get(str, offsetCount)
680 def recallBouquetMode(self):
681 if self.mode == MODE_TV:
682 self.service_types = service_types_tv
683 if config.usage.multibouquet.value:
684 self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "bouquets.tv" ORDER BY bouquet'
686 self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.tv" ORDER BY bouquet'%(self.service_types)
688 self.service_types = service_types_radio
689 if config.usage.multibouquet.value:
690 self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "bouquets.radio" ORDER BY bouquet'
692 self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.radio" ORDER BY bouquet'%(self.service_types)
693 self.bouquet_root = eServiceReference(self.bouquet_rootstr)
697 self.servicePath = self.servicePathTV
698 self.recallBouquetMode()
699 title = self.instance.getTitle()
700 pos = title.find(" (")
706 def setRadioMode(self):
707 self.mode = MODE_RADIO
708 self.servicePath = self.servicePathRadio
709 self.recallBouquetMode()
710 title = self.instance.getTitle()
711 pos = title.find(" (")
717 def setRoot(self, root, justSet=False):
718 path = root.getPath()
719 inBouquetRootList = path.find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
720 pos = path.find('FROM BOUQUET')
721 isBouquet = (pos != -1) and (root.flags & eServiceReference.isDirectory)
722 if not inBouquetRootList and isBouquet:
723 self.servicelist.setMode(ServiceList.MODE_FAVOURITES)
724 self.servicelist.setNumberOffset(self.getBouquetNumOffset(root))
726 self.servicelist.setMode(ServiceList.MODE_NORMAL)
727 self.servicelist.setRoot(root, justSet)
728 self.buildTitleString()
730 def removeModeStr(self, str):
731 if self.mode == MODE_TV:
732 pos = str.find(' (TV)')
734 pos = str.find(' (Radio)')
739 def getServiceName(self, ref):
740 str = self.removeModeStr(ServiceReference(ref).getServiceName())
742 pathstr = ref.getPath()
743 if pathstr.find('FROM PROVIDERS') != -1:
745 if pathstr.find('FROM SATELLITES') != -1:
746 return _("Satellites")
747 if pathstr.find(') ORDER BY name') != -1:
751 def buildTitleString(self):
752 titleStr = self.instance.getTitle()
753 pos = titleStr.find(']')
755 pos = titleStr.find(')')
757 titleStr = titleStr[:pos+1]
758 Len = len(self.servicePath)
760 base_ref = self.servicePath[0]
762 end_ref = self.servicePath[Len-1]
765 nameStr = self.getServiceName(base_ref)
766 titleStr += ' ' + nameStr
767 if end_ref is not None:
772 nameStr = self.getServiceName(end_ref)
774 self.setTitle(titleStr)
777 self.servicelist.moveUp()
780 self.servicelist.moveDown()
783 del self.servicePath[:]
785 def enterPath(self, ref, justSet=False):
786 self.servicePath.append(ref)
787 self.setRoot(ref, justSet)
789 def pathUp(self, justSet=False):
790 prev = self.servicePath.pop()
791 length = len(self.servicePath)
793 current = self.servicePath[length-1]
794 self.setRoot(current, justSet)
796 self.setCurrentSelection(prev)
799 def isBasePathEqual(self, ref):
800 if len(self.servicePath) > 1 and self.servicePath[0] == ref:
804 def isPrevPathEqual(self, ref):
805 length = len(self.servicePath)
806 if length > 1 and self.servicePath[length-2] == ref:
810 def preEnterPath(self, refstr):
813 def showAllServices(self):
814 if not self.pathChangeDisabled:
815 refstr = '%s ORDER BY name'%(self.service_types)
816 if not self.preEnterPath(refstr):
817 ref = eServiceReference(refstr)
818 currentRoot = self.getRoot()
819 if currentRoot is None or currentRoot != ref:
823 def showSatellites(self):
824 if not self.pathChangeDisabled:
825 refstr = '%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types)
826 if not self.preEnterPath(refstr):
827 ref = eServiceReference(refstr)
831 if self.isBasePathEqual(ref):
832 if self.isPrevPathEqual(ref):
834 prev = self.pathUp(justSet)
836 currentRoot = self.getRoot()
837 if currentRoot is None or currentRoot != ref:
840 self.enterPath(ref, True)
842 serviceHandler = eServiceCenter.getInstance()
843 servicelist = serviceHandler.list(ref)
844 if not servicelist is None:
846 service = servicelist.getNext()
847 if not service.valid(): #check if end of list
849 orbpos = service.getUnsignedData(4) >> 16
850 if service.getPath().find("FROM PROVIDER") != -1:
851 service_name = _("Providers")
852 elif service.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
853 service_name = _("New")
855 service_name = _("Services")
857 service_name += str(' - %s'%(nimmanager.getSatDescription(orbpos)))
858 service.setName(service_name) # why we need this cast?
860 if orbpos == 0xFFFF: #Cable
861 n = ("%s (%s)") % (service_name, _("Cable"))
862 elif orbpos == 0xEEEE: #Terrestrial
863 n = ("%s (%s)") % (service_name, _("Terrestrial"))
865 if orbpos > 1800: # west
866 orbpos = 3600 - orbpos
870 n = ("%s (%d.%d" + h + ")") % (service_name, orbpos / 10, orbpos % 10)
872 self.servicelist.addService(service)
873 self.servicelist.finishFill()
875 self.setCurrentSelection(prev)
877 def showProviders(self):
878 if not self.pathChangeDisabled:
879 refstr = '%s FROM PROVIDERS ORDER BY name'%(self.service_types)
880 if not self.preEnterPath(refstr):
881 ref = eServiceReference(refstr)
882 if self.isBasePathEqual(ref):
885 currentRoot = self.getRoot()
886 if currentRoot is None or currentRoot != ref:
890 def changeBouquet(self, direction):
891 if not self.pathChangeDisabled:
892 if len(self.servicePath) > 1:
893 #when enter satellite root list we must do some magic stuff..
894 ref = eServiceReference('%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types))
895 if self.isBasePathEqual(ref):
896 self.showSatellites()
903 ref = self.getCurrentSelection()
907 return self.isBasePathEqual(self.bouquet_root)
910 return self.servicelist.atBegin()
913 return self.servicelist.atEnd()
915 def nextBouquet(self):
916 self.changeBouquet(+1)
918 def prevBouquet(self):
919 self.changeBouquet(-1)
921 def showFavourites(self):
922 if not self.pathChangeDisabled:
923 if not self.preEnterPath(self.bouquet_rootstr):
924 if self.isBasePathEqual(self.bouquet_root):
927 currentRoot = self.getRoot()
928 if currentRoot is None or currentRoot != self.bouquet_root:
930 self.enterPath(self.bouquet_root)
932 def keyNumberGlobal(self, number):
933 unichar = self.numericalTextInput.getKey(number)
934 charstr = unichar.encode("utf-8")
935 if len(charstr) == 1:
936 self.servicelist.moveToChar(charstr[0])
939 return self.servicelist.getRoot()
941 def getCurrentSelection(self):
942 return self.servicelist.getCurrent()
944 def setCurrentSelection(self, service):
945 servicepath = service.getPath()
946 pos = servicepath.find(" FROM BOUQUET")
948 if self.mode == MODE_TV:
949 servicepath = '(type == 1)' + servicepath[pos:]
951 servicepath = '(type == 2)' + servicepath[pos:]
952 service.setPath(servicepath)
953 self.servicelist.setCurrent(service)
955 def getBouquetList(self):
957 serviceHandler = eServiceCenter.getInstance()
958 if config.usage.multibouquet.value:
959 list = serviceHandler.list(self.bouquet_root)
965 if s.flags & eServiceReference.isDirectory:
966 info = serviceHandler.info(s)
968 bouquets.append((info.getName(s), s))
971 info = serviceHandler.info(self.bouquet_root)
973 bouquets.append((info.getName(self.bouquet_root), self.bouquet_root))
977 def keyNumber0(self, num):
978 if len(self.servicePath) > 1:
981 self.keyNumberGlobal(num)
984 if len(self.servicePath) > 1:
985 if self.isBasePathEqual(self.bouquet_root):
986 self.showFavourites()
988 ref = eServiceReference('%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types))
989 if self.isBasePathEqual(ref):
990 self.showSatellites()
992 ref = eServiceReference('%s FROM PROVIDERS ORDER BY name'%(self.service_types))
993 if self.isBasePathEqual(ref):
996 self.showAllServices()
998 def nextMarker(self):
999 self.servicelist.moveToNextMarker()
1001 def prevMarker(self):
1002 self.servicelist.moveToPrevMarker()
1006 #config for lastservice
1007 config.tv = ConfigSubsection()
1008 config.tv.lastservice = ConfigText()
1009 config.tv.lastroot = ConfigText()
1010 config.radio = ConfigSubsection()
1011 config.radio.lastservice = ConfigText()
1012 config.radio.lastroot = ConfigText()
1013 config.servicelist = ConfigSubsection()
1014 config.servicelist.lastmode = ConfigText(default = "tv")
1016 class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG):
1017 def __init__(self, session):
1018 ChannelSelectionBase.__init__(self,session)
1019 ChannelSelectionEdit.__init__(self)
1020 ChannelSelectionEPG.__init__(self)
1022 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1024 "cancel": self.cancel,
1025 "ok": self.channelSelected,
1026 "keyRadio": self.setModeRadio,
1027 "keyTV": self.setModeTv,
1030 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
1032 iPlayableService.evStart: self.__evServiceStart,
1033 iPlayableService.evEnd: self.__evServiceEnd
1036 self.lastChannelRootTimer = eTimer()
1037 self.lastChannelRootTimer.timeout.get().append(self.__onCreate)
1038 self.lastChannelRootTimer.start(100,True)
1040 self.history_tv = [ ]
1041 self.history_radio = [ ]
1042 self.history = self.history_tv
1043 self.history_pos = 0
1045 self.lastservice = config.tv.lastservice
1046 self.lastroot = config.tv.lastroot
1047 self.revertMode = None
1048 config.usage.multibouquet.addNotifier(self.multibouquet_config_changed)
1050 def multibouquet_config_changed(self, val):
1051 self.recallBouquetMode()
1053 def __evServiceStart(self):
1054 service = self.session.nav.getCurrentService()
1056 info = service.info()
1058 refstr = info.getInfoString(iServiceInformation.sServiceref)
1059 self.servicelist.setPlayableIgnoreService(eServiceReference(refstr))
1061 def __evServiceEnd(self):
1062 self.servicelist.setPlayableIgnoreService(eServiceReference())
1066 lastservice=eServiceReference(self.lastservice.value)
1067 if lastservice.valid():
1068 self.setCurrentSelection(lastservice)
1070 def setModeTv(self):
1071 if self.revertMode is None and config.servicelist.lastmode.value == "radio":
1072 self.revertMode = MODE_RADIO
1073 self.history = self.history_tv
1074 self.lastservice = config.tv.lastservice
1075 self.lastroot = config.tv.lastroot
1076 config.servicelist.lastmode.value = "tv"
1080 def setModeRadio(self):
1081 if self.revertMode is None and config.servicelist.lastmode.value == "tv":
1082 self.revertMode = MODE_TV
1083 if config.usage.e1like_radio_mode.value:
1084 self.history = self.history_radio
1085 self.lastservice = config.radio.lastservice
1086 self.lastroot = config.radio.lastroot
1087 config.servicelist.lastmode.value = "radio"
1091 def __onCreate(self):
1092 if config.usage.e1like_radio_mode.value:
1093 if config.servicelist.lastmode.value == "tv":
1099 lastservice=eServiceReference(self.lastservice.value)
1100 if lastservice.valid():
1103 def channelSelected(self):
1104 ref = self.getCurrentSelection()
1106 self.toggleMoveMarked()
1107 elif (ref.flags & 7) == 7:
1109 elif self.bouquet_mark_edit != OFF:
1110 if not (self.bouquet_mark_edit == EDIT_ALTERNATIVES and ref.flags & eServiceReference.isGroup):
1112 elif not (ref.flags & eServiceReference.isMarker): # no marker
1113 root = self.getRoot()
1114 if not root or not (root.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 cur_root = self.getRoot()
1166 if cur_root and cur_root != root:
1168 self.session.nav.playService(ref)
1169 self.setCurrentSelection(ref)
1170 self.saveChannel(ref)
1174 for i in self.servicePath:
1175 path += i.toString()
1177 if len(path) and path != self.lastroot.value:
1178 self.lastroot.value = path
1179 self.lastroot.save()
1181 def restoreRoot(self):
1183 re = compile('.+?;')
1184 tmp = re.findall(self.lastroot.value)
1187 self.servicePath.append(eServiceReference(i[:len(i)-1]))
1190 path = self.servicePath.pop()
1191 self.enterPath(path)
1193 self.showFavourites()
1196 def preEnterPath(self, refstr):
1197 if len(self.servicePath) and self.servicePath[0] != eServiceReference(refstr):
1198 pathstr = self.lastroot.value
1199 if pathstr is not None and pathstr.find(refstr) == 0:
1201 lastservice=eServiceReference(self.lastservice.value)
1202 if lastservice.valid():
1203 self.setCurrentSelection(lastservice)
1207 def saveChannel(self, ref):
1209 refstr = ref.toString()
1212 if refstr != self.lastservice.value:
1213 self.lastservice.value = refstr
1214 self.lastservice.save()
1216 def setCurrentServicePath(self, path):
1217 hlen = len(self.history)
1219 self.history[self.history_pos] = path
1221 self.history.append(path)
1222 self.setHistoryPath()
1224 def getCurrentServicePath(self):
1225 hlen = len(self.history)
1227 return self.history[self.history_pos]
1230 def recallPrevService(self):
1231 hlen = len(self.history)
1233 if self.history_pos == hlen-1:
1234 tmp = self.history[self.history_pos]
1235 self.history[self.history_pos] = self.history[self.history_pos-1]
1236 self.history[self.history_pos-1] = tmp
1238 tmp = self.history[self.history_pos+1]
1239 self.history[self.history_pos+1] = self.history[self.history_pos]
1240 self.history[self.history_pos] = tmp
1241 self.setHistoryPath()
1244 if self.revertMode is None:
1246 lastservice=eServiceReference(self.lastservice.value)
1247 if lastservice.valid() and self.getCurrentSelection() != lastservice:
1248 self.setCurrentSelection(lastservice)
1249 elif self.revertMode == MODE_TV:
1251 elif self.revertMode == MODE_RADIO:
1253 self.revertMode = None
1256 from Screens.InfoBarGenerics import InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord, InfoBarRadioText
1258 class RadioInfoBar(Screen, InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord):
1259 def __init__(self, session):
1260 Screen.__init__(self, session)
1261 InfoBarEvent.__init__(self)
1262 InfoBarServiceName.__init__(self)
1263 InfoBarInstantRecord.__init__(self)
1264 self["CurrentTime"] = Clock()
1266 class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG, InfoBarRadioText):
1268 ALLOW_SUSPEND = True
1270 def __init__(self, session):
1271 ChannelSelectionBase.__init__(self, session)
1272 ChannelSelectionEdit.__init__(self)
1273 ChannelSelectionEPG.__init__(self)
1274 InfoBarRadioText.__init__(self)
1276 config.radio = ConfigSubsection();
1277 config.radio.lastservice = ConfigText()
1278 config.radio.lastroot = ConfigText()
1279 self.onLayoutFinish.append(self.onCreate)
1281 self.info = session.instantiateDialog(RadioInfoBar)
1283 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1285 "keyTV": self.closeRadio,
1286 "keyRadio": self.closeRadio,
1287 "cancel": self.closeRadio,
1288 "ok": self.channelSelected,
1291 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
1293 iPlayableService.evStart: self.__evServiceStart,
1294 iPlayableService.evEnd: self.__evServiceEnd
1297 def __evServiceStart(self):
1298 service = self.session.nav.getCurrentService()
1300 info = service.info()
1302 refstr = info.getInfoString(iServiceInformation.sServiceref)
1303 self.servicelist.setPlayableIgnoreService(eServiceReference(refstr))
1305 def __evServiceEnd(self):
1306 self.servicelist.setPlayableIgnoreService(eServiceReference())
1310 for i in self.servicePathRadio:
1311 path += i.toString()
1313 if len(path) and path != config.radio.lastroot.value:
1314 config.radio.lastroot.value = path
1315 config.radio.lastroot.save()
1317 def restoreRoot(self):
1319 re = compile('.+?;')
1320 tmp = re.findall(config.radio.lastroot.value)
1323 self.servicePathRadio.append(eServiceReference(i[:len(i)-1]))
1326 path = self.servicePathRadio.pop()
1327 self.enterPath(path)
1329 self.showFavourites()
1332 def preEnterPath(self, refstr):
1333 if len(self.servicePathRadio) and self.servicePathRadio[0] != eServiceReference(refstr):
1334 pathstr = config.radio.lastroot.value
1335 if pathstr is not None and pathstr.find(refstr) == 0:
1337 lastservice=eServiceReference(config.radio.lastservice.value)
1338 if lastservice.valid():
1339 self.setCurrentSelection(lastservice)
1346 lastservice=eServiceReference(config.radio.lastservice.value)
1347 if lastservice.valid():
1348 self.servicelist.setCurrent(lastservice)
1349 self.session.nav.playService(lastservice)
1352 def channelSelected(self): # just return selected service
1353 ref = self.getCurrentSelection()
1355 self.toggleMoveMarked()
1356 elif (ref.flags & 7) == 7:
1358 elif self.bouquet_mark_edit != OFF:
1359 if not (self.bouquet_mark_edit == EDIT_ALTERNATIVES and ref.flags & eServiceReference.isGroup):
1361 elif not (ref.flags & eServiceReference.isMarker): # no marker
1362 cur_root = self.getRoot()
1363 if not cur_root or not (cur_root.flags & eServiceReference.isGroup):
1364 playingref = self.session.nav.getCurrentlyPlayingServiceReference()
1365 if playingref is None or playingref != ref:
1366 self.session.nav.playService(ref)
1367 config.radio.lastservice.value = ref.toString()
1368 config.radio.lastservice.save()
1371 def closeRadio(self):
1373 #set previous tv service
1374 lastservice=eServiceReference(config.tv.lastservice.value)
1375 self.session.nav.playService(lastservice)
1378 class SimpleChannelSelection(ChannelSelectionBase):
1379 def __init__(self, session, title):
1380 ChannelSelectionBase.__init__(self, session)
1382 self.onShown.append(self.__onExecCallback)
1384 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1386 "cancel": self.close,
1387 "ok": self.channelSelected,
1388 "keyRadio": self.setModeRadio,
1389 "keyTV": self.setModeTv,
1392 def __onExecCallback(self):
1393 self.setTitle(self.title)
1396 def channelSelected(self): # just return selected service
1397 ref = self.getCurrentSelection()
1398 if (ref.flags & 7) == 7:
1400 elif not (ref.flags & eServiceReference.isMarker):
1401 ref = self.getCurrentSelection()
1404 def setModeTv(self):
1406 self.showFavourites()
1408 def setModeRadio(self):
1410 self.showFavourites()