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
722 # type 31 = High Efficiency Video Coing digital television
724 service_types_tv = '1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17) || (type == 22) || (type == 25) || (type == 31) || (type == 134) || (type == 195)'
725 service_types_radio = '1:7:2:0:0:0:0:0:0:0:(type == 2) || (type == 10)'
727 class ChannelSelectionBase(Screen):
728 def __init__(self, session):
729 Screen.__init__(self, session)
731 self["key_red"] = Button(_("All"))
732 self["key_green"] = Button(_("Satellites"))
733 self["key_yellow"] = Button(_("Provider"))
734 self["key_blue"] = Button(_("Favourites"))
736 self["list"] = ServiceList()
737 self.servicelist = self["list"]
739 self.numericalTextInput = NumericalTextInput()
740 self.numericalTextInput.setUseableChars(u'1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ')
742 self.servicePathTV = [ ]
743 self.servicePathRadio = [ ]
744 self.servicePath = [ ]
745 self.rootChanged = False
749 self.pathChangeDisabled = False
751 self.bouquetNumOffsetCache = { }
753 self["ChannelSelectBaseActions"] = NumberActionMap(["ChannelSelectBaseActions", "NumberActions", "InputAsciiActions"],
755 "showFavourites": self.showFavourites,
756 "showAllServices": self.showAllServices,
757 "showProviders": self.showProviders,
758 "showSatellites": self.showSatellites,
759 "nextBouquet": self.nextBouquet,
760 "prevBouquet": self.prevBouquet,
761 "nextMarker": self.nextMarker,
762 "prevMarker": self.prevMarker,
763 "gotAsciiCode": self.keyAsciiCode,
764 "1": self.keyNumberGlobal,
765 "2": self.keyNumberGlobal,
766 "3": self.keyNumberGlobal,
767 "4": self.keyNumberGlobal,
768 "5": self.keyNumberGlobal,
769 "6": self.keyNumberGlobal,
770 "7": self.keyNumberGlobal,
771 "8": self.keyNumberGlobal,
772 "9": self.keyNumberGlobal,
775 self.recallBouquetMode()
777 def getBouquetNumOffset(self, bouquet):
778 if not config.usage.multibouquet.value:
780 str = bouquet.toString()
782 if not self.bouquetNumOffsetCache.has_key(str):
783 serviceHandler = eServiceCenter.getInstance()
784 bouquetlist = serviceHandler.list(self.bouquet_root)
785 if not bouquetlist is None:
787 bouquetIterator = bouquetlist.getNext()
788 if not bouquetIterator.valid(): #end of list
790 self.bouquetNumOffsetCache[bouquetIterator.toString()]=offsetCount
791 if not (bouquetIterator.flags & eServiceReference.isDirectory):
793 servicelist = serviceHandler.list(bouquetIterator)
794 if not servicelist is None:
796 serviceIterator = servicelist.getNext()
797 if not serviceIterator.valid(): #check if end of list
799 playable = not (serviceIterator.flags & (eServiceReference.isDirectory|eServiceReference.isMarker))
802 return self.bouquetNumOffsetCache.get(str, offsetCount)
804 def recallBouquetMode(self):
805 if self.mode == MODE_TV:
806 self.service_types = service_types_tv
807 if config.usage.multibouquet.value:
808 self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "bouquets.tv" ORDER BY bouquet'
810 self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.tv" ORDER BY bouquet'%(self.service_types)
812 self.service_types = service_types_radio
813 if config.usage.multibouquet.value:
814 self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "bouquets.radio" ORDER BY bouquet'
816 self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.radio" ORDER BY bouquet'%(self.service_types)
817 self.bouquet_root = eServiceReference(self.bouquet_rootstr)
821 self.servicePath = self.servicePathTV
822 self.recallBouquetMode()
823 title = self.getTitle()
824 pos = title.find(" (")
830 def setRadioMode(self):
831 self.mode = MODE_RADIO
832 self.servicePath = self.servicePathRadio
833 self.recallBouquetMode()
834 title = self.getTitle()
835 pos = title.find(" (")
841 def setRoot(self, root, justSet=False):
842 path = root.getPath()
843 inBouquetRootList = path.find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
844 pos = path.find('FROM BOUQUET')
845 isBouquet = (pos != -1) and (root.flags & eServiceReference.isDirectory)
846 if not inBouquetRootList and isBouquet:
847 self.servicelist.setMode(ServiceList.MODE_FAVOURITES)
848 self.servicelist.setNumberOffset(self.getBouquetNumOffset(root))
850 self.servicelist.setMode(ServiceList.MODE_NORMAL)
851 self.servicelist.setRoot(root, justSet)
852 self.rootChanged = True
853 self.buildTitleString()
855 def removeModeStr(self, str):
856 if self.mode == MODE_TV:
857 pos = str.find(' (TV)')
859 pos = str.find(' (Radio)')
864 def getServiceName(self, ref):
865 str = self.removeModeStr(ServiceReference(ref).getServiceName())
867 pathstr = ref.getPath()
868 if 'FROM PROVIDERS' in pathstr:
870 if 'FROM SATELLITES' in pathstr:
871 return _("Satellites")
872 if ') ORDER BY name' in pathstr:
876 def buildTitleString(self):
877 titleStr = self.getTitle()
878 pos = titleStr.find(']')
880 pos = titleStr.find(')')
882 titleStr = titleStr[:pos+1]
883 Len = len(self.servicePath)
885 base_ref = self.servicePath[0]
887 end_ref = self.servicePath[Len-1]
890 nameStr = self.getServiceName(base_ref)
891 titleStr += ' ' + nameStr
892 if end_ref is not None:
897 nameStr = self.getServiceName(end_ref)
899 self.setTitle(titleStr)
902 self.servicelist.moveUp()
905 self.servicelist.moveDown()
908 del self.servicePath[:]
910 def enterPath(self, ref, justSet=False):
911 self.servicePath.append(ref)
912 self.setRoot(ref, justSet)
914 def pathUp(self, justSet=False):
915 prev = self.servicePath.pop()
917 current = self.servicePath[-1]
918 self.setRoot(current, justSet)
920 self.setCurrentSelection(prev)
923 def isBasePathEqual(self, ref):
924 if len(self.servicePath) > 1 and self.servicePath[0] == ref:
928 def isPrevPathEqual(self, ref):
929 length = len(self.servicePath)
930 if length > 1 and self.servicePath[length-2] == ref:
934 def preEnterPath(self, refstr):
937 def showAllServices(self):
938 if not self.pathChangeDisabled:
939 refstr = '%s ORDER BY name'%(self.service_types)
940 if not self.preEnterPath(refstr):
941 ref = eServiceReference(refstr)
942 currentRoot = self.getRoot()
943 if currentRoot is None or currentRoot != ref:
947 def showSatellites(self):
948 if not self.pathChangeDisabled:
949 refstr = '%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types)
950 if not self.preEnterPath(refstr):
951 ref = eServiceReference(refstr)
955 if self.isBasePathEqual(ref):
956 if self.isPrevPathEqual(ref):
958 prev = self.pathUp(justSet)
960 currentRoot = self.getRoot()
961 if currentRoot is None or currentRoot != ref:
964 self.enterPath(ref, True)
966 serviceHandler = eServiceCenter.getInstance()
967 servicelist = serviceHandler.list(ref)
968 if not servicelist is None:
970 service = servicelist.getNext()
971 if not service.valid(): #check if end of list
973 unsigned_orbpos = service.getUnsignedData(4) >> 16
974 orbpos = service.getData(4) >> 16
977 if service.getPath().find("FROM PROVIDER") != -1:
978 service_type = _("Providers")
979 elif service.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
980 service_type = _("New")
982 service_type = _("Services")
984 # why we need this cast?
985 service_name = str(nimmanager.getSatDescription(orbpos))
987 if unsigned_orbpos == 0xFFFF: #Cable
988 service_name = _("Cable")
989 elif unsigned_orbpos == 0xEEEE: #Terrestrial
990 service_name = _("Terrestrial")
992 if orbpos > 1800: # west
993 orbpos = 3600 - orbpos
997 service_name = ("%d.%d" + h) % (orbpos / 10, orbpos % 10)
998 service.setName("%s - %s" % (service_name, service_type))
999 self.servicelist.addService(service)
1000 cur_ref = self.session.nav.getCurrentlyPlayingServiceReference()
1002 pos = self.service_types.rfind(':')
1003 refstr = '%s (channelID == %08x%04x%04x) && %s ORDER BY name' %(self.service_types[:pos+1],
1004 cur_ref.getUnsignedData(4), # NAMESPACE
1005 cur_ref.getUnsignedData(2), # TSID
1006 cur_ref.getUnsignedData(3), # ONID
1007 self.service_types[pos+1:])
1008 ref = eServiceReference(refstr)
1009 ref.setName(_("Current Transponder"))
1010 self.servicelist.addService(ref)
1011 self.servicelist.finishFill()
1012 if prev is not None:
1013 self.setCurrentSelection(prev)
1015 def showProviders(self):
1016 if not self.pathChangeDisabled:
1017 refstr = '%s FROM PROVIDERS ORDER BY name'%(self.service_types)
1018 if not self.preEnterPath(refstr):
1019 ref = eServiceReference(refstr)
1020 if self.isBasePathEqual(ref):
1023 currentRoot = self.getRoot()
1024 if currentRoot is None or currentRoot != ref:
1028 def changeBouquet(self, direction):
1029 if not self.pathChangeDisabled:
1030 if len(self.servicePath) > 1:
1031 #when enter satellite root list we must do some magic stuff..
1032 ref = eServiceReference('%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types))
1033 if self.isBasePathEqual(ref):
1034 self.showSatellites()
1041 ref = self.getCurrentSelection()
1044 def inBouquet(self):
1045 if self.servicePath and self.servicePath[0] == self.bouquet_root:
1050 return self.servicelist.atBegin()
1053 return self.servicelist.atEnd()
1055 def nextBouquet(self):
1056 self.changeBouquet(+1)
1058 def prevBouquet(self):
1059 self.changeBouquet(-1)
1061 def showFavourites(self):
1062 if not self.pathChangeDisabled:
1063 if not self.preEnterPath(self.bouquet_rootstr):
1064 if self.isBasePathEqual(self.bouquet_root):
1067 currentRoot = self.getRoot()
1068 if currentRoot is None or currentRoot != self.bouquet_root:
1070 self.enterPath(self.bouquet_root)
1072 def keyNumberGlobal(self, number):
1073 unichar = self.numericalTextInput.getKey(number)
1074 charstr = unichar.encode("utf-8")
1075 if len(charstr) == 1:
1076 self.servicelist.moveToChar(charstr[0])
1078 def keyAsciiCode(self):
1079 #unichar = unichr(getPrevAsciiCode())
1080 from Components.config import getCharValue
1081 unichar = getCharValue(getPrevAsciiCode())
1084 if len(str(unichar)) > 1:
1086 charstr = unichar.encode("utf-8")
1087 if len(charstr) == 1:
1088 self.servicelist.moveToChar(charstr[0])
1091 return self.servicelist.getRoot()
1093 def getCurrentSelection(self):
1094 return self.servicelist.getCurrent()
1096 def setCurrentSelection(self, service):
1097 self.servicelist.setCurrent(service)
1099 def getBouquetList(self):
1101 serviceHandler = eServiceCenter.getInstance()
1102 if config.usage.multibouquet.value:
1103 list = serviceHandler.list(self.bouquet_root)
1109 if s.flags & eServiceReference.isDirectory:
1110 info = serviceHandler.info(s)
1112 bouquets.append((info.getName(s), s))
1115 info = serviceHandler.info(self.bouquet_root)
1117 bouquets.append((info.getName(self.bouquet_root), self.bouquet_root))
1121 def keyNumber0(self, num):
1122 if len(self.servicePath) > 1:
1125 self.keyNumberGlobal(num)
1128 if len(self.servicePath) > 1:
1129 if self.isBasePathEqual(self.bouquet_root):
1130 self.showFavourites()
1132 ref = eServiceReference('%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types))
1133 if self.isBasePathEqual(ref):
1134 self.showSatellites()
1136 ref = eServiceReference('%s FROM PROVIDERS ORDER BY name'%(self.service_types))
1137 if self.isBasePathEqual(ref):
1138 self.showProviders()
1140 self.showAllServices()
1142 def nextMarker(self):
1143 self.servicelist.moveToNextMarker()
1145 def prevMarker(self):
1146 self.servicelist.moveToPrevMarker()
1150 #config for lastservice
1151 config.tv = ConfigSubsection()
1152 config.tv.lastservice = ConfigText()
1153 config.tv.lastroot = ConfigText()
1154 config.radio = ConfigSubsection()
1155 config.radio.lastservice = ConfigText()
1156 config.radio.lastroot = ConfigText()
1157 config.servicelist = ConfigSubsection()
1158 config.servicelist.lastmode = ConfigText(default = "tv")
1160 class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG, SelectionEventInfo):
1161 def __init__(self, session):
1162 ChannelSelectionBase.__init__(self,session)
1163 ChannelSelectionEdit.__init__(self)
1164 ChannelSelectionEPG.__init__(self)
1165 SelectionEventInfo.__init__(self)
1167 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1169 "cancel": self.cancel,
1170 "ok": self.channelSelected,
1171 "keyRadio": self.setModeRadio,
1172 "keyTV": self.setModeTv,
1175 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
1177 iPlayableService.evStart: self.__evServiceStart,
1178 iPlayableService.evEnd: self.__evServiceEnd
1181 self.lastChannelRootTimer = eTimer()
1182 self.lastChannelRootTimer.callback.append(self.__onCreate)
1183 self.lastChannelRootTimer.start(100,True)
1185 self.history_tv = [ ]
1186 self.history_radio = [ ]
1187 self.history = self.history_tv
1188 self.history_pos = 0
1190 self.lastservice = config.tv.lastservice
1191 self.lastroot = config.tv.lastroot
1192 self.revertMode = None
1193 config.usage.multibouquet.addNotifier(self.multibouquet_config_changed)
1194 self.new_service_played = False
1195 self.onExecBegin.append(self.asciiOn)
1198 rcinput = eRCInput.getInstance()
1199 rcinput.setKeyboardMode(rcinput.kmAscii)
1202 rcinput = eRCInput.getInstance()
1203 rcinput.setKeyboardMode(rcinput.kmNone)
1205 def multibouquet_config_changed(self, val):
1206 self.recallBouquetMode()
1208 def __evServiceStart(self):
1209 service = self.session.nav.getCurrentService()
1211 info = service.info()
1213 refstr = info.getInfoString(iServiceInformation.sServiceref)
1214 self.servicelist.setPlayableIgnoreService(eServiceReference(refstr))
1216 def __evServiceEnd(self):
1217 self.servicelist.setPlayableIgnoreService(eServiceReference())
1220 self.rootChanged = True
1222 lastservice=eServiceReference(self.lastservice.value)
1223 if lastservice.valid():
1224 self.setCurrentSelection(lastservice)
1226 def setModeTv(self):
1227 if self.revertMode is None and config.servicelist.lastmode.value == "radio":
1228 self.revertMode = MODE_RADIO
1229 self.history = self.history_tv
1230 self.lastservice = config.tv.lastservice
1231 self.lastroot = config.tv.lastroot
1232 config.servicelist.lastmode.value = "tv"
1236 def setModeRadio(self):
1237 if self.revertMode is None and config.servicelist.lastmode.value == "tv":
1238 self.revertMode = MODE_TV
1239 if config.usage.e1like_radio_mode.value:
1240 self.history = self.history_radio
1241 self.lastservice = config.radio.lastservice
1242 self.lastroot = config.radio.lastroot
1243 config.servicelist.lastmode.value = "radio"
1247 def __onCreate(self):
1248 if config.usage.e1like_radio_mode.value:
1249 if config.servicelist.lastmode.value == "tv":
1255 lastservice=eServiceReference(self.lastservice.value)
1256 if lastservice.valid():
1259 def channelSelected(self):
1260 ref = self.getCurrentSelection()
1262 self.toggleMoveMarked()
1263 elif (ref.flags & 7) == 7:
1265 elif self.bouquet_mark_edit != OFF:
1266 if not (self.bouquet_mark_edit == EDIT_ALTERNATIVES and ref.flags & eServiceReference.isGroup):
1268 elif not (ref.flags & eServiceReference.isMarker): # no marker
1269 root = self.getRoot()
1270 if not root or not (root.flags & eServiceReference.isGroup):
1275 #called from infoBar and channelSelected
1277 self.revertMode=None
1278 ref = self.session.nav.getCurrentlyPlayingServiceReference()
1279 nref = self.getCurrentSelection()
1280 if ref is None or ref != nref:
1281 self.new_service_played = True
1282 self.session.nav.playService(nref)
1284 self.saveChannel(nref)
1285 config.servicelist.lastmode.save()
1286 self.addToHistory(nref)
1288 def newServicePlayed(self):
1289 ret = self.new_service_played
1290 self.new_service_played = False
1293 def addToHistory(self, ref):
1294 if self.servicePath is not None:
1295 tmp=self.servicePath[:]
1298 del self.history[self.history_pos+1:]
1301 self.history.append(tmp)
1302 hlen = len(self.history)
1303 if hlen > HISTORYSIZE:
1306 self.history_pos = hlen-1
1308 def historyBack(self):
1309 hlen = len(self.history)
1310 if hlen > 1 and self.history_pos > 0:
1311 self.history_pos -= 1
1312 self.setHistoryPath()
1314 def historyNext(self):
1315 hlen = len(self.history)
1316 if hlen > 1 and self.history_pos < (hlen-1):
1317 self.history_pos += 1
1318 self.setHistoryPath()
1320 def setHistoryPath(self):
1321 path = self.history[self.history_pos][:]
1323 del self.servicePath[:]
1324 self.servicePath += path
1327 cur_root = self.getRoot()
1328 if cur_root and cur_root != root:
1330 self.session.nav.playService(ref)
1331 self.setCurrentSelection(ref)
1332 self.saveChannel(ref)
1336 for i in self.servicePath:
1337 path += i.toString()
1339 if path and path != self.lastroot.value:
1340 self.lastroot.value = path
1341 self.lastroot.save()
1343 def restoreRoot(self):
1344 tmp = [x for x in self.lastroot.value.split(';') if x != '']
1345 current = [x.toString() for x in self.servicePath]
1346 if tmp != current or self.rootChanged:
1350 self.servicePath.append(eServiceReference(i))
1353 path = self.servicePath.pop()
1354 self.enterPath(path)
1356 self.showFavourites()
1358 self.rootChanged = False
1360 def preEnterPath(self, refstr):
1361 if self.servicePath and self.servicePath[0] != eServiceReference(refstr):
1362 pathstr = self.lastroot.value
1363 if pathstr is not None and pathstr.find(refstr) == 0:
1365 lastservice=eServiceReference(self.lastservice.value)
1366 if lastservice.valid():
1367 self.setCurrentSelection(lastservice)
1371 def saveChannel(self, ref):
1373 refstr = ref.toString()
1376 if refstr != self.lastservice.value:
1377 self.lastservice.value = refstr
1378 self.lastservice.save()
1380 def setCurrentServicePath(self, path):
1382 self.history[self.history_pos] = path
1384 self.history.append(path)
1385 self.setHistoryPath()
1387 def getCurrentServicePath(self):
1389 return self.history[self.history_pos]
1392 def recallPrevService(self):
1393 hlen = len(self.history)
1395 if self.history_pos == hlen-1:
1396 tmp = self.history[self.history_pos]
1397 self.history[self.history_pos] = self.history[self.history_pos-1]
1398 self.history[self.history_pos-1] = tmp
1400 tmp = self.history[self.history_pos+1]
1401 self.history[self.history_pos+1] = self.history[self.history_pos]
1402 self.history[self.history_pos] = tmp
1403 self.setHistoryPath()
1406 if self.revertMode is None:
1408 lastservice=eServiceReference(self.lastservice.value)
1409 if lastservice.valid() and self.getCurrentSelection() != lastservice:
1410 self.setCurrentSelection(lastservice)
1411 elif self.revertMode == MODE_TV:
1413 elif self.revertMode == MODE_RADIO:
1415 self.revertMode = None
1419 class RadioInfoBar(Screen):
1420 def __init__(self, session):
1421 Screen.__init__(self, session)
1422 self["RdsDecoder"] = RdsDecoder(self.session.nav)
1424 class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG, InfoBarBase):
1425 ALLOW_SUSPEND = True
1427 def __init__(self, session, infobar):
1428 ChannelSelectionBase.__init__(self, session)
1429 ChannelSelectionEdit.__init__(self)
1430 ChannelSelectionEPG.__init__(self)
1431 InfoBarBase.__init__(self)
1432 self.infobar = infobar
1433 self.onLayoutFinish.append(self.onCreate)
1435 self.info = session.instantiateDialog(RadioInfoBar) # our simple infobar
1436 self.info.setAnimationMode(0)
1438 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1440 "keyTV": self.cancel,
1441 "keyRadio": self.cancel,
1442 "cancel": self.cancel,
1443 "ok": self.channelSelected,
1446 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
1448 iPlayableService.evStart: self.__evServiceStart,
1449 iPlayableService.evEnd: self.__evServiceEnd
1452 ########## RDS Radiotext / Rass Support BEGIN
1453 self.infobar = infobar # reference to real infobar (the one and only)
1454 self["RdsDecoder"] = self.info["RdsDecoder"]
1455 self["RdsActions"] = HelpableActionMap(self, "InfobarRdsActions",
1457 "startRassInteractive": (self.startRassInteractive, _("View Rass interactive..."))
1459 self["RdsActions"].setEnabled(False)
1460 infobar.rds_display.onRassInteractivePossibilityChanged.append(self.RassInteractivePossibilityChanged)
1461 self.onClose.append(self.__onClose)
1463 def __onClose(self):
1464 lastservice=eServiceReference(config.tv.lastservice.value)
1465 self.session.nav.playService(lastservice)
1467 def startRassInteractive(self):
1469 self.infobar.rass_interactive = self.session.openWithCallback(self.RassInteractiveClosed, RassInteractive)
1471 def RassInteractiveClosed(self):
1473 self.infobar.rass_interactive = None
1474 self.infobar.RassSlidePicChanged()
1476 def RassInteractivePossibilityChanged(self, state):
1477 self["RdsActions"].setEnabled(state)
1478 ########## RDS Radiotext / Rass Support END
1481 self.infobar.rds_display.onRassInteractivePossibilityChanged.remove(self.RassInteractivePossibilityChanged)
1483 #set previous tv service
1486 def __evServiceStart(self):
1487 service = self.session.nav.getCurrentService()
1489 info = service.info()
1491 refstr = info.getInfoString(iServiceInformation.sServiceref)
1492 self.servicelist.setPlayableIgnoreService(eServiceReference(refstr))
1494 def __evServiceEnd(self):
1495 self.servicelist.setPlayableIgnoreService(eServiceReference())
1499 for i in self.servicePathRadio:
1500 path += i.toString()
1502 if path and path != config.radio.lastroot.value:
1503 config.radio.lastroot.value = path
1504 config.radio.lastroot.save()
1506 def restoreRoot(self):
1507 tmp = [x for x in config.radio.lastroot.value.split(';') if x != '']
1508 current = [x.toString() for x in self.servicePath]
1509 if tmp != current or self.rootChanged:
1512 self.servicePathRadio.append(eServiceReference(i))
1515 path = self.servicePathRadio.pop()
1516 self.enterPath(path)
1518 self.showFavourites()
1520 self.rootChanged = False
1522 def preEnterPath(self, refstr):
1523 if self.servicePathRadio and self.servicePathRadio[0] != eServiceReference(refstr):
1524 pathstr = config.radio.lastroot.value
1525 if pathstr is not None and pathstr.find(refstr) == 0:
1527 lastservice=eServiceReference(config.radio.lastservice.value)
1528 if lastservice.valid():
1529 self.setCurrentSelection(lastservice)
1536 lastservice=eServiceReference(config.radio.lastservice.value)
1537 if lastservice.valid():
1538 self.servicelist.setCurrent(lastservice)
1539 self.session.nav.playService(lastservice)
1541 self.session.nav.stopService()
1544 def channelSelected(self): # just return selected service
1545 ref = self.getCurrentSelection()
1547 self.toggleMoveMarked()
1548 elif (ref.flags & 7) == 7:
1550 elif self.bouquet_mark_edit != OFF:
1551 if not (self.bouquet_mark_edit == EDIT_ALTERNATIVES and ref.flags & eServiceReference.isGroup):
1553 elif not (ref.flags & eServiceReference.isMarker): # no marker
1554 cur_root = self.getRoot()
1555 if not cur_root or not (cur_root.flags & eServiceReference.isGroup):
1556 playingref = self.session.nav.getCurrentlyPlayingServiceReference()
1557 if playingref is None or playingref != ref:
1558 self.session.nav.playService(ref)
1559 config.radio.lastservice.value = ref.toString()
1560 config.radio.lastservice.save()
1563 class SimpleChannelSelection(ChannelSelectionBase):
1564 def __init__(self, session, title):
1565 ChannelSelectionBase.__init__(self, session)
1566 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1568 "cancel": self.close,
1569 "ok": self.channelSelected,
1570 "keyRadio": self.setModeRadio,
1571 "keyTV": self.setModeTv,
1574 self.onLayoutFinish.append(self.layoutFinished)
1576 def layoutFinished(self):
1579 def channelSelected(self): # just return selected service
1580 ref = self.getCurrentSelection()
1581 if (ref.flags & 7) == 7:
1583 elif not (ref.flags & eServiceReference.isMarker):
1584 ref = self.getCurrentSelection()
1587 def setModeTv(self):
1589 self.showFavourites()
1591 def setModeRadio(self):
1593 self.showFavourites()