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
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.ParentalControl import parentalControl
24 from Components.ChoiceList import ChoiceList, ChoiceEntryComponent
25 from Components.SystemInfo import SystemInfo
26 from Screens.InputBox import InputBox, PinInput
27 from Screens.MessageBox import MessageBox
28 from Screens.ServiceInfo import ServiceInfo
29 profile("ChannelSelection.py 4")
30 from Screens.PictureInPicture import PictureInPicture
31 from Screens.RdsDisplay import RassInteractive
32 from ServiceReference import ServiceReference
33 from Tools.BoundFunction import boundFunction
35 profile("ChannelSelection.py after imports")
37 FLAG_SERVICE_NEW_FOUND = 64 #define in lib/dvb/idvb.h as dxNewFound = 64
39 class BouquetSelector(Screen):
40 def __init__(self, session, bouquets, selectedFunc, enableWrapAround=False):
41 Screen.__init__(self, session)
43 self.selectedFunc=selectedFunc
45 self["actions"] = ActionMap(["OkCancelActions"],
47 "ok": self.okbuttonClick,
48 "cancel": self.cancelClick
50 entrys = [ (x[0], x[1]) for x in bouquets ]
51 self["menu"] = MenuList(entrys, enableWrapAround)
54 cur = self["menu"].getCurrent()
57 def okbuttonClick(self):
58 self.selectedFunc(self.getCurrent())
66 def cancelClick(self):
69 class SilentBouquetSelector:
70 def __init__(self, bouquets, enableWrapAround=False, current=0):
71 self.bouquets = [b[1] for b in bouquets]
73 self.count = len(bouquets)
74 self.enableWrapAround = enableWrapAround
77 if self.pos > 0 or self.enableWrapAround:
78 self.pos = (self.pos - 1) % self.count
81 if self.pos < (self.count - 1) or self.enableWrapAround:
82 self.pos = (self.pos + 1) % self.count
85 return self.bouquets[self.pos]
87 # csel.bouquet_mark_edit values
92 def append_when_current_valid(current, menu, args, level = 0, key = ""):
93 if current and current.valid() and level <= config.usage.setup_level.index:
94 menu.append(ChoiceEntryComponent(key, args))
96 class ChannelContextMenu(Screen):
97 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 if parentalControl.getProtectionLevel(csel.getCurrentSelection().toCompareString()) == -1:
128 append_when_current_valid(current, menu, (_("add to parental protection"), boundFunction(self.addParentalProtection, csel.getCurrentSelection())), level = 0)
130 append_when_current_valid(current, menu, (_("remove from parental protection"), boundFunction(self.removeParentalProtection, csel.getCurrentSelection())), level = 0)
132 append_when_current_valid(current, menu, (_("add service to bouquet"), self.addServiceToBouquetSelected), level = 0)
134 append_when_current_valid(current, menu, (_("add service to favourites"), self.addServiceToBouquetSelected), level = 0)
136 if current_root.getPath().find('FROM SATELLITES') != -1:
137 append_when_current_valid(current, menu, (_("remove selected satellite"), self.removeSatelliteServices), level = 0)
139 if not inBouquet and current_sel_path.find("PROVIDERS") == -1:
140 append_when_current_valid(current, menu, (_("copy to bouquets"), self.copyCurrentToBouquetList), level = 0)
141 if current_sel_path.find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
142 append_when_current_valid(current, menu, (_("remove all new found flags"), self.removeAllNewFoundFlags), level = 0)
144 append_when_current_valid(current, menu, (_("remove entry"), self.removeCurrentService), level = 0)
145 if current_root and current_root.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
146 append_when_current_valid(current, menu, (_("remove new found flag"), self.removeNewFoundFlag), level = 0)
147 if isPlayable and SystemInfo.get("NumVideoDecoders", 1) > 1:
148 append_when_current_valid(current, menu, (_("Activate Picture in Picture"), self.showServiceInPiP), level = 0, key = "blue")
149 self.pipAvailable = True
151 menu.append(ChoiceEntryComponent(text = (_("add bouquet"), self.showBouquetInputBox)))
152 append_when_current_valid(current, menu, (_("remove entry"), self.removeBouquet), level = 0)
154 if inBouquet: # current list is editable?
155 if csel.bouquet_mark_edit == OFF:
156 if not csel.movemode:
157 append_when_current_valid(current, menu, (_("enable move mode"), self.toggleMoveMode), level = 1)
158 if not inBouquetRootList and current_root and not (current_root.flags & eServiceReference.isGroup):
159 menu.append(ChoiceEntryComponent(text = (_("add marker"), self.showMarkerInputBox)))
161 append_when_current_valid(current, menu, (_("enable bouquet edit"), self.bouquetMarkStart), level = 0)
163 append_when_current_valid(current, menu, (_("enable favourite edit"), self.bouquetMarkStart), level = 0)
164 if current_sel_flags & eServiceReference.isGroup:
165 append_when_current_valid(current, menu, (_("edit alternatives"), self.editAlternativeServices), level = 2)
166 append_when_current_valid(current, menu, (_("show alternatives"), self.showAlternativeServices), level = 2)
167 append_when_current_valid(current, menu, (_("remove all alternatives"), self.removeAlternativeServices), level = 2)
168 elif not current_sel_flags & eServiceReference.isMarker:
169 append_when_current_valid(current, menu, (_("add alternatives"), self.addAlternativeServices), level = 2)
171 append_when_current_valid(current, menu, (_("disable move mode"), self.toggleMoveMode), level = 0)
173 if csel.bouquet_mark_edit == EDIT_BOUQUET:
175 append_when_current_valid(current, menu, (_("end bouquet edit"), self.bouquetMarkEnd), level = 0)
176 append_when_current_valid(current, menu, (_("abort bouquet edit"), self.bouquetMarkAbort), level = 0)
178 append_when_current_valid(current, menu, (_("end favourites edit"), self.bouquetMarkEnd), level = 0)
179 append_when_current_valid(current, menu, (_("abort favourites edit"), self.bouquetMarkAbort), level = 0)
181 append_when_current_valid(current, menu, (_("end alternatives edit"), self.bouquetMarkEnd), level = 0)
182 append_when_current_valid(current, menu, (_("abort alternatives edit"), self.bouquetMarkAbort), level = 0)
184 menu.append(ChoiceEntryComponent(text = (_("back"), self.cancelClick)))
185 self["menu"] = ChoiceList(menu)
187 def okbuttonClick(self):
188 self["menu"].getCurrent()[0][1]()
190 def cancelClick(self):
193 def showServiceInformations(self):
194 self.session.open( ServiceInfo, self.csel.getCurrentSelection() )
196 def showBouquetInputBox(self):
197 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)
199 def bouquetInputCallback(self, bouquet):
200 if bouquet is not None:
201 self.csel.addBouquet(bouquet, None)
204 def addParentalProtection(self, service):
205 parentalControl.protectService(service.toCompareString())
208 def removeParentalProtection(self, service):
209 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"))
211 def pinEntered(self, service, result):
213 parentalControl.unProtectService(service)
216 self.session.openWithCallback(self.close, MessageBox, _("The pin code you entered is wrong."), MessageBox.TYPE_ERROR)
218 def showServiceInPiP(self):
219 if not self.pipAvailable:
221 if self.session.pipshown:
223 self.session.pip = self.session.instantiateDialog(PictureInPicture)
224 self.session.pip.show()
225 newservice = self.csel.servicelist.getCurrent()
226 if self.session.pip.playService(newservice):
227 self.session.pipshown = True
228 self.session.pip.servicePath = self.csel.getCurrentServicePath()
231 self.session.pipshown = False
233 self.session.openWithCallback(self.close, MessageBox, _("Could not open Picture in Picture"), MessageBox.TYPE_ERROR)
235 def addServiceToBouquetSelected(self):
236 bouquets = self.csel.getBouquetList()
241 if cnt > 1: # show bouquet list
242 self.bsel = self.session.openWithCallback(self.bouquetSelClosed, BouquetSelector, bouquets, self.addCurrentServiceToBouquet)
243 elif cnt == 1: # add to only one existing bouquet
244 self.addCurrentServiceToBouquet(bouquets[0][1])
246 def bouquetSelClosed(self, recursive):
251 def removeSatelliteServices(self):
252 curpath = self.csel.getCurrentSelection().getPath()
253 idx = curpath.find("satellitePosition == ")
255 tmp = curpath[idx+21:]
258 satpos = int(tmp[:idx])
259 eDVBDB.getInstance().removeServices(-1, -1, -1, satpos)
262 def copyCurrentToBouquetList(self):
263 self.csel.copyCurrentToBouquetList()
266 def removeBouquet(self):
267 self.csel.removeBouquet()
270 def showMarkerInputBox(self):
271 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)
273 def markerInputCallback(self, marker):
274 if marker is not None:
275 self.csel.addMarker(marker)
278 def addCurrentServiceToBouquet(self, dest):
279 self.csel.addServiceToBouquet(dest)
280 if self.bsel is not None:
281 self.bsel.close(True)
283 self.close(True) # close bouquet selection
285 def removeCurrentService(self):
286 self.csel.removeCurrentService()
289 def toggleMoveMode(self):
290 self.csel.toggleMoveMode()
293 def bouquetMarkStart(self):
294 self.csel.startMarkedEdit(EDIT_BOUQUET)
297 def bouquetMarkEnd(self):
298 self.csel.endMarkedEdit(abort=False)
301 def bouquetMarkAbort(self):
302 self.csel.endMarkedEdit(abort=True)
305 def removeNewFoundFlag(self):
306 eDVBDB.getInstance().removeFlag(self.csel.getCurrentSelection(), FLAG_SERVICE_NEW_FOUND)
309 def removeAllNewFoundFlags(self):
310 curpath = self.csel.getCurrentSelection().getPath()
311 idx = curpath.find("satellitePosition == ")
313 tmp = curpath[idx+21:]
316 satpos = int(tmp[:idx])
317 eDVBDB.getInstance().removeFlags(FLAG_SERVICE_NEW_FOUND, -1, -1, -1, satpos)
320 def editAlternativeServices(self):
321 self.csel.startMarkedEdit(EDIT_ALTERNATIVES)
324 def showAlternativeServices(self):
325 self.csel.enterPath(self.csel.getCurrentSelection())
328 def removeAlternativeServices(self):
329 self.csel.removeAlternativeServices()
332 def addAlternativeServices(self):
333 self.csel.addAlternativeServices()
334 self.csel.startMarkedEdit(EDIT_ALTERNATIVES)
337 class SelectionEventInfo:
339 self["ServiceEvent"] = ServiceEvent()
340 self.servicelist.connectSelChanged(self.__selectionChanged)
341 self.timer = eTimer()
342 self.timer.callback.append(self.updateEventInfo)
343 self.onShown.append(self.__selectionChanged)
345 def __selectionChanged(self):
347 self.timer.start(100, True)
349 def updateEventInfo(self):
350 cur = self.getCurrentSelection()
351 self["ServiceEvent"].newService(cur)
353 class ChannelSelectionEPG:
355 self["ChannelSelectEPGActions"] = ActionMap(["ChannelSelectEPGActions"],
357 "showEPGList": self.showEPGList,
360 def showEPGList(self):
361 ref=self.getCurrentSelection()
363 self.savedService = ref
364 self.session.openWithCallback(self.SingleServiceEPGClosed, EPGSelection, ref, serviceChangeCB=self.changeServiceCB)
366 def SingleServiceEPGClosed(self, ret=False):
367 self.setCurrentSelection(self.savedService)
369 def changeServiceCB(self, direction, epg):
370 beg = self.getCurrentSelection()
376 cur = self.getCurrentSelection()
377 if cur == beg or not (cur.flags & eServiceReference.isMarker):
379 epg.setService(ServiceReference(self.getCurrentSelection()))
381 class ChannelSelectionEdit:
383 self.entry_marked = False
384 self.movemode = False
385 self.bouquet_mark_edit = OFF
386 self.mutableList = None
388 self.saved_title = None
389 self.saved_root = None
391 class ChannelSelectionEditActionMap(ActionMap):
392 def __init__(self, csel, contexts = [ ], actions = { }, prio=0):
393 ActionMap.__init__(self, contexts, actions, prio)
396 def action(self, contexts, action):
397 if action == "cancel":
398 self.csel.handleEditCancel()
399 return 0 # fall-trough
401 return 0 # fall-trough
403 return ActionMap.action(self, contexts, action)
405 self["ChannelSelectEditActions"] = ChannelSelectionEditActionMap(self, ["ChannelSelectEditActions", "OkCancelActions"],
407 "contextMenu": self.doContext,
410 def getMutableList(self, root=eServiceReference()):
411 if not self.mutableList is None:
412 return self.mutableList
413 serviceHandler = eServiceCenter.getInstance()
416 list = root and serviceHandler.list(root)
418 return list.startEdit()
421 def buildBouquetID(self, str):
425 if (c >= 'a' and c <= 'z') or (c >= '0' and c <= '9'):
431 def addMarker(self, name):
432 current = self.servicelist.getCurrent()
433 mutableList = self.getMutableList()
436 str = '1:64:%d:0:0:0:0:0:0:0::%s'%(cnt, name)
437 ref = eServiceReference(str)
438 if current and current.valid():
439 if not mutableList.addService(ref, current):
440 self.servicelist.addService(ref, True)
441 mutableList.flushChanges()
443 elif not mutableList.addService(ref):
444 self.servicelist.addService(ref, True)
445 mutableList.flushChanges()
449 def addAlternativeServices(self):
450 cur_service = ServiceReference(self.getCurrentSelection())
451 root = self.getRoot()
452 cur_root = root and ServiceReference(root)
453 mutableBouquet = cur_root.list().startEdit()
455 name = cur_service.getServiceName()
457 if self.mode == MODE_TV:
458 str = '1:134:1:0:0:0:0:0:0:0:FROM BOUQUET \"alternatives.%s.tv\" ORDER BY bouquet'%(self.buildBouquetID(name))
460 str = '1:134:2:0:0:0:0:0:0:0:FROM BOUQUET \"alternatives.%s.radio\" ORDER BY bouquet'%(self.buildBouquetID(name))
461 new_ref = ServiceReference(str)
462 if not mutableBouquet.addService(new_ref.ref, cur_service.ref):
463 mutableBouquet.removeService(cur_service.ref)
464 mutableBouquet.flushChanges()
465 eDVBDB.getInstance().reloadBouquets()
466 mutableAlternatives = new_ref.list().startEdit()
467 if mutableAlternatives:
468 mutableAlternatives.setListName(name)
469 if mutableAlternatives.addService(cur_service.ref):
470 print "add", cur_service.toString(), "to new alternatives failed"
471 mutableAlternatives.flushChanges()
472 self.servicelist.addService(new_ref.ref, True)
473 self.servicelist.removeCurrent()
474 self.servicelist.moveUp()
476 print "get mutable list for new created alternatives failed"
478 print "add", str, "to", cur_root.getServiceName(), "failed"
480 print "bouquetlist is not editable"
482 def addBouquet(self, bName, services):
483 serviceHandler = eServiceCenter.getInstance()
484 mutableBouquetList = serviceHandler.list(self.bouquet_root).startEdit()
485 if mutableBouquetList:
486 if self.mode == MODE_TV:
488 str = '1:7:1:0:0:0:0:0:0:0:FROM BOUQUET \"userbouquet.%s.tv\" ORDER BY bouquet'%(self.buildBouquetID(bName))
491 str = '1:7:2:0:0:0:0:0:0:0:FROM BOUQUET \"userbouquet.%s.radio\" ORDER BY bouquet'%(self.buildBouquetID(bName))
492 new_bouquet_ref = eServiceReference(str)
493 if not mutableBouquetList.addService(new_bouquet_ref):
494 mutableBouquetList.flushChanges()
495 eDVBDB.getInstance().reloadBouquets()
496 mutableBouquet = serviceHandler.list(new_bouquet_ref).startEdit()
498 mutableBouquet.setListName(bName)
499 if services is not None:
500 for service in services:
501 if mutableBouquet.addService(service):
502 print "add", service.toString(), "to new bouquet failed"
503 mutableBouquet.flushChanges()
505 print "get mutable list for new created bouquet failed"
506 # do some voodoo to check if current_root is equal to bouquet_root
507 cur_root = self.getRoot();
508 str1 = cur_root and cur_root.toString()
509 pos1 = str1 and str1.find("FROM BOUQUET") or -1
510 pos2 = self.bouquet_rootstr.find("FROM BOUQUET")
511 if pos1 != -1 and pos2 != -1 and str1[pos1:] == self.bouquet_rootstr[pos2:]:
512 self.servicelist.addService(new_bouquet_ref)
514 print "add", str, "to bouquets failed"
516 print "bouquetlist is not editable"
518 def copyCurrentToBouquetList(self):
519 provider = ServiceReference(self.getCurrentSelection())
520 providerName = provider.getServiceName()
521 serviceHandler = eServiceCenter.getInstance()
522 services = serviceHandler.list(provider.ref)
523 self.addBouquet(providerName, services and services.getContent('R', True))
525 def removeAlternativeServices(self):
526 cur_service = ServiceReference(self.getCurrentSelection())
527 root = self.getRoot()
528 cur_root = root and ServiceReference(root)
529 list = cur_service.list()
530 first_in_alternative = list and list.getNext()
531 if first_in_alternative:
532 edit_root = cur_root and cur_root.list().startEdit()
534 if not edit_root.addService(first_in_alternative, cur_service.ref):
535 self.servicelist.addService(first_in_alternative, True)
537 print "couldn't add first alternative service to current root"
539 print "couldn't edit current root!!"
541 print "remove empty alternative list !!"
543 self.servicelist.moveUp()
545 def removeBouquet(self):
546 refstr = self.getCurrentSelection().toString()
547 print "removeBouquet", refstr
548 self.bouquetNumOffsetCache = { }
549 pos = refstr.find('FROM BOUQUET "')
552 refstr = refstr[pos+14:]
553 pos = refstr.find('"')
555 filename = '/etc/enigma2/' + refstr[:pos] # FIXMEEE !!! HARDCODED /etc/enigma2
556 self.removeCurrentService()
558 if filename is not None:
561 print "error during remove of", filename
563 # multiple marked entry stuff ( edit mode, later multiepg selection )
564 def startMarkedEdit(self, type):
565 self.savedPath = self.servicePath[:]
566 if type == EDIT_ALTERNATIVES:
567 self.enterPath(self.getCurrentSelection())
568 self.mutableList = self.getMutableList()
569 # add all services from the current list to internal marked set in listboxservicecontent
570 self.clearMarks() # this clears the internal marked set in the listboxservicecontent
571 self.saved_title = self.getTitle()
572 pos = self.saved_title.find(')')
573 new_title = self.saved_title[:pos+1]
574 if type == EDIT_ALTERNATIVES:
575 self.bouquet_mark_edit = EDIT_ALTERNATIVES
576 new_title += ' ' + _("[alternative edit]")
578 self.bouquet_mark_edit = EDIT_BOUQUET
579 if config.usage.multibouquet.value:
580 new_title += ' ' + _("[bouquet edit]")
582 new_title += ' ' + _("[favourite edit]")
583 self.setTitle(new_title)
584 self.__marked = self.servicelist.getRootServices()
585 for x in self.__marked:
586 self.servicelist.addMarked(eServiceReference(x))
587 self.showAllServices()
589 def endMarkedEdit(self, abort):
590 if not abort and self.mutableList is not None:
591 self.bouquetNumOffsetCache = { }
592 new_marked = set(self.servicelist.getMarked())
593 old_marked = set(self.__marked)
594 removed = old_marked - new_marked
595 added = new_marked - old_marked
599 self.mutableList.removeService(eServiceReference(x))
602 self.mutableList.addService(eServiceReference(x))
604 self.mutableList.flushChanges()
607 self.bouquet_mark_edit = OFF
608 self.mutableList = None
609 self.setTitle(self.saved_title)
610 self.saved_title = None
611 # self.servicePath is just a reference to servicePathTv or Radio...
612 # so we never ever do use the asignment operator in self.servicePath
613 del self.servicePath[:] # remove all elements
614 self.servicePath += self.savedPath # add saved elements
616 self.setRoot(self.servicePath[-1])
618 def clearMarks(self):
619 self.servicelist.clearMarks()
622 ref = self.servicelist.getCurrent()
623 if self.servicelist.isMarked(ref):
624 self.servicelist.removeMarked(ref)
626 self.servicelist.addMarked(ref)
628 def removeCurrentService(self):
629 ref = self.servicelist.getCurrent()
630 mutableList = self.getMutableList()
631 if ref.valid() and mutableList is not None:
632 if not mutableList.removeService(ref):
633 self.bouquetNumOffsetCache = { }
634 mutableList.flushChanges() #FIXME dont flush on each single removed service
635 self.servicelist.removeCurrent()
637 def addServiceToBouquet(self, dest, service=None):
638 mutableList = self.getMutableList(dest)
639 if not mutableList is None:
640 if service is None: #use current selected service
641 service = self.servicelist.getCurrent()
642 if not mutableList.addService(service):
643 self.bouquetNumOffsetCache = { }
644 mutableList.flushChanges()
645 # do some voodoo to check if current_root is equal to dest
646 cur_root = self.getRoot();
647 str1 = cur_root and cur_root.toString() or -1
648 str2 = dest.toString()
649 pos1 = str1.find("FROM BOUQUET")
650 pos2 = str2.find("FROM BOUQUET")
651 if pos1 != -1 and pos2 != -1 and str1[pos1:] == str2[pos2:]:
652 self.servicelist.addService(service)
654 def toggleMoveMode(self):
656 if self.entry_marked:
657 self.toggleMoveMarked() # unmark current entry
658 self.movemode = False
659 self.pathChangeDisabled = False # re-enable path change
660 self.mutableList.flushChanges() # FIXME add check if changes was made
661 self.mutableList = None
662 self.setTitle(self.saved_title)
663 self.saved_title = None
664 cur_root = self.getRoot()
665 if cur_root and cur_root == self.bouquet_root:
666 self.bouquetNumOffsetCache = { }
668 self.mutableList = self.getMutableList()
670 self.pathChangeDisabled = True # no path change allowed in movemode
671 self.saved_title = self.getTitle()
672 new_title = self.saved_title
673 pos = self.saved_title.find(')')
674 new_title = self.saved_title[:pos+1] + ' ' + _("[move mode]") + self.saved_title[pos+1:]
675 self.setTitle(new_title);
677 def handleEditCancel(self):
678 if self.movemode: #movemode active?
679 self.channelSelected() # unmark
680 self.toggleMoveMode() # disable move mode
681 elif self.bouquet_mark_edit != OFF:
682 self.endMarkedEdit(True) # abort edit mode
684 def toggleMoveMarked(self):
685 if self.entry_marked:
686 self.servicelist.setCurrentMarked(False)
687 self.entry_marked = False
689 self.servicelist.setCurrentMarked(True)
690 self.entry_marked = True
693 self.session.openWithCallback(self.exitContext, ChannelContextMenu, self)
695 def exitContext(self, close = False):
702 # type 1 = digital television service
703 # type 4 = nvod reference service (NYI)
704 # type 17 = MPEG-2 HD digital television service
705 # type 22 = advanced codec SD digital television
706 # type 24 = advanced codec SD NVOD reference service (NYI)
707 # type 25 = advanced codec HD digital television
708 # type 27 = advanced codec HD NVOD reference service (NYI)
709 # type 2 = digital radio sound service
710 # type 10 = advanced codec digital radio sound service
712 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)'
713 service_types_radio = '1:7:2:0:0:0:0:0:0:0:(type == 2) || (type == 10)'
715 class ChannelSelectionBase(Screen):
716 def __init__(self, session):
717 Screen.__init__(self, session)
719 self["key_red"] = Button(_("All"))
720 self["key_green"] = Button(_("Satellites"))
721 self["key_yellow"] = Button(_("Provider"))
722 self["key_blue"] = Button(_("Favourites"))
724 self["list"] = ServiceList()
725 self.servicelist = self["list"]
727 self.numericalTextInput = NumericalTextInput()
728 self.numericalTextInput.setUseableChars(u'1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ')
730 self.servicePathTV = [ ]
731 self.servicePathRadio = [ ]
732 self.servicePath = [ ]
733 self.rootChanged = False
737 self.pathChangeDisabled = False
739 self.bouquetNumOffsetCache = { }
741 self["ChannelSelectBaseActions"] = NumberActionMap(["ChannelSelectBaseActions", "NumberActions", "InputAsciiActions"],
743 "showFavourites": self.showFavourites,
744 "showAllServices": self.showAllServices,
745 "showProviders": self.showProviders,
746 "showSatellites": self.showSatellites,
747 "nextBouquet": self.nextBouquet,
748 "prevBouquet": self.prevBouquet,
749 "nextMarker": self.nextMarker,
750 "prevMarker": self.prevMarker,
751 "gotAsciiCode": self.keyAsciiCode,
752 "1": self.keyNumberGlobal,
753 "2": self.keyNumberGlobal,
754 "3": self.keyNumberGlobal,
755 "4": self.keyNumberGlobal,
756 "5": self.keyNumberGlobal,
757 "6": self.keyNumberGlobal,
758 "7": self.keyNumberGlobal,
759 "8": self.keyNumberGlobal,
760 "9": self.keyNumberGlobal,
763 self.recallBouquetMode()
765 def getBouquetNumOffset(self, bouquet):
766 if not config.usage.multibouquet.value:
768 str = bouquet.toString()
770 if not self.bouquetNumOffsetCache.has_key(str):
771 serviceHandler = eServiceCenter.getInstance()
772 bouquetlist = serviceHandler.list(self.bouquet_root)
773 if not bouquetlist is None:
775 bouquetIterator = bouquetlist.getNext()
776 if not bouquetIterator.valid(): #end of list
778 self.bouquetNumOffsetCache[bouquetIterator.toString()]=offsetCount
779 if not (bouquetIterator.flags & eServiceReference.isDirectory):
781 servicelist = serviceHandler.list(bouquetIterator)
782 if not servicelist is None:
784 serviceIterator = servicelist.getNext()
785 if not serviceIterator.valid(): #check if end of list
787 playable = not (serviceIterator.flags & (eServiceReference.isDirectory|eServiceReference.isMarker))
790 return self.bouquetNumOffsetCache.get(str, offsetCount)
792 def recallBouquetMode(self):
793 if self.mode == MODE_TV:
794 self.service_types = service_types_tv
795 if config.usage.multibouquet.value:
796 self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "bouquets.tv" ORDER BY bouquet'
798 self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.tv" ORDER BY bouquet'%(self.service_types)
800 self.service_types = service_types_radio
801 if config.usage.multibouquet.value:
802 self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "bouquets.radio" ORDER BY bouquet'
804 self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.radio" ORDER BY bouquet'%(self.service_types)
805 self.bouquet_root = eServiceReference(self.bouquet_rootstr)
809 self.servicePath = self.servicePathTV
810 self.recallBouquetMode()
811 title = self.getTitle()
812 pos = title.find(" (")
818 def setRadioMode(self):
819 self.mode = MODE_RADIO
820 self.servicePath = self.servicePathRadio
821 self.recallBouquetMode()
822 title = self.getTitle()
823 pos = title.find(" (")
829 def setRoot(self, root, justSet=False):
830 path = root.getPath()
831 inBouquetRootList = path.find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
832 pos = path.find('FROM BOUQUET')
833 isBouquet = (pos != -1) and (root.flags & eServiceReference.isDirectory)
834 if not inBouquetRootList and isBouquet:
835 self.servicelist.setMode(ServiceList.MODE_FAVOURITES)
836 self.servicelist.setNumberOffset(self.getBouquetNumOffset(root))
838 self.servicelist.setMode(ServiceList.MODE_NORMAL)
839 self.servicelist.setRoot(root, justSet)
840 self.rootChanged = True
841 self.buildTitleString()
843 def removeModeStr(self, str):
844 if self.mode == MODE_TV:
845 pos = str.find(' (TV)')
847 pos = str.find(' (Radio)')
852 def getServiceName(self, ref):
853 str = self.removeModeStr(ServiceReference(ref).getServiceName())
855 pathstr = ref.getPath()
856 if 'FROM PROVIDERS' in pathstr:
858 if 'FROM SATELLITES' in pathstr:
859 return _("Satellites")
860 if ') ORDER BY name' in pathstr:
864 def buildTitleString(self):
865 titleStr = self.getTitle()
866 pos = titleStr.find(']')
868 pos = titleStr.find(')')
870 titleStr = titleStr[:pos+1]
871 Len = len(self.servicePath)
873 base_ref = self.servicePath[0]
875 end_ref = self.servicePath[Len-1]
878 nameStr = self.getServiceName(base_ref)
879 titleStr += ' ' + nameStr
880 if end_ref is not None:
885 nameStr = self.getServiceName(end_ref)
887 self.setTitle(titleStr)
890 self.servicelist.moveUp()
893 self.servicelist.moveDown()
896 del self.servicePath[:]
898 def enterPath(self, ref, justSet=False):
899 self.servicePath.append(ref)
900 self.setRoot(ref, justSet)
902 def pathUp(self, justSet=False):
903 prev = self.servicePath.pop()
905 current = self.servicePath[-1]
906 self.setRoot(current, justSet)
908 self.setCurrentSelection(prev)
911 def isBasePathEqual(self, ref):
912 if len(self.servicePath) > 1 and self.servicePath[0] == ref:
916 def isPrevPathEqual(self, ref):
917 length = len(self.servicePath)
918 if length > 1 and self.servicePath[length-2] == ref:
922 def preEnterPath(self, refstr):
925 def showAllServices(self):
926 if not self.pathChangeDisabled:
927 refstr = '%s ORDER BY name'%(self.service_types)
928 if not self.preEnterPath(refstr):
929 ref = eServiceReference(refstr)
930 currentRoot = self.getRoot()
931 if currentRoot is None or currentRoot != ref:
935 def showSatellites(self):
936 if not self.pathChangeDisabled:
937 refstr = '%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types)
938 if not self.preEnterPath(refstr):
939 ref = eServiceReference(refstr)
943 if self.isBasePathEqual(ref):
944 if self.isPrevPathEqual(ref):
946 prev = self.pathUp(justSet)
948 currentRoot = self.getRoot()
949 if currentRoot is None or currentRoot != ref:
952 self.enterPath(ref, True)
954 serviceHandler = eServiceCenter.getInstance()
955 servicelist = serviceHandler.list(ref)
956 if not servicelist is None:
958 service = servicelist.getNext()
959 if not service.valid(): #check if end of list
961 unsigned_orbpos = service.getUnsignedData(4) >> 16
962 orbpos = service.getData(4) >> 16
965 if service.getPath().find("FROM PROVIDER") != -1:
966 service_type = _("Providers")
967 elif service.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
968 service_type = _("New")
970 service_type = _("Services")
972 # why we need this cast?
973 service_name = str(nimmanager.getSatDescription(orbpos))
975 if unsigned_orbpos == 0xFFFF: #Cable
976 service_name = _("Cable")
977 elif unsigned_orbpos == 0xEEEE: #Terrestrial
978 service_name = _("Terrestrial")
980 if orbpos > 1800: # west
981 orbpos = 3600 - orbpos
985 service_name = ("%d.%d" + h) % (orbpos / 10, orbpos % 10)
986 service.setName("%s - %s" % (service_name, service_type))
987 self.servicelist.addService(service)
988 cur_ref = self.session.nav.getCurrentlyPlayingServiceReference()
990 pos = self.service_types.rfind(':')
991 refstr = '%s (channelID == %08x%04x%04x) && %s ORDER BY name' %(self.service_types[:pos+1],
992 cur_ref.getUnsignedData(4), # NAMESPACE
993 cur_ref.getUnsignedData(2), # TSID
994 cur_ref.getUnsignedData(3), # ONID
995 self.service_types[pos+1:])
996 ref = eServiceReference(refstr)
997 ref.setName(_("Current Transponder"))
998 self.servicelist.addService(ref)
999 self.servicelist.finishFill()
1000 if prev is not None:
1001 self.setCurrentSelection(prev)
1003 def showProviders(self):
1004 if not self.pathChangeDisabled:
1005 refstr = '%s FROM PROVIDERS ORDER BY name'%(self.service_types)
1006 if not self.preEnterPath(refstr):
1007 ref = eServiceReference(refstr)
1008 if self.isBasePathEqual(ref):
1011 currentRoot = self.getRoot()
1012 if currentRoot is None or currentRoot != ref:
1016 def changeBouquet(self, direction):
1017 if not self.pathChangeDisabled:
1018 if len(self.servicePath) > 1:
1019 #when enter satellite root list we must do some magic stuff..
1020 ref = eServiceReference('%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types))
1021 if self.isBasePathEqual(ref):
1022 self.showSatellites()
1029 ref = self.getCurrentSelection()
1032 def inBouquet(self):
1033 if self.servicePath and self.servicePath[0] == self.bouquet_root:
1038 return self.servicelist.atBegin()
1041 return self.servicelist.atEnd()
1043 def nextBouquet(self):
1044 self.changeBouquet(+1)
1046 def prevBouquet(self):
1047 self.changeBouquet(-1)
1049 def showFavourites(self):
1050 if not self.pathChangeDisabled:
1051 if not self.preEnterPath(self.bouquet_rootstr):
1052 if self.isBasePathEqual(self.bouquet_root):
1055 currentRoot = self.getRoot()
1056 if currentRoot is None or currentRoot != self.bouquet_root:
1058 self.enterPath(self.bouquet_root)
1060 def keyNumberGlobal(self, number):
1061 unichar = self.numericalTextInput.getKey(number)
1062 charstr = unichar.encode("utf-8")
1063 if len(charstr) == 1:
1064 self.servicelist.moveToChar(charstr[0])
1066 def keyAsciiCode(self):
1067 unichar = unichr(getPrevAsciiCode())
1068 charstr = unichar.encode("utf-8")
1069 if len(charstr) == 1:
1070 self.servicelist.moveToChar(charstr[0])
1073 return self.servicelist.getRoot()
1075 def getCurrentSelection(self):
1076 return self.servicelist.getCurrent()
1078 def setCurrentSelection(self, service):
1079 self.servicelist.setCurrent(service)
1081 def getBouquetList(self):
1083 serviceHandler = eServiceCenter.getInstance()
1084 if config.usage.multibouquet.value:
1085 list = serviceHandler.list(self.bouquet_root)
1091 if s.flags & eServiceReference.isDirectory:
1092 info = serviceHandler.info(s)
1094 bouquets.append((info.getName(s), s))
1097 info = serviceHandler.info(self.bouquet_root)
1099 bouquets.append((info.getName(self.bouquet_root), self.bouquet_root))
1103 def keyNumber0(self, num):
1104 if len(self.servicePath) > 1:
1107 self.keyNumberGlobal(num)
1110 if len(self.servicePath) > 1:
1111 if self.isBasePathEqual(self.bouquet_root):
1112 self.showFavourites()
1114 ref = eServiceReference('%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types))
1115 if self.isBasePathEqual(ref):
1116 self.showSatellites()
1118 ref = eServiceReference('%s FROM PROVIDERS ORDER BY name'%(self.service_types))
1119 if self.isBasePathEqual(ref):
1120 self.showProviders()
1122 self.showAllServices()
1124 def nextMarker(self):
1125 self.servicelist.moveToNextMarker()
1127 def prevMarker(self):
1128 self.servicelist.moveToPrevMarker()
1132 #config for lastservice
1133 config.tv = ConfigSubsection()
1134 config.tv.lastservice = ConfigText()
1135 config.tv.lastroot = ConfigText()
1136 config.radio = ConfigSubsection()
1137 config.radio.lastservice = ConfigText()
1138 config.radio.lastroot = ConfigText()
1139 config.servicelist = ConfigSubsection()
1140 config.servicelist.lastmode = ConfigText(default = "tv")
1142 class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG, SelectionEventInfo):
1143 def __init__(self, session):
1144 ChannelSelectionBase.__init__(self,session)
1145 ChannelSelectionEdit.__init__(self)
1146 ChannelSelectionEPG.__init__(self)
1147 SelectionEventInfo.__init__(self)
1149 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1151 "cancel": self.cancel,
1152 "ok": self.channelSelected,
1153 "keyRadio": self.setModeRadio,
1154 "keyTV": self.setModeTv,
1157 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
1159 iPlayableService.evStart: self.__evServiceStart,
1160 iPlayableService.evEnd: self.__evServiceEnd
1163 self.lastChannelRootTimer = eTimer()
1164 self.lastChannelRootTimer.callback.append(self.__onCreate)
1165 self.lastChannelRootTimer.start(100,True)
1167 self.history_tv = [ ]
1168 self.history_radio = [ ]
1169 self.history = self.history_tv
1170 self.history_pos = 0
1172 self.lastservice = config.tv.lastservice
1173 self.lastroot = config.tv.lastroot
1174 self.revertMode = None
1175 config.usage.multibouquet.addNotifier(self.multibouquet_config_changed)
1176 self.new_service_played = False
1177 self.onExecBegin.append(self.asciiOn)
1180 rcinput = eRCInput.getInstance()
1181 rcinput.setKeyboardMode(rcinput.kmAscii)
1184 rcinput = eRCInput.getInstance()
1185 rcinput.setKeyboardMode(rcinput.kmNone)
1187 def multibouquet_config_changed(self, val):
1188 self.recallBouquetMode()
1190 def __evServiceStart(self):
1191 service = self.session.nav.getCurrentService()
1193 info = service.info()
1195 refstr = info.getInfoString(iServiceInformation.sServiceref)
1196 self.servicelist.setPlayableIgnoreService(eServiceReference(refstr))
1198 def __evServiceEnd(self):
1199 self.servicelist.setPlayableIgnoreService(eServiceReference())
1202 self.rootChanged = True
1204 lastservice=eServiceReference(self.lastservice.value)
1205 if lastservice.valid():
1206 self.setCurrentSelection(lastservice)
1208 def setModeTv(self):
1209 if self.revertMode is None and config.servicelist.lastmode.value == "radio":
1210 self.revertMode = MODE_RADIO
1211 self.history = self.history_tv
1212 self.lastservice = config.tv.lastservice
1213 self.lastroot = config.tv.lastroot
1214 config.servicelist.lastmode.value = "tv"
1218 def setModeRadio(self):
1219 if self.revertMode is None and config.servicelist.lastmode.value == "tv":
1220 self.revertMode = MODE_TV
1221 if config.usage.e1like_radio_mode.value:
1222 self.history = self.history_radio
1223 self.lastservice = config.radio.lastservice
1224 self.lastroot = config.radio.lastroot
1225 config.servicelist.lastmode.value = "radio"
1229 def __onCreate(self):
1230 if config.usage.e1like_radio_mode.value:
1231 if config.servicelist.lastmode.value == "tv":
1237 lastservice=eServiceReference(self.lastservice.value)
1238 if lastservice.valid():
1241 def channelSelected(self):
1242 ref = self.getCurrentSelection()
1244 self.toggleMoveMarked()
1245 elif (ref.flags & 7) == 7:
1247 elif self.bouquet_mark_edit != OFF:
1248 if not (self.bouquet_mark_edit == EDIT_ALTERNATIVES and ref.flags & eServiceReference.isGroup):
1250 elif not (ref.flags & eServiceReference.isMarker): # no marker
1251 root = self.getRoot()
1252 if not root or not (root.flags & eServiceReference.isGroup):
1257 #called from infoBar and channelSelected
1259 self.revertMode=None
1260 ref = self.session.nav.getCurrentlyPlayingServiceReference()
1261 nref = self.getCurrentSelection()
1262 if ref is None or ref != nref:
1263 self.new_service_played = True
1264 self.session.nav.playService(nref)
1266 self.saveChannel(nref)
1267 config.servicelist.lastmode.save()
1268 self.addToHistory(nref)
1270 def newServicePlayed(self):
1271 ret = self.new_service_played
1272 self.new_service_played = False
1275 def addToHistory(self, ref):
1276 if self.servicePath is not None:
1277 tmp=self.servicePath[:]
1280 del self.history[self.history_pos+1:]
1283 self.history.append(tmp)
1284 hlen = len(self.history)
1285 if hlen > HISTORYSIZE:
1288 self.history_pos = hlen-1
1290 def historyBack(self):
1291 hlen = len(self.history)
1292 if hlen > 1 and self.history_pos > 0:
1293 self.history_pos -= 1
1294 self.setHistoryPath()
1296 def historyNext(self):
1297 hlen = len(self.history)
1298 if hlen > 1 and self.history_pos < (hlen-1):
1299 self.history_pos += 1
1300 self.setHistoryPath()
1302 def setHistoryPath(self):
1303 path = self.history[self.history_pos][:]
1305 del self.servicePath[:]
1306 self.servicePath += path
1309 cur_root = self.getRoot()
1310 if cur_root and cur_root != root:
1312 self.session.nav.playService(ref)
1313 self.setCurrentSelection(ref)
1314 self.saveChannel(ref)
1318 for i in self.servicePath:
1319 path += i.toString()
1321 if path and path != self.lastroot.value:
1322 self.lastroot.value = path
1323 self.lastroot.save()
1325 def restoreRoot(self):
1326 tmp = [x for x in self.lastroot.value.split(';') if x != '']
1327 current = [x.toString() for x in self.servicePath]
1328 if tmp != current or self.rootChanged:
1332 self.servicePath.append(eServiceReference(i))
1335 path = self.servicePath.pop()
1336 self.enterPath(path)
1338 self.showFavourites()
1340 self.rootChanged = False
1342 def preEnterPath(self, refstr):
1343 if self.servicePath and self.servicePath[0] != eServiceReference(refstr):
1344 pathstr = self.lastroot.value
1345 if pathstr is not None and pathstr.find(refstr) == 0:
1347 lastservice=eServiceReference(self.lastservice.value)
1348 if lastservice.valid():
1349 self.setCurrentSelection(lastservice)
1353 def saveChannel(self, ref):
1355 refstr = ref.toString()
1358 if refstr != self.lastservice.value:
1359 self.lastservice.value = refstr
1360 self.lastservice.save()
1362 def setCurrentServicePath(self, path):
1364 self.history[self.history_pos] = path
1366 self.history.append(path)
1367 self.setHistoryPath()
1369 def getCurrentServicePath(self):
1371 return self.history[self.history_pos]
1374 def recallPrevService(self):
1375 hlen = len(self.history)
1377 if self.history_pos == hlen-1:
1378 tmp = self.history[self.history_pos]
1379 self.history[self.history_pos] = self.history[self.history_pos-1]
1380 self.history[self.history_pos-1] = tmp
1382 tmp = self.history[self.history_pos+1]
1383 self.history[self.history_pos+1] = self.history[self.history_pos]
1384 self.history[self.history_pos] = tmp
1385 self.setHistoryPath()
1388 if self.revertMode is None:
1390 lastservice=eServiceReference(self.lastservice.value)
1391 if lastservice.valid() and self.getCurrentSelection() != lastservice:
1392 self.setCurrentSelection(lastservice)
1393 elif self.revertMode == MODE_TV:
1395 elif self.revertMode == MODE_RADIO:
1397 self.revertMode = None
1401 class RadioInfoBar(Screen):
1402 def __init__(self, session):
1403 Screen.__init__(self, session)
1404 self["RdsDecoder"] = RdsDecoder(self.session.nav)
1406 class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG, InfoBarBase):
1407 ALLOW_SUSPEND = True
1409 def __init__(self, session, infobar):
1410 ChannelSelectionBase.__init__(self, session)
1411 ChannelSelectionEdit.__init__(self)
1412 ChannelSelectionEPG.__init__(self)
1413 InfoBarBase.__init__(self)
1414 self.infobar = infobar
1415 self.onLayoutFinish.append(self.onCreate)
1417 self.info = session.instantiateDialog(RadioInfoBar) # our simple infobar
1419 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1421 "keyTV": self.closeRadio,
1422 "keyRadio": self.closeRadio,
1423 "cancel": self.closeRadio,
1424 "ok": self.channelSelected,
1427 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
1429 iPlayableService.evStart: self.__evServiceStart,
1430 iPlayableService.evEnd: self.__evServiceEnd
1433 ########## RDS Radiotext / Rass Support BEGIN
1434 self.infobar = infobar # reference to real infobar (the one and only)
1435 self["RdsDecoder"] = self.info["RdsDecoder"]
1436 self["RdsActions"] = HelpableActionMap(self, "InfobarRdsActions",
1438 "startRassInteractive": (self.startRassInteractive, _("View Rass interactive..."))
1440 self["RdsActions"].setEnabled(False)
1441 infobar.rds_display.onRassInteractivePossibilityChanged.append(self.RassInteractivePossibilityChanged)
1442 self.onClose.append(self.__onClose)
1444 def __onClose(self):
1445 lastservice=eServiceReference(config.tv.lastservice.value)
1446 self.session.nav.playService(lastservice)
1448 def startRassInteractive(self):
1450 self.infobar.rass_interactive = self.session.openWithCallback(self.RassInteractiveClosed, RassInteractive)
1452 def RassInteractiveClosed(self):
1454 self.infobar.rass_interactive = None
1455 self.infobar.RassSlidePicChanged()
1457 def RassInteractivePossibilityChanged(self, state):
1458 self["RdsActions"].setEnabled(state)
1459 ########## RDS Radiotext / Rass Support END
1461 def closeRadio(self):
1462 self.infobar.rds_display.onRassInteractivePossibilityChanged.remove(self.RassInteractivePossibilityChanged)
1464 #set previous tv service
1467 def __evServiceStart(self):
1468 service = self.session.nav.getCurrentService()
1470 info = service.info()
1472 refstr = info.getInfoString(iServiceInformation.sServiceref)
1473 self.servicelist.setPlayableIgnoreService(eServiceReference(refstr))
1475 def __evServiceEnd(self):
1476 self.servicelist.setPlayableIgnoreService(eServiceReference())
1480 for i in self.servicePathRadio:
1481 path += i.toString()
1483 if path and path != config.radio.lastroot.value:
1484 config.radio.lastroot.value = path
1485 config.radio.lastroot.save()
1487 def restoreRoot(self):
1488 tmp = [x for x in config.radio.lastroot.value.split(';') if x != '']
1489 current = [x.toString() for x in self.servicePath]
1490 if tmp != current or self.rootChanged:
1493 self.servicePathRadio.append(eServiceReference(i))
1496 path = self.servicePathRadio.pop()
1497 self.enterPath(path)
1499 self.showFavourites()
1501 self.rootChanged = False
1503 def preEnterPath(self, refstr):
1504 if self.servicePathRadio and self.servicePathRadio[0] != eServiceReference(refstr):
1505 pathstr = config.radio.lastroot.value
1506 if pathstr is not None and pathstr.find(refstr) == 0:
1508 lastservice=eServiceReference(config.radio.lastservice.value)
1509 if lastservice.valid():
1510 self.setCurrentSelection(lastservice)
1517 lastservice=eServiceReference(config.radio.lastservice.value)
1518 if lastservice.valid():
1519 self.servicelist.setCurrent(lastservice)
1520 self.session.nav.playService(lastservice)
1522 self.session.nav.stopService()
1525 def channelSelected(self): # just return selected service
1526 ref = self.getCurrentSelection()
1528 self.toggleMoveMarked()
1529 elif (ref.flags & 7) == 7:
1531 elif self.bouquet_mark_edit != OFF:
1532 if not (self.bouquet_mark_edit == EDIT_ALTERNATIVES and ref.flags & eServiceReference.isGroup):
1534 elif not (ref.flags & eServiceReference.isMarker): # no marker
1535 cur_root = self.getRoot()
1536 if not cur_root or not (cur_root.flags & eServiceReference.isGroup):
1537 playingref = self.session.nav.getCurrentlyPlayingServiceReference()
1538 if playingref is None or playingref != ref:
1539 self.session.nav.playService(ref)
1540 config.radio.lastservice.value = ref.toString()
1541 config.radio.lastservice.save()
1544 class SimpleChannelSelection(ChannelSelectionBase):
1545 def __init__(self, session, title):
1546 ChannelSelectionBase.__init__(self, session)
1547 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1549 "cancel": self.close,
1550 "ok": self.channelSelected,
1551 "keyRadio": self.setModeRadio,
1552 "keyTV": self.setModeTv,
1555 self.onLayoutFinish.append(self.layoutFinished)
1557 def layoutFinished(self):
1560 def channelSelected(self): # just return selected service
1561 ref = self.getCurrentSelection()
1562 if (ref.flags & 7) == 7:
1564 elif not (ref.flags & eServiceReference.isMarker):
1565 ref = self.getCurrentSelection()
1568 def setModeTv(self):
1570 self.showFavourites()
1572 def setModeRadio(self):
1574 self.showFavourites()