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
11 import xml.dom.minidom
13 class BouquetSelector(FixedMenu):
14 def __init__(self, session, bouquets, parent):
18 entrys.append((x[0], self.bouquetSelected, x[1]))
19 FixedMenu.__init__(self, session, "Bouquetlist", entrys)
20 self.skinName = "Menu"
22 def bouquetSelected(self):
23 self.parent.addCurrentServiceToBouquet(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().type & 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):
71 serviceHandler = eServiceCenter.getInstance()
72 list = serviceHandler.list(self.csel.bouquet_root)
78 if ((s.flags & eServiceReference.flagDirectory) == eServiceReference.flagDirectory):
79 info = serviceHandler.info(s)
81 bouquets.append((info.getName(s), s))
83 if cnt > 1: # show bouquet list
84 self.session.open(BouquetSelector, bouquets, self)
85 elif cnt == 1: # add to only one existing bouquet
86 self.addCurrentServiceToBouquet(bouquet[0][1])
87 else: #no bouquets in root.. so assume only one favourite list is used
88 self.addCurrentServiceToBouquet(self.csel.bouquet_root)
90 def addCurrentServiceToBouquet(self, dest):
91 self.csel.addCurrentServiceToBouquet(dest)
94 def removeCurrentService(self):
95 self.csel.removeCurrentService()
98 def toggleMoveMode(self):
99 self.csel.toggleMoveMode()
102 def bouquetMarkStart(self):
103 self.csel.startMarkedEdit()
106 def bouquetMarkEnd(self):
107 self.csel.endMarkedEdit(abort=False)
110 def bouquetMarkAbort(self):
111 self.csel.endMarkedEdit(abort=True)
114 class ChannelSelectionEdit:
116 self.entry_marked = False
117 self.movemode = False
118 self.bouquet_mark_edit = False
119 self.mutableList = None
121 self.saved_title = None
122 self.saved_root = None
124 def getMutableList(self, root=eServiceReference()):
125 if not self.mutableList is None:
126 return self.mutableList
127 serviceHandler = eServiceCenter.getInstance()
129 root=self.servicelist.getRoot()
130 list = serviceHandler.list(root)
132 return list.startEdit()
135 # multiple marked entry stuff ( edit mode, later multiepg selection )
136 def startMarkedEdit(self):
137 self.mutableList = self.getMutableList()
138 # add all services from the current list to internal marked set in listboxservicecontent
139 self.bouquetRoot = self.servicelist.getRoot()
140 self.clearMarks() # this clears the internal marked set in the listboxservicecontent
141 self.saved_title = self.instance.getTitle()
142 new_title = self.saved_title
143 if self.bouquet_root.getPath().find('FROM BOUQUET "bouquets.') != -1:
144 new_title += ' ' + _("[bouquet edit]")
146 new_title += ' ' + _("[favourite edit]")
147 self.instance.setTitle(new_title)
148 self.bouquet_mark_edit = True
149 self.__marked = self.servicelist.getRootServices()
150 for x in self.__marked:
151 self.servicelist.addMarked(eServiceReference(x))
152 self.saved_root = self.getRoot()
153 self.showAllServices()
155 def endMarkedEdit(self, abort):
156 if not abort and self.mutableList is not None:
157 new_marked = set(self.servicelist.getMarked())
158 old_marked = set(self.__marked)
159 removed = old_marked - new_marked
160 added = new_marked - old_marked
164 self.mutableList.removeService(eServiceReference(x))
167 self.mutableList.addService(eServiceReference(x))
169 self.mutableList.flushChanges()
172 self.bouquet_mark_edit = False
173 self.bouquetRoot = None
174 self.mutableList = None
175 self.instance.setTitle(self.saved_title)
176 self.saved_title = None
177 self.setRoot(self.saved_root)
179 def clearMarks(self):
180 self.servicelist.clearMarks()
183 ref = self.servicelist.getCurrent()
184 if self.servicelist.isMarked(ref):
185 self.servicelist.removeMarked(ref)
187 self.servicelist.addMarked(ref)
189 def removeCurrentService(self):
190 ref = self.servicelist.getCurrent()
191 mutableList = self.getMutableList()
192 if ref.valid() and mutableList is not None:
193 if not mutableList.removeService(ref):
194 currentIndex = self.servicelist.getCurrentIndex()
195 self.servicelist.moveDown()
196 if self.servicelist.getCurrentIndex() == currentIndex:
198 mutableList.flushChanges() #FIXME dont flush on each single removed service
199 self.setRoot(self.servicelist.getRoot())
200 self.servicelist.moveToIndex(currentIndex)
202 def addCurrentServiceToBouquet(self, dest):
203 mutableList = self.getMutableList(dest)
204 if not mutableList is None:
205 if not mutableList.addService(self.servicelist.getCurrent()):
206 mutableList.flushChanges()
209 def toggleMoveMode(self):
211 if self.entry_marked:
212 self.toggleMoveMarked() # unmark current entry
213 self.movemode = False
214 self.mutableList.flushChanges() # FIXME add check if changes was made
215 self.mutableList = None
216 self.instance.setTitle(self.saved_title)
217 self.saved_title = None
219 self.mutableList = self.getMutableList()
221 self.saved_title = self.instance.getTitle()
222 new_title = self.saved_title
223 new_title += ' ' + _("[move mode]");
224 self.instance.setTitle(new_title);
226 def handleEditCancel(self):
227 if self.movemode: #movemode active?
228 self.channelSelected() # unmark
229 self.toggleMoveMode() # disable move mode
230 elif self.bouquet_mark_edit:
231 self.endMarkedEdit(True) # abort edit mode
233 def toggleMoveMarked(self):
234 if self.entry_marked:
235 self.servicelist.setCurrentMarked(False)
236 self.entry_marked = False
238 self.servicelist.setCurrentMarked(True)
239 self.entry_marked = True
242 self.session.open(ChannelContextMenu, self)
244 class ChannelSelectionBase(Screen):
245 def __init__(self, session):
246 Screen.__init__(self, session)
248 # this makes it much simple to implement a selectable radio or tv mode :)
249 self.service_types_tv = '1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17)'
250 self.service_types_radio = '1:7:1:0:0:0:0:0:0:0:(type == 2)'
252 self.service_types = self.service_types_tv
254 #self.bouquet_root = eServiceReference('1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET "bouquets.tv" ORDER BY bouquet')
255 self.bouquet_root = eServiceReference('%s FROM BOUQUET "userbouquet.favourites.tv" ORDER BY bouquet'%(self.service_types))
257 self["key_red"] = Button(_("All"))
258 self["key_green"] = Button(_("Satellites"))
259 self["key_yellow"] = Button(_("Provider"))
260 self["key_blue"] = Button(_("Favourites"))
262 self["list"] = ServiceList()
263 self.servicelist = self["list"]
265 #self["okbutton"] = Button("ok", [self.channelSelected])
267 self.numericalTextInput = NumericalTextInput()
269 def getBouquetNumOffset(self, bouquet):
270 if self.bouquet_root.getPath().find('FROM BOUQUET "bouquets.') == -1: #FIXME HACK
273 serviceHandler = eServiceCenter.getInstance()
274 bouquetlist = serviceHandler.list(self.bouquet_root)
275 if not bouquetlist is None:
277 bouquetIterator = bouquetlist.getNext()
278 if not bouquetIterator.valid() or bouquetIterator == bouquet: #end of list or bouquet found
280 if ((bouquetIterator.flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory):
282 servicelist = serviceHandler.list(bouquetIterator)
283 if not servicelist is None:
285 serviceIterator = servicelist.getNext()
286 if not serviceIterator.valid(): #check if end of list
288 if serviceIterator.flags: #playable services have no flags
293 def setRootBase(self, root):
294 inBouquetRootList = root.getPath().find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
295 if not inBouquetRootList and (root.getPath().find('FROM BOUQUET') != -1):
296 self.servicelist.setMode(ServiceList.MODE_FAVOURITES)
297 self.servicelist.setNumberOffset(self.getBouquetNumOffset(root))
299 self.servicelist.setMode(ServiceList.MODE_NORMAL)
300 self.servicelist.setRoot(root)
303 self.servicelist.moveUp()
306 self.servicelist.moveDown()
308 def showAllServices(self):
309 ref = eServiceReference('%s ORDER BY name'%(self.service_types))
312 def showSatellites(self):
313 ref = eServiceReference('%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types))
316 def showProviders(self):
317 ref = eServiceReference('%s FROM PROVIDERS ORDER BY name'%(self.service_types))
320 def showFavourites(self):
321 self.setRoot(self.bouquet_root)
323 def keyNumberGlobal(self, number):
324 char = self.numericalTextInput.getKey(number)
325 print "You pressed number " + str(number)
326 print "You would go to character " + str(char)
327 self.servicelist.moveToChar(char)
329 def enterBouquet(self, action):
330 if action[:7] == "bouquet":
331 if action.find("FROM BOUQUET") != -1:
332 self.setRoot(eServiceReference("1:7:1:0:0:0:0:0:0:0:" + action[8:]))
334 self.setRoot(eServiceReference("1:0:1:0:0:0:0:0:0:0:" + action[8:]))
339 return self.servicelist.getRoot()
341 def getCurrentSelection(self):
342 return self.servicelist.getCurrent()
344 def setCurrentSelection(self, service):
345 self.servicelist.setCurrent(service)
350 class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit):
351 def __init__(self, session):
352 ChannelSelectionBase.__init__(self,session)
353 ChannelSelectionEdit.__init__(self)
355 #config for lastservice
356 config.tv = ConfigSubsection();
357 config.tv.lastservice = configElement("config.tv.lastservice", configText, "", 0);
358 config.tv.lastroot = configElement("config.tv.lastroot", configText, "", 0);
360 class ChannelActionMap(NumberActionMap):
361 def action(self, contexts, action):
362 if not self.csel.enterBouquet(action):
363 if action == "cancel":
364 self.csel.handleEditCancel()
365 NumberActionMap.action(self, contexts, action)
366 self["actions"] = ChannelActionMap(["ChannelSelectActions", "OkCancelActions", "ContextMenuActions"],
368 "cancel": self.cancel,
369 "ok": self.channelSelected,
371 "contextMenu": self.doContext,
372 "showFavourites": self.showFavourites,
373 "showAllServices": self.showAllServices,
374 "showProviders": self.showProviders,
375 "showSatellites": self.showSatellites,
376 "showEPGList": self.showEPGList,
377 "1": self.keyNumberGlobal,
378 "2": self.keyNumberGlobal,
379 "3": self.keyNumberGlobal,
380 "4": self.keyNumberGlobal,
381 "5": self.keyNumberGlobal,
382 "6": self.keyNumberGlobal,
383 "7": self.keyNumberGlobal,
384 "8": self.keyNumberGlobal,
385 "9": self.keyNumberGlobal,
386 "0": self.keyNumberGlobal
388 self["actions"].csel = self
389 self.onShown.append(self.onShow)
391 # self.onLayoutFinish.append(self.onCreate)
392 self.lastChannelRootTimer = eTimer()
393 self.lastChannelRootTimer.timeout.get().append(self.onCreate)
394 self.lastChannelRootTimer.start(100,True)
397 lastroot=eServiceReference(config.tv.lastroot.value)
399 self.setRoot(lastroot)
401 self.showFavourites()
402 self.saveRoot(self.getRoot())
403 lastservice=eServiceReference(config.tv.lastservice.value)
404 if lastservice.valid():
405 self.session.nav.playService(lastservice)
406 self.servicelist.setCurrent(lastservice)
409 ref = self.session.nav.getCurrentlyPlayingServiceReference()
410 if ref is not None and ref.valid() and ref.getPath() == "":
411 self.servicelist.setPlayableIgnoreService(ref)
413 self.servicelist.setPlayableIgnoreService(eServiceReference())
415 def showEPGList(self):
416 ref=self.getCurrentSelection()
417 ptr=eEPGCache.getInstance()
418 if ptr.startTimeQuery(ref) != -1:
419 self.session.open(EPGSelection, ref)
421 print 'no epg for service', ref.toString()
423 def channelSelected(self):
424 ref = self.getCurrentSelection()
426 self.toggleMoveMarked()
427 elif (ref.flags & 7) == 7:
429 elif self.bouquet_mark_edit:
435 def setRoot(self, root):
436 if not self.movemode:
437 self.setRootBase(root)
439 #called from infoBar and channelSelected
441 self.session.nav.playService(self.getCurrentSelection())
442 self.saveRoot(self.getRoot())
445 def saveRoot(self, root):
447 config.tv.lastroot.value = root.toString()
448 config.tv.lastroot.save()
450 def saveChannel(self):
451 ref = self.session.nav.getCurrentlyPlayingServiceReference()
453 refstr = ref.toString()
456 config.tv.lastservice.value = refstr
457 config.tv.lastservice.save()
461 lastroot=eServiceReference(config.tv.lastroot.value)
462 lastservice=eServiceReference(config.tv.lastservice.value)
463 if lastroot.valid() and self.getRoot() != lastroot:
464 self.setRoot(lastroot)
465 if lastservice.valid() and self.getCurrentSelection() != lastservice:
466 self.servicelist.setCurrent(lastservice)
468 class SimpleChannelSelection(ChannelSelectionBase):
469 def __init__(self, session, title):
470 ChannelSelectionBase.__init__(self, session)
472 self.onShown.append(self.onExecCallback)
474 class ChannelActionMap(NumberActionMap):
475 def action(self, contexts, action):
476 if not self.csel.enterBouquet(action):
477 NumberActionMap.action(self, contexts, action)
478 self["actions"] = ChannelActionMap(["ChannelSelectActions", "OkCancelActions", "ContextMenuActions"],
480 "cancel": self.cancel,
481 "ok": self.channelSelected,
482 "showFavourites": self.showFavourites,
483 "showAllServices": self.showAllServices,
484 "showProviders": self.showProviders,
485 "showSatellites": self.showSatellites,
486 "1": self.keyNumberGlobal,
487 "2": self.keyNumberGlobal,
488 "3": self.keyNumberGlobal,
489 "4": self.keyNumberGlobal,
490 "5": self.keyNumberGlobal,
491 "6": self.keyNumberGlobal,
492 "7": self.keyNumberGlobal,
493 "8": self.keyNumberGlobal,
494 "9": self.keyNumberGlobal,
495 "0": self.keyNumberGlobal
497 self["actions"].csel = self
499 def onExecCallback(self):
500 print "onExecCallback"
501 self.showFavourites()
502 self.session.currentDialog.instance.setTitle(self.title)
504 def channelSelected(self): # just return selected service
505 ref = self.getCurrentSelection()
508 def setRoot(self, root):
509 self.setRootBase(root)