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
34 from re import compile
36 profile("ChannelSelection.py after imports")
38 FLAG_SERVICE_NEW_FOUND = 64 #define in lib/dvb/idvb.h as dxNewFound = 64
40 class BouquetSelector(Screen):
41 def __init__(self, session, bouquets, selectedFunc, enableWrapAround=False):
42 Screen.__init__(self, session)
44 self.selectedFunc=selectedFunc
46 self["actions"] = ActionMap(["OkCancelActions"],
48 "ok": self.okbuttonClick,
49 "cancel": self.cancelClick
51 entrys = [ (x[0], x[1]) for x in bouquets ]
52 self["menu"] = MenuList(entrys, enableWrapAround)
55 cur = self["menu"].getCurrent()
58 def okbuttonClick(self):
59 self.selectedFunc(self.getCurrent())
67 def cancelClick(self):
70 # csel.bouquet_mark_edit values
75 def append_when_current_valid(current, menu, args, level = 0, key = ""):
76 if current and current.valid() and level <= config.usage.setup_level.index:
77 menu.append(ChoiceEntryComponent(key, args))
79 class ChannelContextMenu(Screen):
80 def __init__(self, session, csel):
81 Screen.__init__(self, session)
82 #raise Exception("we need a better summary screen here")
86 self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "NumberActions"],
88 "ok": self.okbuttonClick,
89 "cancel": self.cancelClick,
90 "blue": self.showServiceInPiP
94 self.pipAvailable = False
95 current = csel.getCurrentSelection()
96 current_root = csel.getRoot()
97 current_sel_path = current.getPath()
98 current_sel_flags = current.flags
99 inBouquetRootList = current_root and current_root.getPath().find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
100 inBouquet = csel.getMutableList() is not None
101 haveBouquets = config.usage.multibouquet.value
103 if not (current_sel_path or current_sel_flags & (eServiceReference.isDirectory|eServiceReference.isMarker)):
104 append_when_current_valid(current, menu, (_("show transponder info"), self.showServiceInformations), level = 2)
105 if csel.bouquet_mark_edit == OFF and not csel.movemode:
106 if not inBouquetRootList:
107 isPlayable = not (current_sel_flags & (eServiceReference.isMarker|eServiceReference.isDirectory))
109 if config.ParentalControl.configured.value:
110 if parentalControl.getProtectionLevel(csel.getCurrentSelection().toCompareString()) == -1:
111 append_when_current_valid(current, menu, (_("add to parental protection"), boundFunction(self.addParentalProtection, csel.getCurrentSelection())), level = 0)
113 append_when_current_valid(current, menu, (_("remove from parental protection"), boundFunction(self.removeParentalProtection, csel.getCurrentSelection())), level = 0)
115 append_when_current_valid(current, menu, (_("add service to bouquet"), self.addServiceToBouquetSelected), level = 0)
117 append_when_current_valid(current, menu, (_("add service to favourites"), self.addServiceToBouquetSelected), level = 0)
119 if current_root.getPath().find('FROM SATELLITES') != -1:
120 append_when_current_valid(current, menu, (_("remove selected satellite"), self.removeSatelliteServices), level = 0)
122 if not inBouquet and current_sel_path.find("PROVIDERS") == -1:
123 append_when_current_valid(current, menu, (_("copy to bouquets"), self.copyCurrentToBouquetList), level = 0)
124 if current_sel_path.find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
125 append_when_current_valid(current, menu, (_("remove all new found flags"), self.removeAllNewFoundFlags), level = 0)
127 append_when_current_valid(current, menu, (_("remove entry"), self.removeCurrentService), level = 0)
128 if current_root and current_root.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
129 append_when_current_valid(current, menu, (_("remove new found flag"), self.removeNewFoundFlag), level = 0)
130 if isPlayable and SystemInfo.get("NumVideoDecoders", 1) > 1:
131 append_when_current_valid(current, menu, (_("Activate Picture in Picture"), self.showServiceInPiP), level = 0, key = "blue")
132 self.pipAvailable = True
134 menu.append(ChoiceEntryComponent(text = (_("add bouquet"), self.showBouquetInputBox)))
135 append_when_current_valid(current, menu, (_("remove entry"), self.removeBouquet), level = 0)
137 if inBouquet: # current list is editable?
138 if csel.bouquet_mark_edit == OFF:
139 if not csel.movemode:
140 append_when_current_valid(current, menu, (_("enable move mode"), self.toggleMoveMode), level = 1)
141 if not inBouquetRootList and current_root and not (current_root.flags & eServiceReference.isGroup):
142 menu.append(ChoiceEntryComponent(text = (_("add marker"), self.showMarkerInputBox)))
144 append_when_current_valid(current, menu, (_("enable bouquet edit"), self.bouquetMarkStart), level = 0)
146 append_when_current_valid(current, menu, (_("enable favourite edit"), self.bouquetMarkStart), level = 0)
147 if current_sel_flags & eServiceReference.isGroup:
148 append_when_current_valid(current, menu, (_("edit alternatives"), self.editAlternativeServices), level = 2)
149 append_when_current_valid(current, menu, (_("show alternatives"), self.showAlternativeServices), level = 2)
150 append_when_current_valid(current, menu, (_("remove all alternatives"), self.removeAlternativeServices), level = 2)
151 elif not current_sel_flags & eServiceReference.isMarker:
152 append_when_current_valid(current, menu, (_("add alternatives"), self.addAlternativeServices), level = 2)
154 append_when_current_valid(current, menu, (_("disable move mode"), self.toggleMoveMode), level = 0)
156 if csel.bouquet_mark_edit == EDIT_BOUQUET:
158 append_when_current_valid(current, menu, (_("end bouquet edit"), self.bouquetMarkEnd), level = 0)
159 append_when_current_valid(current, menu, (_("abort bouquet edit"), self.bouquetMarkAbort), level = 0)
161 append_when_current_valid(current, menu, (_("end favourites edit"), self.bouquetMarkEnd), level = 0)
162 append_when_current_valid(current, menu, (_("abort favourites edit"), self.bouquetMarkAbort), level = 0)
164 append_when_current_valid(current, menu, (_("end alternatives edit"), self.bouquetMarkEnd), level = 0)
165 append_when_current_valid(current, menu, (_("abort alternatives edit"), self.bouquetMarkAbort), level = 0)
167 menu.append(ChoiceEntryComponent(text = (_("back"), self.cancelClick)))
168 self["menu"] = ChoiceList(menu)
170 def okbuttonClick(self):
171 self["menu"].getCurrent()[0][1]()
173 def cancelClick(self):
176 def showServiceInformations(self):
177 self.session.open( ServiceInfo, self.csel.getCurrentSelection() )
179 def showBouquetInputBox(self):
180 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)
182 def bouquetInputCallback(self, bouquet):
183 if bouquet is not None:
184 self.csel.addBouquet(bouquet, None)
187 def addParentalProtection(self, service):
188 parentalControl.protectService(service.toCompareString())
191 def removeParentalProtection(self, service):
192 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"))
194 def pinEntered(self, service, result):
196 parentalControl.unProtectService(service)
199 self.session.openWithCallback(self.close, MessageBox, _("The pin code you entered is wrong."), MessageBox.TYPE_ERROR)
201 def showServiceInPiP(self):
202 if not self.pipAvailable:
204 if self.session.pipshown:
206 self.session.pip = self.session.instantiateDialog(PictureInPicture)
207 self.session.pip.show()
208 newservice = self.csel.servicelist.getCurrent()
209 if self.session.pip.playService(newservice):
210 self.session.pipshown = True
211 self.session.pip.servicePath = self.csel.getCurrentServicePath()
214 self.session.pipshown = False
216 self.session.openWithCallback(self.close, MessageBox, _("Could not open Picture in Picture"), MessageBox.TYPE_ERROR)
218 def addServiceToBouquetSelected(self):
219 bouquets = self.csel.getBouquetList()
224 if cnt > 1: # show bouquet list
225 self.bsel = self.session.openWithCallback(self.bouquetSelClosed, BouquetSelector, bouquets, self.addCurrentServiceToBouquet)
226 elif cnt == 1: # add to only one existing bouquet
227 self.addCurrentServiceToBouquet(bouquets[0][1])
229 def bouquetSelClosed(self, recursive):
234 def removeSatelliteServices(self):
235 curpath = self.csel.getCurrentSelection().getPath()
236 idx = curpath.find("satellitePosition == ")
238 tmp = curpath[idx+21:]
241 satpos = int(tmp[:idx])
242 eDVBDB.getInstance().removeServices(-1, -1, -1, satpos)
245 def copyCurrentToBouquetList(self):
246 self.csel.copyCurrentToBouquetList()
249 def removeBouquet(self):
250 self.csel.removeBouquet()
253 def showMarkerInputBox(self):
254 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)
256 def markerInputCallback(self, marker):
257 if marker is not None:
258 self.csel.addMarker(marker)
261 def addCurrentServiceToBouquet(self, dest):
262 self.csel.addServiceToBouquet(dest)
263 if self.bsel is not None:
264 self.bsel.close(True)
266 self.close(True) # close bouquet selection
268 def removeCurrentService(self):
269 self.csel.removeCurrentService()
272 def toggleMoveMode(self):
273 self.csel.toggleMoveMode()
276 def bouquetMarkStart(self):
277 self.csel.startMarkedEdit(EDIT_BOUQUET)
280 def bouquetMarkEnd(self):
281 self.csel.endMarkedEdit(abort=False)
284 def bouquetMarkAbort(self):
285 self.csel.endMarkedEdit(abort=True)
288 def removeNewFoundFlag(self):
289 eDVBDB.getInstance().removeFlag(self.csel.getCurrentSelection(), FLAG_SERVICE_NEW_FOUND)
292 def removeAllNewFoundFlags(self):
293 curpath = self.csel.getCurrentSelection().getPath()
294 idx = curpath.find("satellitePosition == ")
296 tmp = curpath[idx+21:]
299 satpos = int(tmp[:idx])
300 eDVBDB.getInstance().removeFlags(FLAG_SERVICE_NEW_FOUND, -1, -1, -1, satpos)
303 def editAlternativeServices(self):
304 self.csel.startMarkedEdit(EDIT_ALTERNATIVES)
307 def showAlternativeServices(self):
308 self.csel.enterPath(self.csel.getCurrentSelection())
311 def removeAlternativeServices(self):
312 self.csel.removeAlternativeServices()
315 def addAlternativeServices(self):
316 self.csel.addAlternativeServices()
317 self.csel.startMarkedEdit(EDIT_ALTERNATIVES)
320 class SelectionEventInfo:
322 self["ServiceEvent"] = ServiceEvent()
323 self.servicelist.connectSelChanged(self.__selectionChanged)
324 self.timer = eTimer()
325 self.timer.callback.append(self.updateEventInfo)
326 self.onShown.append(self.__selectionChanged)
328 def __selectionChanged(self):
330 self.timer.start(100, True)
332 def updateEventInfo(self):
333 cur = self.getCurrentSelection()
334 self["ServiceEvent"].newService(cur)
336 class ChannelSelectionEPG:
338 self["ChannelSelectEPGActions"] = ActionMap(["ChannelSelectEPGActions"],
340 "showEPGList": self.showEPGList,
343 def showEPGList(self):
344 ref=self.getCurrentSelection()
346 self.savedService = ref
347 self.session.openWithCallback(self.SingleServiceEPGClosed, EPGSelection, ref, serviceChangeCB=self.changeServiceCB)
349 def SingleServiceEPGClosed(self, ret=False):
350 self.setCurrentSelection(self.savedService)
352 def changeServiceCB(self, direction, epg):
353 beg = self.getCurrentSelection()
359 cur = self.getCurrentSelection()
360 if cur == beg or not (cur.flags & eServiceReference.isMarker):
362 epg.setService(ServiceReference(self.getCurrentSelection()))
364 class ChannelSelectionEdit:
366 self.entry_marked = False
367 self.movemode = False
368 self.bouquet_mark_edit = OFF
369 self.mutableList = None
371 self.saved_title = None
372 self.saved_root = None
374 class ChannelSelectionEditActionMap(ActionMap):
375 def __init__(self, csel, contexts = [ ], actions = { }, prio=0):
376 ActionMap.__init__(self, contexts, actions, prio)
379 def action(self, contexts, action):
380 if action == "cancel":
381 self.csel.handleEditCancel()
382 return 0 # fall-trough
384 return 0 # fall-trough
386 return ActionMap.action(self, contexts, action)
388 self["ChannelSelectEditActions"] = ChannelSelectionEditActionMap(self, ["ChannelSelectEditActions", "OkCancelActions"],
390 "contextMenu": self.doContext,
393 def getMutableList(self, root=eServiceReference()):
394 if not self.mutableList is None:
395 return self.mutableList
396 serviceHandler = eServiceCenter.getInstance()
399 list = root and serviceHandler.list(root)
401 return list.startEdit()
404 def buildBouquetID(self, str):
408 if (c >= 'a' and c <= 'z') or (c >= '0' and c <= '9'):
414 def addMarker(self, name):
415 current = self.servicelist.getCurrent()
416 mutableList = self.getMutableList()
419 str = '1:64:%d:0:0:0:0:0:0:0::%s'%(cnt, name)
420 ref = eServiceReference(str)
421 if current and current.valid():
422 if not mutableList.addService(ref, current):
423 self.servicelist.addService(ref, True)
424 mutableList.flushChanges()
426 elif not mutableList.addService(ref):
427 self.servicelist.addService(ref, True)
428 mutableList.flushChanges()
432 def addAlternativeServices(self):
433 cur_service = ServiceReference(self.getCurrentSelection())
434 root = self.getRoot()
435 cur_root = root and ServiceReference(root)
436 mutableBouquet = cur_root.list().startEdit()
438 name = cur_service.getServiceName()
440 if self.mode == MODE_TV:
441 str = '1:134:1:0:0:0:0:0:0:0:FROM BOUQUET \"alternatives.%s.tv\" ORDER BY bouquet'%(self.buildBouquetID(name))
443 str = '1:134:2:0:0:0:0:0:0:0:FROM BOUQUET \"alternatives.%s.radio\" ORDER BY bouquet'%(self.buildBouquetID(name))
444 new_ref = ServiceReference(str)
445 if not mutableBouquet.addService(new_ref.ref, cur_service.ref):
446 mutableBouquet.removeService(cur_service.ref)
447 mutableBouquet.flushChanges()
448 eDVBDB.getInstance().reloadBouquets()
449 mutableAlternatives = new_ref.list().startEdit()
450 if mutableAlternatives:
451 mutableAlternatives.setListName(name)
452 if mutableAlternatives.addService(cur_service.ref):
453 print "add", cur_service.toString(), "to new alternatives failed"
454 mutableAlternatives.flushChanges()
455 self.servicelist.addService(new_ref.ref, True)
456 self.servicelist.removeCurrent()
457 self.servicelist.moveUp()
459 print "get mutable list for new created alternatives failed"
461 print "add", str, "to", cur_root.getServiceName(), "failed"
463 print "bouquetlist is not editable"
465 def addBouquet(self, bName, services):
466 serviceHandler = eServiceCenter.getInstance()
467 mutableBouquetList = serviceHandler.list(self.bouquet_root).startEdit()
468 if mutableBouquetList:
469 if self.mode == MODE_TV:
471 str = '1:7:1:0:0:0:0:0:0:0:FROM BOUQUET \"userbouquet.%s.tv\" ORDER BY bouquet'%(self.buildBouquetID(bName))
474 str = '1:7:2:0:0:0:0:0:0:0:FROM BOUQUET \"userbouquet.%s.radio\" ORDER BY bouquet'%(self.buildBouquetID(bName))
475 new_bouquet_ref = eServiceReference(str)
476 if not mutableBouquetList.addService(new_bouquet_ref):
477 mutableBouquetList.flushChanges()
478 eDVBDB.getInstance().reloadBouquets()
479 mutableBouquet = serviceHandler.list(new_bouquet_ref).startEdit()
481 mutableBouquet.setListName(bName)
482 if services is not None:
483 for service in services:
484 if mutableBouquet.addService(service):
485 print "add", service.toString(), "to new bouquet failed"
486 mutableBouquet.flushChanges()
488 print "get mutable list for new created bouquet failed"
489 # do some voodoo to check if current_root is equal to bouquet_root
490 cur_root = self.getRoot();
491 str1 = cur_root and cur_root.toString()
492 pos1 = str1 and str1.find("FROM BOUQUET") or -1
493 pos2 = self.bouquet_rootstr.find("FROM BOUQUET")
494 if pos1 != -1 and pos2 != -1 and str1[pos1:] == self.bouquet_rootstr[pos2:]:
495 self.servicelist.addService(new_bouquet_ref)
497 print "add", str, "to bouquets failed"
499 print "bouquetlist is not editable"
501 def copyCurrentToBouquetList(self):
502 provider = ServiceReference(self.getCurrentSelection())
503 providerName = provider.getServiceName()
504 serviceHandler = eServiceCenter.getInstance()
505 services = serviceHandler.list(provider.ref)
506 self.addBouquet(providerName, services and services.getContent('R', True))
508 def removeAlternativeServices(self):
509 cur_service = ServiceReference(self.getCurrentSelection())
510 root = self.getRoot()
511 cur_root = root and ServiceReference(root)
512 list = cur_service.list()
513 first_in_alternative = list and list.getNext()
514 if first_in_alternative:
515 edit_root = cur_root and cur_root.list().startEdit()
517 if not edit_root.addService(first_in_alternative, cur_service.ref):
518 self.servicelist.addService(first_in_alternative, True)
520 print "couldn't add first alternative service to current root"
522 print "couldn't edit current root!!"
524 print "remove empty alternative list !!"
526 self.servicelist.moveUp()
528 def removeBouquet(self):
529 refstr = self.getCurrentSelection().toString()
530 print "removeBouquet", refstr
531 self.bouquetNumOffsetCache = { }
532 pos = refstr.find('FROM BOUQUET "')
535 refstr = refstr[pos+14:]
536 pos = refstr.find('"')
538 filename = '/etc/enigma2/' + refstr[:pos] # FIXMEEE !!! HARDCODED /etc/enigma2
539 self.removeCurrentService()
541 if filename is not None:
544 print "error during remove of", filename
546 # multiple marked entry stuff ( edit mode, later multiepg selection )
547 def startMarkedEdit(self, type):
548 self.savedPath = self.servicePath[:]
549 if type == EDIT_ALTERNATIVES:
550 self.enterPath(self.getCurrentSelection())
551 self.mutableList = self.getMutableList()
552 # add all services from the current list to internal marked set in listboxservicecontent
553 self.clearMarks() # this clears the internal marked set in the listboxservicecontent
554 self.saved_title = self.getTitle()
555 pos = self.saved_title.find(')')
556 new_title = self.saved_title[:pos+1]
557 if type == EDIT_ALTERNATIVES:
558 self.bouquet_mark_edit = EDIT_ALTERNATIVES
559 new_title += ' ' + _("[alternative edit]")
561 self.bouquet_mark_edit = EDIT_BOUQUET
562 if config.usage.multibouquet.value:
563 new_title += ' ' + _("[bouquet edit]")
565 new_title += ' ' + _("[favourite edit]")
566 self.setTitle(new_title)
567 self.__marked = self.servicelist.getRootServices()
568 for x in self.__marked:
569 self.servicelist.addMarked(eServiceReference(x))
570 self.showAllServices()
572 def endMarkedEdit(self, abort):
573 if not abort and self.mutableList is not None:
574 self.bouquetNumOffsetCache = { }
575 new_marked = set(self.servicelist.getMarked())
576 old_marked = set(self.__marked)
577 removed = old_marked - new_marked
578 added = new_marked - old_marked
582 self.mutableList.removeService(eServiceReference(x))
585 self.mutableList.addService(eServiceReference(x))
587 self.mutableList.flushChanges()
590 self.bouquet_mark_edit = OFF
591 self.mutableList = None
592 self.setTitle(self.saved_title)
593 self.saved_title = None
594 # self.servicePath is just a reference to servicePathTv or Radio...
595 # so we never ever do use the asignment operator in self.servicePath
596 del self.servicePath[:] # remove all elements
597 self.servicePath += self.savedPath # add saved elements
599 self.setRoot(self.servicePath[-1])
601 def clearMarks(self):
602 self.servicelist.clearMarks()
605 ref = self.servicelist.getCurrent()
606 if self.servicelist.isMarked(ref):
607 self.servicelist.removeMarked(ref)
609 self.servicelist.addMarked(ref)
611 def removeCurrentService(self):
612 ref = self.servicelist.getCurrent()
613 mutableList = self.getMutableList()
614 if ref.valid() and mutableList is not None:
615 if not mutableList.removeService(ref):
616 self.bouquetNumOffsetCache = { }
617 mutableList.flushChanges() #FIXME dont flush on each single removed service
618 self.servicelist.removeCurrent()
620 def addServiceToBouquet(self, dest, service=None):
621 mutableList = self.getMutableList(dest)
622 if not mutableList is None:
623 if service is None: #use current selected service
624 service = self.servicelist.getCurrent()
625 if not mutableList.addService(service):
626 self.bouquetNumOffsetCache = { }
627 mutableList.flushChanges()
628 # do some voodoo to check if current_root is equal to dest
629 cur_root = self.getRoot();
630 str1 = cur_root and cur_root.toString() or -1
631 str2 = dest.toString()
632 pos1 = str1.find("FROM BOUQUET")
633 pos2 = str2.find("FROM BOUQUET")
634 if pos1 != -1 and pos2 != -1 and str1[pos1:] == str2[pos2:]:
635 self.servicelist.addService(service)
637 def toggleMoveMode(self):
639 if self.entry_marked:
640 self.toggleMoveMarked() # unmark current entry
641 self.movemode = False
642 self.pathChangeDisabled = False # re-enable path change
643 self.mutableList.flushChanges() # FIXME add check if changes was made
644 self.mutableList = None
645 self.setTitle(self.saved_title)
646 self.saved_title = None
647 cur_root = self.getRoot()
648 if cur_root and cur_root == self.bouquet_root:
649 self.bouquetNumOffsetCache = { }
651 self.mutableList = self.getMutableList()
653 self.pathChangeDisabled = True # no path change allowed in movemode
654 self.saved_title = self.getTitle()
655 new_title = self.saved_title
656 pos = self.saved_title.find(')')
657 new_title = self.saved_title[:pos+1] + ' ' + _("[move mode]") + self.saved_title[pos+1:]
658 self.setTitle(new_title);
660 def handleEditCancel(self):
661 if self.movemode: #movemode active?
662 self.channelSelected() # unmark
663 self.toggleMoveMode() # disable move mode
664 elif self.bouquet_mark_edit != OFF:
665 self.endMarkedEdit(True) # abort edit mode
667 def toggleMoveMarked(self):
668 if self.entry_marked:
669 self.servicelist.setCurrentMarked(False)
670 self.entry_marked = False
672 self.servicelist.setCurrentMarked(True)
673 self.entry_marked = True
676 self.session.openWithCallback(self.exitContext, ChannelContextMenu, self)
678 def exitContext(self, close = False):
685 # type 1 = digital television service
686 # type 4 = nvod reference service (NYI)
687 # type 17 = MPEG-2 HD digital television service
688 # type 22 = advanced codec SD digital television
689 # type 24 = advanced codec SD NVOD reference service (NYI)
690 # type 25 = advanced codec HD digital television
691 # type 27 = advanced codec HD NVOD reference service (NYI)
692 # type 2 = digital radio sound service
693 # type 10 = advanced codec digital radio sound service
695 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)'
696 service_types_radio = '1:7:2:0:0:0:0:0:0:0:(type == 2) || (type == 10)'
698 class ChannelSelectionBase(Screen):
699 def __init__(self, session):
700 Screen.__init__(self, session)
702 self["key_red"] = Button(_("All"))
703 self["key_green"] = Button(_("Satellites"))
704 self["key_yellow"] = Button(_("Provider"))
705 self["key_blue"] = Button(_("Favourites"))
707 self["list"] = ServiceList()
708 self.servicelist = self["list"]
710 self.numericalTextInput = NumericalTextInput()
711 self.numericalTextInput.setUseableChars(u'1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ')
713 self.servicePathTV = [ ]
714 self.servicePathRadio = [ ]
715 self.servicePath = [ ]
719 self.pathChangeDisabled = False
721 self.bouquetNumOffsetCache = { }
723 self["ChannelSelectBaseActions"] = NumberActionMap(["ChannelSelectBaseActions", "NumberActions", "InputAsciiActions"],
725 "showFavourites": self.showFavourites,
726 "showAllServices": self.showAllServices,
727 "showProviders": self.showProviders,
728 "showSatellites": self.showSatellites,
729 "nextBouquet": self.nextBouquet,
730 "prevBouquet": self.prevBouquet,
731 "nextMarker": self.nextMarker,
732 "prevMarker": self.prevMarker,
733 "gotAsciiCode": self.keyAsciiCode,
734 "1": self.keyNumberGlobal,
735 "2": self.keyNumberGlobal,
736 "3": self.keyNumberGlobal,
737 "4": self.keyNumberGlobal,
738 "5": self.keyNumberGlobal,
739 "6": self.keyNumberGlobal,
740 "7": self.keyNumberGlobal,
741 "8": self.keyNumberGlobal,
742 "9": self.keyNumberGlobal,
745 self.recallBouquetMode()
747 def getBouquetNumOffset(self, bouquet):
748 if not config.usage.multibouquet.value:
750 str = bouquet.toString()
752 if not self.bouquetNumOffsetCache.has_key(str):
753 serviceHandler = eServiceCenter.getInstance()
754 bouquetlist = serviceHandler.list(self.bouquet_root)
755 if not bouquetlist is None:
757 bouquetIterator = bouquetlist.getNext()
758 if not bouquetIterator.valid(): #end of list
760 self.bouquetNumOffsetCache[bouquetIterator.toString()]=offsetCount
761 if not (bouquetIterator.flags & eServiceReference.isDirectory):
763 servicelist = serviceHandler.list(bouquetIterator)
764 if not servicelist is None:
766 serviceIterator = servicelist.getNext()
767 if not serviceIterator.valid(): #check if end of list
769 playable = not (serviceIterator.flags & (eServiceReference.isDirectory|eServiceReference.isMarker))
772 return self.bouquetNumOffsetCache.get(str, offsetCount)
774 def recallBouquetMode(self):
775 if self.mode == MODE_TV:
776 self.service_types = service_types_tv
777 if config.usage.multibouquet.value:
778 self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "bouquets.tv" ORDER BY bouquet'
780 self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.tv" ORDER BY bouquet'%(self.service_types)
782 self.service_types = service_types_radio
783 if config.usage.multibouquet.value:
784 self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "bouquets.radio" ORDER BY bouquet'
786 self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.radio" ORDER BY bouquet'%(self.service_types)
787 self.bouquet_root = eServiceReference(self.bouquet_rootstr)
791 self.servicePath = self.servicePathTV
792 self.recallBouquetMode()
793 title = self.getTitle()
794 pos = title.find(" (")
800 def setRadioMode(self):
801 self.mode = MODE_RADIO
802 self.servicePath = self.servicePathRadio
803 self.recallBouquetMode()
804 title = self.getTitle()
805 pos = title.find(" (")
811 def setRoot(self, root, justSet=False):
812 path = root.getPath()
813 inBouquetRootList = path.find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
814 pos = path.find('FROM BOUQUET')
815 isBouquet = (pos != -1) and (root.flags & eServiceReference.isDirectory)
816 if not inBouquetRootList and isBouquet:
817 self.servicelist.setMode(ServiceList.MODE_FAVOURITES)
818 self.servicelist.setNumberOffset(self.getBouquetNumOffset(root))
820 self.servicelist.setMode(ServiceList.MODE_NORMAL)
821 self.servicelist.setRoot(root, justSet)
822 self.buildTitleString()
824 def removeModeStr(self, str):
825 if self.mode == MODE_TV:
826 pos = str.find(' (TV)')
828 pos = str.find(' (Radio)')
833 def getServiceName(self, ref):
834 str = self.removeModeStr(ServiceReference(ref).getServiceName())
836 pathstr = ref.getPath()
837 if 'FROM PROVIDERS' in pathstr:
839 if 'FROM SATELLITES' in pathstr:
840 return _("Satellites")
841 if ') ORDER BY name' in pathstr:
845 def buildTitleString(self):
846 titleStr = self.getTitle()
847 pos = titleStr.find(']')
849 pos = titleStr.find(')')
851 titleStr = titleStr[:pos+1]
852 Len = len(self.servicePath)
854 base_ref = self.servicePath[0]
856 end_ref = self.servicePath[Len-1]
859 nameStr = self.getServiceName(base_ref)
860 titleStr += ' ' + nameStr
861 if end_ref is not None:
866 nameStr = self.getServiceName(end_ref)
868 self.setTitle(titleStr)
871 self.servicelist.moveUp()
874 self.servicelist.moveDown()
877 del self.servicePath[:]
879 def enterPath(self, ref, justSet=False):
880 self.servicePath.append(ref)
881 self.setRoot(ref, justSet)
883 def pathUp(self, justSet=False):
884 prev = self.servicePath.pop()
886 current = self.servicePath[-1]
887 self.setRoot(current, justSet)
889 self.setCurrentSelection(prev)
892 def isBasePathEqual(self, ref):
893 if len(self.servicePath) > 1 and self.servicePath[0] == ref:
897 def isPrevPathEqual(self, ref):
898 length = len(self.servicePath)
899 if length > 1 and self.servicePath[length-2] == ref:
903 def preEnterPath(self, refstr):
906 def showAllServices(self):
907 if not self.pathChangeDisabled:
908 refstr = '%s ORDER BY name'%(self.service_types)
909 if not self.preEnterPath(refstr):
910 ref = eServiceReference(refstr)
911 currentRoot = self.getRoot()
912 if currentRoot is None or currentRoot != ref:
916 def showSatellites(self):
917 if not self.pathChangeDisabled:
918 refstr = '%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types)
919 if not self.preEnterPath(refstr):
920 ref = eServiceReference(refstr)
924 if self.isBasePathEqual(ref):
925 if self.isPrevPathEqual(ref):
927 prev = self.pathUp(justSet)
929 currentRoot = self.getRoot()
930 if currentRoot is None or currentRoot != ref:
933 self.enterPath(ref, True)
935 serviceHandler = eServiceCenter.getInstance()
936 servicelist = serviceHandler.list(ref)
937 if not servicelist is None:
939 service = servicelist.getNext()
940 if not service.valid(): #check if end of list
942 unsigned_orbpos = service.getUnsignedData(4) >> 16
943 orbpos = service.getData(4) >> 16
946 if service.getPath().find("FROM PROVIDER") != -1:
947 service_type = _("Providers")
948 elif service.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
949 service_type = _("New")
951 service_type = _("Services")
953 # why we need this cast?
954 service_name = str(nimmanager.getSatDescription(orbpos))
956 if unsigned_orbpos == 0xFFFF: #Cable
957 service_name = _("Cable")
958 elif unsigned_orbpos == 0xEEEE: #Terrestrial
959 service_name = _("Terrestrial")
961 if orbpos > 1800: # west
962 orbpos = 3600 - orbpos
966 service_name = ("%d.%d" + h) % (orbpos / 10, orbpos % 10)
967 service.setName("%s - %s" % (service_name, service_type))
968 self.servicelist.addService(service)
969 cur_ref = self.session.nav.getCurrentlyPlayingServiceReference()
971 pos = self.service_types.rfind(':')
972 refstr = '%s (channelID == %08x%04x%04x) && %s ORDER BY name' %(self.service_types[:pos+1],
973 cur_ref.getUnsignedData(4), # NAMESPACE
974 cur_ref.getUnsignedData(2), # TSID
975 cur_ref.getUnsignedData(3), # ONID
976 self.service_types[pos+1:])
977 ref = eServiceReference(refstr)
978 ref.setName(_("Current Transponder"))
979 self.servicelist.addService(ref)
980 self.servicelist.finishFill()
982 self.setCurrentSelection(prev)
984 def showProviders(self):
985 if not self.pathChangeDisabled:
986 refstr = '%s FROM PROVIDERS ORDER BY name'%(self.service_types)
987 if not self.preEnterPath(refstr):
988 ref = eServiceReference(refstr)
989 if self.isBasePathEqual(ref):
992 currentRoot = self.getRoot()
993 if currentRoot is None or currentRoot != ref:
997 def changeBouquet(self, direction):
998 if not self.pathChangeDisabled:
999 if len(self.servicePath) > 1:
1000 #when enter satellite root list we must do some magic stuff..
1001 ref = eServiceReference('%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types))
1002 if self.isBasePathEqual(ref):
1003 self.showSatellites()
1010 ref = self.getCurrentSelection()
1013 def inBouquet(self):
1014 if self.servicePath and self.servicePath[0] == self.bouquet_root:
1019 return self.servicelist.atBegin()
1022 return self.servicelist.atEnd()
1024 def nextBouquet(self):
1025 self.changeBouquet(+1)
1027 def prevBouquet(self):
1028 self.changeBouquet(-1)
1030 def showFavourites(self):
1031 if not self.pathChangeDisabled:
1032 if not self.preEnterPath(self.bouquet_rootstr):
1033 if self.isBasePathEqual(self.bouquet_root):
1036 currentRoot = self.getRoot()
1037 if currentRoot is None or currentRoot != self.bouquet_root:
1039 self.enterPath(self.bouquet_root)
1041 def keyNumberGlobal(self, number):
1042 unichar = self.numericalTextInput.getKey(number)
1043 charstr = unichar.encode("utf-8")
1044 if len(charstr) == 1:
1045 self.servicelist.moveToChar(charstr[0])
1047 def keyAsciiCode(self):
1048 unichar = unichr(getPrevAsciiCode())
1049 charstr = unichar.encode("utf-8")
1050 if len(charstr) == 1:
1051 self.servicelist.moveToChar(charstr[0])
1054 return self.servicelist.getRoot()
1056 def getCurrentSelection(self):
1057 return self.servicelist.getCurrent()
1059 def setCurrentSelection(self, service):
1060 self.servicelist.setCurrent(service)
1062 def getBouquetList(self):
1064 serviceHandler = eServiceCenter.getInstance()
1065 if config.usage.multibouquet.value:
1066 list = serviceHandler.list(self.bouquet_root)
1072 if s.flags & eServiceReference.isDirectory:
1073 info = serviceHandler.info(s)
1075 bouquets.append((info.getName(s), s))
1078 info = serviceHandler.info(self.bouquet_root)
1080 bouquets.append((info.getName(self.bouquet_root), self.bouquet_root))
1084 def keyNumber0(self, num):
1085 if len(self.servicePath) > 1:
1088 self.keyNumberGlobal(num)
1091 if len(self.servicePath) > 1:
1092 if self.isBasePathEqual(self.bouquet_root):
1093 self.showFavourites()
1095 ref = eServiceReference('%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types))
1096 if self.isBasePathEqual(ref):
1097 self.showSatellites()
1099 ref = eServiceReference('%s FROM PROVIDERS ORDER BY name'%(self.service_types))
1100 if self.isBasePathEqual(ref):
1101 self.showProviders()
1103 self.showAllServices()
1105 def nextMarker(self):
1106 self.servicelist.moveToNextMarker()
1108 def prevMarker(self):
1109 self.servicelist.moveToPrevMarker()
1113 #config for lastservice
1114 config.tv = ConfigSubsection()
1115 config.tv.lastservice = ConfigText()
1116 config.tv.lastroot = ConfigText()
1117 config.radio = ConfigSubsection()
1118 config.radio.lastservice = ConfigText()
1119 config.radio.lastroot = ConfigText()
1120 config.servicelist = ConfigSubsection()
1121 config.servicelist.lastmode = ConfigText(default = "tv")
1123 class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG, SelectionEventInfo):
1124 def __init__(self, session):
1125 ChannelSelectionBase.__init__(self,session)
1126 ChannelSelectionEdit.__init__(self)
1127 ChannelSelectionEPG.__init__(self)
1128 SelectionEventInfo.__init__(self)
1130 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1132 "cancel": self.cancel,
1133 "ok": self.channelSelected,
1134 "keyRadio": self.setModeRadio,
1135 "keyTV": self.setModeTv,
1138 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
1140 iPlayableService.evStart: self.__evServiceStart,
1141 iPlayableService.evEnd: self.__evServiceEnd
1144 self.lastChannelRootTimer = eTimer()
1145 self.lastChannelRootTimer.callback.append(self.__onCreate)
1146 self.lastChannelRootTimer.start(100,True)
1148 self.history_tv = [ ]
1149 self.history_radio = [ ]
1150 self.history = self.history_tv
1151 self.history_pos = 0
1153 self.lastservice = config.tv.lastservice
1154 self.lastroot = config.tv.lastroot
1155 self.revertMode = None
1156 config.usage.multibouquet.addNotifier(self.multibouquet_config_changed)
1157 self.new_service_played = False
1158 self.onExecBegin.append(self.asciiOn)
1161 rcinput = eRCInput.getInstance()
1162 rcinput.setKeyboardMode(rcinput.kmAscii)
1165 rcinput = eRCInput.getInstance()
1166 rcinput.setKeyboardMode(rcinput.kmNone)
1168 def multibouquet_config_changed(self, val):
1169 self.recallBouquetMode()
1171 def __evServiceStart(self):
1172 service = self.session.nav.getCurrentService()
1174 info = service.info()
1176 refstr = info.getInfoString(iServiceInformation.sServiceref)
1177 self.servicelist.setPlayableIgnoreService(eServiceReference(refstr))
1179 def __evServiceEnd(self):
1180 self.servicelist.setPlayableIgnoreService(eServiceReference())
1184 lastservice=eServiceReference(self.lastservice.value)
1185 if lastservice.valid():
1186 self.setCurrentSelection(lastservice)
1188 def setModeTv(self):
1189 if self.revertMode is None and config.servicelist.lastmode.value == "radio":
1190 self.revertMode = MODE_RADIO
1191 self.history = self.history_tv
1192 self.lastservice = config.tv.lastservice
1193 self.lastroot = config.tv.lastroot
1194 config.servicelist.lastmode.value = "tv"
1198 def setModeRadio(self):
1199 if self.revertMode is None and config.servicelist.lastmode.value == "tv":
1200 self.revertMode = MODE_TV
1201 if config.usage.e1like_radio_mode.value:
1202 self.history = self.history_radio
1203 self.lastservice = config.radio.lastservice
1204 self.lastroot = config.radio.lastroot
1205 config.servicelist.lastmode.value = "radio"
1209 def __onCreate(self):
1210 if config.usage.e1like_radio_mode.value:
1211 if config.servicelist.lastmode.value == "tv":
1217 lastservice=eServiceReference(self.lastservice.value)
1218 if lastservice.valid():
1221 def channelSelected(self):
1222 ref = self.getCurrentSelection()
1224 self.toggleMoveMarked()
1225 elif (ref.flags & 7) == 7:
1227 elif self.bouquet_mark_edit != OFF:
1228 if not (self.bouquet_mark_edit == EDIT_ALTERNATIVES and ref.flags & eServiceReference.isGroup):
1230 elif not (ref.flags & eServiceReference.isMarker): # no marker
1231 root = self.getRoot()
1232 if not root or not (root.flags & eServiceReference.isGroup):
1237 #called from infoBar and channelSelected
1239 self.revertMode=None
1240 ref = self.session.nav.getCurrentlyPlayingServiceReference()
1241 nref = self.getCurrentSelection()
1242 if ref is None or ref != nref:
1243 self.new_service_played = True
1244 self.session.nav.playService(nref)
1246 self.saveChannel(nref)
1247 config.servicelist.lastmode.save()
1248 self.addToHistory(nref)
1250 def newServicePlayed(self):
1251 ret = self.new_service_played
1252 self.new_service_played = False
1255 def addToHistory(self, ref):
1256 if self.servicePath is not None:
1257 tmp=self.servicePath[:]
1260 del self.history[self.history_pos+1:]
1263 self.history.append(tmp)
1264 hlen = len(self.history)
1265 if hlen > HISTORYSIZE:
1268 self.history_pos = hlen-1
1270 def historyBack(self):
1271 hlen = len(self.history)
1272 if hlen > 1 and self.history_pos > 0:
1273 self.history_pos -= 1
1274 self.setHistoryPath()
1276 def historyNext(self):
1277 hlen = len(self.history)
1278 if hlen > 1 and self.history_pos < (hlen-1):
1279 self.history_pos += 1
1280 self.setHistoryPath()
1282 def setHistoryPath(self):
1283 path = self.history[self.history_pos][:]
1285 del self.servicePath[:]
1286 self.servicePath += path
1289 cur_root = self.getRoot()
1290 if cur_root and cur_root != root:
1292 self.session.nav.playService(ref)
1293 self.setCurrentSelection(ref)
1294 self.saveChannel(ref)
1298 for i in self.servicePath:
1299 path += i.toString()
1301 if path and path != self.lastroot.value:
1302 self.lastroot.value = path
1303 self.lastroot.save()
1305 def restoreRoot(self):
1307 re = compile('.+?;')
1308 tmp = re.findall(self.lastroot.value)
1311 self.servicePath.append(eServiceReference(i[:-1]))
1314 path = self.servicePath.pop()
1315 self.enterPath(path)
1317 self.showFavourites()
1320 def preEnterPath(self, refstr):
1321 if self.servicePath and self.servicePath[0] != eServiceReference(refstr):
1322 pathstr = self.lastroot.value
1323 if pathstr is not None and pathstr.find(refstr) == 0:
1325 lastservice=eServiceReference(self.lastservice.value)
1326 if lastservice.valid():
1327 self.setCurrentSelection(lastservice)
1331 def saveChannel(self, ref):
1333 refstr = ref.toString()
1336 if refstr != self.lastservice.value:
1337 self.lastservice.value = refstr
1338 self.lastservice.save()
1340 def setCurrentServicePath(self, path):
1342 self.history[self.history_pos] = path
1344 self.history.append(path)
1345 self.setHistoryPath()
1347 def getCurrentServicePath(self):
1349 return self.history[self.history_pos]
1352 def recallPrevService(self):
1353 hlen = len(self.history)
1355 if self.history_pos == hlen-1:
1356 tmp = self.history[self.history_pos]
1357 self.history[self.history_pos] = self.history[self.history_pos-1]
1358 self.history[self.history_pos-1] = tmp
1360 tmp = self.history[self.history_pos+1]
1361 self.history[self.history_pos+1] = self.history[self.history_pos]
1362 self.history[self.history_pos] = tmp
1363 self.setHistoryPath()
1366 if self.revertMode is None:
1368 lastservice=eServiceReference(self.lastservice.value)
1369 if lastservice.valid() and self.getCurrentSelection() != lastservice:
1370 self.setCurrentSelection(lastservice)
1371 elif self.revertMode == MODE_TV:
1373 elif self.revertMode == MODE_RADIO:
1375 self.revertMode = None
1379 class RadioInfoBar(Screen):
1380 def __init__(self, session):
1381 Screen.__init__(self, session)
1382 self["RdsDecoder"] = RdsDecoder(self.session.nav)
1384 class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG, InfoBarBase):
1385 ALLOW_SUSPEND = True
1387 def __init__(self, session, infobar):
1388 ChannelSelectionBase.__init__(self, session)
1389 ChannelSelectionEdit.__init__(self)
1390 ChannelSelectionEPG.__init__(self)
1391 InfoBarBase.__init__(self)
1392 self.infobar = infobar
1393 self.onLayoutFinish.append(self.onCreate)
1395 self.info = session.instantiateDialog(RadioInfoBar) # our simple infobar
1397 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1399 "keyTV": self.closeRadio,
1400 "keyRadio": self.closeRadio,
1401 "cancel": self.closeRadio,
1402 "ok": self.channelSelected,
1405 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
1407 iPlayableService.evStart: self.__evServiceStart,
1408 iPlayableService.evEnd: self.__evServiceEnd
1411 ########## RDS Radiotext / Rass Support BEGIN
1412 self.infobar = infobar # reference to real infobar (the one and only)
1413 self["RdsDecoder"] = self.info["RdsDecoder"]
1414 self["RdsActions"] = HelpableActionMap(self, "InfobarRdsActions",
1416 "startRassInteractive": (self.startRassInteractive, _("View Rass interactive..."))
1418 self["RdsActions"].setEnabled(False)
1419 infobar.rds_display.onRassInteractivePossibilityChanged.append(self.RassInteractivePossibilityChanged)
1420 self.onClose.append(self.__onClose)
1422 def __onClose(self):
1423 lastservice=eServiceReference(config.tv.lastservice.value)
1424 self.session.nav.playService(lastservice)
1426 def startRassInteractive(self):
1428 self.infobar.rass_interactive = self.session.openWithCallback(self.RassInteractiveClosed, RassInteractive)
1430 def RassInteractiveClosed(self):
1432 self.infobar.rass_interactive = None
1433 self.infobar.RassSlidePicChanged()
1435 def RassInteractivePossibilityChanged(self, state):
1436 self["RdsActions"].setEnabled(state)
1437 ########## RDS Radiotext / Rass Support END
1439 def closeRadio(self):
1440 self.infobar.rds_display.onRassInteractivePossibilityChanged.remove(self.RassInteractivePossibilityChanged)
1442 #set previous tv service
1445 def __evServiceStart(self):
1446 service = self.session.nav.getCurrentService()
1448 info = service.info()
1450 refstr = info.getInfoString(iServiceInformation.sServiceref)
1451 self.servicelist.setPlayableIgnoreService(eServiceReference(refstr))
1453 def __evServiceEnd(self):
1454 self.servicelist.setPlayableIgnoreService(eServiceReference())
1458 for i in self.servicePathRadio:
1459 path += i.toString()
1461 if path and path != config.radio.lastroot.value:
1462 config.radio.lastroot.value = path
1463 config.radio.lastroot.save()
1465 def restoreRoot(self):
1467 re = compile('.+?;')
1468 tmp = re.findall(config.radio.lastroot.value)
1471 self.servicePathRadio.append(eServiceReference(i[:-1]))
1474 path = self.servicePathRadio.pop()
1475 self.enterPath(path)
1477 self.showFavourites()
1480 def preEnterPath(self, refstr):
1481 if self.servicePathRadio and self.servicePathRadio[0] != eServiceReference(refstr):
1482 pathstr = config.radio.lastroot.value
1483 if pathstr is not None and pathstr.find(refstr) == 0:
1485 lastservice=eServiceReference(config.radio.lastservice.value)
1486 if lastservice.valid():
1487 self.setCurrentSelection(lastservice)
1494 lastservice=eServiceReference(config.radio.lastservice.value)
1495 if lastservice.valid():
1496 self.servicelist.setCurrent(lastservice)
1497 self.session.nav.playService(lastservice)
1499 self.session.nav.stopService()
1502 def channelSelected(self): # just return selected service
1503 ref = self.getCurrentSelection()
1505 self.toggleMoveMarked()
1506 elif (ref.flags & 7) == 7:
1508 elif self.bouquet_mark_edit != OFF:
1509 if not (self.bouquet_mark_edit == EDIT_ALTERNATIVES and ref.flags & eServiceReference.isGroup):
1511 elif not (ref.flags & eServiceReference.isMarker): # no marker
1512 cur_root = self.getRoot()
1513 if not cur_root or not (cur_root.flags & eServiceReference.isGroup):
1514 playingref = self.session.nav.getCurrentlyPlayingServiceReference()
1515 if playingref is None or playingref != ref:
1516 self.session.nav.playService(ref)
1517 config.radio.lastservice.value = ref.toString()
1518 config.radio.lastservice.save()
1521 class SimpleChannelSelection(ChannelSelectionBase):
1522 def __init__(self, session, title):
1523 ChannelSelectionBase.__init__(self, session)
1524 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1526 "cancel": self.close,
1527 "ok": self.channelSelected,
1528 "keyRadio": self.setModeRadio,
1529 "keyTV": self.setModeTv,
1532 self.onLayoutFinish.append(self.layoutFinished)
1534 def layoutFinished(self):
1537 def channelSelected(self): # just return selected service
1538 ref = self.getCurrentSelection()
1539 if (ref.flags & 7) == 7:
1541 elif not (ref.flags & eServiceReference.isMarker):
1542 ref = self.getCurrentSelection()
1545 def setModeTv(self):
1547 self.showFavourites()
1549 def setModeRadio(self):
1551 self.showFavourites()