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 appendDVBTypes(self, ref):
655 pos = path.find(' FROM BOUQUET')
657 return eServiceReference(self.service_types + path[pos:])
660 def getBouquetNumOffset(self, bouquet):
661 if not config.usage.multibouquet.value:
663 bouquet = self.appendDVBTypes(bouquet)
664 str = bouquet.toString()
666 if not self.bouquetNumOffsetCache.has_key(str):
667 serviceHandler = eServiceCenter.getInstance()
668 bouquetlist = serviceHandler.list(self.bouquet_root)
669 if not bouquetlist is None:
671 bouquetIterator = self.appendDVBTypes(bouquetlist.getNext())
672 if not bouquetIterator.valid(): #end of list
674 self.bouquetNumOffsetCache[bouquetIterator.toString()]=offsetCount
675 if not (bouquetIterator.flags & eServiceReference.isDirectory):
677 servicelist = serviceHandler.list(bouquetIterator)
678 if not servicelist is None:
680 serviceIterator = servicelist.getNext()
681 if not serviceIterator.valid(): #check if end of list
683 playable = not (serviceIterator.flags & (eServiceReference.isDirectory|eServiceReference.isMarker))
686 return self.bouquetNumOffsetCache.get(str, offsetCount)
688 def recallBouquetMode(self):
689 if self.mode == MODE_TV:
690 self.service_types = service_types_tv
691 if config.usage.multibouquet.value:
692 self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET "bouquets.tv" ORDER BY bouquet'
694 self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.tv" ORDER BY bouquet'%(self.service_types)
696 self.service_types = service_types_radio
697 if config.usage.multibouquet.value:
698 self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET "bouquets.radio" ORDER BY bouquet'
700 self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.radio" ORDER BY bouquet'%(self.service_types)
701 self.bouquet_root = eServiceReference(self.bouquet_rootstr)
705 self.servicePath = self.servicePathTV
706 self.recallBouquetMode()
707 title = self.instance.getTitle()
708 pos = title.find(" (")
714 def setRadioMode(self):
715 self.mode = MODE_RADIO
716 self.servicePath = self.servicePathRadio
717 self.recallBouquetMode()
718 title = self.instance.getTitle()
719 pos = title.find(" (")
725 def setRoot(self, root, justSet=False):
726 path = root.getPath()
727 inBouquetRootList = path.find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
728 pos = path.find(' FROM BOUQUET')
729 isBouquet = (pos != -1) and (root.flags & eServiceReference.isDirectory)
730 if not inBouquetRootList and isBouquet:
731 self.servicelist.setMode(ServiceList.MODE_FAVOURITES)
732 self.servicelist.setNumberOffset(self.getBouquetNumOffset(root))
733 refstr = self.service_types + path[pos:]
734 root = eServiceReference(refstr)
736 self.servicelist.setMode(ServiceList.MODE_NORMAL)
737 self.servicelist.setRoot(root, justSet)
738 self.buildTitleString()
740 def removeModeStr(self, str):
741 if self.mode == MODE_TV:
742 pos = str.find(' (TV)')
744 pos = str.find(' (Radio)')
749 def getServiceName(self, ref):
750 str = self.removeModeStr(ServiceReference(ref).getServiceName())
752 pathstr = ref.getPath()
753 if pathstr.find('FROM PROVIDERS') != -1:
755 if pathstr.find('FROM SATELLITES') != -1:
756 return _("Satellites")
757 if pathstr.find(') ORDER BY name') != -1:
761 def buildTitleString(self):
762 titleStr = self.instance.getTitle()
763 pos = titleStr.find(']')
765 pos = titleStr.find(')')
767 titleStr = titleStr[:pos+1]
768 Len = len(self.servicePath)
770 base_ref = self.servicePath[0]
772 end_ref = self.servicePath[Len-1]
775 nameStr = self.getServiceName(base_ref)
776 titleStr += ' ' + nameStr
777 if end_ref is not None:
782 nameStr = self.getServiceName(end_ref)
784 self.setTitle(titleStr)
787 self.servicelist.moveUp()
790 self.servicelist.moveDown()
793 del self.servicePath[:]
795 def enterPath(self, ref, justSet=False):
796 self.servicePath.append(ref)
797 self.setRoot(ref, justSet)
799 def pathUp(self, justSet=False):
800 prev = self.servicePath.pop()
801 length = len(self.servicePath)
803 current = self.servicePath[length-1]
804 self.setRoot(current, justSet)
806 self.setCurrentSelection(prev)
809 def isBasePathEqual(self, ref):
810 if len(self.servicePath) > 1 and self.servicePath[0] == ref:
814 def isPrevPathEqual(self, ref):
815 length = len(self.servicePath)
816 if length > 1 and self.servicePath[length-2] == ref:
820 def preEnterPath(self, refstr):
823 def showAllServices(self):
824 if not self.pathChangeDisabled:
825 refstr = '%s ORDER BY name'%(self.service_types)
826 if not self.preEnterPath(refstr):
827 ref = eServiceReference(refstr)
828 currentRoot = self.getRoot()
829 if currentRoot is None or currentRoot != ref:
833 def showSatellites(self):
834 if not self.pathChangeDisabled:
835 refstr = '%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types)
836 if not self.preEnterPath(refstr):
837 ref = eServiceReference(refstr)
841 if self.isBasePathEqual(ref):
842 if self.isPrevPathEqual(ref):
844 prev = self.pathUp(justSet)
846 currentRoot = self.getRoot()
847 if currentRoot is None or currentRoot != ref:
850 self.enterPath(ref, True)
852 serviceHandler = eServiceCenter.getInstance()
853 servicelist = serviceHandler.list(ref)
854 if not servicelist is None:
856 service = servicelist.getNext()
857 if not service.valid(): #check if end of list
859 orbpos = service.getUnsignedData(4) >> 16
860 if service.getPath().find("FROM PROVIDER") != -1:
861 service_name = _("Providers")
862 elif service.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
863 service_name = _("New")
865 service_name = _("Services")
867 service_name += str(' - %s'%(nimmanager.getSatDescription(orbpos)))
868 service.setName(service_name) # why we need this cast?
870 if orbpos == 0xFFFF: #Cable
871 n = ("%s (%s)") % (service_name, _("Cable"))
872 elif orbpos == 0xEEEE: #Terrestrial
873 n = ("%s (%s)") % (service_name, _("Terrestrial"))
875 if orbpos > 1800: # west
876 orbpos = 3600 - orbpos
880 n = ("%s (%d.%d" + h + ")") % (service_name, orbpos / 10, orbpos % 10)
882 self.servicelist.addService(service)
883 self.servicelist.finishFill()
885 self.setCurrentSelection(prev)
887 def showProviders(self):
888 if not self.pathChangeDisabled:
889 refstr = '%s FROM PROVIDERS ORDER BY name'%(self.service_types)
890 if not self.preEnterPath(refstr):
891 ref = eServiceReference(refstr)
892 if self.isBasePathEqual(ref):
895 currentRoot = self.getRoot()
896 if currentRoot is None or currentRoot != ref:
900 def changeBouquet(self, direction):
901 if not self.pathChangeDisabled:
902 if len(self.servicePath) > 1:
903 #when enter satellite root list we must do some magic stuff..
904 ref = eServiceReference('%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types))
905 if self.isBasePathEqual(ref):
906 self.showSatellites()
913 ref = self.getCurrentSelection()
917 return self.isBasePathEqual(self.bouquet_root)
920 return self.servicelist.atBegin()
923 return self.servicelist.atEnd()
925 def nextBouquet(self):
926 self.changeBouquet(+1)
928 def prevBouquet(self):
929 self.changeBouquet(-1)
931 def showFavourites(self):
932 if not self.pathChangeDisabled:
933 if not self.preEnterPath(self.bouquet_rootstr):
934 if self.isBasePathEqual(self.bouquet_root):
937 currentRoot = self.getRoot()
938 if currentRoot is None or currentRoot != self.bouquet_root:
940 self.enterPath(self.bouquet_root)
942 def keyNumberGlobal(self, number):
943 unichar = self.numericalTextInput.getKey(number)
944 charstr = unichar.encode("utf-8")
945 if len(charstr) == 1:
946 self.servicelist.moveToChar(charstr[0])
949 return self.servicelist.getRoot()
951 def getCurrentSelection(self):
952 return self.servicelist.getCurrent()
954 def setCurrentSelection(self, service):
955 servicepath = service.getPath()
956 pos = servicepath.find(" FROM BOUQUET")
958 if self.mode == MODE_TV:
959 servicepath = '(type == 1)' + servicepath[pos:]
961 servicepath = '(type == 2)' + servicepath[pos:]
962 service.setPath(servicepath)
963 self.servicelist.setCurrent(service)
965 def getBouquetList(self):
967 serviceHandler = eServiceCenter.getInstance()
968 if config.usage.multibouquet.value:
969 list = serviceHandler.list(self.bouquet_root)
975 if s.flags & eServiceReference.isDirectory:
976 info = serviceHandler.info(s)
978 bouquets.append((info.getName(s), s))
981 info = serviceHandler.info(self.bouquet_root)
983 bouquets.append((info.getName(self.bouquet_root), self.bouquet_root))
987 def keyNumber0(self, num):
988 if len(self.servicePath) > 1:
991 self.keyNumberGlobal(num)
994 if len(self.servicePath) > 1:
995 if self.isBasePathEqual(self.bouquet_root):
996 self.showFavourites()
998 ref = eServiceReference('%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types))
999 if self.isBasePathEqual(ref):
1000 self.showSatellites()
1002 ref = eServiceReference('%s FROM PROVIDERS ORDER BY name'%(self.service_types))
1003 if self.isBasePathEqual(ref):
1004 self.showProviders()
1006 self.showAllServices()
1008 def nextMarker(self):
1009 self.servicelist.moveToNextMarker()
1011 def prevMarker(self):
1012 self.servicelist.moveToPrevMarker()
1016 #config for lastservice
1017 config.tv = ConfigSubsection()
1018 config.tv.lastservice = ConfigText()
1019 config.tv.lastroot = ConfigText()
1020 config.radio = ConfigSubsection()
1021 config.radio.lastservice = ConfigText()
1022 config.radio.lastroot = ConfigText()
1023 config.servicelist = ConfigSubsection()
1024 config.servicelist.lastmode = ConfigText(default = "tv")
1026 class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG):
1027 def __init__(self, session):
1028 ChannelSelectionBase.__init__(self,session)
1029 ChannelSelectionEdit.__init__(self)
1030 ChannelSelectionEPG.__init__(self)
1032 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1034 "cancel": self.cancel,
1035 "ok": self.channelSelected,
1036 "keyRadio": self.setModeRadio,
1037 "keyTV": self.setModeTv,
1040 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
1042 iPlayableService.evStart: self.__evServiceStart,
1043 iPlayableService.evEnd: self.__evServiceEnd
1046 self.lastChannelRootTimer = eTimer()
1047 self.lastChannelRootTimer.timeout.get().append(self.__onCreate)
1048 self.lastChannelRootTimer.start(100,True)
1050 self.history_tv = [ ]
1051 self.history_radio = [ ]
1052 self.history = self.history_tv
1053 self.history_pos = 0
1055 self.lastservice = config.tv.lastservice
1056 self.lastroot = config.tv.lastroot
1057 self.revertMode = None
1058 config.usage.multibouquet.addNotifier(self.multibouquet_config_changed)
1060 def multibouquet_config_changed(self, val):
1061 self.recallBouquetMode()
1063 def __evServiceStart(self):
1064 service = self.session.nav.getCurrentService()
1066 info = service.info()
1068 refstr = info.getInfoString(iServiceInformation.sServiceref)
1069 self.servicelist.setPlayableIgnoreService(eServiceReference(refstr))
1071 def __evServiceEnd(self):
1072 self.servicelist.setPlayableIgnoreService(eServiceReference())
1076 lastservice=eServiceReference(self.lastservice.value)
1077 if lastservice.valid():
1078 self.setCurrentSelection(lastservice)
1080 def setModeTv(self):
1081 if self.revertMode is None and config.servicelist.lastmode.value == "radio":
1082 self.revertMode = MODE_RADIO
1083 self.history = self.history_tv
1084 self.lastservice = config.tv.lastservice
1085 self.lastroot = config.tv.lastroot
1086 config.servicelist.lastmode.value = "tv"
1090 def setModeRadio(self):
1091 if self.revertMode is None and config.servicelist.lastmode.value == "tv":
1092 self.revertMode = MODE_TV
1093 if config.usage.e1like_radio_mode.value:
1094 self.history = self.history_radio
1095 self.lastservice = config.radio.lastservice
1096 self.lastroot = config.radio.lastroot
1097 config.servicelist.lastmode.value = "radio"
1101 def __onCreate(self):
1102 if config.usage.e1like_radio_mode.value:
1103 if config.servicelist.lastmode.value == "tv":
1109 lastservice=eServiceReference(self.lastservice.value)
1110 if lastservice.valid():
1113 def channelSelected(self):
1114 ref = self.getCurrentSelection()
1116 self.toggleMoveMarked()
1117 elif (ref.flags & 7) == 7:
1119 elif self.bouquet_mark_edit != OFF:
1120 if not (self.bouquet_mark_edit == EDIT_ALTERNATIVES and ref.flags & eServiceReference.isGroup):
1122 elif not (ref.flags & eServiceReference.isMarker): # no marker
1123 root = self.getRoot()
1124 if not root or not (root.flags & eServiceReference.isGroup):
1128 #called from infoBar and channelSelected
1130 self.revertMode=None
1131 ref = self.session.nav.getCurrentlyPlayingServiceReference()
1132 nref = self.getCurrentSelection()
1133 if ref is None or ref != nref:
1134 self.session.nav.playService(nref)
1136 self.saveChannel(nref)
1137 config.servicelist.lastmode.save()
1138 self.addToHistory(nref)
1140 def addToHistory(self, ref):
1141 if self.servicePath is not None:
1142 tmp=self.servicePath[:]
1145 del self.history[self.history_pos+1:]
1148 self.history.append(tmp)
1149 hlen = len(self.history)
1150 if hlen > HISTORYSIZE:
1153 self.history_pos = hlen-1
1155 def historyBack(self):
1156 hlen = len(self.history)
1157 if hlen > 1 and self.history_pos > 0:
1158 self.history_pos -= 1
1159 self.setHistoryPath()
1161 def historyNext(self):
1162 hlen = len(self.history)
1163 if hlen > 1 and self.history_pos < (hlen-1):
1164 self.history_pos += 1
1165 self.setHistoryPath()
1167 def setHistoryPath(self):
1168 path = self.history[self.history_pos][:]
1170 del self.servicePath[:]
1171 self.servicePath += path
1175 cur_root = self.getRoot()
1176 if cur_root and cur_root != root:
1178 self.session.nav.playService(ref)
1179 self.setCurrentSelection(ref)
1180 self.saveChannel(ref)
1184 for i in self.servicePath:
1185 path += i.toString()
1187 if len(path) and path != self.lastroot.value:
1188 self.lastroot.value = path
1189 self.lastroot.save()
1191 def restoreRoot(self):
1193 re = compile('.+?;')
1194 tmp = re.findall(self.lastroot.value)
1197 self.servicePath.append(eServiceReference(i[:len(i)-1]))
1200 path = self.servicePath.pop()
1201 self.enterPath(path)
1203 self.showFavourites()
1206 def preEnterPath(self, refstr):
1207 if len(self.servicePath) and self.servicePath[0] != eServiceReference(refstr):
1208 pathstr = self.lastroot.value
1209 if pathstr is not None and pathstr.find(refstr) == 0:
1211 lastservice=eServiceReference(self.lastservice.value)
1212 if lastservice.valid():
1213 self.setCurrentSelection(lastservice)
1217 def saveChannel(self, ref):
1219 refstr = ref.toString()
1222 if refstr != self.lastservice.value:
1223 self.lastservice.value = refstr
1224 self.lastservice.save()
1226 def setCurrentServicePath(self, path):
1227 hlen = len(self.history)
1229 self.history[self.history_pos] = path
1231 self.history.append(path)
1232 self.setHistoryPath()
1234 def getCurrentServicePath(self):
1235 hlen = len(self.history)
1237 return self.history[self.history_pos]
1240 def recallPrevService(self):
1241 hlen = len(self.history)
1243 if self.history_pos == hlen-1:
1244 tmp = self.history[self.history_pos]
1245 self.history[self.history_pos] = self.history[self.history_pos-1]
1246 self.history[self.history_pos-1] = tmp
1248 tmp = self.history[self.history_pos+1]
1249 self.history[self.history_pos+1] = self.history[self.history_pos]
1250 self.history[self.history_pos] = tmp
1251 self.setHistoryPath()
1254 if self.revertMode is None:
1256 lastservice=eServiceReference(self.lastservice.value)
1257 if lastservice.valid() and self.getCurrentSelection() != lastservice:
1258 self.setCurrentSelection(lastservice)
1259 elif self.revertMode == MODE_TV:
1261 elif self.revertMode == MODE_RADIO:
1263 self.revertMode = None
1266 from Screens.InfoBarGenerics import InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord, InfoBarRadioText
1268 class RadioInfoBar(Screen, InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord):
1269 def __init__(self, session):
1270 Screen.__init__(self, session)
1271 InfoBarEvent.__init__(self)
1272 InfoBarServiceName.__init__(self)
1273 InfoBarInstantRecord.__init__(self)
1274 self["CurrentTime"] = Clock()
1276 class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG, InfoBarRadioText):
1278 ALLOW_SUSPEND = True
1280 def __init__(self, session):
1281 ChannelSelectionBase.__init__(self, session)
1282 ChannelSelectionEdit.__init__(self)
1283 ChannelSelectionEPG.__init__(self)
1284 InfoBarRadioText.__init__(self)
1286 config.radio = ConfigSubsection();
1287 config.radio.lastservice = ConfigText()
1288 config.radio.lastroot = ConfigText()
1289 self.onLayoutFinish.append(self.onCreate)
1291 self.info = session.instantiateDialog(RadioInfoBar)
1293 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1295 "keyTV": self.closeRadio,
1296 "keyRadio": self.closeRadio,
1297 "cancel": self.closeRadio,
1298 "ok": self.channelSelected,
1301 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
1303 iPlayableService.evStart: self.__evServiceStart,
1304 iPlayableService.evEnd: self.__evServiceEnd
1307 def __evServiceStart(self):
1308 service = self.session.nav.getCurrentService()
1310 info = service.info()
1312 refstr = info.getInfoString(iServiceInformation.sServiceref)
1313 self.servicelist.setPlayableIgnoreService(eServiceReference(refstr))
1315 def __evServiceEnd(self):
1316 self.servicelist.setPlayableIgnoreService(eServiceReference())
1320 for i in self.servicePathRadio:
1321 path += i.toString()
1323 if len(path) and path != config.radio.lastroot.value:
1324 config.radio.lastroot.value = path
1325 config.radio.lastroot.save()
1327 def restoreRoot(self):
1329 re = compile('.+?;')
1330 tmp = re.findall(config.radio.lastroot.value)
1333 self.servicePathRadio.append(eServiceReference(i[:len(i)-1]))
1336 path = self.servicePathRadio.pop()
1337 self.enterPath(path)
1339 self.showFavourites()
1342 def preEnterPath(self, refstr):
1343 if len(self.servicePathRadio) and self.servicePathRadio[0] != eServiceReference(refstr):
1344 pathstr = config.radio.lastroot.value
1345 if pathstr is not None and pathstr.find(refstr) == 0:
1347 lastservice=eServiceReference(config.radio.lastservice.value)
1348 if lastservice.valid():
1349 self.setCurrentSelection(lastservice)
1356 lastservice=eServiceReference(config.radio.lastservice.value)
1357 if lastservice.valid():
1358 self.servicelist.setCurrent(lastservice)
1359 self.session.nav.playService(lastservice)
1362 def channelSelected(self): # just return selected service
1363 ref = self.getCurrentSelection()
1365 self.toggleMoveMarked()
1366 elif (ref.flags & 7) == 7:
1368 elif self.bouquet_mark_edit != OFF:
1369 if not (self.bouquet_mark_edit == EDIT_ALTERNATIVES and ref.flags & eServiceReference.isGroup):
1371 elif not (ref.flags & eServiceReference.isMarker): # no marker
1372 cur_root = self.getRoot()
1373 if not cur_root or not (cur_root.flags & eServiceReference.isGroup):
1374 playingref = self.session.nav.getCurrentlyPlayingServiceReference()
1375 if playingref is None or playingref != ref:
1376 self.session.nav.playService(ref)
1377 config.radio.lastservice.value = ref.toString()
1378 config.radio.lastservice.save()
1381 def closeRadio(self):
1383 #set previous tv service
1384 lastservice=eServiceReference(config.tv.lastservice.value)
1385 self.session.nav.playService(lastservice)
1388 class SimpleChannelSelection(ChannelSelectionBase):
1389 def __init__(self, session, title):
1390 ChannelSelectionBase.__init__(self, session)
1392 self.onShown.append(self.__onExecCallback)
1394 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1396 "cancel": self.close,
1397 "ok": self.channelSelected,
1398 "keyRadio": self.setModeRadio,
1399 "keyTV": self.setModeTv,
1402 def __onExecCallback(self):
1403 self.setTitle(self.title)
1406 def channelSelected(self): # just return selected service
1407 ref = self.getCurrentSelection()
1408 if (ref.flags & 7) == 7:
1410 elif not (ref.flags & eServiceReference.isMarker):
1411 ref = self.getCurrentSelection()
1414 def setModeTv(self):
1416 self.showFavourites()
1418 def setModeRadio(self):
1420 self.showFavourites()