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.setAnimationMode(0)
235 self.session.pip.show()
236 newservice = self.csel.servicelist.getCurrent()
237 if self.session.pip.playService(newservice):
238 self.session.pipshown = True
239 self.session.pip.servicePath = self.csel.getCurrentServicePath()
242 self.session.pipshown = False
244 self.session.openWithCallback(self.close, MessageBox, _("Could not open Picture in Picture"), MessageBox.TYPE_ERROR)
246 def addServiceToBouquetSelected(self):
247 bouquets = self.csel.getBouquetList()
252 if cnt > 1: # show bouquet list
253 self.bsel = self.session.openWithCallback(self.bouquetSelClosed, BouquetSelector, bouquets, self.addCurrentServiceToBouquet)
254 elif cnt == 1: # add to only one existing bouquet
255 self.addCurrentServiceToBouquet(bouquets[0][1], closeBouquetSelection = False)
257 def bouquetSelClosed(self, recursive):
262 def removeSatelliteServices(self):
263 curpath = self.csel.getCurrentSelection().getPath()
264 idx = curpath.find("satellitePosition == ")
266 tmp = curpath[idx+21:]
269 satpos = int(tmp[:idx])
270 eDVBDB.getInstance().removeServices(-1, -1, -1, satpos)
273 def copyCurrentToBouquetList(self):
274 self.csel.copyCurrentToBouquetList()
277 def removeBouquet(self):
278 self.csel.removeBouquet()
281 def showMarkerInputBox(self):
282 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)
284 def markerInputCallback(self, marker):
285 if marker is not None:
286 self.csel.addMarker(marker)
289 def addCurrentServiceToBouquet(self, dest, closeBouquetSelection = True):
290 self.csel.addServiceToBouquet(dest)
291 if self.bsel is not None:
292 self.bsel.close(True)
294 self.close(closeBouquetSelection) # close bouquet selection
296 def removeCurrentService(self):
297 self.csel.removeCurrentService()
300 def toggleMoveMode(self):
301 self.csel.toggleMoveMode()
304 def bouquetMarkStart(self):
305 self.csel.startMarkedEdit(EDIT_BOUQUET)
308 def bouquetMarkEnd(self):
309 self.csel.endMarkedEdit(abort=False)
312 def bouquetMarkAbort(self):
313 self.csel.endMarkedEdit(abort=True)
316 def removeNewFoundFlag(self):
317 eDVBDB.getInstance().removeFlag(self.csel.getCurrentSelection(), FLAG_SERVICE_NEW_FOUND)
320 def removeAllNewFoundFlags(self):
321 curpath = self.csel.getCurrentSelection().getPath()
322 idx = curpath.find("satellitePosition == ")
324 tmp = curpath[idx+21:]
327 satpos = int(tmp[:idx])
328 eDVBDB.getInstance().removeFlags(FLAG_SERVICE_NEW_FOUND, -1, -1, -1, satpos)
331 def editAlternativeServices(self):
332 self.csel.startMarkedEdit(EDIT_ALTERNATIVES)
335 def showAlternativeServices(self):
336 self.csel.enterPath(self.csel.getCurrentSelection())
339 def removeAlternativeServices(self):
340 self.csel.removeAlternativeServices()
343 def addAlternativeServices(self):
344 self.csel.addAlternativeServices()
345 self.csel.startMarkedEdit(EDIT_ALTERNATIVES)
348 class SelectionEventInfo:
350 self["ServiceEvent"] = ServiceEvent()
351 self.servicelist.connectSelChanged(self.__selectionChanged)
352 self.timer = eTimer()
353 self.timer.callback.append(self.updateEventInfo)
354 self.onShown.append(self.__selectionChanged)
356 def __selectionChanged(self):
358 self.timer.start(100, True)
360 def updateEventInfo(self):
361 cur = self.getCurrentSelection()
362 self["ServiceEvent"].newService(cur)
364 class ChannelSelectionEPG:
366 self["ChannelSelectEPGActions"] = ActionMap(["ChannelSelectEPGActions"],
368 "showEPGList": self.showEPGList,
371 def showEPGList(self):
372 ref=self.getCurrentSelection()
374 self.savedService = ref
375 self.session.openWithCallback(self.SingleServiceEPGClosed, EPGSelection, ref, serviceChangeCB=self.changeServiceCB)
377 def SingleServiceEPGClosed(self, ret=False):
378 self.setCurrentSelection(self.savedService)
380 def changeServiceCB(self, direction, epg):
381 beg = self.getCurrentSelection()
387 cur = self.getCurrentSelection()
388 if cur == beg or not (cur.flags & eServiceReference.isMarker):
390 epg.setService(ServiceReference(self.getCurrentSelection()))
392 class ChannelSelectionEdit:
394 self.entry_marked = False
395 self.movemode = False
396 self.bouquet_mark_edit = OFF
397 self.mutableList = None
399 self.saved_title = None
400 self.saved_root = None
402 class ChannelSelectionEditActionMap(ActionMap):
403 def __init__(self, csel, contexts = [ ], actions = { }, prio=0):
404 ActionMap.__init__(self, contexts, actions, prio)
407 def action(self, contexts, action):
408 if action == "cancel":
409 self.csel.handleEditCancel()
410 return 0 # fall-trough
412 return 0 # fall-trough
414 return ActionMap.action(self, contexts, action)
416 self["ChannelSelectEditActions"] = ChannelSelectionEditActionMap(self, ["ChannelSelectEditActions", "OkCancelActions"],
418 "contextMenu": self.doContext,
421 def getMutableList(self, root=eServiceReference()):
422 if not self.mutableList is None:
423 return self.mutableList
424 serviceHandler = eServiceCenter.getInstance()
427 list = root and serviceHandler.list(root)
429 return list.startEdit()
432 def buildBouquetID(self, str):
436 if (c >= 'a' and c <= 'z') or (c >= '0' and c <= '9'):
442 def addMarker(self, name):
443 current = self.servicelist.getCurrent()
444 mutableList = self.getMutableList()
447 str = '1:64:%d:0:0:0:0:0:0:0::%s'%(cnt, name)
448 ref = eServiceReference(str)
449 if current and current.valid():
450 if not mutableList.addService(ref, current):
451 self.servicelist.addService(ref, True)
452 mutableList.flushChanges()
454 elif not mutableList.addService(ref):
455 self.servicelist.addService(ref, True)
456 mutableList.flushChanges()
460 def addAlternativeServices(self):
461 cur_service = ServiceReference(self.getCurrentSelection())
462 root = self.getRoot()
463 cur_root = root and ServiceReference(root)
464 mutableBouquet = cur_root.list().startEdit()
466 name = cur_service.getServiceName()
468 if self.mode == MODE_TV:
469 str = '1:134:1:0:0:0:0:0:0:0:FROM BOUQUET \"alternatives.%s.tv\" ORDER BY bouquet'%(self.buildBouquetID(name))
471 str = '1:134:2:0:0:0:0:0:0:0:FROM BOUQUET \"alternatives.%s.radio\" ORDER BY bouquet'%(self.buildBouquetID(name))
472 new_ref = ServiceReference(str)
473 if not mutableBouquet.addService(new_ref.ref, cur_service.ref):
474 mutableBouquet.removeService(cur_service.ref)
475 mutableBouquet.flushChanges()
476 eDVBDB.getInstance().reloadBouquets()
477 mutableAlternatives = new_ref.list().startEdit()
478 if mutableAlternatives:
479 mutableAlternatives.setListName(name)
480 if mutableAlternatives.addService(cur_service.ref):
481 print "add", cur_service.ref.toString(), "to new alternatives failed"
482 mutableAlternatives.flushChanges()
483 self.servicelist.addService(new_ref.ref, True)
484 self.servicelist.removeCurrent()
485 self.servicelist.moveUp()
487 print "get mutable list for new created alternatives failed"
489 print "add", str, "to", cur_root.getServiceName(), "failed"
491 print "bouquetlist is not editable"
493 def addBouquet(self, bName, services):
494 serviceHandler = eServiceCenter.getInstance()
495 mutableBouquetList = serviceHandler.list(self.bouquet_root).startEdit()
496 if mutableBouquetList:
497 if self.mode == MODE_TV:
499 str = '1:7:1:0:0:0:0:0:0:0:FROM BOUQUET \"userbouquet.%s.tv\" ORDER BY bouquet'%(self.buildBouquetID(bName))
502 str = '1:7:2:0:0:0:0:0:0:0:FROM BOUQUET \"userbouquet.%s.radio\" ORDER BY bouquet'%(self.buildBouquetID(bName))
503 new_bouquet_ref = eServiceReference(str)
504 if not mutableBouquetList.addService(new_bouquet_ref):
505 mutableBouquetList.flushChanges()
506 eDVBDB.getInstance().reloadBouquets()
507 mutableBouquet = serviceHandler.list(new_bouquet_ref).startEdit()
509 mutableBouquet.setListName(bName)
510 if services is not None:
511 for service in services:
512 if mutableBouquet.addService(service):
513 print "add", service.toString(), "to new bouquet failed"
514 mutableBouquet.flushChanges()
516 print "get mutable list for new created bouquet failed"
517 # do some voodoo to check if current_root is equal to bouquet_root
518 cur_root = self.getRoot();
519 str1 = cur_root and cur_root.toString()
520 pos1 = str1 and str1.find("FROM BOUQUET") or -1
521 pos2 = self.bouquet_rootstr.find("FROM BOUQUET")
522 if pos1 != -1 and pos2 != -1 and str1[pos1:] == self.bouquet_rootstr[pos2:]:
523 self.servicelist.addService(new_bouquet_ref)
525 print "add", str, "to bouquets failed"
527 print "bouquetlist is not editable"
529 def copyCurrentToBouquetList(self):
530 provider = ServiceReference(self.getCurrentSelection())
531 providerName = provider.getServiceName()
532 serviceHandler = eServiceCenter.getInstance()
533 services = serviceHandler.list(provider.ref)
534 self.addBouquet(providerName, services and services.getContent('R', True))
536 def removeAlternativeServices(self):
537 cur_service = ServiceReference(self.getCurrentSelection())
538 root = self.getRoot()
539 cur_root = root and ServiceReference(root)
540 list = cur_service.list()
541 first_in_alternative = list and list.getNext()
542 if first_in_alternative:
543 edit_root = cur_root and cur_root.list().startEdit()
545 if not edit_root.addService(first_in_alternative, cur_service.ref):
546 self.servicelist.addService(first_in_alternative, True)
548 print "couldn't add first alternative service to current root"
550 print "couldn't edit current root!!"
552 print "remove empty alternative list !!"
554 self.servicelist.moveUp()
556 def removeBouquet(self):
557 refstr = self.getCurrentSelection().toString()
558 print "removeBouquet", refstr
559 self.bouquetNumOffsetCache = { }
560 pos = refstr.find('FROM BOUQUET "')
563 refstr = refstr[pos+14:]
564 pos = refstr.find('"')
566 filename = eEnv.resolve('${sysconfdir}/enigma2/') + refstr[:pos]
567 self.removeCurrentService()
569 if filename is not None:
572 print "error during remove of", filename
574 # multiple marked entry stuff ( edit mode, later multiepg selection )
575 def startMarkedEdit(self, type):
576 self.savedPath = self.servicePath[:]
577 if type == EDIT_ALTERNATIVES:
578 self.enterPath(self.getCurrentSelection())
579 self.mutableList = self.getMutableList()
580 # add all services from the current list to internal marked set in listboxservicecontent
581 self.clearMarks() # this clears the internal marked set in the listboxservicecontent
582 self.saved_title = self.getTitle()
583 pos = self.saved_title.find(')')
584 new_title = self.saved_title[:pos+1]
585 if type == EDIT_ALTERNATIVES:
586 self.bouquet_mark_edit = EDIT_ALTERNATIVES
587 new_title += ' ' + _("[alternative edit]")
589 self.bouquet_mark_edit = EDIT_BOUQUET
590 if config.usage.multibouquet.value:
591 new_title += ' ' + _("[bouquet edit]")
593 new_title += ' ' + _("[favourite edit]")
594 self.setTitle(new_title)
595 self.__marked = self.servicelist.getRootServices()
596 for x in self.__marked:
597 self.servicelist.addMarked(eServiceReference(x))
598 self.showAllServices()
600 def endMarkedEdit(self, abort):
601 if not abort and self.mutableList is not None:
602 self.bouquetNumOffsetCache = { }
603 new_marked = set(self.servicelist.getMarked())
604 old_marked = set(self.__marked)
605 removed = old_marked - new_marked
606 added = new_marked - old_marked
610 self.mutableList.removeService(eServiceReference(x))
613 self.mutableList.addService(eServiceReference(x))
615 self.mutableList.flushChanges()
618 self.bouquet_mark_edit = OFF
619 self.mutableList = None
620 self.setTitle(self.saved_title)
621 self.saved_title = None
622 # self.servicePath is just a reference to servicePathTv or Radio...
623 # so we never ever do use the asignment operator in self.servicePath
624 del self.servicePath[:] # remove all elements
625 self.servicePath += self.savedPath # add saved elements
627 self.setRoot(self.servicePath[-1])
629 def clearMarks(self):
630 self.servicelist.clearMarks()
633 ref = self.servicelist.getCurrent()
634 if self.servicelist.isMarked(ref):
635 self.servicelist.removeMarked(ref)
637 self.servicelist.addMarked(ref)
639 def removeCurrentService(self):
640 ref = self.servicelist.getCurrent()
641 mutableList = self.getMutableList()
642 if ref.valid() and mutableList is not None:
643 if not mutableList.removeService(ref):
644 self.bouquetNumOffsetCache = { }
645 mutableList.flushChanges() #FIXME dont flush on each single removed service
646 self.servicelist.removeCurrent()
648 def addServiceToBouquet(self, dest, service=None):
649 mutableList = self.getMutableList(dest)
650 if not mutableList is None:
651 if service is None: #use current selected service
652 service = self.servicelist.getCurrent()
653 if not mutableList.addService(service):
654 self.bouquetNumOffsetCache = { }
655 mutableList.flushChanges()
656 # do some voodoo to check if current_root is equal to dest
657 cur_root = self.getRoot();
658 str1 = cur_root and cur_root.toString() or -1
659 str2 = dest.toString()
660 pos1 = str1.find("FROM BOUQUET")
661 pos2 = str2.find("FROM BOUQUET")
662 if pos1 != -1 and pos2 != -1 and str1[pos1:] == str2[pos2:]:
663 self.servicelist.addService(service)
665 def toggleMoveMode(self):
667 if self.entry_marked:
668 self.toggleMoveMarked() # unmark current entry
669 self.movemode = False
670 self.pathChangeDisabled = False # re-enable path change
671 self.mutableList.flushChanges() # FIXME add check if changes was made
672 self.mutableList = None
673 self.setTitle(self.saved_title)
674 self.saved_title = None
675 cur_root = self.getRoot()
676 if cur_root and cur_root == self.bouquet_root:
677 self.bouquetNumOffsetCache = { }
679 self.mutableList = self.getMutableList()
681 self.pathChangeDisabled = True # no path change allowed in movemode
682 self.saved_title = self.getTitle()
683 new_title = self.saved_title
684 pos = self.saved_title.find(')')
685 new_title = self.saved_title[:pos+1] + ' ' + _("[move mode]") + self.saved_title[pos+1:]
686 self.setTitle(new_title);
688 def handleEditCancel(self):
689 if self.movemode: #movemode active?
690 self.channelSelected() # unmark
691 self.toggleMoveMode() # disable move mode
692 elif self.bouquet_mark_edit != OFF:
693 self.endMarkedEdit(True) # abort edit mode
695 def toggleMoveMarked(self):
696 if self.entry_marked:
697 self.servicelist.setCurrentMarked(False)
698 self.entry_marked = False
700 self.servicelist.setCurrentMarked(True)
701 self.entry_marked = True
704 self.session.openWithCallback(self.exitContext, ChannelContextMenu, self)
706 def exitContext(self, close = False):
713 # type 1 = digital television service
714 # type 4 = nvod reference service (NYI)
715 # type 17 = MPEG-2 HD digital television service
716 # type 22 = advanced codec SD digital television
717 # type 24 = advanced codec SD NVOD reference service (NYI)
718 # type 25 = advanced codec HD digital television
719 # type 27 = advanced codec HD NVOD reference service (NYI)
720 # type 2 = digital radio sound service
721 # type 10 = advanced codec digital radio sound service
723 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)'
724 service_types_radio = '1:7:2:0:0:0:0:0:0:0:(type == 2) || (type == 10)'
726 class ChannelSelectionBase(Screen):
727 def __init__(self, session):
728 Screen.__init__(self, session)
730 self["key_red"] = Button(_("All"))
731 self["key_green"] = Button(_("Satellites"))
732 self["key_yellow"] = Button(_("Provider"))
733 self["key_blue"] = Button(_("Favourites"))
735 self["list"] = ServiceList()
736 self.servicelist = self["list"]
738 self.numericalTextInput = NumericalTextInput()
739 self.numericalTextInput.setUseableChars(u'1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ')
741 self.servicePathTV = [ ]
742 self.servicePathRadio = [ ]
743 self.servicePath = [ ]
744 self.rootChanged = False
748 self.pathChangeDisabled = False
750 self.bouquetNumOffsetCache = { }
752 self["ChannelSelectBaseActions"] = NumberActionMap(["ChannelSelectBaseActions", "NumberActions", "InputAsciiActions"],
754 "showFavourites": self.showFavourites,
755 "showAllServices": self.showAllServices,
756 "showProviders": self.showProviders,
757 "showSatellites": self.showSatellites,
758 "nextBouquet": self.nextBouquet,
759 "prevBouquet": self.prevBouquet,
760 "nextMarker": self.nextMarker,
761 "prevMarker": self.prevMarker,
762 "gotAsciiCode": self.keyAsciiCode,
763 "1": self.keyNumberGlobal,
764 "2": self.keyNumberGlobal,
765 "3": self.keyNumberGlobal,
766 "4": self.keyNumberGlobal,
767 "5": self.keyNumberGlobal,
768 "6": self.keyNumberGlobal,
769 "7": self.keyNumberGlobal,
770 "8": self.keyNumberGlobal,
771 "9": self.keyNumberGlobal,
774 self.recallBouquetMode()
776 def getBouquetNumOffset(self, bouquet):
777 if not config.usage.multibouquet.value:
779 str = bouquet.toString()
781 if not self.bouquetNumOffsetCache.has_key(str):
782 serviceHandler = eServiceCenter.getInstance()
783 bouquetlist = serviceHandler.list(self.bouquet_root)
784 if not bouquetlist is None:
786 bouquetIterator = bouquetlist.getNext()
787 if not bouquetIterator.valid(): #end of list
789 self.bouquetNumOffsetCache[bouquetIterator.toString()]=offsetCount
790 if not (bouquetIterator.flags & eServiceReference.isDirectory):
792 servicelist = serviceHandler.list(bouquetIterator)
793 if not servicelist is None:
795 serviceIterator = servicelist.getNext()
796 if not serviceIterator.valid(): #check if end of list
798 playable = not (serviceIterator.flags & (eServiceReference.isDirectory|eServiceReference.isMarker))
801 return self.bouquetNumOffsetCache.get(str, offsetCount)
803 def recallBouquetMode(self):
804 if self.mode == MODE_TV:
805 self.service_types = service_types_tv
806 if config.usage.multibouquet.value:
807 self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "bouquets.tv" ORDER BY bouquet'
809 self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.tv" ORDER BY bouquet'%(self.service_types)
811 self.service_types = service_types_radio
812 if config.usage.multibouquet.value:
813 self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "bouquets.radio" ORDER BY bouquet'
815 self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.radio" ORDER BY bouquet'%(self.service_types)
816 self.bouquet_root = eServiceReference(self.bouquet_rootstr)
820 self.servicePath = self.servicePathTV
821 self.recallBouquetMode()
822 title = self.getTitle()
823 pos = title.find(" (")
829 def setRadioMode(self):
830 self.mode = MODE_RADIO
831 self.servicePath = self.servicePathRadio
832 self.recallBouquetMode()
833 title = self.getTitle()
834 pos = title.find(" (")
840 def setRoot(self, root, justSet=False):
841 path = root.getPath()
842 inBouquetRootList = path.find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
843 pos = path.find('FROM BOUQUET')
844 isBouquet = (pos != -1) and (root.flags & eServiceReference.isDirectory)
845 if not inBouquetRootList and isBouquet:
846 self.servicelist.setMode(ServiceList.MODE_FAVOURITES)
847 self.servicelist.setNumberOffset(self.getBouquetNumOffset(root))
849 self.servicelist.setMode(ServiceList.MODE_NORMAL)
850 self.servicelist.setRoot(root, justSet)
851 self.rootChanged = True
852 self.buildTitleString()
854 def removeModeStr(self, str):
855 if self.mode == MODE_TV:
856 pos = str.find(' (TV)')
858 pos = str.find(' (Radio)')
863 def getServiceName(self, ref):
864 str = self.removeModeStr(ServiceReference(ref).getServiceName())
866 pathstr = ref.getPath()
867 if 'FROM PROVIDERS' in pathstr:
869 if 'FROM SATELLITES' in pathstr:
870 return _("Satellites")
871 if ') ORDER BY name' in pathstr:
875 def buildTitleString(self):
876 titleStr = self.getTitle()
877 pos = titleStr.find(']')
879 pos = titleStr.find(')')
881 titleStr = titleStr[:pos+1]
882 Len = len(self.servicePath)
884 base_ref = self.servicePath[0]
886 end_ref = self.servicePath[Len-1]
889 nameStr = self.getServiceName(base_ref)
890 titleStr += ' ' + nameStr
891 if end_ref is not None:
896 nameStr = self.getServiceName(end_ref)
898 self.setTitle(titleStr)
901 self.servicelist.moveUp()
904 self.servicelist.moveDown()
907 del self.servicePath[:]
909 def enterPath(self, ref, justSet=False):
910 self.servicePath.append(ref)
911 self.setRoot(ref, justSet)
913 def pathUp(self, justSet=False):
914 prev = self.servicePath.pop()
916 current = self.servicePath[-1]
917 self.setRoot(current, justSet)
919 self.setCurrentSelection(prev)
922 def isBasePathEqual(self, ref):
923 if len(self.servicePath) > 1 and self.servicePath[0] == ref:
927 def isPrevPathEqual(self, ref):
928 length = len(self.servicePath)
929 if length > 1 and self.servicePath[length-2] == ref:
933 def preEnterPath(self, refstr):
936 def showAllServices(self):
937 if not self.pathChangeDisabled:
938 refstr = '%s ORDER BY name'%(self.service_types)
939 if not self.preEnterPath(refstr):
940 ref = eServiceReference(refstr)
941 currentRoot = self.getRoot()
942 if currentRoot is None or currentRoot != ref:
946 def showSatellites(self):
947 if not self.pathChangeDisabled:
948 refstr = '%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types)
949 if not self.preEnterPath(refstr):
950 ref = eServiceReference(refstr)
954 if self.isBasePathEqual(ref):
955 if self.isPrevPathEqual(ref):
957 prev = self.pathUp(justSet)
959 currentRoot = self.getRoot()
960 if currentRoot is None or currentRoot != ref:
963 self.enterPath(ref, True)
965 serviceHandler = eServiceCenter.getInstance()
966 servicelist = serviceHandler.list(ref)
967 if not servicelist is None:
969 service = servicelist.getNext()
970 if not service.valid(): #check if end of list
972 unsigned_orbpos = service.getUnsignedData(4) >> 16
973 orbpos = service.getData(4) >> 16
976 if service.getPath().find("FROM PROVIDER") != -1:
977 service_type = _("Providers")
978 elif service.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
979 service_type = _("New")
981 service_type = _("Services")
983 # why we need this cast?
984 service_name = str(nimmanager.getSatDescription(orbpos))
986 if unsigned_orbpos == 0xFFFF: #Cable
987 service_name = _("Cable")
988 elif unsigned_orbpos == 0xEEEE: #Terrestrial
989 service_name = _("Terrestrial")
991 if orbpos > 1800: # west
992 orbpos = 3600 - orbpos
996 service_name = ("%d.%d" + h) % (orbpos / 10, orbpos % 10)
997 service.setName("%s - %s" % (service_name, service_type))
998 self.servicelist.addService(service)
999 cur_ref = self.session.nav.getCurrentlyPlayingServiceReference()
1001 pos = self.service_types.rfind(':')
1002 refstr = '%s (channelID == %08x%04x%04x) && %s ORDER BY name' %(self.service_types[:pos+1],
1003 cur_ref.getUnsignedData(4), # NAMESPACE
1004 cur_ref.getUnsignedData(2), # TSID
1005 cur_ref.getUnsignedData(3), # ONID
1006 self.service_types[pos+1:])
1007 ref = eServiceReference(refstr)
1008 ref.setName(_("Current Transponder"))
1009 self.servicelist.addService(ref)
1010 self.servicelist.finishFill()
1011 if prev is not None:
1012 self.setCurrentSelection(prev)
1014 def showProviders(self):
1015 if not self.pathChangeDisabled:
1016 refstr = '%s FROM PROVIDERS ORDER BY name'%(self.service_types)
1017 if not self.preEnterPath(refstr):
1018 ref = eServiceReference(refstr)
1019 if self.isBasePathEqual(ref):
1022 currentRoot = self.getRoot()
1023 if currentRoot is None or currentRoot != ref:
1027 def changeBouquet(self, direction):
1028 if not self.pathChangeDisabled:
1029 if len(self.servicePath) > 1:
1030 #when enter satellite root list we must do some magic stuff..
1031 ref = eServiceReference('%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types))
1032 if self.isBasePathEqual(ref):
1033 self.showSatellites()
1040 ref = self.getCurrentSelection()
1043 def inBouquet(self):
1044 if self.servicePath and self.servicePath[0] == self.bouquet_root:
1049 return self.servicelist.atBegin()
1052 return self.servicelist.atEnd()
1054 def nextBouquet(self):
1055 self.changeBouquet(+1)
1057 def prevBouquet(self):
1058 self.changeBouquet(-1)
1060 def showFavourites(self):
1061 if not self.pathChangeDisabled:
1062 if not self.preEnterPath(self.bouquet_rootstr):
1063 if self.isBasePathEqual(self.bouquet_root):
1066 currentRoot = self.getRoot()
1067 if currentRoot is None or currentRoot != self.bouquet_root:
1069 self.enterPath(self.bouquet_root)
1071 def keyNumberGlobal(self, number):
1072 unichar = self.numericalTextInput.getKey(number)
1073 charstr = unichar.encode("utf-8")
1074 if len(charstr) == 1:
1075 self.servicelist.moveToChar(charstr[0])
1077 def keyAsciiCode(self):
1078 #unichar = unichr(getPrevAsciiCode())
1079 from Components.config import getCharValue
1080 unichar = getCharValue(getPrevAsciiCode())
1083 if len(str(unichar)) > 1:
1085 charstr = unichar.encode("utf-8")
1086 if len(charstr) == 1:
1087 self.servicelist.moveToChar(charstr[0])
1090 return self.servicelist.getRoot()
1092 def getCurrentSelection(self):
1093 return self.servicelist.getCurrent()
1095 def setCurrentSelection(self, service):
1096 self.servicelist.setCurrent(service)
1098 def getBouquetList(self):
1100 serviceHandler = eServiceCenter.getInstance()
1101 if config.usage.multibouquet.value:
1102 list = serviceHandler.list(self.bouquet_root)
1108 if s.flags & eServiceReference.isDirectory:
1109 info = serviceHandler.info(s)
1111 bouquets.append((info.getName(s), s))
1114 info = serviceHandler.info(self.bouquet_root)
1116 bouquets.append((info.getName(self.bouquet_root), self.bouquet_root))
1120 def keyNumber0(self, num):
1121 if len(self.servicePath) > 1:
1124 self.keyNumberGlobal(num)
1127 if len(self.servicePath) > 1:
1128 if self.isBasePathEqual(self.bouquet_root):
1129 self.showFavourites()
1131 ref = eServiceReference('%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types))
1132 if self.isBasePathEqual(ref):
1133 self.showSatellites()
1135 ref = eServiceReference('%s FROM PROVIDERS ORDER BY name'%(self.service_types))
1136 if self.isBasePathEqual(ref):
1137 self.showProviders()
1139 self.showAllServices()
1141 def nextMarker(self):
1142 self.servicelist.moveToNextMarker()
1144 def prevMarker(self):
1145 self.servicelist.moveToPrevMarker()
1149 #config for lastservice
1150 config.tv = ConfigSubsection()
1151 config.tv.lastservice = ConfigText()
1152 config.tv.lastroot = ConfigText()
1153 config.radio = ConfigSubsection()
1154 config.radio.lastservice = ConfigText()
1155 config.radio.lastroot = ConfigText()
1156 config.servicelist = ConfigSubsection()
1157 config.servicelist.lastmode = ConfigText(default = "tv")
1159 class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG, SelectionEventInfo):
1160 def __init__(self, session):
1161 ChannelSelectionBase.__init__(self,session)
1162 ChannelSelectionEdit.__init__(self)
1163 ChannelSelectionEPG.__init__(self)
1164 SelectionEventInfo.__init__(self)
1166 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1168 "cancel": self.cancel,
1169 "ok": self.channelSelected,
1170 "keyRadio": self.setModeRadio,
1171 "keyTV": self.setModeTv,
1174 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
1176 iPlayableService.evStart: self.__evServiceStart,
1177 iPlayableService.evEnd: self.__evServiceEnd
1180 self.lastChannelRootTimer = eTimer()
1181 self.lastChannelRootTimer.callback.append(self.__onCreate)
1182 self.lastChannelRootTimer.start(100,True)
1184 self.history_tv = [ ]
1185 self.history_radio = [ ]
1186 self.history = self.history_tv
1187 self.history_pos = 0
1189 self.lastservice = config.tv.lastservice
1190 self.lastroot = config.tv.lastroot
1191 self.revertMode = None
1192 config.usage.multibouquet.addNotifier(self.multibouquet_config_changed)
1193 self.new_service_played = False
1194 self.onExecBegin.append(self.asciiOn)
1197 rcinput = eRCInput.getInstance()
1198 rcinput.setKeyboardMode(rcinput.kmAscii)
1201 rcinput = eRCInput.getInstance()
1202 rcinput.setKeyboardMode(rcinput.kmNone)
1204 def multibouquet_config_changed(self, val):
1205 self.recallBouquetMode()
1207 def __evServiceStart(self):
1208 service = self.session.nav.getCurrentService()
1210 info = service.info()
1212 refstr = info.getInfoString(iServiceInformation.sServiceref)
1213 self.servicelist.setPlayableIgnoreService(eServiceReference(refstr))
1215 def __evServiceEnd(self):
1216 self.servicelist.setPlayableIgnoreService(eServiceReference())
1219 self.rootChanged = True
1221 lastservice=eServiceReference(self.lastservice.value)
1222 if lastservice.valid():
1223 self.setCurrentSelection(lastservice)
1225 def setModeTv(self):
1226 if self.revertMode is None and config.servicelist.lastmode.value == "radio":
1227 self.revertMode = MODE_RADIO
1228 self.history = self.history_tv
1229 self.lastservice = config.tv.lastservice
1230 self.lastroot = config.tv.lastroot
1231 config.servicelist.lastmode.value = "tv"
1235 def setModeRadio(self):
1236 if self.revertMode is None and config.servicelist.lastmode.value == "tv":
1237 self.revertMode = MODE_TV
1238 if config.usage.e1like_radio_mode.value:
1239 self.history = self.history_radio
1240 self.lastservice = config.radio.lastservice
1241 self.lastroot = config.radio.lastroot
1242 config.servicelist.lastmode.value = "radio"
1246 def __onCreate(self):
1247 if config.usage.e1like_radio_mode.value:
1248 if config.servicelist.lastmode.value == "tv":
1254 lastservice=eServiceReference(self.lastservice.value)
1255 if lastservice.valid():
1258 def channelSelected(self):
1259 ref = self.getCurrentSelection()
1261 self.toggleMoveMarked()
1262 elif (ref.flags & 7) == 7:
1264 elif self.bouquet_mark_edit != OFF:
1265 if not (self.bouquet_mark_edit == EDIT_ALTERNATIVES and ref.flags & eServiceReference.isGroup):
1267 elif not (ref.flags & eServiceReference.isMarker): # no marker
1268 root = self.getRoot()
1269 if not root or not (root.flags & eServiceReference.isGroup):
1274 #called from infoBar and channelSelected
1276 self.revertMode=None
1277 ref = self.session.nav.getCurrentlyPlayingServiceReference()
1278 nref = self.getCurrentSelection()
1279 if ref is None or ref != nref:
1280 self.new_service_played = True
1281 self.session.nav.playService(nref)
1283 self.saveChannel(nref)
1284 config.servicelist.lastmode.save()
1285 self.addToHistory(nref)
1287 def newServicePlayed(self):
1288 ret = self.new_service_played
1289 self.new_service_played = False
1292 def addToHistory(self, ref):
1293 if self.servicePath is not None:
1294 tmp=self.servicePath[:]
1297 del self.history[self.history_pos+1:]
1300 self.history.append(tmp)
1301 hlen = len(self.history)
1302 if hlen > HISTORYSIZE:
1305 self.history_pos = hlen-1
1307 def historyBack(self):
1308 hlen = len(self.history)
1309 if hlen > 1 and self.history_pos > 0:
1310 self.history_pos -= 1
1311 self.setHistoryPath()
1313 def historyNext(self):
1314 hlen = len(self.history)
1315 if hlen > 1 and self.history_pos < (hlen-1):
1316 self.history_pos += 1
1317 self.setHistoryPath()
1319 def setHistoryPath(self):
1320 path = self.history[self.history_pos][:]
1322 del self.servicePath[:]
1323 self.servicePath += path
1326 cur_root = self.getRoot()
1327 if cur_root and cur_root != root:
1329 self.session.nav.playService(ref)
1330 self.setCurrentSelection(ref)
1331 self.saveChannel(ref)
1335 for i in self.servicePath:
1336 path += i.toString()
1338 if path and path != self.lastroot.value:
1339 self.lastroot.value = path
1340 self.lastroot.save()
1342 def restoreRoot(self):
1343 tmp = [x for x in self.lastroot.value.split(';') if x != '']
1344 current = [x.toString() for x in self.servicePath]
1345 if tmp != current or self.rootChanged:
1349 self.servicePath.append(eServiceReference(i))
1352 path = self.servicePath.pop()
1353 self.enterPath(path)
1355 self.showFavourites()
1357 self.rootChanged = False
1359 def preEnterPath(self, refstr):
1360 if self.servicePath and self.servicePath[0] != eServiceReference(refstr):
1361 pathstr = self.lastroot.value
1362 if pathstr is not None and pathstr.find(refstr) == 0:
1364 lastservice=eServiceReference(self.lastservice.value)
1365 if lastservice.valid():
1366 self.setCurrentSelection(lastservice)
1370 def saveChannel(self, ref):
1372 refstr = ref.toString()
1375 if refstr != self.lastservice.value:
1376 self.lastservice.value = refstr
1377 self.lastservice.save()
1379 def setCurrentServicePath(self, path):
1381 self.history[self.history_pos] = path
1383 self.history.append(path)
1384 self.setHistoryPath()
1386 def getCurrentServicePath(self):
1388 return self.history[self.history_pos]
1391 def recallPrevService(self):
1392 hlen = len(self.history)
1394 if self.history_pos == hlen-1:
1395 tmp = self.history[self.history_pos]
1396 self.history[self.history_pos] = self.history[self.history_pos-1]
1397 self.history[self.history_pos-1] = tmp
1399 tmp = self.history[self.history_pos+1]
1400 self.history[self.history_pos+1] = self.history[self.history_pos]
1401 self.history[self.history_pos] = tmp
1402 self.setHistoryPath()
1405 if self.revertMode is None:
1407 lastservice=eServiceReference(self.lastservice.value)
1408 if lastservice.valid() and self.getCurrentSelection() != lastservice:
1409 self.setCurrentSelection(lastservice)
1410 elif self.revertMode == MODE_TV:
1412 elif self.revertMode == MODE_RADIO:
1414 self.revertMode = None
1418 class RadioInfoBar(Screen):
1419 def __init__(self, session):
1420 Screen.__init__(self, session)
1421 self["RdsDecoder"] = RdsDecoder(self.session.nav)
1423 class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG, InfoBarBase):
1424 ALLOW_SUSPEND = True
1426 def __init__(self, session, infobar):
1427 ChannelSelectionBase.__init__(self, session)
1428 ChannelSelectionEdit.__init__(self)
1429 ChannelSelectionEPG.__init__(self)
1430 InfoBarBase.__init__(self)
1431 self.infobar = infobar
1432 self.onLayoutFinish.append(self.onCreate)
1434 self.info = session.instantiateDialog(RadioInfoBar) # our simple infobar
1435 self.info.setAnimationMode(0)
1437 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1439 "keyTV": self.cancel,
1440 "keyRadio": self.cancel,
1441 "cancel": self.cancel,
1442 "ok": self.channelSelected,
1445 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
1447 iPlayableService.evStart: self.__evServiceStart,
1448 iPlayableService.evEnd: self.__evServiceEnd
1451 ########## RDS Radiotext / Rass Support BEGIN
1452 self.infobar = infobar # reference to real infobar (the one and only)
1453 self["RdsDecoder"] = self.info["RdsDecoder"]
1454 self["RdsActions"] = HelpableActionMap(self, "InfobarRdsActions",
1456 "startRassInteractive": (self.startRassInteractive, _("View Rass interactive..."))
1458 self["RdsActions"].setEnabled(False)
1459 infobar.rds_display.onRassInteractivePossibilityChanged.append(self.RassInteractivePossibilityChanged)
1460 self.onClose.append(self.__onClose)
1462 def __onClose(self):
1463 lastservice=eServiceReference(config.tv.lastservice.value)
1464 self.session.nav.playService(lastservice)
1466 def startRassInteractive(self):
1468 self.infobar.rass_interactive = self.session.openWithCallback(self.RassInteractiveClosed, RassInteractive)
1470 def RassInteractiveClosed(self):
1472 self.infobar.rass_interactive = None
1473 self.infobar.RassSlidePicChanged()
1475 def RassInteractivePossibilityChanged(self, state):
1476 self["RdsActions"].setEnabled(state)
1477 ########## RDS Radiotext / Rass Support END
1480 self.infobar.rds_display.onRassInteractivePossibilityChanged.remove(self.RassInteractivePossibilityChanged)
1482 #set previous tv service
1485 def __evServiceStart(self):
1486 service = self.session.nav.getCurrentService()
1488 info = service.info()
1490 refstr = info.getInfoString(iServiceInformation.sServiceref)
1491 self.servicelist.setPlayableIgnoreService(eServiceReference(refstr))
1493 def __evServiceEnd(self):
1494 self.servicelist.setPlayableIgnoreService(eServiceReference())
1498 for i in self.servicePathRadio:
1499 path += i.toString()
1501 if path and path != config.radio.lastroot.value:
1502 config.radio.lastroot.value = path
1503 config.radio.lastroot.save()
1505 def restoreRoot(self):
1506 tmp = [x for x in config.radio.lastroot.value.split(';') if x != '']
1507 current = [x.toString() for x in self.servicePath]
1508 if tmp != current or self.rootChanged:
1511 self.servicePathRadio.append(eServiceReference(i))
1514 path = self.servicePathRadio.pop()
1515 self.enterPath(path)
1517 self.showFavourites()
1519 self.rootChanged = False
1521 def preEnterPath(self, refstr):
1522 if self.servicePathRadio and self.servicePathRadio[0] != eServiceReference(refstr):
1523 pathstr = config.radio.lastroot.value
1524 if pathstr is not None and pathstr.find(refstr) == 0:
1526 lastservice=eServiceReference(config.radio.lastservice.value)
1527 if lastservice.valid():
1528 self.setCurrentSelection(lastservice)
1535 lastservice=eServiceReference(config.radio.lastservice.value)
1536 if lastservice.valid():
1537 self.servicelist.setCurrent(lastservice)
1538 self.session.nav.playService(lastservice)
1540 self.session.nav.stopService()
1543 def channelSelected(self): # just return selected service
1544 ref = self.getCurrentSelection()
1546 self.toggleMoveMarked()
1547 elif (ref.flags & 7) == 7:
1549 elif self.bouquet_mark_edit != OFF:
1550 if not (self.bouquet_mark_edit == EDIT_ALTERNATIVES and ref.flags & eServiceReference.isGroup):
1552 elif not (ref.flags & eServiceReference.isMarker): # no marker
1553 cur_root = self.getRoot()
1554 if not cur_root or not (cur_root.flags & eServiceReference.isGroup):
1555 playingref = self.session.nav.getCurrentlyPlayingServiceReference()
1556 if playingref is None or playingref != ref:
1557 self.session.nav.playService(ref)
1558 config.radio.lastservice.value = ref.toString()
1559 config.radio.lastservice.save()
1562 class SimpleChannelSelection(ChannelSelectionBase):
1563 def __init__(self, session, title):
1564 ChannelSelectionBase.__init__(self, session)
1565 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1567 "cancel": self.close,
1568 "ok": self.channelSelected,
1569 "keyRadio": self.setModeRadio,
1570 "keyTV": self.setModeTv,
1573 self.onLayoutFinish.append(self.layoutFinished)
1575 def layoutFinished(self):
1578 def channelSelected(self): # just return selected service
1579 ref = self.getCurrentSelection()
1580 if (ref.flags & 7) == 7:
1582 elif not (ref.flags & eServiceReference.isMarker):
1583 ref = self.getCurrentSelection()
1586 def setModeTv(self):
1588 self.showFavourites()
1590 def setModeRadio(self):
1592 self.showFavourites()