1 from Tools.Profile import profile
3 from Screen import Screen
4 from Components.Button import Button
5 from Components.ServiceList import ServiceList
6 from Components.ActionMap import NumberActionMap, ActionMap, HelpableActionMap
7 from Components.MenuList import MenuList
8 from Components.ServiceEventTracker import ServiceEventTracker, InfoBarBase
9 profile("ChannelSelection.py 1")
10 from EpgSelection import EPGSelection
11 from enigma import eServiceReference, eEPGCache, eServiceCenter, eRCInput, eTimer, eDVBDB, iPlayableService, iServiceInformation, getPrevAsciiCode, eEnv
12 from Components.config import config, ConfigSubsection, ConfigText
13 from Tools.NumericalTextInput import NumericalTextInput
14 profile("ChannelSelection.py 2")
15 from Components.NimManager import nimmanager
16 profile("ChannelSelection.py 2.1")
17 from Components.Sources.RdsDecoder import RdsDecoder
18 profile("ChannelSelection.py 2.2")
19 from Components.Sources.ServiceEvent import ServiceEvent
20 profile("ChannelSelection.py 2.3")
21 from Components.Input import Input
22 profile("ChannelSelection.py 3")
23 from Components.ChoiceList import ChoiceList, ChoiceEntryComponent
24 from Components.SystemInfo import SystemInfo
25 from Screens.InputBox import InputBox, PinInput
26 from Screens.MessageBox import MessageBox
27 from Screens.ServiceInfo import ServiceInfo
28 profile("ChannelSelection.py 4")
29 from Screens.PictureInPicture import PictureInPicture
30 from Screens.RdsDisplay import RassInteractive
31 from ServiceReference import ServiceReference
32 from Tools.BoundFunction import boundFunction
34 profile("ChannelSelection.py after imports")
36 FLAG_SERVICE_NEW_FOUND = 64 #define in lib/dvb/idvb.h as dxNewFound = 64
38 class BouquetSelector(Screen):
39 def __init__(self, session, bouquets, selectedFunc, enableWrapAround=False):
40 Screen.__init__(self, session)
42 self.selectedFunc=selectedFunc
44 self["actions"] = ActionMap(["OkCancelActions"],
46 "ok": self.okbuttonClick,
47 "cancel": self.cancelClick
49 entrys = [ (x[0], x[1]) for x in bouquets ]
50 self["menu"] = MenuList(entrys, enableWrapAround)
53 cur = self["menu"].getCurrent()
56 def okbuttonClick(self):
57 self.selectedFunc(self.getCurrent())
65 def cancelClick(self):
68 class SilentBouquetSelector:
69 def __init__(self, bouquets, enableWrapAround=False, current=0):
70 self.bouquets = [b[1] for b in bouquets]
72 self.count = len(bouquets)
73 self.enableWrapAround = enableWrapAround
76 if self.pos > 0 or self.enableWrapAround:
77 self.pos = (self.pos - 1) % self.count
80 if self.pos < (self.count - 1) or self.enableWrapAround:
81 self.pos = (self.pos + 1) % self.count
84 return self.bouquets[self.pos]
86 # csel.bouquet_mark_edit values
91 def append_when_current_valid(current, menu, args, level = 0, key = ""):
92 if current and current.valid() and level <= config.usage.setup_level.index:
93 menu.append(ChoiceEntryComponent(key, args))
95 class ChannelContextMenu(Screen):
96 def __init__(self, session, csel):
98 Screen.__init__(self, session)
99 #raise Exception("we need a better summary screen here")
103 self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "NumberActions"],
105 "ok": self.okbuttonClick,
106 "cancel": self.cancelClick,
107 "blue": self.showServiceInPiP
111 self.pipAvailable = False
112 current = csel.getCurrentSelection()
113 current_root = csel.getRoot()
114 current_sel_path = current.getPath()
115 current_sel_flags = current.flags
116 inBouquetRootList = current_root and current_root.getPath().find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
117 inBouquet = csel.getMutableList() is not None
118 haveBouquets = config.usage.multibouquet.value
120 if not (current_sel_path or current_sel_flags & (eServiceReference.isDirectory|eServiceReference.isMarker)):
121 append_when_current_valid(current, menu, (_("show transponder info"), self.showServiceInformations), level = 2)
122 if csel.bouquet_mark_edit == OFF and not csel.movemode:
123 if not inBouquetRootList:
124 isPlayable = not (current_sel_flags & (eServiceReference.isMarker|eServiceReference.isDirectory))
126 if config.ParentalControl.configured.value:
127 from Components.ParentalControl import parentalControl
128 if parentalControl.getProtectionLevel(csel.getCurrentSelection().toCompareString()) == -1:
129 append_when_current_valid(current, menu, (_("add to parental protection"), boundFunction(self.addParentalProtection, csel.getCurrentSelection())), level = 0)
131 append_when_current_valid(current, menu, (_("remove from parental protection"), boundFunction(self.removeParentalProtection, csel.getCurrentSelection())), level = 0)
133 bouquets = self.csel.getBouquetList()
137 bouquetCnt = len(bouquets)
138 if not inBouquet or bouquetCnt > 1:
139 append_when_current_valid(current, menu, (_("add service to bouquet"), self.addServiceToBouquetSelected), level = 0)
142 append_when_current_valid(current, menu, (_("add service to favourites"), self.addServiceToBouquetSelected), level = 0)
144 if current_root.getPath().find('FROM SATELLITES') != -1:
145 append_when_current_valid(current, menu, (_("remove selected satellite"), self.removeSatelliteServices), level = 0)
147 if not inBouquet and current_sel_path.find("PROVIDERS") == -1:
148 append_when_current_valid(current, menu, (_("copy to bouquets"), self.copyCurrentToBouquetList), level = 0)
149 if current_sel_path.find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
150 append_when_current_valid(current, menu, (_("remove all new found flags"), self.removeAllNewFoundFlags), level = 0)
152 append_when_current_valid(current, menu, (_("remove entry"), self.removeCurrentService), level = 0)
153 if current_root and current_root.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
154 append_when_current_valid(current, menu, (_("remove new found flag"), self.removeNewFoundFlag), level = 0)
155 if isPlayable and SystemInfo.get("NumVideoDecoders", 1) > 1:
156 append_when_current_valid(current, menu, (_("Activate Picture in Picture"), self.showServiceInPiP), level = 0, key = "blue")
157 self.pipAvailable = True
159 menu.append(ChoiceEntryComponent(text = (_("add bouquet"), self.showBouquetInputBox)))
160 append_when_current_valid(current, menu, (_("remove entry"), self.removeBouquet), level = 0)
162 if inBouquet: # current list is editable?
163 if csel.bouquet_mark_edit == OFF:
164 if not csel.movemode:
165 append_when_current_valid(current, menu, (_("enable move mode"), self.toggleMoveMode), level = 1)
166 if not inBouquetRootList and current_root and not (current_root.flags & eServiceReference.isGroup):
167 menu.append(ChoiceEntryComponent(text = (_("add marker"), self.showMarkerInputBox)))
169 append_when_current_valid(current, menu, (_("enable bouquet edit"), self.bouquetMarkStart), level = 0)
171 append_when_current_valid(current, menu, (_("enable favourite edit"), self.bouquetMarkStart), level = 0)
172 if current_sel_flags & eServiceReference.isGroup:
173 append_when_current_valid(current, menu, (_("edit alternatives"), self.editAlternativeServices), level = 2)
174 append_when_current_valid(current, menu, (_("show alternatives"), self.showAlternativeServices), level = 2)
175 append_when_current_valid(current, menu, (_("remove all alternatives"), self.removeAlternativeServices), level = 2)
176 elif not current_sel_flags & eServiceReference.isMarker:
177 append_when_current_valid(current, menu, (_("add alternatives"), self.addAlternativeServices), level = 2)
179 append_when_current_valid(current, menu, (_("disable move mode"), self.toggleMoveMode), level = 0)
181 if csel.bouquet_mark_edit == EDIT_BOUQUET:
183 append_when_current_valid(current, menu, (_("end bouquet edit"), self.bouquetMarkEnd), level = 0)
184 append_when_current_valid(current, menu, (_("abort bouquet edit"), self.bouquetMarkAbort), level = 0)
186 append_when_current_valid(current, menu, (_("end favourites edit"), self.bouquetMarkEnd), level = 0)
187 append_when_current_valid(current, menu, (_("abort favourites edit"), self.bouquetMarkAbort), level = 0)
189 append_when_current_valid(current, menu, (_("end alternatives edit"), self.bouquetMarkEnd), level = 0)
190 append_when_current_valid(current, menu, (_("abort alternatives edit"), self.bouquetMarkAbort), level = 0)
192 menu.append(ChoiceEntryComponent(text = (_("back"), self.cancelClick)))
193 self["menu"] = ChoiceList(menu)
195 def okbuttonClick(self):
196 self["menu"].getCurrent()[0][1]()
198 def cancelClick(self):
201 def showServiceInformations(self):
202 self.session.open( ServiceInfo, self.csel.getCurrentSelection() )
204 def showBouquetInputBox(self):
205 self.session.openWithCallback(self.bouquetInputCallback, InputBox, title=_("Please enter a name for the new bouquet"), text="bouquetname", maxSize=False, visible_width = 56, type=Input.TEXT)
207 def bouquetInputCallback(self, bouquet):
208 if bouquet is not None:
209 self.csel.addBouquet(bouquet, None)
212 def addParentalProtection(self, service):
213 from Components.ParentalControl import parentalControl
214 parentalControl.protectService(service.toCompareString())
217 def removeParentalProtection(self, service):
218 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"))
220 def pinEntered(self, service, result):
222 from Components.ParentalControl import parentalControl
223 parentalControl.unProtectService(service)
226 self.session.openWithCallback(self.close, MessageBox, _("The pin code you entered is wrong."), MessageBox.TYPE_ERROR)
228 def showServiceInPiP(self):
229 if not self.pipAvailable:
231 if self.session.pipshown:
233 self.session.pip = self.session.instantiateDialog(PictureInPicture)
234 self.session.pip.show()
235 newservice = self.csel.servicelist.getCurrent()
236 if self.session.pip.playService(newservice):
237 self.session.pipshown = True
238 self.session.pip.servicePath = self.csel.getCurrentServicePath()
241 self.session.pipshown = False
243 self.session.openWithCallback(self.close, MessageBox, _("Could not open Picture in Picture"), MessageBox.TYPE_ERROR)
245 def addServiceToBouquetSelected(self):
246 bouquets = self.csel.getBouquetList()
251 if cnt > 1: # show bouquet list
252 self.bsel = self.session.openWithCallback(self.bouquetSelClosed, BouquetSelector, bouquets, self.addCurrentServiceToBouquet)
253 elif cnt == 1: # add to only one existing bouquet
254 self.addCurrentServiceToBouquet(bouquets[0][1], closeBouquetSelection = False)
256 def bouquetSelClosed(self, recursive):
261 def removeSatelliteServices(self):
262 curpath = self.csel.getCurrentSelection().getPath()
263 idx = curpath.find("satellitePosition == ")
265 tmp = curpath[idx+21:]
268 satpos = int(tmp[:idx])
269 eDVBDB.getInstance().removeServices(-1, -1, -1, satpos)
272 def copyCurrentToBouquetList(self):
273 self.csel.copyCurrentToBouquetList()
276 def removeBouquet(self):
277 self.csel.removeBouquet()
280 def showMarkerInputBox(self):
281 self.session.openWithCallback(self.markerInputCallback, InputBox, title=_("Please enter a name for the new marker"), text="markername", maxSize=False, visible_width = 56, type=Input.TEXT)
283 def markerInputCallback(self, marker):
284 if marker is not None:
285 self.csel.addMarker(marker)
288 def addCurrentServiceToBouquet(self, dest, closeBouquetSelection = True):
289 self.csel.addServiceToBouquet(dest)
290 if self.bsel is not None:
291 self.bsel.close(True)
293 self.close(closeBouquetSelection) # close bouquet selection
295 def removeCurrentService(self):
296 self.csel.removeCurrentService()
299 def toggleMoveMode(self):
300 self.csel.toggleMoveMode()
303 def bouquetMarkStart(self):
304 self.csel.startMarkedEdit(EDIT_BOUQUET)
307 def bouquetMarkEnd(self):
308 self.csel.endMarkedEdit(abort=False)
311 def bouquetMarkAbort(self):
312 self.csel.endMarkedEdit(abort=True)
315 def removeNewFoundFlag(self):
316 eDVBDB.getInstance().removeFlag(self.csel.getCurrentSelection(), FLAG_SERVICE_NEW_FOUND)
319 def removeAllNewFoundFlags(self):
320 curpath = self.csel.getCurrentSelection().getPath()
321 idx = curpath.find("satellitePosition == ")
323 tmp = curpath[idx+21:]
326 satpos = int(tmp[:idx])
327 eDVBDB.getInstance().removeFlags(FLAG_SERVICE_NEW_FOUND, -1, -1, -1, satpos)
330 def editAlternativeServices(self):
331 self.csel.startMarkedEdit(EDIT_ALTERNATIVES)
334 def showAlternativeServices(self):
335 self.csel.enterPath(self.csel.getCurrentSelection())
338 def removeAlternativeServices(self):
339 self.csel.removeAlternativeServices()
342 def addAlternativeServices(self):
343 self.csel.addAlternativeServices()
344 self.csel.startMarkedEdit(EDIT_ALTERNATIVES)
347 class SelectionEventInfo:
349 self["ServiceEvent"] = ServiceEvent()
350 self.servicelist.connectSelChanged(self.__selectionChanged)
351 self.timer = eTimer()
352 self.timer.callback.append(self.updateEventInfo)
353 self.onShown.append(self.__selectionChanged)
355 def __selectionChanged(self):
357 self.timer.start(100, True)
359 def updateEventInfo(self):
360 cur = self.getCurrentSelection()
361 self["ServiceEvent"].newService(cur)
363 class ChannelSelectionEPG:
365 self["ChannelSelectEPGActions"] = ActionMap(["ChannelSelectEPGActions"],
367 "showEPGList": self.showEPGList,
370 def showEPGList(self):
371 ref=self.getCurrentSelection()
373 self.savedService = ref
374 self.session.openWithCallback(self.SingleServiceEPGClosed, EPGSelection, ref, serviceChangeCB=self.changeServiceCB)
376 def SingleServiceEPGClosed(self, ret=False):
377 self.setCurrentSelection(self.savedService)
379 def changeServiceCB(self, direction, epg):
380 beg = self.getCurrentSelection()
386 cur = self.getCurrentSelection()
387 if cur == beg or not (cur.flags & eServiceReference.isMarker):
389 epg.setService(ServiceReference(self.getCurrentSelection()))
391 class ChannelSelectionEdit:
393 self.entry_marked = False
394 self.movemode = False
395 self.bouquet_mark_edit = OFF
396 self.mutableList = None
398 self.saved_title = None
399 self.saved_root = None
401 class ChannelSelectionEditActionMap(ActionMap):
402 def __init__(self, csel, contexts = [ ], actions = { }, prio=0):
403 ActionMap.__init__(self, contexts, actions, prio)
406 def action(self, contexts, action):
407 if action == "cancel":
408 self.csel.handleEditCancel()
409 return 0 # fall-trough
411 return 0 # fall-trough
413 return ActionMap.action(self, contexts, action)
415 self["ChannelSelectEditActions"] = ChannelSelectionEditActionMap(self, ["ChannelSelectEditActions", "OkCancelActions"],
417 "contextMenu": self.doContext,
420 def getMutableList(self, root=eServiceReference()):
421 if not self.mutableList is None:
422 return self.mutableList
423 serviceHandler = eServiceCenter.getInstance()
426 list = root and serviceHandler.list(root)
428 return list.startEdit()
431 def buildBouquetID(self, str):
435 if (c >= 'a' and c <= 'z') or (c >= '0' and c <= '9'):
441 def addMarker(self, name):
442 current = self.servicelist.getCurrent()
443 mutableList = self.getMutableList()
446 str = '1:64:%d:0:0:0:0:0:0:0::%s'%(cnt, name)
447 ref = eServiceReference(str)
448 if current and current.valid():
449 if not mutableList.addService(ref, current):
450 self.servicelist.addService(ref, True)
451 mutableList.flushChanges()
453 elif not mutableList.addService(ref):
454 self.servicelist.addService(ref, True)
455 mutableList.flushChanges()
459 def addAlternativeServices(self):
460 cur_service = ServiceReference(self.getCurrentSelection())
461 root = self.getRoot()
462 cur_root = root and ServiceReference(root)
463 mutableBouquet = cur_root.list().startEdit()
465 name = cur_service.getServiceName()
467 if self.mode == MODE_TV:
468 str = '1:134:1:0:0:0:0:0:0:0:FROM BOUQUET \"alternatives.%s.tv\" ORDER BY bouquet'%(self.buildBouquetID(name))
470 str = '1:134:2:0:0:0:0:0:0:0:FROM BOUQUET \"alternatives.%s.radio\" ORDER BY bouquet'%(self.buildBouquetID(name))
471 new_ref = ServiceReference(str)
472 if not mutableBouquet.addService(new_ref.ref, cur_service.ref):
473 mutableBouquet.removeService(cur_service.ref)
474 mutableBouquet.flushChanges()
475 eDVBDB.getInstance().reloadBouquets()
476 mutableAlternatives = new_ref.list().startEdit()
477 if mutableAlternatives:
478 mutableAlternatives.setListName(name)
479 if mutableAlternatives.addService(cur_service.ref):
480 print "add", cur_service.ref.toString(), "to new alternatives failed"
481 mutableAlternatives.flushChanges()
482 self.servicelist.addService(new_ref.ref, True)
483 self.servicelist.removeCurrent()
484 self.servicelist.moveUp()
486 print "get mutable list for new created alternatives failed"
488 print "add", str, "to", cur_root.getServiceName(), "failed"
490 print "bouquetlist is not editable"
492 def addBouquet(self, bName, services):
493 serviceHandler = eServiceCenter.getInstance()
494 mutableBouquetList = serviceHandler.list(self.bouquet_root).startEdit()
495 if mutableBouquetList:
496 if self.mode == MODE_TV:
498 str = '1:7:1:0:0:0:0:0:0:0:FROM BOUQUET \"userbouquet.%s.tv\" ORDER BY bouquet'%(self.buildBouquetID(bName))
501 str = '1:7:2:0:0:0:0:0:0:0:FROM BOUQUET \"userbouquet.%s.radio\" ORDER BY bouquet'%(self.buildBouquetID(bName))
502 new_bouquet_ref = eServiceReference(str)
503 if not mutableBouquetList.addService(new_bouquet_ref):
504 mutableBouquetList.flushChanges()
505 eDVBDB.getInstance().reloadBouquets()
506 mutableBouquet = serviceHandler.list(new_bouquet_ref).startEdit()
508 mutableBouquet.setListName(bName)
509 if services is not None:
510 for service in services:
511 if mutableBouquet.addService(service):
512 print "add", service.toString(), "to new bouquet failed"
513 mutableBouquet.flushChanges()
515 print "get mutable list for new created bouquet failed"
516 # do some voodoo to check if current_root is equal to bouquet_root
517 cur_root = self.getRoot();
518 str1 = cur_root and cur_root.toString()
519 pos1 = str1 and str1.find("FROM BOUQUET") or -1
520 pos2 = self.bouquet_rootstr.find("FROM BOUQUET")
521 if pos1 != -1 and pos2 != -1 and str1[pos1:] == self.bouquet_rootstr[pos2:]:
522 self.servicelist.addService(new_bouquet_ref)
524 print "add", str, "to bouquets failed"
526 print "bouquetlist is not editable"
528 def copyCurrentToBouquetList(self):
529 provider = ServiceReference(self.getCurrentSelection())
530 providerName = provider.getServiceName()
531 serviceHandler = eServiceCenter.getInstance()
532 services = serviceHandler.list(provider.ref)
533 self.addBouquet(providerName, services and services.getContent('R', True))
535 def removeAlternativeServices(self):
536 cur_service = ServiceReference(self.getCurrentSelection())
537 root = self.getRoot()
538 cur_root = root and ServiceReference(root)
539 list = cur_service.list()
540 first_in_alternative = list and list.getNext()
541 if first_in_alternative:
542 edit_root = cur_root and cur_root.list().startEdit()
544 if not edit_root.addService(first_in_alternative, cur_service.ref):
545 self.servicelist.addService(first_in_alternative, True)
547 print "couldn't add first alternative service to current root"
549 print "couldn't edit current root!!"
551 print "remove empty alternative list !!"
553 self.servicelist.moveUp()
555 def removeBouquet(self):
556 refstr = self.getCurrentSelection().toString()
557 print "removeBouquet", refstr
558 self.bouquetNumOffsetCache = { }
559 pos = refstr.find('FROM BOUQUET "')
562 refstr = refstr[pos+14:]
563 pos = refstr.find('"')
565 filename = eEnv.resolve('${sysconfdir}/enigma2/') + refstr[:pos]
566 self.removeCurrentService()
568 if filename is not None:
571 print "error during remove of", filename
573 # multiple marked entry stuff ( edit mode, later multiepg selection )
574 def startMarkedEdit(self, type):
575 self.savedPath = self.servicePath[:]
576 if type == EDIT_ALTERNATIVES:
577 self.enterPath(self.getCurrentSelection())
578 self.mutableList = self.getMutableList()
579 # add all services from the current list to internal marked set in listboxservicecontent
580 self.clearMarks() # this clears the internal marked set in the listboxservicecontent
581 self.saved_title = self.getTitle()
582 pos = self.saved_title.find(')')
583 new_title = self.saved_title[:pos+1]
584 if type == EDIT_ALTERNATIVES:
585 self.bouquet_mark_edit = EDIT_ALTERNATIVES
586 new_title += ' ' + _("[alternative edit]")
588 self.bouquet_mark_edit = EDIT_BOUQUET
589 if config.usage.multibouquet.value:
590 new_title += ' ' + _("[bouquet edit]")
592 new_title += ' ' + _("[favourite edit]")
593 self.setTitle(new_title)
594 self.__marked = self.servicelist.getRootServices()
595 for x in self.__marked:
596 self.servicelist.addMarked(eServiceReference(x))
597 self.showAllServices()
599 def endMarkedEdit(self, abort):
600 if not abort and self.mutableList is not None:
601 self.bouquetNumOffsetCache = { }
602 new_marked = set(self.servicelist.getMarked())
603 old_marked = set(self.__marked)
604 removed = old_marked - new_marked
605 added = new_marked - old_marked
609 self.mutableList.removeService(eServiceReference(x))
612 self.mutableList.addService(eServiceReference(x))
614 self.mutableList.flushChanges()
617 self.bouquet_mark_edit = OFF
618 self.mutableList = None
619 self.setTitle(self.saved_title)
620 self.saved_title = None
621 # self.servicePath is just a reference to servicePathTv or Radio...
622 # so we never ever do use the asignment operator in self.servicePath
623 del self.servicePath[:] # remove all elements
624 self.servicePath += self.savedPath # add saved elements
626 self.setRoot(self.servicePath[-1])
628 def clearMarks(self):
629 self.servicelist.clearMarks()
632 ref = self.servicelist.getCurrent()
633 if self.servicelist.isMarked(ref):
634 self.servicelist.removeMarked(ref)
636 self.servicelist.addMarked(ref)
638 def removeCurrentService(self):
639 ref = self.servicelist.getCurrent()
640 mutableList = self.getMutableList()
641 if ref.valid() and mutableList is not None:
642 if not mutableList.removeService(ref):
643 self.bouquetNumOffsetCache = { }
644 mutableList.flushChanges() #FIXME dont flush on each single removed service
645 self.servicelist.removeCurrent()
647 def addServiceToBouquet(self, dest, service=None):
648 mutableList = self.getMutableList(dest)
649 if not mutableList is None:
650 if service is None: #use current selected service
651 service = self.servicelist.getCurrent()
652 if not mutableList.addService(service):
653 self.bouquetNumOffsetCache = { }
654 mutableList.flushChanges()
655 # do some voodoo to check if current_root is equal to dest
656 cur_root = self.getRoot();
657 str1 = cur_root and cur_root.toString() or -1
658 str2 = dest.toString()
659 pos1 = str1.find("FROM BOUQUET")
660 pos2 = str2.find("FROM BOUQUET")
661 if pos1 != -1 and pos2 != -1 and str1[pos1:] == str2[pos2:]:
662 self.servicelist.addService(service)
664 def toggleMoveMode(self):
666 if self.entry_marked:
667 self.toggleMoveMarked() # unmark current entry
668 self.movemode = False
669 self.pathChangeDisabled = False # re-enable path change
670 self.mutableList.flushChanges() # FIXME add check if changes was made
671 self.mutableList = None
672 self.setTitle(self.saved_title)
673 self.saved_title = None
674 cur_root = self.getRoot()
675 if cur_root and cur_root == self.bouquet_root:
676 self.bouquetNumOffsetCache = { }
678 self.mutableList = self.getMutableList()
680 self.pathChangeDisabled = True # no path change allowed in movemode
681 self.saved_title = self.getTitle()
682 new_title = self.saved_title
683 pos = self.saved_title.find(')')
684 new_title = self.saved_title[:pos+1] + ' ' + _("[move mode]") + self.saved_title[pos+1:]
685 self.setTitle(new_title);
687 def handleEditCancel(self):
688 if self.movemode: #movemode active?
689 self.channelSelected() # unmark
690 self.toggleMoveMode() # disable move mode
691 elif self.bouquet_mark_edit != OFF:
692 self.endMarkedEdit(True) # abort edit mode
694 def toggleMoveMarked(self):
695 if self.entry_marked:
696 self.servicelist.setCurrentMarked(False)
697 self.entry_marked = False
699 self.servicelist.setCurrentMarked(True)
700 self.entry_marked = True
703 self.session.openWithCallback(self.exitContext, ChannelContextMenu, self)
705 def exitContext(self, close = False):
712 # type 1 = digital television service
713 # type 4 = nvod reference service (NYI)
714 # type 17 = MPEG-2 HD digital television service
715 # type 22 = advanced codec SD digital television
716 # type 24 = advanced codec SD NVOD reference service (NYI)
717 # type 25 = advanced codec HD digital television
718 # type 27 = advanced codec HD NVOD reference service (NYI)
719 # type 2 = digital radio sound service
720 # type 10 = advanced codec digital radio sound service
722 service_types_tv = '1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17) || (type == 22) || (type == 25) || (type == 134) || (type == 195)'
723 service_types_radio = '1:7:2:0:0:0:0:0:0:0:(type == 2) || (type == 10)'
725 class ChannelSelectionBase(Screen):
726 def __init__(self, session):
727 Screen.__init__(self, session)
729 self["key_red"] = Button(_("All"))
730 self["key_green"] = Button(_("Satellites"))
731 self["key_yellow"] = Button(_("Provider"))
732 self["key_blue"] = Button(_("Favourites"))
734 self["list"] = ServiceList()
735 self.servicelist = self["list"]
737 self.numericalTextInput = NumericalTextInput()
738 self.numericalTextInput.setUseableChars(u'1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ')
740 self.servicePathTV = [ ]
741 self.servicePathRadio = [ ]
742 self.servicePath = [ ]
743 self.rootChanged = False
747 self.pathChangeDisabled = False
749 self.bouquetNumOffsetCache = { }
751 self["ChannelSelectBaseActions"] = NumberActionMap(["ChannelSelectBaseActions", "NumberActions", "InputAsciiActions"],
753 "showFavourites": self.showFavourites,
754 "showAllServices": self.showAllServices,
755 "showProviders": self.showProviders,
756 "showSatellites": self.showSatellites,
757 "nextBouquet": self.nextBouquet,
758 "prevBouquet": self.prevBouquet,
759 "nextMarker": self.nextMarker,
760 "prevMarker": self.prevMarker,
761 "gotAsciiCode": self.keyAsciiCode,
762 "1": self.keyNumberGlobal,
763 "2": self.keyNumberGlobal,
764 "3": self.keyNumberGlobal,
765 "4": self.keyNumberGlobal,
766 "5": self.keyNumberGlobal,
767 "6": self.keyNumberGlobal,
768 "7": self.keyNumberGlobal,
769 "8": self.keyNumberGlobal,
770 "9": self.keyNumberGlobal,
773 self.recallBouquetMode()
775 def getBouquetNumOffset(self, bouquet):
776 if not config.usage.multibouquet.value:
778 str = bouquet.toString()
780 if not self.bouquetNumOffsetCache.has_key(str):
781 serviceHandler = eServiceCenter.getInstance()
782 bouquetlist = serviceHandler.list(self.bouquet_root)
783 if not bouquetlist is None:
785 bouquetIterator = bouquetlist.getNext()
786 if not bouquetIterator.valid(): #end of list
788 self.bouquetNumOffsetCache[bouquetIterator.toString()]=offsetCount
789 if not (bouquetIterator.flags & eServiceReference.isDirectory):
791 servicelist = serviceHandler.list(bouquetIterator)
792 if not servicelist is None:
794 serviceIterator = servicelist.getNext()
795 if not serviceIterator.valid(): #check if end of list
797 playable = not (serviceIterator.flags & (eServiceReference.isDirectory|eServiceReference.isMarker))
800 return self.bouquetNumOffsetCache.get(str, offsetCount)
802 def recallBouquetMode(self):
803 if self.mode == MODE_TV:
804 self.service_types = service_types_tv
805 if config.usage.multibouquet.value:
806 self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "bouquets.tv" ORDER BY bouquet'
808 self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.tv" ORDER BY bouquet'%(self.service_types)
810 self.service_types = service_types_radio
811 if config.usage.multibouquet.value:
812 self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "bouquets.radio" ORDER BY bouquet'
814 self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.radio" ORDER BY bouquet'%(self.service_types)
815 self.bouquet_root = eServiceReference(self.bouquet_rootstr)
819 self.servicePath = self.servicePathTV
820 self.recallBouquetMode()
821 title = self.getTitle()
822 pos = title.find(" (")
828 def setRadioMode(self):
829 self.mode = MODE_RADIO
830 self.servicePath = self.servicePathRadio
831 self.recallBouquetMode()
832 title = self.getTitle()
833 pos = title.find(" (")
839 def setRoot(self, root, justSet=False):
840 path = root.getPath()
841 inBouquetRootList = path.find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
842 pos = path.find('FROM BOUQUET')
843 isBouquet = (pos != -1) and (root.flags & eServiceReference.isDirectory)
844 if not inBouquetRootList and isBouquet:
845 self.servicelist.setMode(ServiceList.MODE_FAVOURITES)
846 self.servicelist.setNumberOffset(self.getBouquetNumOffset(root))
848 self.servicelist.setMode(ServiceList.MODE_NORMAL)
849 self.servicelist.setRoot(root, justSet)
850 self.rootChanged = True
851 self.buildTitleString()
853 def removeModeStr(self, str):
854 if self.mode == MODE_TV:
855 pos = str.find(' (TV)')
857 pos = str.find(' (Radio)')
862 def getServiceName(self, ref):
863 str = self.removeModeStr(ServiceReference(ref).getServiceName())
865 pathstr = ref.getPath()
866 if 'FROM PROVIDERS' in pathstr:
868 if 'FROM SATELLITES' in pathstr:
869 return _("Satellites")
870 if ') ORDER BY name' in pathstr:
874 def buildTitleString(self):
875 titleStr = self.getTitle()
876 pos = titleStr.find(']')
878 pos = titleStr.find(')')
880 titleStr = titleStr[:pos+1]
881 Len = len(self.servicePath)
883 base_ref = self.servicePath[0]
885 end_ref = self.servicePath[Len-1]
888 nameStr = self.getServiceName(base_ref)
889 titleStr += ' ' + nameStr
890 if end_ref is not None:
895 nameStr = self.getServiceName(end_ref)
897 self.setTitle(titleStr)
900 self.servicelist.moveUp()
903 self.servicelist.moveDown()
906 del self.servicePath[:]
908 def enterPath(self, ref, justSet=False):
909 self.servicePath.append(ref)
910 self.setRoot(ref, justSet)
912 def pathUp(self, justSet=False):
913 prev = self.servicePath.pop()
915 current = self.servicePath[-1]
916 self.setRoot(current, justSet)
918 self.setCurrentSelection(prev)
921 def isBasePathEqual(self, ref):
922 if len(self.servicePath) > 1 and self.servicePath[0] == ref:
926 def isPrevPathEqual(self, ref):
927 length = len(self.servicePath)
928 if length > 1 and self.servicePath[length-2] == ref:
932 def preEnterPath(self, refstr):
935 def showAllServices(self):
936 if not self.pathChangeDisabled:
937 refstr = '%s ORDER BY name'%(self.service_types)
938 if not self.preEnterPath(refstr):
939 ref = eServiceReference(refstr)
940 currentRoot = self.getRoot()
941 if currentRoot is None or currentRoot != ref:
945 def showSatellites(self):
946 if not self.pathChangeDisabled:
947 refstr = '%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types)
948 if not self.preEnterPath(refstr):
949 ref = eServiceReference(refstr)
953 if self.isBasePathEqual(ref):
954 if self.isPrevPathEqual(ref):
956 prev = self.pathUp(justSet)
958 currentRoot = self.getRoot()
959 if currentRoot is None or currentRoot != ref:
962 self.enterPath(ref, True)
964 serviceHandler = eServiceCenter.getInstance()
965 servicelist = serviceHandler.list(ref)
966 if not servicelist is None:
968 service = servicelist.getNext()
969 if not service.valid(): #check if end of list
971 unsigned_orbpos = service.getUnsignedData(4) >> 16
972 orbpos = service.getData(4) >> 16
975 if service.getPath().find("FROM PROVIDER") != -1:
976 service_type = _("Providers")
977 elif service.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
978 service_type = _("New")
980 service_type = _("Services")
982 # why we need this cast?
983 service_name = str(nimmanager.getSatDescription(orbpos))
985 if unsigned_orbpos == 0xFFFF: #Cable
986 service_name = _("Cable")
987 elif unsigned_orbpos == 0xEEEE: #Terrestrial
988 service_name = _("Terrestrial")
990 if orbpos > 1800: # west
991 orbpos = 3600 - orbpos
995 service_name = ("%d.%d" + h) % (orbpos / 10, orbpos % 10)
996 service.setName("%s - %s" % (service_name, service_type))
997 self.servicelist.addService(service)
998 cur_ref = self.session.nav.getCurrentlyPlayingServiceReference()
1000 pos = self.service_types.rfind(':')
1001 refstr = '%s (channelID == %08x%04x%04x) && %s ORDER BY name' %(self.service_types[:pos+1],
1002 cur_ref.getUnsignedData(4), # NAMESPACE
1003 cur_ref.getUnsignedData(2), # TSID
1004 cur_ref.getUnsignedData(3), # ONID
1005 self.service_types[pos+1:])
1006 ref = eServiceReference(refstr)
1007 ref.setName(_("Current Transponder"))
1008 self.servicelist.addService(ref)
1009 self.servicelist.finishFill()
1010 if prev is not None:
1011 self.setCurrentSelection(prev)
1013 def showProviders(self):
1014 if not self.pathChangeDisabled:
1015 refstr = '%s FROM PROVIDERS ORDER BY name'%(self.service_types)
1016 if not self.preEnterPath(refstr):
1017 ref = eServiceReference(refstr)
1018 if self.isBasePathEqual(ref):
1021 currentRoot = self.getRoot()
1022 if currentRoot is None or currentRoot != ref:
1026 def changeBouquet(self, direction):
1027 if not self.pathChangeDisabled:
1028 if len(self.servicePath) > 1:
1029 #when enter satellite root list we must do some magic stuff..
1030 ref = eServiceReference('%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types))
1031 if self.isBasePathEqual(ref):
1032 self.showSatellites()
1039 ref = self.getCurrentSelection()
1042 def inBouquet(self):
1043 if self.servicePath and self.servicePath[0] == self.bouquet_root:
1048 return self.servicelist.atBegin()
1051 return self.servicelist.atEnd()
1053 def nextBouquet(self):
1054 self.changeBouquet(+1)
1056 def prevBouquet(self):
1057 self.changeBouquet(-1)
1059 def showFavourites(self):
1060 if not self.pathChangeDisabled:
1061 if not self.preEnterPath(self.bouquet_rootstr):
1062 if self.isBasePathEqual(self.bouquet_root):
1065 currentRoot = self.getRoot()
1066 if currentRoot is None or currentRoot != self.bouquet_root:
1068 self.enterPath(self.bouquet_root)
1070 def keyNumberGlobal(self, number):
1071 unichar = self.numericalTextInput.getKey(number)
1072 charstr = unichar.encode("utf-8")
1073 if len(charstr) == 1:
1074 self.servicelist.moveToChar(charstr[0])
1076 def keyAsciiCode(self):
1077 unichar = unichr(getPrevAsciiCode())
1078 charstr = unichar.encode("utf-8")
1079 if len(charstr) == 1:
1080 self.servicelist.moveToChar(charstr[0])
1083 return self.servicelist.getRoot()
1085 def getCurrentSelection(self):
1086 return self.servicelist.getCurrent()
1088 def setCurrentSelection(self, service):
1089 self.servicelist.setCurrent(service)
1091 def getBouquetList(self):
1093 serviceHandler = eServiceCenter.getInstance()
1094 if config.usage.multibouquet.value:
1095 list = serviceHandler.list(self.bouquet_root)
1101 if s.flags & eServiceReference.isDirectory:
1102 info = serviceHandler.info(s)
1104 bouquets.append((info.getName(s), s))
1107 info = serviceHandler.info(self.bouquet_root)
1109 bouquets.append((info.getName(self.bouquet_root), self.bouquet_root))
1113 def keyNumber0(self, num):
1114 if len(self.servicePath) > 1:
1117 self.keyNumberGlobal(num)
1120 if len(self.servicePath) > 1:
1121 if self.isBasePathEqual(self.bouquet_root):
1122 self.showFavourites()
1124 ref = eServiceReference('%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types))
1125 if self.isBasePathEqual(ref):
1126 self.showSatellites()
1128 ref = eServiceReference('%s FROM PROVIDERS ORDER BY name'%(self.service_types))
1129 if self.isBasePathEqual(ref):
1130 self.showProviders()
1132 self.showAllServices()
1134 def nextMarker(self):
1135 self.servicelist.moveToNextMarker()
1137 def prevMarker(self):
1138 self.servicelist.moveToPrevMarker()
1142 #config for lastservice
1143 config.tv = ConfigSubsection()
1144 config.tv.lastservice = ConfigText()
1145 config.tv.lastroot = ConfigText()
1146 config.radio = ConfigSubsection()
1147 config.radio.lastservice = ConfigText()
1148 config.radio.lastroot = ConfigText()
1149 config.servicelist = ConfigSubsection()
1150 config.servicelist.lastmode = ConfigText(default = "tv")
1152 class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG, SelectionEventInfo):
1153 def __init__(self, session):
1154 ChannelSelectionBase.__init__(self,session)
1155 ChannelSelectionEdit.__init__(self)
1156 ChannelSelectionEPG.__init__(self)
1157 SelectionEventInfo.__init__(self)
1159 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1161 "cancel": self.cancel,
1162 "ok": self.channelSelected,
1163 "keyRadio": self.setModeRadio,
1164 "keyTV": self.setModeTv,
1167 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
1169 iPlayableService.evStart: self.__evServiceStart,
1170 iPlayableService.evEnd: self.__evServiceEnd
1173 self.lastChannelRootTimer = eTimer()
1174 self.lastChannelRootTimer.callback.append(self.__onCreate)
1175 self.lastChannelRootTimer.start(100,True)
1177 self.history_tv = [ ]
1178 self.history_radio = [ ]
1179 self.history = self.history_tv
1180 self.history_pos = 0
1182 self.lastservice = config.tv.lastservice
1183 self.lastroot = config.tv.lastroot
1184 self.revertMode = None
1185 config.usage.multibouquet.addNotifier(self.multibouquet_config_changed)
1186 self.new_service_played = False
1187 self.onExecBegin.append(self.asciiOn)
1190 rcinput = eRCInput.getInstance()
1191 rcinput.setKeyboardMode(rcinput.kmAscii)
1194 rcinput = eRCInput.getInstance()
1195 rcinput.setKeyboardMode(rcinput.kmNone)
1197 def multibouquet_config_changed(self, val):
1198 self.recallBouquetMode()
1200 def __evServiceStart(self):
1201 service = self.session.nav.getCurrentService()
1203 info = service.info()
1205 refstr = info.getInfoString(iServiceInformation.sServiceref)
1206 self.servicelist.setPlayableIgnoreService(eServiceReference(refstr))
1208 def __evServiceEnd(self):
1209 self.servicelist.setPlayableIgnoreService(eServiceReference())
1212 self.rootChanged = True
1214 lastservice=eServiceReference(self.lastservice.value)
1215 if lastservice.valid():
1216 self.setCurrentSelection(lastservice)
1218 def setModeTv(self):
1219 if self.revertMode is None and config.servicelist.lastmode.value == "radio":
1220 self.revertMode = MODE_RADIO
1221 self.history = self.history_tv
1222 self.lastservice = config.tv.lastservice
1223 self.lastroot = config.tv.lastroot
1224 config.servicelist.lastmode.value = "tv"
1228 def setModeRadio(self):
1229 if self.revertMode is None and config.servicelist.lastmode.value == "tv":
1230 self.revertMode = MODE_TV
1231 if config.usage.e1like_radio_mode.value:
1232 self.history = self.history_radio
1233 self.lastservice = config.radio.lastservice
1234 self.lastroot = config.radio.lastroot
1235 config.servicelist.lastmode.value = "radio"
1239 def __onCreate(self):
1240 if config.usage.e1like_radio_mode.value:
1241 if config.servicelist.lastmode.value == "tv":
1247 lastservice=eServiceReference(self.lastservice.value)
1248 if lastservice.valid():
1251 def channelSelected(self):
1252 ref = self.getCurrentSelection()
1254 self.toggleMoveMarked()
1255 elif (ref.flags & 7) == 7:
1257 elif self.bouquet_mark_edit != OFF:
1258 if not (self.bouquet_mark_edit == EDIT_ALTERNATIVES and ref.flags & eServiceReference.isGroup):
1260 elif not (ref.flags & eServiceReference.isMarker): # no marker
1261 root = self.getRoot()
1262 if not root or not (root.flags & eServiceReference.isGroup):
1267 #called from infoBar and channelSelected
1269 self.revertMode=None
1270 ref = self.session.nav.getCurrentlyPlayingServiceReference()
1271 nref = self.getCurrentSelection()
1272 if ref is None or ref != nref:
1273 self.new_service_played = True
1274 self.session.nav.playService(nref)
1276 self.saveChannel(nref)
1277 config.servicelist.lastmode.save()
1278 self.addToHistory(nref)
1280 def newServicePlayed(self):
1281 ret = self.new_service_played
1282 self.new_service_played = False
1285 def addToHistory(self, ref):
1286 if self.servicePath is not None:
1287 tmp=self.servicePath[:]
1290 del self.history[self.history_pos+1:]
1293 self.history.append(tmp)
1294 hlen = len(self.history)
1295 if hlen > HISTORYSIZE:
1298 self.history_pos = hlen-1
1300 def historyBack(self):
1301 hlen = len(self.history)
1302 if hlen > 1 and self.history_pos > 0:
1303 self.history_pos -= 1
1304 self.setHistoryPath()
1306 def historyNext(self):
1307 hlen = len(self.history)
1308 if hlen > 1 and self.history_pos < (hlen-1):
1309 self.history_pos += 1
1310 self.setHistoryPath()
1312 def setHistoryPath(self):
1313 path = self.history[self.history_pos][:]
1315 del self.servicePath[:]
1316 self.servicePath += path
1319 cur_root = self.getRoot()
1320 if cur_root and cur_root != root:
1322 self.session.nav.playService(ref)
1323 self.setCurrentSelection(ref)
1324 self.saveChannel(ref)
1328 for i in self.servicePath:
1329 path += i.toString()
1331 if path and path != self.lastroot.value:
1332 self.lastroot.value = path
1333 self.lastroot.save()
1335 def restoreRoot(self):
1336 tmp = [x for x in self.lastroot.value.split(';') if x != '']
1337 current = [x.toString() for x in self.servicePath]
1338 if tmp != current or self.rootChanged:
1342 self.servicePath.append(eServiceReference(i))
1345 path = self.servicePath.pop()
1346 self.enterPath(path)
1348 self.showFavourites()
1350 self.rootChanged = False
1352 def preEnterPath(self, refstr):
1353 if self.servicePath and self.servicePath[0] != eServiceReference(refstr):
1354 pathstr = self.lastroot.value
1355 if pathstr is not None and pathstr.find(refstr) == 0:
1357 lastservice=eServiceReference(self.lastservice.value)
1358 if lastservice.valid():
1359 self.setCurrentSelection(lastservice)
1363 def saveChannel(self, ref):
1365 refstr = ref.toString()
1368 if refstr != self.lastservice.value:
1369 self.lastservice.value = refstr
1370 self.lastservice.save()
1372 def setCurrentServicePath(self, path):
1374 self.history[self.history_pos] = path
1376 self.history.append(path)
1377 self.setHistoryPath()
1379 def getCurrentServicePath(self):
1381 return self.history[self.history_pos]
1384 def recallPrevService(self):
1385 hlen = len(self.history)
1387 if self.history_pos == hlen-1:
1388 tmp = self.history[self.history_pos]
1389 self.history[self.history_pos] = self.history[self.history_pos-1]
1390 self.history[self.history_pos-1] = tmp
1392 tmp = self.history[self.history_pos+1]
1393 self.history[self.history_pos+1] = self.history[self.history_pos]
1394 self.history[self.history_pos] = tmp
1395 self.setHistoryPath()
1398 if self.revertMode is None:
1400 lastservice=eServiceReference(self.lastservice.value)
1401 if lastservice.valid() and self.getCurrentSelection() != lastservice:
1402 self.setCurrentSelection(lastservice)
1403 elif self.revertMode == MODE_TV:
1405 elif self.revertMode == MODE_RADIO:
1407 self.revertMode = None
1411 class RadioInfoBar(Screen):
1412 def __init__(self, session):
1413 Screen.__init__(self, session)
1414 self["RdsDecoder"] = RdsDecoder(self.session.nav)
1416 class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG, InfoBarBase):
1417 ALLOW_SUSPEND = True
1419 def __init__(self, session, infobar):
1420 ChannelSelectionBase.__init__(self, session)
1421 ChannelSelectionEdit.__init__(self)
1422 ChannelSelectionEPG.__init__(self)
1423 InfoBarBase.__init__(self)
1424 self.infobar = infobar
1425 self.onLayoutFinish.append(self.onCreate)
1427 self.info = session.instantiateDialog(RadioInfoBar) # our simple infobar
1429 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1431 "keyTV": self.cancel,
1432 "keyRadio": self.cancel,
1433 "cancel": self.cancel,
1434 "ok": self.channelSelected,
1437 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
1439 iPlayableService.evStart: self.__evServiceStart,
1440 iPlayableService.evEnd: self.__evServiceEnd
1443 ########## RDS Radiotext / Rass Support BEGIN
1444 self.infobar = infobar # reference to real infobar (the one and only)
1445 self["RdsDecoder"] = self.info["RdsDecoder"]
1446 self["RdsActions"] = HelpableActionMap(self, "InfobarRdsActions",
1448 "startRassInteractive": (self.startRassInteractive, _("View Rass interactive..."))
1450 self["RdsActions"].setEnabled(False)
1451 infobar.rds_display.onRassInteractivePossibilityChanged.append(self.RassInteractivePossibilityChanged)
1452 self.onClose.append(self.__onClose)
1454 def __onClose(self):
1455 lastservice=eServiceReference(config.tv.lastservice.value)
1456 self.session.nav.playService(lastservice)
1458 def startRassInteractive(self):
1460 self.infobar.rass_interactive = self.session.openWithCallback(self.RassInteractiveClosed, RassInteractive)
1462 def RassInteractiveClosed(self):
1464 self.infobar.rass_interactive = None
1465 self.infobar.RassSlidePicChanged()
1467 def RassInteractivePossibilityChanged(self, state):
1468 self["RdsActions"].setEnabled(state)
1469 ########## RDS Radiotext / Rass Support END
1472 self.infobar.rds_display.onRassInteractivePossibilityChanged.remove(self.RassInteractivePossibilityChanged)
1474 #set previous tv service
1477 def __evServiceStart(self):
1478 service = self.session.nav.getCurrentService()
1480 info = service.info()
1482 refstr = info.getInfoString(iServiceInformation.sServiceref)
1483 self.servicelist.setPlayableIgnoreService(eServiceReference(refstr))
1485 def __evServiceEnd(self):
1486 self.servicelist.setPlayableIgnoreService(eServiceReference())
1490 for i in self.servicePathRadio:
1491 path += i.toString()
1493 if path and path != config.radio.lastroot.value:
1494 config.radio.lastroot.value = path
1495 config.radio.lastroot.save()
1497 def restoreRoot(self):
1498 tmp = [x for x in config.radio.lastroot.value.split(';') if x != '']
1499 current = [x.toString() for x in self.servicePath]
1500 if tmp != current or self.rootChanged:
1503 self.servicePathRadio.append(eServiceReference(i))
1506 path = self.servicePathRadio.pop()
1507 self.enterPath(path)
1509 self.showFavourites()
1511 self.rootChanged = False
1513 def preEnterPath(self, refstr):
1514 if self.servicePathRadio and self.servicePathRadio[0] != eServiceReference(refstr):
1515 pathstr = config.radio.lastroot.value
1516 if pathstr is not None and pathstr.find(refstr) == 0:
1518 lastservice=eServiceReference(config.radio.lastservice.value)
1519 if lastservice.valid():
1520 self.setCurrentSelection(lastservice)
1527 lastservice=eServiceReference(config.radio.lastservice.value)
1528 if lastservice.valid():
1529 self.servicelist.setCurrent(lastservice)
1530 self.session.nav.playService(lastservice)
1532 self.session.nav.stopService()
1535 def channelSelected(self): # just return selected service
1536 ref = self.getCurrentSelection()
1538 self.toggleMoveMarked()
1539 elif (ref.flags & 7) == 7:
1541 elif self.bouquet_mark_edit != OFF:
1542 if not (self.bouquet_mark_edit == EDIT_ALTERNATIVES and ref.flags & eServiceReference.isGroup):
1544 elif not (ref.flags & eServiceReference.isMarker): # no marker
1545 cur_root = self.getRoot()
1546 if not cur_root or not (cur_root.flags & eServiceReference.isGroup):
1547 playingref = self.session.nav.getCurrentlyPlayingServiceReference()
1548 if playingref is None or playingref != ref:
1549 self.session.nav.playService(ref)
1550 config.radio.lastservice.value = ref.toString()
1551 config.radio.lastservice.save()
1554 class SimpleChannelSelection(ChannelSelectionBase):
1555 def __init__(self, session, title):
1556 ChannelSelectionBase.__init__(self, session)
1557 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1559 "cancel": self.close,
1560 "ok": self.channelSelected,
1561 "keyRadio": self.setModeRadio,
1562 "keyTV": self.setModeTv,
1565 self.onLayoutFinish.append(self.layoutFinished)
1567 def layoutFinished(self):
1570 def channelSelected(self): # just return selected service
1571 ref = self.getCurrentSelection()
1572 if (ref.flags & 7) == 7:
1574 elif not (ref.flags & eServiceReference.isMarker):
1575 ref = self.getCurrentSelection()
1578 def setModeTv(self):
1580 self.showFavourites()
1582 def setModeRadio(self):
1584 self.showFavourites()