1 from Screen import Screen
2 from Components.Button import Button
3 from Components.ServiceList import ServiceList
4 from Components.ActionMap import NumberActionMap
5 from EpgSelection import EPGSelection
6 from enigma import eServiceReference, eEPGCache, eEPGCachePtr, eServiceCenter, eServiceCenterPtr, iMutableServiceListPtr, iStaticServiceInformationPtr, eTimer
7 from Components.config import config, configElement, ConfigSubsection, configText
8 from Screens.FixedMenu import FixedMenu
9 from Tools.NumericalTextInput import NumericalTextInput
10 from Components.NimManager import nimmanager
12 import xml.dom.minidom
14 class BouquetSelector(FixedMenu):
15 def __init__(self, session, bouquets, selectedFunc):
16 self.selectedFunc=selectedFunc
19 entrys.append((x[0], self.bouquetSelected, x[1]))
20 FixedMenu.__init__(self, session, "Bouquetlist", entrys)
21 self.skinName = "Menu"
23 def bouquetSelected(self):
24 self.selectedFunc(self["menu"].getCurrent()[2])
26 class ChannelContextMenu(FixedMenu):
27 def __init__(self, session, csel):
32 inBouquetRootList = csel.servicelist.getRoot().getPath().find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
33 inBouquet = csel.getMutableList() is not None
34 haveBouquets = csel.bouquet_root.getPath().find('FROM BOUQUET "bouquets.') != -1
36 if not csel.bouquet_mark_edit and not csel.movemode and not inBouquetRootList:
37 if (csel.getCurrentSelection().flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory:
39 menu.append((_("add service to bouquet"), self.addServiceToBouquetSelected))
41 menu.append((_("add service to favourites"), self.addServiceToBouquetSelected))
43 menu.append((_("remove service"), self.removeCurrentService))
45 if inBouquet: # current list is editable?
46 if not csel.bouquet_mark_edit:
48 menu.append((_("enable move mode"), self.toggleMoveMode))
49 if not inBouquetRootList:
51 menu.append((_("enable bouquet edit"), self.bouquetMarkStart))
53 menu.append((_("enable favourite edit"), self.bouquetMarkStart))
55 menu.append((_("disable move mode"), self.toggleMoveMode))
56 elif not inBouquetRootList:
58 menu.append((_("end bouquet edit"), self.bouquetMarkEnd))
59 menu.append((_("abort bouquet edit"), self.bouquetMarkAbort))
61 menu.append((_("end favourites edit"), self.bouquetMarkEnd))
62 menu.append((_("abort favourites edit"), self.bouquetMarkAbort))
64 menu.append((_("back"), self.close))
66 FixedMenu.__init__(self, session, _("Channel Selection"), menu)
67 self.skinName = "Menu"
69 def addServiceToBouquetSelected(self):
70 bouquets = self.csel.getBouquetList()
75 if cnt > 1: # show bouquet list
76 self.session.open(BouquetSelector, bouquets, self.addCurrentServiceToBouquet)
77 elif cnt == 1: # add to only one existing bouquet
78 self.addCurrentServiceToBouquet(bouquets[0][1])
79 else: #no bouquets in root.. so assume only one favourite list is used
80 self.addCurrentServiceToBouquet(self.csel.bouquet_root)
82 def addCurrentServiceToBouquet(self, dest):
83 self.csel.addCurrentServiceToBouquet(dest)
86 def removeCurrentService(self):
87 self.csel.removeCurrentService()
90 def toggleMoveMode(self):
91 self.csel.toggleMoveMode()
94 def bouquetMarkStart(self):
95 self.csel.startMarkedEdit()
98 def bouquetMarkEnd(self):
99 self.csel.endMarkedEdit(abort=False)
102 def bouquetMarkAbort(self):
103 self.csel.endMarkedEdit(abort=True)
106 class ChannelSelectionEdit:
108 self.entry_marked = False
109 self.movemode = False
110 self.bouquet_mark_edit = False
111 self.mutableList = None
113 self.saved_title = None
114 self.saved_root = None
116 def getMutableList(self, root=eServiceReference()):
117 if not self.mutableList is None:
118 return self.mutableList
119 serviceHandler = eServiceCenter.getInstance()
121 root=self.servicelist.getRoot()
122 list = serviceHandler.list(root)
124 return list.startEdit()
127 # multiple marked entry stuff ( edit mode, later multiepg selection )
128 def startMarkedEdit(self):
129 self.mutableList = self.getMutableList()
130 # add all services from the current list to internal marked set in listboxservicecontent
131 self.bouquetRoot = self.servicelist.getRoot()
132 self.clearMarks() # this clears the internal marked set in the listboxservicecontent
133 self.saved_title = self.instance.getTitle()
134 new_title = self.saved_title
135 if self.bouquet_root.getPath().find('FROM BOUQUET "bouquets.') != -1:
136 new_title += ' ' + _("[bouquet edit]")
138 new_title += ' ' + _("[favourite edit]")
139 self.instance.setTitle(new_title)
140 self.bouquet_mark_edit = True
141 self.__marked = self.servicelist.getRootServices()
142 for x in self.__marked:
143 self.servicelist.addMarked(eServiceReference(x))
144 self.saved_root = self.getRoot()
145 self.showAllServices()
147 def endMarkedEdit(self, abort):
148 if not abort and self.mutableList is not None:
149 new_marked = set(self.servicelist.getMarked())
150 old_marked = set(self.__marked)
151 removed = old_marked - new_marked
152 added = new_marked - old_marked
156 self.mutableList.removeService(eServiceReference(x))
159 self.mutableList.addService(eServiceReference(x))
161 self.mutableList.flushChanges()
164 self.bouquet_mark_edit = False
165 self.bouquetRoot = None
166 self.mutableList = None
167 self.instance.setTitle(self.saved_title)
168 self.saved_title = None
169 self.setRoot(self.saved_root)
171 def clearMarks(self):
172 self.servicelist.clearMarks()
175 ref = self.servicelist.getCurrent()
176 if self.servicelist.isMarked(ref):
177 self.servicelist.removeMarked(ref)
179 self.servicelist.addMarked(ref)
181 def removeCurrentService(self):
182 ref = self.servicelist.getCurrent()
183 mutableList = self.getMutableList()
184 if ref.valid() and mutableList is not None:
185 if not mutableList.removeService(ref):
186 currentIndex = self.servicelist.getCurrentIndex()
187 self.servicelist.moveDown()
188 if self.servicelist.getCurrentIndex() == currentIndex:
190 mutableList.flushChanges() #FIXME dont flush on each single removed service
191 self.setRoot(self.servicelist.getRoot())
192 self.servicelist.moveToIndex(currentIndex)
194 def addCurrentServiceToBouquet(self, dest):
195 mutableList = self.getMutableList(dest)
196 if not mutableList is None:
197 if not mutableList.addService(self.servicelist.getCurrent()):
198 mutableList.flushChanges()
201 def toggleMoveMode(self):
203 if self.entry_marked:
204 self.toggleMoveMarked() # unmark current entry
205 self.movemode = False
206 self.mutableList.flushChanges() # FIXME add check if changes was made
207 self.mutableList = None
208 self.instance.setTitle(self.saved_title)
209 self.saved_title = None
211 self.mutableList = self.getMutableList()
213 self.saved_title = self.instance.getTitle()
214 new_title = self.saved_title
215 new_title += ' ' + _("[move mode]");
216 self.instance.setTitle(new_title);
218 def handleEditCancel(self):
219 if self.movemode: #movemode active?
220 self.channelSelected() # unmark
221 self.toggleMoveMode() # disable move mode
222 elif self.bouquet_mark_edit:
223 self.endMarkedEdit(True) # abort edit mode
225 def toggleMoveMarked(self):
226 if self.entry_marked:
227 self.servicelist.setCurrentMarked(False)
228 self.entry_marked = False
230 self.servicelist.setCurrentMarked(True)
231 self.entry_marked = True
234 self.session.open(ChannelContextMenu, self)
236 USE_MULTIBOUQUETS = False
241 class ChannelSelectionBase(Screen):
242 def __init__(self, session):
243 Screen.__init__(self, session)
245 # this makes it much simple to implement a selectable radio or tv mode :)
246 self.service_types_tv = '1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17)'
247 self.service_types_radio = '1:7:1:0:0:0:0:0:0:0:(type == 2)'
249 self["key_red"] = Button(_("All"))
250 self["key_green"] = Button(_("Satellites"))
251 self["key_yellow"] = Button(_("Provider"))
252 self["key_blue"] = Button(_("Favourites"))
254 self["list"] = ServiceList()
255 self.servicelist = self["list"]
257 self.numericalTextInput = NumericalTextInput()
259 def appendDVBTypes(self, ref):
261 pos = path.find(' FROM BOUQUET')
263 return eServiceReference(self.service_types + path[pos:])
266 def getBouquetNumOffset(self, bouquet):
267 bouquet = self.appendDVBTypes(bouquet)
268 if self.bouquet_root.getPath().find('FROM BOUQUET "bouquets.') == -1: #FIXME HACK
271 serviceHandler = eServiceCenter.getInstance()
272 bouquetlist = serviceHandler.list(self.bouquet_root)
273 if not bouquetlist is None:
275 bouquetIterator = self.appendDVBTypes(bouquetlist.getNext())
276 if not bouquetIterator.valid() or bouquetIterator == bouquet: #end of list or bouquet found
278 if ((bouquetIterator.flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory):
280 servicelist = serviceHandler.list(bouquetIterator)
281 if not servicelist is None:
283 serviceIterator = servicelist.getNext()
284 if not serviceIterator.valid(): #check if end of list
286 if serviceIterator.flags: #playable services have no flags
292 self.service_types = self.service_types_tv
293 if USE_MULTIBOUQUETS:
294 self.bouquet_root = eServiceReference('1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET "bouquets.tv" ORDER BY bouquet')
296 self.bouquet_root = eServiceReference('%s FROM BOUQUET "userbouquet.favourites.tv" ORDER BY bouquet'%(self.service_types))
297 title = self.instance.getTitle()
298 pos = title.find(" (")
302 self.instance.setTitle(title)
305 def setRadioMode(self):
306 self.service_types = self.service_types_radio
307 if USE_MULTIBOUQUETS:
308 self.bouquet_root = eServiceReference('1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET "bouquets.radio" ORDER BY bouquet')
310 self.bouquet_root = eServiceReference('%s FROM BOUQUET "userbouquet.favourites.radio" ORDER BY bouquet'%(self.service_types))
311 title = self.instance.getTitle()
312 pos = title.find(" (")
316 self.instance.setTitle(title)
317 self.mode = MODE_RADIO
319 def setRootBase(self, root, justSet=False):
320 path = root.getPath()
321 inBouquetRootList = path.find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
322 pos = path.find(' FROM BOUQUET')
323 isBouquet = pos != -1
324 if not inBouquetRootList and isBouquet:
325 self.servicelist.setMode(ServiceList.MODE_FAVOURITES)
326 self.servicelist.setNumberOffset(self.getBouquetNumOffset(root))
327 refstr = self.service_types + path[pos:]
328 root = eServiceReference(refstr)
330 self.servicelist.setMode(ServiceList.MODE_NORMAL)
331 self.servicelist.setRoot(root, justSet)
334 self.servicelist.moveUp()
337 self.servicelist.moveDown()
339 def showAllServices(self):
340 ref = eServiceReference('%s ORDER BY name'%(self.service_types))
343 def showSatellites(self):
344 ref = eServiceReference('%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types))
345 self.setRoot(ref, True)
346 serviceHandler = eServiceCenter.getInstance()
347 servicelist = serviceHandler.list(ref)
348 if not servicelist is None:
350 service = servicelist.getNext()
351 if not service.valid(): #check if end of list
353 orbpos = service.getData(4) >> 16
354 if service.getPath().find("FROM PROVIDER") != -1:
355 service_name = _("Providers")
357 service_name = _("Services")
359 service_name += str(' - %s'%(nimmanager.getSatDescription(orbpos)))
360 service.setName(service_name) # why we need this cast?
362 if orbpos > 1800: # west
363 service.setName("%s (%3.1f" + _("W") + ")" %(str, (0 - (orbpos - 3600)) / 10.0))
365 service.setName("%s (%3.1f" + _("E") + ")" % (str, orbpos / 10.0))
366 self.servicelist.addService(service)
367 self.servicelist.finishFill()
369 def showProviders(self):
370 ref = eServiceReference('%s FROM PROVIDERS ORDER BY name'%(self.service_types))
373 def showFavourites(self):
374 self.setRoot(self.bouquet_root)
376 def keyNumberGlobal(self, number):
377 char = self.numericalTextInput.getKey(number)
378 print "You pressed number " + str(number)
379 print "You would go to character " + str(char)
380 self.servicelist.moveToChar(char)
382 def enterBouquet(self, action):
383 if action[:7] == "bouquet":
384 if action.find("FROM BOUQUET") != -1:
385 self.setRoot(eServiceReference("1:7:1:0:0:0:0:0:0:0:" + action[8:]))
387 self.setRoot(eServiceReference("1:0:1:0:0:0:0:0:0:0:" + action[8:]))
392 return self.servicelist.getRoot()
394 def getCurrentSelection(self):
395 return self.servicelist.getCurrent()
397 def setCurrentSelection(self, service):
398 self.servicelist.setCurrent(service)
403 def getBouquetList(self):
406 serviceHandler = eServiceCenter.getInstance()
407 list = serviceHandler.list(self.bouquet_root)
413 if ((s.flags & eServiceReference.flagDirectory) == eServiceReference.flagDirectory):
414 info = serviceHandler.info(s)
416 bouquets.append((info.getName(s), s))
419 if len(bouquets) == 0 and serviceCount > 0:
420 info = serviceHandler.info(self.bouquet_root)
422 bouquets.append((info.getName(self.bouquet_root), self.bouquet_root))
426 class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit):
427 def __init__(self, session):
428 ChannelSelectionBase.__init__(self,session)
429 ChannelSelectionEdit.__init__(self)
431 #config for lastservice
432 config.tv = ConfigSubsection();
433 config.tv.lastservice = configElement("config.tv.lastservice", configText, "", 0);
434 config.tv.lastroot = configElement("config.tv.lastroot", configText, "", 0);
436 class ChannelActionMap(NumberActionMap):
437 def action(self, contexts, action):
438 if not self.csel.enterBouquet(action):
439 if action == "cancel":
440 self.csel.handleEditCancel()
441 NumberActionMap.action(self, contexts, action)
442 self["actions"] = ChannelActionMap(["ChannelSelectActions", "OkCancelActions", "ContextMenuActions"],
444 "cancel": self.cancel,
445 "ok": self.channelSelected,
447 "contextMenu": self.doContext,
448 "showFavourites": self.showFavourites,
449 "showAllServices": self.showAllServices,
450 "showProviders": self.showProviders,
451 "showSatellites": self.showSatellites,
452 "showEPGList": self.showEPGList,
453 "1": self.keyNumberGlobal,
454 "2": self.keyNumberGlobal,
455 "3": self.keyNumberGlobal,
456 "4": self.keyNumberGlobal,
457 "5": self.keyNumberGlobal,
458 "6": self.keyNumberGlobal,
459 "7": self.keyNumberGlobal,
460 "8": self.keyNumberGlobal,
461 "9": self.keyNumberGlobal,
462 "0": self.keyNumberGlobal
464 self["actions"].csel = self
465 self.onShown.append(self.onShow)
467 self.lastChannelRootTimer = eTimer()
468 self.lastChannelRootTimer.timeout.get().append(self.onCreate)
469 self.lastChannelRootTimer.start(100,True)
473 lastroot=eServiceReference(config.tv.lastroot.value)
475 self.setRoot(lastroot)
477 self.showFavourites()
478 self.saveRoot(self.getRoot())
480 lastservice=eServiceReference(config.tv.lastservice.value)
481 if lastservice.valid():
482 self.servicelist.setCurrent(lastservice)
483 self.session.nav.playService(lastservice)
486 ref = self.session.nav.getCurrentlyPlayingServiceReference()
487 if ref is not None and ref.valid() and ref.getPath() == "":
488 self.servicelist.setPlayableIgnoreService(ref)
490 self.servicelist.setPlayableIgnoreService(eServiceReference())
492 def showEPGList(self):
493 ref=self.getCurrentSelection()
494 ptr=eEPGCache.getInstance()
495 if ptr.startTimeQuery(ref) != -1:
496 self.session.open(EPGSelection, ref)
498 print 'no epg for service', ref.toString()
500 def channelSelected(self):
501 ref = self.getCurrentSelection()
503 self.toggleMoveMarked()
504 elif (ref.flags & 7) == 7:
506 elif self.bouquet_mark_edit:
512 def setRoot(self, root, justSet=False):
513 if not self.movemode:
514 self.setRootBase(root, justSet)
516 #called from infoBar and channelSelected
518 self.session.nav.playService(self.getCurrentSelection())
519 self.saveRoot(self.getRoot())
522 def saveRoot(self, root):
524 config.tv.lastroot.value = root.toString()
525 config.tv.lastroot.save()
527 def saveChannel(self):
528 ref = self.session.nav.getCurrentlyPlayingServiceReference()
530 refstr = ref.toString()
533 config.tv.lastservice.value = refstr
534 config.tv.lastservice.save()
538 lastroot=eServiceReference(config.tv.lastroot.value)
539 lastservice=eServiceReference(config.tv.lastservice.value)
540 if lastroot.valid() and self.getRoot() != lastroot:
541 self.setRoot(lastroot)
542 if lastservice.valid() and self.getCurrentSelection() != lastservice:
543 self.servicelist.setCurrent(lastservice)
545 class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit):
546 def __init__(self, session):
547 ChannelSelectionBase.__init__(self, session)
548 ChannelSelectionEdit.__init__(self)
550 config.radio = ConfigSubsection();
551 config.radio.lastservice = configElement("config.radio.lastservice", configText, "", 0);
552 config.radio.lastroot = configElement("config.radio.lastroot", configText, "", 0);
553 self.onLayoutFinish.append(self.onCreate)
555 class ChannelActionMap(NumberActionMap):
556 def action(self, contexts, action):
557 if not self.csel.enterBouquet(action):
558 NumberActionMap.action(self, contexts, action)
559 self["actions"] = ChannelActionMap(["ChannelSelectActions", "OkCancelActions", "ContextMenuActions", "TvRadioActions"],
561 "keyTV": self.closeRadio,
562 "keyRadio": self.closeRadio,
563 "contextMenu": self.doContext,
564 "cancel": self.closeRadio,
565 "ok": self.channelSelected,
566 "showFavourites": self.showFavourites,
567 "showAllServices": self.showAllServices,
568 "showProviders": self.showProviders,
569 "showSatellites": self.showSatellites,
570 "1": self.keyNumberGlobal,
571 "2": self.keyNumberGlobal,
572 "3": self.keyNumberGlobal,
573 "4": self.keyNumberGlobal,
574 "5": self.keyNumberGlobal,
575 "6": self.keyNumberGlobal,
576 "7": self.keyNumberGlobal,
577 "8": self.keyNumberGlobal,
578 "9": self.keyNumberGlobal,
579 "0": self.keyNumberGlobal
581 self["actions"].csel = self
585 lastroot=eServiceReference(config.radio.lastroot.value)
587 self.setRoot(lastroot)
589 self.showFavourites()
590 self.saveRoot(self.getRoot())
591 lastservice=eServiceReference(config.radio.lastservice.value)
592 if lastservice.valid():
593 self.servicelist.setCurrent(lastservice)
594 self.session.nav.playService(lastservice)
595 self.servicelist.setPlayableIgnoreService(lastservice)
597 def channelSelected(self): # just return selected service
598 ref = self.getCurrentSelection()
600 self.toggleMoveMarked()
601 elif (ref.flags & 7) == 7:
603 elif self.bouquet_mark_edit:
606 self.session.nav.playService(ref)
607 self.servicelist.setPlayableIgnoreService(ref)
608 config.radio.lastservice.value = ref.toString()
609 config.radio.lastservice.save()
611 def setRoot(self, root, justSet=False):
612 self.setRootBase(root, justSet)
614 def closeRadio(self):
615 lastroot=eServiceReference(config.radio.lastroot.value)
616 lastservice=eServiceReference(config.radio.lastservice.value)
617 if lastroot.valid() and self.getRoot() != lastroot:
618 self.setRoot(lastroot)
619 if lastservice.valid() and self.getCurrentSelection() != lastservice:
620 self.servicelist.setCurrent(lastservice)
621 #set previous tv service
622 lastservice=eServiceReference(config.tv.lastservice.value)
623 self.session.nav.playService(lastservice)
626 class SimpleChannelSelection(ChannelSelectionBase):
627 def __init__(self, session, title):
628 ChannelSelectionBase.__init__(self, session)
630 self.onShown.append(self.onExecCallback)
632 class ChannelActionMap(NumberActionMap):
633 def action(self, contexts, action):
634 if not self.csel.enterBouquet(action):
635 NumberActionMap.action(self, contexts, action)
636 self["actions"] = ChannelActionMap(["ChannelSelectActions", "OkCancelActions", "ContextMenuActions", "TvRadioActions"],
638 "cancel": self.cancel,
639 "ok": self.channelSelected,
640 "showFavourites": self.showFavourites,
641 "showAllServices": self.showAllServices,
642 "showProviders": self.showProviders,
643 "showSatellites": self.showSatellites,
644 "keyRadio": self.setModeRadio,
645 "keyTV": self.setModeTv,
646 "1": self.keyNumberGlobal,
647 "2": self.keyNumberGlobal,
648 "3": self.keyNumberGlobal,
649 "4": self.keyNumberGlobal,
650 "5": self.keyNumberGlobal,
651 "6": self.keyNumberGlobal,
652 "7": self.keyNumberGlobal,
653 "8": self.keyNumberGlobal,
654 "9": self.keyNumberGlobal,
655 "0": self.keyNumberGlobal
657 self["actions"].csel = self
659 def onExecCallback(self):
660 self.session.currentDialog.instance.setTitle(self.title)
663 def channelSelected(self): # just return selected service
664 ref = self.getCurrentSelection()
665 if (ref.flags & 7) == 7:
668 ref = self.getCurrentSelection()
671 def setRoot(self, root, justSet=False):
672 self.setRootBase(root, justSet)
676 self.showFavourites()
678 def setModeRadio(self):
680 self.showFavourites()