1 from Screen import Screen
2 from Components.Button import Button
3 from Components.ServiceList import ServiceList
4 from Components.ActionMap import NumberActionMap, ActionMap
5 from Components.MenuList import MenuList
6 from EpgSelection import EPGSelection
7 from enigma import eServiceReference, eEPGCache, eServiceCenter, eServiceCenterPtr, iMutableServiceListPtr, iStaticServiceInformationPtr, eTimer, eDVBDB
8 from Components.config import config, ConfigSubsection, ConfigText
9 from Screens.FixedMenu import FixedMenu
10 from Tools.NumericalTextInput import NumericalTextInput
11 from Components.NimManager import nimmanager
12 from Components.Sources.Clock import Clock
13 from Components.Input import Input
14 from Components.ParentalControl import parentalControl
15 from Screens.InputBox import InputBox, PinInput
16 from Screens.MessageBox import MessageBox
17 from ServiceReference import ServiceReference
18 from Tools.BoundFunction import boundFunction
22 FLAG_SERVICE_NEW_FOUND = 64 #define in lib/dvb/idvb.h as dxNewFound = 64
24 import xml.dom.minidom
26 class BouquetSelector(Screen):
27 def __init__(self, session, bouquets, selectedFunc, enableWrapAround=False):
28 Screen.__init__(self, session)
30 self.selectedFunc=selectedFunc
32 self["actions"] = ActionMap(["OkCancelActions"],
34 "ok": self.okbuttonClick,
35 "cancel": self.cancelClick
39 entrys.append((x[0], x[1]))
40 self["menu"] = MenuList(entrys, enableWrapAround)
43 cur = self["menu"].getCurrent()
46 def okbuttonClick(self):
47 self.selectedFunc(self.getCurrent())
55 def cancelClick(self):
58 class ChannelContextMenu(Screen):
59 def __init__(self, session, csel):
60 Screen.__init__(self, session)
64 self["actions"] = ActionMap(["OkCancelActions"],
66 "ok": self.okbuttonClick,
67 "cancel": self.cancelClick
71 current_root = csel.getRoot()
72 current_sel_path = csel.getCurrentSelection().getPath()
73 current_sel_flags = csel.getCurrentSelection().flags
74 inBouquetRootList = current_root and current_root.getPath().find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
75 inBouquet = csel.getMutableList() is not None
76 haveBouquets = config.usage.multibouquet.value
78 if not csel.bouquet_mark_edit and not csel.movemode:
79 if not inBouquetRootList:
80 if (csel.getCurrentSelection().flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory:
81 if config.ParentalControl.configured.value:
82 if parentalControl.getProtectionLevel(csel.getCurrentSelection().toCompareString()) == -1:
83 menu.append((_("add to parental protection"), boundFunction(self.addParentalProtection, csel.getCurrentSelection())))
85 menu.append((_("remove from parental protection"), boundFunction(self.removeParentalProtection, csel.getCurrentSelection())))
87 menu.append((_("add service to bouquet"), self.addServiceToBouquetSelected))
89 menu.append((_("add service to favourites"), self.addServiceToBouquetSelected))
92 if not inBouquet and current_sel_path.find("PROVIDERS") == -1:
93 menu.append((_("copy to bouquets"), self.copyCurrentToBouquetList))
94 if current_sel_path.find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
95 menu.append((_("remove all new found flags"), self.removeAllNewFoundFlags))
97 menu.append((_("remove entry"), self.removeCurrentService))
98 if current_root is not None and current_root.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
99 menu.append((_("remove new found flag"), self.removeNewFoundFlag))
101 menu.append((_("add bouquet"), self.showBouquetInputBox))
102 menu.append((_("remove entry"), self.removeBouquet))
104 if inBouquet: # current list is editable?
105 if not csel.bouquet_mark_edit:
106 if not csel.movemode:
107 menu.append((_("add marker"), self.showMarkerInputBox))
108 menu.append((_("enable move mode"), self.toggleMoveMode))
109 if not inBouquetRootList:
111 menu.append((_("enable bouquet edit"), self.bouquetMarkStart))
113 menu.append((_("enable favourite edit"), self.bouquetMarkStart))
115 menu.append((_("disable move mode"), self.toggleMoveMode))
116 elif not inBouquetRootList:
118 menu.append((_("end bouquet edit"), self.bouquetMarkEnd))
119 menu.append((_("abort bouquet edit"), self.bouquetMarkAbort))
121 menu.append((_("end favourites edit"), self.bouquetMarkEnd))
122 menu.append((_("abort favourites edit"), self.bouquetMarkAbort))
124 menu.append((_("back"), self.cancelClick))
125 self["menu"] = MenuList(menu)
127 def okbuttonClick(self):
128 self["menu"].getCurrent()[1]()
130 def cancelClick(self):
133 def showBouquetInputBox(self):
134 self.session.openWithCallback(self.bouquetInputCallback, InputBox, title=_("Please enter a name for the new bouquet"), text="bouquetname", maxSize=False, type=Input.TEXT)
136 def bouquetInputCallback(self, bouquet):
137 if bouquet is not None:
138 self.csel.addBouquet(bouquet, None)
141 def addParentalProtection(self, service):
142 parentalControl.protectService(service.toCompareString())
145 def removeParentalProtection(self, service):
146 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"))
148 def pinEntered(self, service, result):
150 parentalControl.unProtectService(service)
153 self.session.openWithCallback(self.close, MessageBox, _("The pin code you entered is wrong."), MessageBox.TYPE_ERROR)
155 def addServiceToBouquetSelected(self):
156 bouquets = self.csel.getBouquetList()
161 if cnt > 1: # show bouquet list
162 self.bsel = self.session.openWithCallback(self.bouquetSelClosed, BouquetSelector, bouquets, self.addCurrentServiceToBouquet)
163 elif cnt == 1: # add to only one existing bouquet
164 self.addCurrentServiceToBouquet(bouquets[0][1])
166 def bouquetSelClosed(self, recursive):
171 def copyCurrentToBouquetList(self):
172 self.csel.copyCurrentToBouquetList()
175 def removeBouquet(self):
176 self.csel.removeBouquet()
179 def showMarkerInputBox(self):
180 self.session.openWithCallback(self.markerInputCallback, InputBox, title=_("Please enter a name for the new marker"), text="markername", maxSize=False, type=Input.TEXT)
182 def markerInputCallback(self, marker):
183 if marker is not None:
184 self.csel.addMarker(marker)
187 def addCurrentServiceToBouquet(self, dest):
188 self.csel.addCurrentServiceToBouquet(dest)
189 if self.bsel is not None:
190 self.bsel.close(True)
192 self.close(True) # close bouquet selection
194 def removeCurrentService(self):
195 self.csel.removeCurrentService()
198 def toggleMoveMode(self):
199 self.csel.toggleMoveMode()
202 def bouquetMarkStart(self):
203 self.csel.startMarkedEdit()
206 def bouquetMarkEnd(self):
207 self.csel.endMarkedEdit(abort=False)
210 def bouquetMarkAbort(self):
211 self.csel.endMarkedEdit(abort=True)
214 def removeNewFoundFlag(self):
215 eDVBDB.getInstance().removeFlag(self.csel.getCurrentSelection(), FLAG_SERVICE_NEW_FOUND)
218 def removeAllNewFoundFlags(self):
219 curpath = self.csel.getCurrentSelection().getPath()
220 idx = curpath.find("satellitePosition == ")
222 tmp = curpath[idx+21:]
225 satpos = int(tmp[:idx])
226 eDVBDB.getInstance().removeFlags(FLAG_SERVICE_NEW_FOUND, -1, -1, -1, satpos)
229 class ChannelSelectionEPG:
231 self["ChannelSelectEPGActions"] = ActionMap(["ChannelSelectEPGActions"],
233 "showEPGList": self.showEPGList,
236 def showEPGList(self):
237 ref=self.getCurrentSelection()
238 ptr=eEPGCache.getInstance()
239 if ptr.startTimeQuery(ref) != -1:
240 self.session.open(EPGSelection, ref)
242 print 'no epg for service', ref.toString()
244 class ChannelSelectionEdit:
246 self.entry_marked = False
247 self.movemode = False
248 self.bouquet_mark_edit = False
249 self.mutableList = None
251 self.saved_title = None
252 self.saved_root = None
254 class ChannelSelectionEditActionMap(ActionMap):
255 def __init__(self, csel, contexts = [ ], actions = { }, prio=0):
256 ActionMap.__init__(self, contexts, actions, prio)
259 def action(self, contexts, action):
260 if action == "cancel":
261 self.csel.handleEditCancel()
262 return 0 # fall-trough
264 return 0 # fall-trough
266 return ActionMap.action(self, contexts, action)
268 self["ChannelSelectEditActions"] = ChannelSelectionEditActionMap(self, ["ChannelSelectEditActions", "OkCancelActions"],
270 "contextMenu": self.doContext,
273 def getMutableList(self, root=eServiceReference()):
274 if not self.mutableList is None:
275 return self.mutableList
276 serviceHandler = eServiceCenter.getInstance()
279 list = root and serviceHandler.list(root)
281 return list.startEdit()
284 def buildBouquetID(self, str):
288 if (c >= 'a' and c <= 'z') or (c >= '0' and c <= '9'):
294 def addMarker(self, name):
295 current = self.servicelist.getCurrent()
296 mutableList = self.getMutableList()
299 str = '1:64:%d:0:0:0:0:0:0:0::%s'%(cnt, name)
300 ref = eServiceReference(str)
301 if current and current.valid():
302 if not mutableList.addService(ref, current):
303 self.servicelist.addService(ref, True)
304 mutableList.flushChanges()
306 elif not mutableList.addService(ref):
307 self.servicelist.addService(ref, True)
308 mutableList.flushChanges()
312 def addBouquet(self, bName, services):
313 serviceHandler = eServiceCenter.getInstance()
314 mutableBouquetList = serviceHandler.list(self.bouquet_root).startEdit()
315 if mutableBouquetList:
316 if self.mode == MODE_TV:
318 str = '1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET \"userbouquet.%s.tv\" ORDER BY bouquet'%(self.buildBouquetID(bName))
321 str = '1:7:2:0:0:0:0:0:0:0:(type == 2) FROM BOUQUET \"userbouquet.%s.radio\" ORDER BY bouquet'%(self.buildBouquetID(bName))
322 new_bouquet_ref = eServiceReference(str)
323 if not mutableBouquetList.addService(new_bouquet_ref):
324 self.bouquetNumOffsetCache = { }
325 mutableBouquetList.flushChanges()
326 eDVBDB.getInstance().reloadBouquets()
327 mutableBouquet = serviceHandler.list(new_bouquet_ref).startEdit()
329 mutableBouquet.setListName(bName)
330 if services is not None:
331 for service in services:
332 if mutableBouquet.addService(service):
333 print "add", service.toString(), "to new bouquet failed"
335 current = self.servicelist.getCurrent()
336 if current and current.toString() == self.bouquet_rootstr:
337 self.servicelist.addService(service, True)
338 mutableBouquet.flushChanges()
340 print "get mutable list for new created bouquet failed"
341 # do some voodoo to check if current_root is equal to bouquet_root
342 cur_root = self.getRoot();
343 str1 = cur_root.toString()
344 pos1 = str1.find("FROM BOUQUET")
345 pos2 = self.bouquet_rootstr.find("FROM BOUQUET")
346 if pos1 != -1 and pos2 != -1 and str1[pos1:] == self.bouquet_rootstr[pos2:]:
347 self.setRoot(self.bouquet_root)
349 print "add", str, "to bouquets failed"
351 print "bouquetlist is not editable"
353 def copyCurrentToBouquetList(self):
354 provider = ServiceReference(self.getCurrentSelection())
355 providerName = provider.getServiceName()
356 serviceHandler = eServiceCenter.getInstance()
357 services = serviceHandler.list(provider.ref)
358 self.addBouquet(providerName, services and services.getContent('R', True))
360 def removeBouquet(self):
361 refstr = self.getCurrentSelection().toString()
362 self.bouquetNumOffsetCache = { }
363 pos = refstr.find('FROM BOUQUET "')
366 refstr = refstr[pos+14:]
367 pos = refstr.find('"')
369 filename = '/etc/enigma2/' + refstr[:pos] # FIXMEEE !!! HARDCODED /etc/enigma2
370 self.removeCurrentService()
372 if filename is not None:
375 print "error during remove of", filename
377 # multiple marked entry stuff ( edit mode, later multiepg selection )
378 def startMarkedEdit(self):
379 self.mutableList = self.getMutableList()
380 # add all services from the current list to internal marked set in listboxservicecontent
381 self.clearMarks() # this clears the internal marked set in the listboxservicecontent
382 self.saved_title = self.instance.getTitle()
383 pos = self.saved_title.find(')')
384 new_title = self.saved_title[:pos+1]
385 if config.usage.multibouquet.value:
386 new_title += ' ' + _("[bouquet edit]")
388 new_title += ' ' + _("[favourite edit]")
389 self.setTitle(new_title)
390 self.bouquet_mark_edit = True
391 self.__marked = self.servicelist.getRootServices()
392 for x in self.__marked:
393 self.servicelist.addMarked(eServiceReference(x))
394 self.savedPath = self.servicePath[:]
395 self.showAllServices()
397 def endMarkedEdit(self, abort):
398 if not abort and self.mutableList is not None:
399 self.bouquetNumOffsetCache = { }
400 new_marked = set(self.servicelist.getMarked())
401 old_marked = set(self.__marked)
402 removed = old_marked - new_marked
403 added = new_marked - old_marked
407 self.mutableList.removeService(eServiceReference(x))
410 self.mutableList.addService(eServiceReference(x))
412 self.mutableList.flushChanges()
415 self.bouquet_mark_edit = False
416 self.mutableList = None
417 self.setTitle(self.saved_title)
418 self.saved_title = None
419 # self.servicePath is just a reference to servicePathTv or Radio...
420 # so we never ever do use the asignment operator in self.servicePath
421 del self.servicePath[:] # remove all elements
422 self.servicePath += self.savedPath # add saved elements
424 self.setRoot(self.servicePath[len(self.servicePath)-1])
426 def clearMarks(self):
427 self.servicelist.clearMarks()
430 ref = self.servicelist.getCurrent()
431 if self.servicelist.isMarked(ref):
432 self.servicelist.removeMarked(ref)
434 self.servicelist.addMarked(ref)
436 def removeCurrentService(self):
437 ref = self.servicelist.getCurrent()
438 mutableList = self.getMutableList()
439 if ref.valid() and mutableList is not None:
440 if not mutableList.removeService(ref):
441 self.bouquetNumOffsetCache = { }
442 mutableList.flushChanges() #FIXME dont flush on each single removed service
443 self.servicelist.removeCurrent()
445 def addCurrentServiceToBouquet(self, dest):
446 mutableList = self.getMutableList(dest)
447 if not mutableList is None:
448 if not mutableList.addService(self.servicelist.getCurrent()):
449 self.bouquetNumOffsetCache = { }
450 mutableList.flushChanges()
452 def toggleMoveMode(self):
454 if self.entry_marked:
455 self.toggleMoveMarked() # unmark current entry
456 self.movemode = False
457 self.pathChangedDisabled = False # re-enable path change
458 self.mutableList.flushChanges() # FIXME add check if changes was made
459 self.mutableList = None
460 self.setTitle(self.saved_title)
461 self.saved_title = None
462 if self.getRoot() == self.bouquet_root:
463 self.bouquetNumOffsetCache = { }
465 self.mutableList = self.getMutableList()
467 self.pathChangedDisabled = True # no path change allowed in movemode
468 self.saved_title = self.instance.getTitle()
469 new_title = self.saved_title
470 pos = self.saved_title.find(')')
471 new_title = self.saved_title[:pos+1] + ' ' + _("[move mode]") + self.saved_title[pos+1:]
472 self.setTitle(new_title);
474 def handleEditCancel(self):
475 if self.movemode: #movemode active?
476 self.channelSelected() # unmark
477 self.toggleMoveMode() # disable move mode
478 elif self.bouquet_mark_edit:
479 self.endMarkedEdit(True) # abort edit mode
481 def toggleMoveMarked(self):
482 if self.entry_marked:
483 self.servicelist.setCurrentMarked(False)
484 self.entry_marked = False
486 self.servicelist.setCurrentMarked(True)
487 self.entry_marked = True
490 self.session.open(ChannelContextMenu, self)
495 # this makes it much simple to implement a selectable radio or tv mode :)
496 service_types_tv = '1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17) || (type == 195) || (type == 25)'
497 service_types_radio = '1:7:2:0:0:0:0:0:0:0:(type == 2)'
499 class ChannelSelectionBase(Screen):
500 def __init__(self, session):
501 Screen.__init__(self, session)
503 self["key_red"] = Button(_("All"))
504 self["key_green"] = Button(_("Satellites"))
505 self["key_yellow"] = Button(_("Provider"))
506 self["key_blue"] = Button(_("Favourites"))
508 self["list"] = ServiceList()
509 self.servicelist = self["list"]
511 self.numericalTextInput = NumericalTextInput()
512 self.numericalTextInput.setUseableChars(u'1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ')
514 self.servicePathTV = [ ]
515 self.servicePathRadio = [ ]
516 self.servicePath = [ ]
520 self.pathChangedDisabled = False
522 self.bouquetNumOffsetCache = { }
524 self["ChannelSelectBaseActions"] = NumberActionMap(["ChannelSelectBaseActions", "NumberActions"],
526 "showFavourites": self.showFavourites,
527 "showAllServices": self.showAllServices,
528 "showProviders": self.showProviders,
529 "showSatellites": self.showSatellites,
530 "nextBouquet": self.nextBouquet,
531 "prevBouquet": self.prevBouquet,
532 "nextMarker": self.nextMarker,
533 "prevMarker": self.prevMarker,
534 "1": self.keyNumberGlobal,
535 "2": self.keyNumberGlobal,
536 "3": self.keyNumberGlobal,
537 "4": self.keyNumberGlobal,
538 "5": self.keyNumberGlobal,
539 "6": self.keyNumberGlobal,
540 "7": self.keyNumberGlobal,
541 "8": self.keyNumberGlobal,
542 "9": self.keyNumberGlobal,
545 self.recallBouquetMode()
547 def appendDVBTypes(self, ref):
549 pos = path.find(' FROM BOUQUET')
551 return eServiceReference(self.service_types + path[pos:])
554 def getBouquetNumOffset(self, bouquet):
555 if config.usage.multibouquet.value:
557 bouquet = self.appendDVBTypes(bouquet)
559 return self.bouquetNumOffsetCache[bouquet.toString()]
562 serviceHandler = eServiceCenter.getInstance()
563 bouquetlist = serviceHandler.list(self.bouquet_root)
564 if not bouquetlist is None:
566 bouquetIterator = self.appendDVBTypes(bouquetlist.getNext())
567 if not bouquetIterator.valid(): #end of list
569 self.bouquetNumOffsetCache[bouquetIterator.toString()]=offsetCount
570 if ((bouquetIterator.flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory):
572 servicelist = serviceHandler.list(bouquetIterator)
573 if not servicelist is None:
575 serviceIterator = servicelist.getNext()
576 if not serviceIterator.valid(): #check if end of list
578 if serviceIterator.flags: #playable services have no flags
581 return self.bouquetNumOffsetCache.get(bouquet.toString(), offsetCount)
583 def recallBouquetMode(self):
584 if self.mode == MODE_TV:
585 self.service_types = service_types_tv
586 if config.usage.multibouquet.value:
587 self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET "bouquets.tv" ORDER BY bouquet'
589 self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.tv" ORDER BY bouquet'%(self.service_types)
591 self.service_types = service_types_radio
592 if config.usage.multibouquet.value:
593 self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET "bouquets.radio" ORDER BY bouquet'
595 self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.radio" ORDER BY bouquet'%(self.service_types)
596 self.bouquet_root = eServiceReference(self.bouquet_rootstr)
600 self.servicePath = self.servicePathTV
601 self.recallBouquetMode()
602 title = self.instance.getTitle()
603 pos = title.find(" (")
609 def setRadioMode(self):
610 self.mode = MODE_RADIO
611 self.servicePath = self.servicePathRadio
612 self.recallBouquetMode()
613 title = self.instance.getTitle()
614 pos = title.find(" (")
620 def setRoot(self, root, justSet=False):
621 path = root.getPath()
622 inBouquetRootList = path.find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
623 pos = path.find(' FROM BOUQUET')
624 isBouquet = pos != -1
625 if not inBouquetRootList and isBouquet:
626 self.servicelist.setMode(ServiceList.MODE_FAVOURITES)
627 self.servicelist.setNumberOffset(self.getBouquetNumOffset(root))
628 refstr = self.service_types + path[pos:]
629 root = eServiceReference(refstr)
631 self.servicelist.setMode(ServiceList.MODE_NORMAL)
632 self.servicelist.setRoot(root, justSet)
633 self.buildTitleString()
635 def removeModeStr(self, str):
636 if self.mode == MODE_TV:
637 pos = str.find(' (TV)')
639 pos = str.find(' (Radio)')
644 def getServiceName(self, ref):
645 str = self.removeModeStr(ServiceReference(ref).getServiceName())
647 pathstr = ref.getPath()
648 if pathstr.find('FROM PROVIDERS') != -1:
650 if pathstr.find('FROM SATELLITES') != -1:
651 return _("Satellites")
652 if pathstr.find(') ORDER BY name') != -1:
656 def buildTitleString(self):
657 titleStr = self.instance.getTitle()
658 pos = titleStr.find(']')
660 pos = titleStr.find(')')
662 titleStr = titleStr[:pos+1]
663 Len = len(self.servicePath)
665 base_ref = self.servicePath[0]
667 end_ref = self.servicePath[Len-1]
670 nameStr = self.getServiceName(base_ref)
671 titleStr += ' ' + nameStr
672 if end_ref is not None:
677 nameStr = self.getServiceName(end_ref)
679 self.setTitle(titleStr)
682 self.servicelist.moveUp()
685 self.servicelist.moveDown()
688 del self.servicePath[:]
690 def enterPath(self, ref, justSet=False):
691 self.servicePath.append(ref)
692 self.setRoot(ref, justSet)
694 def pathUp(self, justSet=False):
695 prev = self.servicePath.pop()
696 length = len(self.servicePath)
698 current = self.servicePath[length-1]
699 self.setRoot(current, justSet)
701 self.setCurrentSelection(prev)
704 def isBasePathEqual(self, ref):
705 if len(self.servicePath) > 1 and self.servicePath[0] == ref:
709 def isPrevPathEqual(self, ref):
710 length = len(self.servicePath)
711 if length > 1 and self.servicePath[length-2] == ref:
715 def preEnterPath(self, refstr):
718 def showAllServices(self):
719 if not self.pathChangedDisabled:
720 refstr = '%s ORDER BY name'%(self.service_types)
721 if not self.preEnterPath(refstr):
722 ref = eServiceReference(refstr)
723 currentRoot = self.getRoot()
724 if currentRoot is None or currentRoot != ref:
728 def showSatellites(self):
729 if not self.pathChangedDisabled:
730 refstr = '%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types)
731 if not self.preEnterPath(refstr):
732 ref = eServiceReference(refstr)
736 if self.isBasePathEqual(ref):
737 if self.isPrevPathEqual(ref):
739 prev = self.pathUp(justSet)
741 currentRoot = self.getRoot()
742 if currentRoot is None or currentRoot != ref:
745 self.enterPath(ref, True)
747 serviceHandler = eServiceCenter.getInstance()
748 servicelist = serviceHandler.list(ref)
749 if not servicelist is None:
751 service = servicelist.getNext()
752 if not service.valid(): #check if end of list
754 orbpos = service.getUnsignedData(4) >> 16
755 if service.getPath().find("FROM PROVIDER") != -1:
756 service_name = _("Providers")
757 elif service.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
758 service_name = _("New")
760 service_name = _("Services")
762 service_name += str(' - %s'%(nimmanager.getSatDescription(orbpos)))
763 service.setName(service_name) # why we need this cast?
765 if orbpos == 0xFFFF: #Cable
766 n = ("%s (%s)") % (service_name, _("Cable"))
767 elif orbpos == 0xEEEE: #Terrestrial
768 n = ("%s (%s)") % (service_name, _("Terrestrial"))
770 if orbpos > 1800: # west
771 orbpos = 3600 - orbpos
775 n = ("%s (%d.%d" + h + ")") % (service_name, orbpos / 10, orbpos % 10)
777 self.servicelist.addService(service)
778 self.servicelist.finishFill()
780 self.setCurrentSelection(prev)
782 def showProviders(self):
783 if not self.pathChangedDisabled:
784 refstr = '%s FROM PROVIDERS ORDER BY name'%(self.service_types)
785 if not self.preEnterPath(refstr):
786 ref = eServiceReference(refstr)
787 if self.isBasePathEqual(ref):
790 currentRoot = self.getRoot()
791 if currentRoot is None or currentRoot != ref:
795 def changeBouquet(self, direction):
796 if not self.pathChangedDisabled:
797 if self.isBasePathEqual(self.bouquet_root):
803 ref = self.getCurrentSelection()
807 return self.isBasePathEqual(self.bouquet_root)
810 return self.servicelist.atBegin()
813 return self.servicelist.atEnd()
815 def nextBouquet(self):
816 self.changeBouquet(+1)
818 def prevBouquet(self):
819 self.changeBouquet(-1)
821 def showFavourites(self):
822 if not self.pathChangedDisabled:
823 if not self.preEnterPath(self.bouquet_rootstr):
824 if self.isBasePathEqual(self.bouquet_root):
827 currentRoot = self.getRoot()
828 if currentRoot is None or currentRoot != self.bouquet_root:
830 self.enterPath(self.bouquet_root)
832 def keyNumberGlobal(self, number):
833 unichar = self.numericalTextInput.getKey(number)
834 charstr = unichar.encode("utf-8")
835 if len(charstr) == 1:
836 self.servicelist.moveToChar(charstr[0])
839 return self.servicelist.getRoot()
841 def getCurrentSelection(self):
842 return self.servicelist.getCurrent()
844 def setCurrentSelection(self, service):
845 servicepath = service.getPath()
846 pos = servicepath.find(" FROM BOUQUET")
848 if self.mode == MODE_TV:
849 servicepath = '(type == 1)' + servicepath[pos:]
851 servicepath = '(type == 2)' + servicepath[pos:]
852 service.setPath(servicepath)
853 self.servicelist.setCurrent(service)
855 def getBouquetList(self):
857 serviceHandler = eServiceCenter.getInstance()
858 if config.usage.multibouquet.value:
859 list = serviceHandler.list(self.bouquet_root)
865 if ((s.flags & eServiceReference.flagDirectory) == eServiceReference.flagDirectory):
866 info = serviceHandler.info(s)
868 bouquets.append((info.getName(s), s))
871 info = serviceHandler.info(self.bouquet_root)
873 bouquets.append((info.getName(self.bouquet_root), self.bouquet_root))
877 def keyNumber0(self, num):
878 if len(self.servicePath) > 1:
881 self.keyNumberGlobal(num)
884 if len(self.servicePath) > 1:
885 if self.isBasePathEqual(self.bouquet_root):
886 self.showFavourites()
888 ref = eServiceReference('%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types))
889 if self.isBasePathEqual(ref):
890 self.showSatellites()
892 ref = eServiceReference('%s FROM PROVIDERS ORDER BY name'%(self.service_types))
893 if self.isBasePathEqual(ref):
896 self.showAllServices()
898 def nextMarker(self):
899 self.servicelist.moveToNextMarker()
901 def prevMarker(self):
902 self.servicelist.moveToPrevMarker()
906 #config for lastservice
907 config.tv = ConfigSubsection()
908 config.tv.lastservice = ConfigText()
909 config.tv.lastroot = ConfigText()
910 config.radio = ConfigSubsection()
911 config.radio.lastservice = ConfigText()
912 config.radio.lastroot = ConfigText()
913 config.servicelist = ConfigSubsection()
914 config.servicelist.lastmode = ConfigText(default = "tv")
916 class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG):
917 def __init__(self, session):
918 ChannelSelectionBase.__init__(self,session)
919 ChannelSelectionEdit.__init__(self)
920 ChannelSelectionEPG.__init__(self)
922 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
924 "cancel": self.cancel,
925 "ok": self.channelSelected,
926 "keyRadio": self.setModeRadio,
927 "keyTV": self.setModeTv,
930 self.onShown.append(self.__onShown)
932 self.lastChannelRootTimer = eTimer()
933 self.lastChannelRootTimer.timeout.get().append(self.__onCreate)
934 self.lastChannelRootTimer.start(100,True)
936 self.history_tv = [ ]
937 self.history_radio = [ ]
938 self.history = self.history_tv
941 self.lastservice = config.tv.lastservice
942 self.lastroot = config.tv.lastroot
943 self.revertMode = None
947 lastservice=eServiceReference(self.lastservice.value)
948 if lastservice.valid():
949 self.setCurrentSelection(lastservice)
952 if self.revertMode is None and config.servicelist.lastmode.value == "radio":
953 self.revertMode = MODE_RADIO
954 self.history = self.history_tv
955 self.lastservice = config.tv.lastservice
956 self.lastroot = config.tv.lastroot
957 config.servicelist.lastmode.value = "tv"
961 def setModeRadio(self):
962 if self.revertMode is None and config.servicelist.lastmode.value == "tv":
963 self.revertMode = MODE_TV
964 if config.usage.e1like_radio_mode.value:
965 self.history = self.history_radio
966 self.lastservice = config.radio.lastservice
967 self.lastroot = config.radio.lastroot
968 config.servicelist.lastmode.value = "radio"
972 def __onCreate(self):
973 if config.usage.e1like_radio_mode.value:
974 if config.servicelist.lastmode.value == "tv":
980 lastservice=eServiceReference(self.lastservice.value)
981 if lastservice.valid():
985 self.recallBouquetMode()
986 ref = self.session.nav.getCurrentlyPlayingServiceReference()
987 if ref is not None and ref.valid() and ref.getPath() == "":
988 self.servicelist.setPlayableIgnoreService(ref)
990 self.servicelist.setPlayableIgnoreService(eServiceReference())
992 def channelSelected(self):
993 ref = self.getCurrentSelection()
995 self.toggleMoveMarked()
996 elif (ref.flags & 7) == 7:
998 elif self.bouquet_mark_edit:
1000 elif not (ref.flags & 64): # no marker
1004 #called from infoBar and channelSelected
1006 self.revertMode=None
1007 ref = self.session.nav.getCurrentlyPlayingServiceReference()
1008 nref = self.getCurrentSelection()
1009 if ref is None or ref != nref:
1010 self.session.nav.playService(nref)
1013 config.servicelist.lastmode.save()
1014 self.addToHistory(nref)
1016 def addToHistory(self, ref):
1017 if self.servicePath is not None:
1018 tmp=self.servicePath[:]
1021 del self.history[self.history_pos+1:]
1024 self.history.append(tmp)
1025 hlen = len(self.history)
1026 if hlen > HISTORYSIZE:
1029 self.history_pos = hlen-1
1031 def historyBack(self):
1032 hlen = len(self.history)
1033 if hlen > 1 and self.history_pos > 0:
1034 self.history_pos -= 1
1035 self.setHistoryPath()
1037 def historyNext(self):
1038 hlen = len(self.history)
1039 if hlen > 1 and self.history_pos < (hlen-1):
1040 self.history_pos += 1
1041 self.setHistoryPath()
1043 def setHistoryPath(self):
1044 path = self.history[self.history_pos][:]
1046 del self.servicePath[:]
1047 self.servicePath += path
1051 if self.getRoot() != root:
1053 self.session.nav.playService(ref)
1054 self.setCurrentSelection(ref)
1059 for i in self.servicePath:
1060 path += i.toString()
1062 if len(path) and path != self.lastroot.value:
1063 self.lastroot.value = path
1064 self.lastroot.save()
1066 def restoreRoot(self):
1068 re = compile('.+?;')
1069 tmp = re.findall(self.lastroot.value)
1072 self.servicePath.append(eServiceReference(i[:len(i)-1]))
1075 path = self.servicePath.pop()
1076 self.enterPath(path)
1078 self.showFavourites()
1081 def preEnterPath(self, refstr):
1082 if len(self.servicePath) and self.servicePath[0] != eServiceReference(refstr):
1083 pathstr = self.lastroot.value
1084 if pathstr is not None and pathstr.find(refstr) == 0:
1086 lastservice=eServiceReference(self.lastservice.value)
1087 if lastservice.valid():
1088 self.setCurrentSelection(lastservice)
1092 def saveChannel(self):
1093 ref = self.session.nav.getCurrentlyPlayingServiceReference()
1095 refstr = ref.toString()
1098 if refstr != self.lastservice.value:
1099 self.lastservice.value = refstr
1100 self.lastservice.save()
1102 def setCurrentServicePath(self, path):
1103 hlen = len(self.history)
1105 self.history[self.history_pos] = path
1107 self.history.append(path)
1108 self.setHistoryPath()
1110 def getCurrentServicePath(self):
1111 hlen = len(self.history)
1113 return self.history[self.history_pos]
1116 def recallPrevService(self):
1117 hlen = len(self.history)
1119 if self.history_pos == hlen-1:
1120 tmp = self.history[self.history_pos]
1121 self.history[self.history_pos] = self.history[self.history_pos-1]
1122 self.history[self.history_pos-1] = tmp
1124 tmp = self.history[self.history_pos+1]
1125 self.history[self.history_pos+1] = self.history[self.history_pos]
1126 self.history[self.history_pos] = tmp
1127 self.setHistoryPath()
1130 if self.revertMode is None:
1132 lastservice=eServiceReference(self.lastservice.value)
1133 if lastservice.valid() and self.getCurrentSelection() != lastservice:
1134 self.setCurrentSelection(lastservice)
1135 elif self.revertMode == MODE_TV:
1137 elif self.revertMode == MODE_RADIO:
1139 self.revertMode = None
1142 from Screens.InfoBarGenerics import InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord, InfoBarRadioText
1144 class RadioInfoBar(Screen, InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord):
1145 def __init__(self, session):
1146 Screen.__init__(self, session)
1147 InfoBarEvent.__init__(self)
1148 InfoBarServiceName.__init__(self)
1149 InfoBarInstantRecord.__init__(self)
1150 self["CurrentTime"] = Clock()
1152 class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG, InfoBarRadioText):
1154 ALLOW_SUSPEND = True
1156 def __init__(self, session):
1157 ChannelSelectionBase.__init__(self, session)
1158 ChannelSelectionEdit.__init__(self)
1159 ChannelSelectionEPG.__init__(self)
1160 InfoBarRadioText.__init__(self)
1162 config.radio = ConfigSubsection();
1163 config.radio.lastservice = ConfigText()
1164 config.radio.lastroot = ConfigText()
1165 self.onLayoutFinish.append(self.onCreate)
1167 self.info = session.instantiateDialog(RadioInfoBar)
1169 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1171 "keyTV": self.closeRadio,
1172 "keyRadio": self.closeRadio,
1173 "cancel": self.closeRadio,
1174 "ok": self.channelSelected,
1179 for i in self.servicePathRadio:
1180 path += i.toString()
1182 if len(path) and path != config.radio.lastroot.value:
1183 config.radio.lastroot.value = path
1184 config.radio.lastroot.save()
1186 def restoreRoot(self):
1188 re = compile('.+?;')
1189 tmp = re.findall(config.radio.lastroot.value)
1192 self.servicePathRadio.append(eServiceReference(i[:len(i)-1]))
1195 path = self.servicePathRadio.pop()
1196 self.enterPath(path)
1198 self.showFavourites()
1201 def preEnterPath(self, refstr):
1202 if len(self.servicePathRadio) and self.servicePathRadio[0] != eServiceReference(refstr):
1203 pathstr = config.radio.lastroot.value
1204 if pathstr is not None and pathstr.find(refstr) == 0:
1206 lastservice=eServiceReference(config.radio.lastservice.value)
1207 if lastservice.valid():
1208 self.setCurrentSelection(lastservice)
1215 lastservice=eServiceReference(config.radio.lastservice.value)
1216 if lastservice.valid():
1217 self.servicelist.setCurrent(lastservice)
1218 self.session.nav.playService(lastservice)
1219 self.servicelist.setPlayableIgnoreService(lastservice)
1222 def channelSelected(self): # just return selected service
1223 ref = self.getCurrentSelection()
1225 self.toggleMoveMarked()
1226 elif (ref.flags & 7) == 7:
1228 elif self.bouquet_mark_edit:
1230 elif not (ref.flags & 64): # no marker
1231 playingref = self.session.nav.getCurrentlyPlayingServiceReference()
1232 if playingref is None or playingref != ref:
1233 self.session.nav.playService(ref)
1234 self.servicelist.setPlayableIgnoreService(ref)
1235 config.radio.lastservice.value = ref.toString()
1236 config.radio.lastservice.save()
1239 def closeRadio(self):
1241 #set previous tv service
1242 lastservice=eServiceReference(config.tv.lastservice.value)
1243 self.session.nav.playService(lastservice)
1246 class SimpleChannelSelection(ChannelSelectionBase):
1247 def __init__(self, session, title):
1248 ChannelSelectionBase.__init__(self, session)
1250 self.onShown.append(self.__onExecCallback)
1252 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
1254 "cancel": self.close,
1255 "ok": self.channelSelected,
1256 "keyRadio": self.setModeRadio,
1257 "keyTV": self.setModeTv,
1260 def __onExecCallback(self):
1261 self.setTitle(self.title)
1264 def channelSelected(self): # just return selected service
1265 ref = self.getCurrentSelection()
1266 if (ref.flags & 7) == 7:
1268 elif not (ref.flags & 64):
1269 ref = self.getCurrentSelection()
1272 def setModeTv(self):
1274 self.showFavourites()
1276 def setModeRadio(self):
1278 self.showFavourites()