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, parent):
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.parent.addCurrentServiceToBouquet(self["menu"].getCurrent()[2])
27 class ChannelContextMenu(FixedMenu):
28 def __init__(self, session, csel):
33 inBouquetRootList = csel.servicelist.getRoot().getPath().find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
34 inBouquet = csel.getMutableList() is not None
35 haveBouquets = csel.bouquet_root.getPath().find('FROM BOUQUET "bouquets.') != -1
37 if not csel.bouquet_mark_edit and not csel.movemode and not inBouquetRootList:
38 if (csel.getCurrentSelection().flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory:
40 menu.append((_("add service to bouquet"), self.addServiceToBouquetSelected))
42 menu.append((_("add service to favourites"), self.addServiceToBouquetSelected))
44 menu.append((_("remove service"), self.removeCurrentService))
46 if inBouquet: # current list is editable?
47 if not csel.bouquet_mark_edit:
49 menu.append((_("enable move mode"), self.toggleMoveMode))
50 if not inBouquetRootList:
52 menu.append((_("enable bouquet edit"), self.bouquetMarkStart))
54 menu.append((_("enable favourite edit"), self.bouquetMarkStart))
56 menu.append((_("disable move mode"), self.toggleMoveMode))
57 elif not inBouquetRootList:
59 menu.append((_("end bouquet edit"), self.bouquetMarkEnd))
60 menu.append((_("abort bouquet edit"), self.bouquetMarkAbort))
62 menu.append((_("end favourites edit"), self.bouquetMarkEnd))
63 menu.append((_("abort favourites edit"), self.bouquetMarkAbort))
65 menu.append((_("back"), self.close))
67 FixedMenu.__init__(self, session, _("Channel Selection"), menu)
68 self.skinName = "Menu"
70 def addServiceToBouquetSelected(self):
72 serviceHandler = eServiceCenter.getInstance()
73 list = serviceHandler.list(self.csel.bouquet_root)
79 if ((s.flags & eServiceReference.flagDirectory) == eServiceReference.flagDirectory):
80 info = serviceHandler.info(s)
82 bouquets.append((info.getName(s), s))
84 if cnt > 1: # show bouquet list
85 self.session.open(BouquetSelector, bouquets, self)
86 elif cnt == 1: # add to only one existing bouquet
87 self.addCurrentServiceToBouquet(bouquet[0][1])
88 else: #no bouquets in root.. so assume only one favourite list is used
89 self.addCurrentServiceToBouquet(self.csel.bouquet_root)
91 def addCurrentServiceToBouquet(self, dest):
92 self.csel.addCurrentServiceToBouquet(dest)
95 def removeCurrentService(self):
96 self.csel.removeCurrentService()
99 def toggleMoveMode(self):
100 self.csel.toggleMoveMode()
103 def bouquetMarkStart(self):
104 self.csel.startMarkedEdit()
107 def bouquetMarkEnd(self):
108 self.csel.endMarkedEdit(abort=False)
111 def bouquetMarkAbort(self):
112 self.csel.endMarkedEdit(abort=True)
115 class ChannelSelectionEdit:
117 self.entry_marked = False
118 self.movemode = False
119 self.bouquet_mark_edit = False
120 self.mutableList = None
122 self.saved_title = None
123 self.saved_root = None
125 def getMutableList(self, root=eServiceReference()):
126 if not self.mutableList is None:
127 return self.mutableList
128 serviceHandler = eServiceCenter.getInstance()
130 root=self.servicelist.getRoot()
131 list = serviceHandler.list(root)
133 return list.startEdit()
136 # multiple marked entry stuff ( edit mode, later multiepg selection )
137 def startMarkedEdit(self):
138 self.mutableList = self.getMutableList()
139 # add all services from the current list to internal marked set in listboxservicecontent
140 self.bouquetRoot = self.servicelist.getRoot()
141 self.clearMarks() # this clears the internal marked set in the listboxservicecontent
142 self.saved_title = self.instance.getTitle()
143 new_title = self.saved_title
144 if self.bouquet_root.getPath().find('FROM BOUQUET "bouquets.') != -1:
145 new_title += ' ' + _("[bouquet edit]")
147 new_title += ' ' + _("[favourite edit]")
148 self.instance.setTitle(new_title)
149 self.bouquet_mark_edit = True
150 self.__marked = self.servicelist.getRootServices()
151 for x in self.__marked:
152 self.servicelist.addMarked(eServiceReference(x))
153 self.saved_root = self.getRoot()
154 self.showAllServices()
156 def endMarkedEdit(self, abort):
157 if not abort and self.mutableList is not None:
158 new_marked = set(self.servicelist.getMarked())
159 old_marked = set(self.__marked)
160 removed = old_marked - new_marked
161 added = new_marked - old_marked
165 self.mutableList.removeService(eServiceReference(x))
168 self.mutableList.addService(eServiceReference(x))
170 self.mutableList.flushChanges()
173 self.bouquet_mark_edit = False
174 self.bouquetRoot = None
175 self.mutableList = None
176 self.instance.setTitle(self.saved_title)
177 self.saved_title = None
178 self.setRoot(self.saved_root)
180 def clearMarks(self):
181 self.servicelist.clearMarks()
184 ref = self.servicelist.getCurrent()
185 if self.servicelist.isMarked(ref):
186 self.servicelist.removeMarked(ref)
188 self.servicelist.addMarked(ref)
190 def removeCurrentService(self):
191 ref = self.servicelist.getCurrent()
192 mutableList = self.getMutableList()
193 if ref.valid() and mutableList is not None:
194 if not mutableList.removeService(ref):
195 currentIndex = self.servicelist.getCurrentIndex()
196 self.servicelist.moveDown()
197 if self.servicelist.getCurrentIndex() == currentIndex:
199 mutableList.flushChanges() #FIXME dont flush on each single removed service
200 self.setRoot(self.servicelist.getRoot())
201 self.servicelist.moveToIndex(currentIndex)
203 def addCurrentServiceToBouquet(self, dest):
204 mutableList = self.getMutableList(dest)
205 if not mutableList is None:
206 if not mutableList.addService(self.servicelist.getCurrent()):
207 mutableList.flushChanges()
210 def toggleMoveMode(self):
212 if self.entry_marked:
213 self.toggleMoveMarked() # unmark current entry
214 self.movemode = False
215 self.mutableList.flushChanges() # FIXME add check if changes was made
216 self.mutableList = None
217 self.instance.setTitle(self.saved_title)
218 self.saved_title = None
220 self.mutableList = self.getMutableList()
222 self.saved_title = self.instance.getTitle()
223 new_title = self.saved_title
224 new_title += ' ' + _("[move mode]");
225 self.instance.setTitle(new_title);
227 def handleEditCancel(self):
228 if self.movemode: #movemode active?
229 self.channelSelected() # unmark
230 self.toggleMoveMode() # disable move mode
231 elif self.bouquet_mark_edit:
232 self.endMarkedEdit(True) # abort edit mode
234 def toggleMoveMarked(self):
235 if self.entry_marked:
236 self.servicelist.setCurrentMarked(False)
237 self.entry_marked = False
239 self.servicelist.setCurrentMarked(True)
240 self.entry_marked = True
243 self.session.open(ChannelContextMenu, self)
245 class ChannelSelectionBase(Screen):
246 def __init__(self, session):
247 Screen.__init__(self, session)
249 # this makes it much simple to implement a selectable radio or tv mode :)
250 self.service_types_tv = '1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17)'
251 self.service_types_radio = '1:7:1:0:0:0:0:0:0:0:(type == 2)'
253 self.service_types = self.service_types_tv
255 #self.bouquet_root = eServiceReference('1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET "bouquets.tv" ORDER BY bouquet')
256 self.bouquet_root = eServiceReference('%s FROM BOUQUET "userbouquet.favourites.tv" ORDER BY bouquet'%(self.service_types))
258 self["key_red"] = Button(_("All"))
259 self["key_green"] = Button(_("Satellites"))
260 self["key_yellow"] = Button(_("Provider"))
261 self["key_blue"] = Button(_("Favourites"))
263 self["list"] = ServiceList()
264 self.servicelist = self["list"]
266 #self["okbutton"] = Button("ok", [self.channelSelected])
268 self.numericalTextInput = NumericalTextInput()
270 def getBouquetNumOffset(self, bouquet):
271 if self.bouquet_root.getPath().find('FROM BOUQUET "bouquets.') == -1: #FIXME HACK
274 serviceHandler = eServiceCenter.getInstance()
275 bouquetlist = serviceHandler.list(self.bouquet_root)
276 if not bouquetlist is None:
278 bouquetIterator = bouquetlist.getNext()
279 if not bouquetIterator.valid() or bouquetIterator == bouquet: #end of list or bouquet found
281 if ((bouquetIterator.flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory):
283 servicelist = serviceHandler.list(bouquetIterator)
284 if not servicelist is None:
286 serviceIterator = servicelist.getNext()
287 if not serviceIterator.valid(): #check if end of list
289 if serviceIterator.flags: #playable services have no flags
294 def setRootBase(self, root, justSet=False):
295 inBouquetRootList = root.getPath().find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
296 if not inBouquetRootList and (root.getPath().find('FROM BOUQUET') != -1):
297 self.servicelist.setMode(ServiceList.MODE_FAVOURITES)
298 self.servicelist.setNumberOffset(self.getBouquetNumOffset(root))
300 self.servicelist.setMode(ServiceList.MODE_NORMAL)
301 self.servicelist.setRoot(root, justSet)
304 self.servicelist.moveUp()
307 self.servicelist.moveDown()
309 def showAllServices(self):
310 ref = eServiceReference('%s ORDER BY name'%(self.service_types))
313 def showSatellites(self):
314 ref = eServiceReference('%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types))
315 self.setRoot(ref, True)
316 serviceHandler = eServiceCenter.getInstance()
317 servicelist = serviceHandler.list(ref)
318 if not servicelist is None:
320 service = servicelist.getNext()
321 if not service.valid(): #check if end of list
323 orbpos = service.getData(4) >> 16
324 if service.getPath().find("FROM PROVIDER") != -1:
325 service_name = _("Providers")
327 service_name = _("Services")
329 service_name += str(' - %s'%(nimmanager.getSatDescription(orbpos)))
330 service.setName(service_name) # why we need this cast?
332 if orbpos > 1800: # west
333 service.setName("%s (%3.1f" + _("W") + ")" %(str, (0 - (orbpos - 3600)) / 10.0))
335 service.setName("%s (%3.1f" + _("E") + ")" % (str, orbpos / 10.0))
336 self.servicelist.addService(service)
337 self.servicelist.finishFill()
339 def showProviders(self):
340 ref = eServiceReference('%s FROM PROVIDERS ORDER BY name'%(self.service_types))
343 def showFavourites(self):
344 self.setRoot(self.bouquet_root)
346 def keyNumberGlobal(self, number):
347 char = self.numericalTextInput.getKey(number)
348 print "You pressed number " + str(number)
349 print "You would go to character " + str(char)
350 self.servicelist.moveToChar(char)
352 def enterBouquet(self, action):
353 if action[:7] == "bouquet":
354 if action.find("FROM BOUQUET") != -1:
355 self.setRoot(eServiceReference("1:7:1:0:0:0:0:0:0:0:" + action[8:]))
357 self.setRoot(eServiceReference("1:0:1:0:0:0:0:0:0:0:" + action[8:]))
362 return self.servicelist.getRoot()
364 def getCurrentSelection(self):
365 return self.servicelist.getCurrent()
367 def setCurrentSelection(self, service):
368 self.servicelist.setCurrent(service)
373 class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit):
374 def __init__(self, session):
375 ChannelSelectionBase.__init__(self,session)
376 ChannelSelectionEdit.__init__(self)
378 #config for lastservice
379 config.tv = ConfigSubsection();
380 config.tv.lastservice = configElement("config.tv.lastservice", configText, "", 0);
381 config.tv.lastroot = configElement("config.tv.lastroot", configText, "", 0);
383 class ChannelActionMap(NumberActionMap):
384 def action(self, contexts, action):
385 if not self.csel.enterBouquet(action):
386 if action == "cancel":
387 self.csel.handleEditCancel()
388 NumberActionMap.action(self, contexts, action)
389 self["actions"] = ChannelActionMap(["ChannelSelectActions", "OkCancelActions", "ContextMenuActions"],
391 "cancel": self.cancel,
392 "ok": self.channelSelected,
394 "contextMenu": self.doContext,
395 "showFavourites": self.showFavourites,
396 "showAllServices": self.showAllServices,
397 "showProviders": self.showProviders,
398 "showSatellites": self.showSatellites,
399 "showEPGList": self.showEPGList,
400 "1": self.keyNumberGlobal,
401 "2": self.keyNumberGlobal,
402 "3": self.keyNumberGlobal,
403 "4": self.keyNumberGlobal,
404 "5": self.keyNumberGlobal,
405 "6": self.keyNumberGlobal,
406 "7": self.keyNumberGlobal,
407 "8": self.keyNumberGlobal,
408 "9": self.keyNumberGlobal,
409 "0": self.keyNumberGlobal
411 self["actions"].csel = self
412 self.onShown.append(self.onShow)
414 # self.onLayoutFinish.append(self.onCreate)
415 self.lastChannelRootTimer = eTimer()
416 self.lastChannelRootTimer.timeout.get().append(self.onCreate)
417 self.lastChannelRootTimer.start(100,True)
420 lastroot=eServiceReference(config.tv.lastroot.value)
422 self.setRoot(lastroot)
424 self.showFavourites()
425 self.saveRoot(self.getRoot())
426 lastservice=eServiceReference(config.tv.lastservice.value)
427 if lastservice.valid():
428 self.session.nav.playService(lastservice)
429 self.servicelist.setCurrent(lastservice)
432 ref = self.session.nav.getCurrentlyPlayingServiceReference()
433 if ref is not None and ref.valid() and ref.getPath() == "":
434 self.servicelist.setPlayableIgnoreService(ref)
436 self.servicelist.setPlayableIgnoreService(eServiceReference())
438 def showEPGList(self):
439 ref=self.getCurrentSelection()
440 ptr=eEPGCache.getInstance()
441 if ptr.startTimeQuery(ref) != -1:
442 self.session.open(EPGSelection, ref)
444 print 'no epg for service', ref.toString()
446 def channelSelected(self):
447 ref = self.getCurrentSelection()
449 self.toggleMoveMarked()
450 elif (ref.flags & 7) == 7:
452 elif self.bouquet_mark_edit:
458 def setRoot(self, root, justSet=False):
459 if not self.movemode:
460 self.setRootBase(root, justSet)
462 #called from infoBar and channelSelected
464 self.session.nav.playService(self.getCurrentSelection())
465 self.saveRoot(self.getRoot())
468 def saveRoot(self, root):
470 config.tv.lastroot.value = root.toString()
471 config.tv.lastroot.save()
473 def saveChannel(self):
474 ref = self.session.nav.getCurrentlyPlayingServiceReference()
476 refstr = ref.toString()
479 config.tv.lastservice.value = refstr
480 config.tv.lastservice.save()
484 lastroot=eServiceReference(config.tv.lastroot.value)
485 lastservice=eServiceReference(config.tv.lastservice.value)
486 if lastroot.valid() and self.getRoot() != lastroot:
487 self.setRoot(lastroot)
488 if lastservice.valid() and self.getCurrentSelection() != lastservice:
489 self.servicelist.setCurrent(lastservice)
491 class SimpleChannelSelection(ChannelSelectionBase):
492 def __init__(self, session, title):
493 ChannelSelectionBase.__init__(self, session)
495 self.onShown.append(self.onExecCallback)
497 class ChannelActionMap(NumberActionMap):
498 def action(self, contexts, action):
499 if not self.csel.enterBouquet(action):
500 NumberActionMap.action(self, contexts, action)
501 self["actions"] = ChannelActionMap(["ChannelSelectActions", "OkCancelActions", "ContextMenuActions"],
503 "cancel": self.cancel,
504 "ok": self.channelSelected,
505 "showFavourites": self.showFavourites,
506 "showAllServices": self.showAllServices,
507 "showProviders": self.showProviders,
508 "showSatellites": self.showSatellites,
509 "1": self.keyNumberGlobal,
510 "2": self.keyNumberGlobal,
511 "3": self.keyNumberGlobal,
512 "4": self.keyNumberGlobal,
513 "5": self.keyNumberGlobal,
514 "6": self.keyNumberGlobal,
515 "7": self.keyNumberGlobal,
516 "8": self.keyNumberGlobal,
517 "9": self.keyNumberGlobal,
518 "0": self.keyNumberGlobal
520 self["actions"].csel = self
522 def onExecCallback(self):
523 print "onExecCallback"
524 self.showFavourites()
525 self.session.currentDialog.instance.setTitle(self.title)
527 def channelSelected(self): # just return selected service
528 ref = self.getCurrentSelection()
531 def setRoot(self, root):
532 self.setRootBase(root)