fix no more working multi epg since previous BouquetSelector change
[vuplus_dvbapp] / lib / python / Screens / ChannelSelection.py
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, eEPGCachePtr, eServiceCenter, eServiceCenterPtr, iMutableServiceListPtr, iStaticServiceInformationPtr, eTimer, eDVBDB
8 from Components.config import config, configElement, ConfigSubsection, configText, currentConfigSelectionElement
9 from Screens.FixedMenu import FixedMenu
10 from Tools.NumericalTextInput import NumericalTextInput
11 from Components.NimManager import nimmanager
12 from Components.ServiceName import ServiceName
13 from Components.Clock import Clock
14 from Components.EventInfo import EventInfo
15 from ServiceReference import ServiceReference
16 from re import *
17 from os import remove
18
19 import xml.dom.minidom
20
21 class BouquetSelector(Screen):
22         def __init__(self, session, bouquets, selectedFunc):
23                 Screen.__init__(self, session)
24
25                 self.selectedFunc=selectedFunc
26
27                 self["actions"] = ActionMap(["OkCancelActions"],
28                         {
29                                 "ok": self.okbuttonClick,
30                                 "cancel": self.cancelClick
31                         })
32                 entrys = [ ]
33                 for x in bouquets:
34                         entrys.append((x[0], x[1]))
35                 self["menu"] = MenuList(entrys)
36
37         def okbuttonClick(self):
38                 self.selectedFunc(self["menu"].getCurrent()[1])
39
40         def cancelClick(self):
41                 self.close(False)
42
43 class ChannelContextMenu(Screen):
44         def __init__(self, session, csel):
45                 Screen.__init__(self, session)
46                 self.csel = csel
47
48                 self["actions"] = ActionMap(["OkCancelActions"],
49                         {
50                                 "ok": self.okbuttonClick,
51                                 "cancel": self.cancelClick
52                         })
53                 menu = [ ]
54
55                 inBouquetRootList = csel.getRoot().getPath().find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
56                 inBouquet = csel.getMutableList() is not None
57                 haveBouquets = csel.bouquet_root.getPath().find('FROM BOUQUET "bouquets.') != -1
58
59                 if not csel.bouquet_mark_edit and not csel.movemode:
60                         if not inBouquetRootList:
61                                 if (csel.getCurrentSelection().flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory:
62                                         if haveBouquets:
63                                                 menu.append((_("add service to bouquet"), self.addServiceToBouquetSelected))
64                                         else:
65                                                 menu.append((_("add service to favourites"), self.addServiceToBouquetSelected))
66                                 elif haveBouquets:
67                                         if not inBouquet and csel.getCurrentSelection().getPath().find("PROVIDERS") == -1:
68                                                 menu.append((_("copy to favourites"), csel.copyCurrentToBouquetList))
69                                 if inBouquet:
70                                         menu.append((_("remove service"), self.removeCurrentService))
71                         elif haveBouquets:
72                                 menu.append((_("remove bouquet"), csel.removeBouquet))
73
74                 if inBouquet: # current list is editable?
75                         if not csel.bouquet_mark_edit:
76                                 if not csel.movemode:
77                                         menu.append((_("enable move mode"), self.toggleMoveMode))
78                                         if not inBouquetRootList:
79                                                 if haveBouquets:
80                                                         menu.append((_("enable bouquet edit"), self.bouquetMarkStart))
81                                                 else:
82                                                         menu.append((_("enable favourite edit"), self.bouquetMarkStart))
83                                 else:
84                                         menu.append((_("disable move mode"), self.toggleMoveMode))
85                         elif not inBouquetRootList:
86                                 if haveBouquets:
87                                         menu.append((_("end bouquet edit"), self.bouquetMarkEnd))
88                                         menu.append((_("abort bouquet edit"), self.bouquetMarkAbort))
89                                 else:
90                                         menu.append((_("end favourites edit"), self.bouquetMarkEnd))
91                                         menu.append((_("abort favourites edit"), self.bouquetMarkAbort))
92
93                 menu.append((_("back"), self.cancelClick))
94                 self["menu"] = MenuList(menu)
95
96         def okbuttonClick(self):
97                 self["menu"].getCurrent()[1]()
98
99         def cancelClick(self):
100                 self.close(False)
101
102         def addServiceToBouquetSelected(self):
103                 bouquets = self.csel.getBouquetList()
104                 if bouquets is None:
105                         cnt = 0
106                 else:
107                         cnt = len(bouquets)
108                 if cnt > 1: # show bouquet list
109                         self.session.openWithCallback(self.bouquetSelClosed, BouquetSelector, bouquets, self.bouquetSelected)
110                 elif cnt == 1: # add to only one existing bouquet
111                         self.addCurrentServiceToBouquet(bouquets[0][1])
112                 else: #no bouquets in root.. so assume only one favourite list is used
113                         self.addCurrentServiceToBouquet(self.csel.bouquet_root)
114
115         def bouquetSelected(self, bouquet):
116                 self.addCurrentServiceToBouquet(bouquet)
117                 self.close(True) # close bouquet selection
118
119         def bouquetSelClosed(self, recursive):
120                 if recursive:
121                         self.close(False)
122
123         def copyCurrentToBouquetList(self):
124                 self.csel.copyCurrentToBouquetList()
125                 self.close()
126
127         def removeBouquet(self):
128                 self.csel.removeBouquet()
129                 self.close()
130
131         def addCurrentServiceToBouquet(self, dest):
132                 self.csel.addCurrentServiceToBouquet(dest)
133
134         def removeCurrentService(self):
135                 self.csel.removeCurrentService()
136                 self.close()
137
138         def toggleMoveMode(self):
139                 self.csel.toggleMoveMode()
140                 self.close()
141
142         def bouquetMarkStart(self):
143                 self.csel.startMarkedEdit()
144                 self.close()
145
146         def bouquetMarkEnd(self):
147                 self.csel.endMarkedEdit(abort=False)
148                 self.close()
149
150         def bouquetMarkAbort(self):
151                 self.csel.endMarkedEdit(abort=True)
152                 self.close()
153
154 class ChannelSelectionEPG:
155         def __init__(self):
156                 self["ChannelSelectEPGActions"] = ActionMap(["ChannelSelectEPGActions"],
157                         {
158                                 "showEPGList": self.showEPGList,
159                         })
160
161         def showEPGList(self):
162                 ref=self.getCurrentSelection()
163                 ptr=eEPGCache.getInstance()
164                 if ptr.startTimeQuery(ref) != -1:
165                         self.session.open(EPGSelection, ref)
166                 else:
167                         print 'no epg for service', ref.toString()
168
169 class ChannelSelectionEdit:
170         def __init__(self):
171                 self.entry_marked = False
172                 self.movemode = False
173                 self.bouquet_mark_edit = False
174                 self.mutableList = None
175                 self.__marked = [ ]
176                 self.saved_title = None
177                 self.saved_root = None
178
179                 class ChannelSelectionEditActionMap(ActionMap):
180                         def __init__(self, csel, contexts = [ ], actions = { }, prio=0):
181                                 ActionMap.__init__(self, contexts, actions, prio)
182                                 self.csel = csel
183                         def action(self, contexts, action):
184                                 if action == "cancel":
185                                         self.csel.handleEditCancel()
186                                 elif action == "ok":
187                                         pass # avoid typo warning...
188                                 else:
189                                         ActionMap.action(self, contexts, action)
190                 self["ChannelSelectEditActions"] = ChannelSelectionEditActionMap(self, ["ChannelSelectEditActions", "OkCancelActions"],
191                         {
192                                 "contextMenu": self.doContext,
193                         })
194
195         def getMutableList(self, root=eServiceReference()):
196                 if not self.mutableList is None:
197                         return self.mutableList
198                 serviceHandler = eServiceCenter.getInstance()
199                 if not root.valid():
200                         root=self.getRoot()
201                 list = serviceHandler.list(root)
202                 if list is not None:
203                         return list.startEdit()
204                 return None
205
206         def buildBouquetID(self, str):
207                 tmp = str.lower()
208                 name = ''
209                 for c in tmp:
210                         if (c >= 'a' and c <= 'z') or (c >= '0' and c <= '9'):
211                                 name += c
212                         else:
213                                 name += '_'
214                 return name
215
216         def copyCurrentToBouquetList(self):
217                 provider = ServiceReference(self.getCurrentSelection())
218                 serviceHandler = eServiceCenter.getInstance()
219                 mutableBouquetList = serviceHandler.list(self.bouquet_root).startEdit()
220                 if mutableBouquetList:
221                         providerName = provider.getServiceName()
222                         if self.mode == MODE_TV:
223                                 str = '1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET \"userbouquet.%s.tv\" ORDER BY bouquet'%(self.buildBouquetID(providerName))
224                         else:
225                                 str = '1:7:2:0:0:0:0:0:0:0:(type == 2) FROM BOUQUET \"userbouquet.%s.radio\" ORDER BY bouquet'%(self.buildBouquetID(providerName))
226                         new_bouquet_ref = eServiceReference(str)
227                         if not mutableBouquetList.addService(new_bouquet_ref):
228                                 mutableBouquetList.flushChanges()
229                                 eDVBDB.getInstance().reloadBouquets()
230                                 mutableBouquet = serviceHandler.list(new_bouquet_ref).startEdit()
231                                 if mutableBouquet:
232                                         mutableBouquet.setListName(providerName)
233                                         list = [ ]
234                                         services = serviceHandler.list(provider.ref)
235                                         if not services is None:
236                                                 if not services.getContent(list, True):
237                                                         for service in list:
238                                                                 if mutableBouquet.addService(service):
239                                                                         print "add", service.toString(), "to new bouquet failed"
240                                                         mutableBouquet.flushChanges()
241                                                 else:
242                                                         print "getContent failed"
243                                         else:
244                                                 print "list provider", providerName, "failed"
245                                 else:
246                                         print "get mutable list for new created bouquet failed"
247                         else:
248                                 print "add", str, "to bouquets failed"
249                 else:
250                         print "bouquetlist is not editable"
251
252         def removeBouquet(self):
253                 refstr = self.getCurrentSelection().toString()
254                 pos = refstr.find('FROM BOUQUET "')
255                 if pos != -1:
256                         refstr = refstr[pos+14:]
257                         print refstr
258                         pos = refstr.find('"')
259                         if pos != -1:
260                                 filename = '/etc/enigma2/' + refstr[:pos] # FIXMEEE !!! HARDCODED /etc/enigma2
261                 self.removeCurrentService()
262                 remove(filename)
263                 eDVBDB.getInstance().reloadBouquets()
264
265 #  multiple marked entry stuff ( edit mode, later multiepg selection )
266         def startMarkedEdit(self):
267                 self.mutableList = self.getMutableList()
268                 # add all services from the current list to internal marked set in listboxservicecontent
269                 self.bouquetRoot = self.getRoot()
270                 self.clearMarks() # this clears the internal marked set in the listboxservicecontent
271                 self.saved_title = self.instance.getTitle()
272                 new_title = self.saved_title
273                 if self.bouquet_root.getPath().find('FROM BOUQUET "bouquets.') != -1:
274                         new_title += ' ' + _("[bouquet edit]")
275                 else:
276                         new_title += ' ' + _("[favourite edit]")
277                 self.instance.setTitle(new_title)
278                 self.bouquet_mark_edit = True
279                 self.__marked = self.servicelist.getRootServices()
280                 for x in self.__marked:
281                         self.servicelist.addMarked(eServiceReference(x))
282                 self.saved_root = self.getRoot()
283                 self.showAllServices()
284
285         def endMarkedEdit(self, abort):
286                 if not abort and self.mutableList is not None:
287                         new_marked = set(self.servicelist.getMarked())
288                         old_marked = set(self.__marked)
289                         removed = old_marked - new_marked
290                         added = new_marked - old_marked
291                         changed = False
292                         for x in removed:
293                                 changed = True
294                                 self.mutableList.removeService(eServiceReference(x))
295                         for x in added:
296                                 changed = True
297                                 self.mutableList.addService(eServiceReference(x))
298                         if changed:
299                                 self.mutableList.flushChanges()
300                 self.__marked = []
301                 self.clearMarks()
302                 self.bouquet_mark_edit = False
303                 self.bouquetRoot = None
304                 self.mutableList = None
305                 self.instance.setTitle(self.saved_title)
306                 self.saved_title = None
307                 self.setRoot(self.saved_root)
308
309         def clearMarks(self):
310                 self.servicelist.clearMarks()
311
312         def doMark(self):
313                 ref = self.servicelist.getCurrent()
314                 if self.servicelist.isMarked(ref):
315                         self.servicelist.removeMarked(ref)
316                 else:
317                         self.servicelist.addMarked(ref)
318
319         def removeCurrentService(self):
320                 ref = self.servicelist.getCurrent()
321                 mutableList = self.getMutableList()
322                 if ref.valid() and mutableList is not None:
323                         if not mutableList.removeService(ref):
324                                 currentIndex = self.servicelist.getCurrentIndex()
325                                 self.servicelist.moveDown()
326                                 if self.servicelist.getCurrentIndex() == currentIndex:
327                                         currentIndex -= 1
328                                 mutableList.flushChanges() #FIXME dont flush on each single removed service
329                                 self.setRoot(self.getRoot())
330                                 self.servicelist.moveToIndex(currentIndex)
331
332         def addCurrentServiceToBouquet(self, dest):
333                 mutableList = self.getMutableList(dest)
334                 if not mutableList is None:
335                         if not mutableList.addService(self.servicelist.getCurrent()):
336                                 mutableList.flushChanges()
337                 self.close()
338
339         def toggleMoveMode(self):
340                 if self.movemode:
341                         if self.entry_marked:
342                                 self.toggleMoveMarked() # unmark current entry
343                         self.movemode = False
344                         self.pathChangedDisabled = False # re-enable path change
345                         self.mutableList.flushChanges() # FIXME add check if changes was made
346                         self.mutableList = None
347                         self.instance.setTitle(self.saved_title)
348                         self.saved_title = None
349                 else:
350                         self.mutableList = self.getMutableList()
351                         self.movemode = True
352                         self.pathChangedDisabled = True # no path change allowed in movemode
353                         self.saved_title = self.instance.getTitle()
354                         new_title = self.saved_title
355                         new_title += ' ' + _("[move mode]");
356                         self.instance.setTitle(new_title);
357
358         def handleEditCancel(self):
359                 if self.movemode: #movemode active?
360                         self.channelSelected() # unmark
361                         self.toggleMoveMode() # disable move mode
362                 elif self.bouquet_mark_edit:
363                         self.endMarkedEdit(True) # abort edit mode
364
365         def toggleMoveMarked(self):
366                 if self.entry_marked:
367                         self.servicelist.setCurrentMarked(False)
368                         self.entry_marked = False
369                 else:
370                         self.servicelist.setCurrentMarked(True)
371                         self.entry_marked = True
372
373         def doContext(self):
374                 self.session.open(ChannelContextMenu, self)
375
376 MODE_TV = 0
377 MODE_RADIO = 1
378
379 class ChannelSelectionBase(Screen):
380         def __init__(self, session):
381                 Screen.__init__(self, session)
382
383                 # this makes it much simple to implement a selectable radio or tv mode :)
384                 self.service_types_tv = '1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17)'
385                 self.service_types_radio = '1:7:2:0:0:0:0:0:0:0:(type == 2)'
386
387                 self["key_red"] = Button(_("All"))
388                 self["key_green"] = Button(_("Satellites"))
389                 self["key_yellow"] = Button(_("Provider"))
390                 self["key_blue"] = Button(_("Favourites"))
391
392                 self["list"] = ServiceList()
393                 self.servicelist = self["list"]
394
395                 self.numericalTextInput = NumericalTextInput()
396
397                 self.servicePathTV = [ ]
398                 self.servicePathRadio = [ ]
399
400                 self.pathChangedDisabled = False
401
402                 self["ChannelSelectBaseActions"] = NumberActionMap(["ChannelSelectBaseActions", "NumberActions"],
403                         {
404                                 "showFavourites": self.showFavourites,
405                                 "showAllServices": self.showAllServices,
406                                 "showProviders": self.showProviders,
407                                 "showSatellites": self.showSatellites,
408                                 "nextBouquet": self.nextBouquet,
409                                 "prevBouquet": self.prevBouquet,
410                                 "1": self.keyNumberGlobal,
411                                 "2": self.keyNumberGlobal,
412                                 "3": self.keyNumberGlobal,
413                                 "4": self.keyNumberGlobal,
414                                 "5": self.keyNumberGlobal,
415                                 "6": self.keyNumberGlobal,
416                                 "7": self.keyNumberGlobal,
417                                 "8": self.keyNumberGlobal,
418                                 "9": self.keyNumberGlobal,
419                                 "0": self.keyNumberGlobal
420                         })
421
422         def appendDVBTypes(self, ref):
423                 path = ref.getPath()
424                 pos = path.find(' FROM BOUQUET')
425                 if pos != -1:
426                         return eServiceReference(self.service_types + path[pos:])
427                 return ref
428
429         def getBouquetNumOffset(self, bouquet):
430                 bouquet = self.appendDVBTypes(bouquet)
431                 if self.bouquet_root.getPath().find('FROM BOUQUET "bouquets.') == -1: #FIXME HACK
432                         return 0
433                 offsetCount = 0
434                 serviceHandler = eServiceCenter.getInstance()
435                 bouquetlist = serviceHandler.list(self.bouquet_root)
436                 if not bouquetlist is None:
437                         while True:
438                                 bouquetIterator = self.appendDVBTypes(bouquetlist.getNext())
439                                 if not bouquetIterator.valid() or bouquetIterator == bouquet: #end of list or bouquet found
440                                         break
441                                 if ((bouquetIterator.flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory):
442                                         continue
443                                 servicelist = serviceHandler.list(bouquetIterator)
444                                 if not servicelist is None:
445                                         while True:
446                                                 serviceIterator = servicelist.getNext()
447                                                 if not serviceIterator.valid(): #check if end of list
448                                                         break
449                                                 if serviceIterator.flags: #playable services have no flags
450                                                         continue
451                                                 offsetCount += 1
452                 return offsetCount
453
454         def recallBouquetMode(self):
455                 if self.mode == MODE_TV:
456                         self.service_types = self.service_types_tv
457                         if currentConfigSelectionElement(config.usage.multibouquet) == "yes":
458                                 self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET "bouquets.tv" ORDER BY bouquet'
459                         else:
460                                 self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.tv" ORDER BY bouquet'%(self.service_types)
461                 else:
462                         self.service_types = self.service_types_radio
463                         if currentConfigSelectionElement(config.usage.multibouquet) == "yes":
464                                 self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET "bouquets.radio" ORDER BY bouquet'
465                         else:
466                                 self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.radio" ORDER BY bouquet'%(self.service_types)
467                 self.bouquet_root = eServiceReference(self.bouquet_rootstr)
468
469         def setTvMode(self):
470                 title = self.instance.getTitle()
471                 pos = title.find(" (")
472                 if pos != -1:
473                         title = title[:pos]
474                 title += " (TV)"
475                 self.instance.setTitle(title)
476                 self.mode = MODE_TV
477                 self.recallBouquetMode()
478
479         def setRadioMode(self):
480                 title = self.instance.getTitle()
481                 pos = title.find(" (")
482                 if pos != -1:
483                         title = title[:pos]
484                 title += " (Radio)"
485                 self.instance.setTitle(title)
486                 self.mode = MODE_RADIO
487                 self.recallBouquetMode()
488
489         def setRoot(self, root, justSet=False):
490                 path = root.getPath()
491                 inBouquetRootList = path.find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
492                 pos = path.find(' FROM BOUQUET')
493                 isBouquet = pos != -1
494                 if not inBouquetRootList and isBouquet:
495                         self.servicelist.setMode(ServiceList.MODE_FAVOURITES)
496                         self.servicelist.setNumberOffset(self.getBouquetNumOffset(root))
497                         refstr = self.service_types + path[pos:]
498                         root = eServiceReference(refstr)
499                 else:
500                         self.servicelist.setMode(ServiceList.MODE_NORMAL)
501                 self.servicelist.setRoot(root, justSet)
502
503         def moveUp(self):
504                 self.servicelist.moveUp()
505
506         def moveDown(self):
507                 self.servicelist.moveDown()
508
509         def clearPath(self):
510                 if self.mode == MODE_RADIO:
511                         self.servicePathRadio = [ ]
512                 else:
513                         self.servicePathTV = [ ]
514
515         def enterPath(self, ref, justSet=False):
516                 if self.mode == MODE_RADIO:
517                         self.servicePathRadio.append(ref)
518                 else:
519                         self.servicePathTV.append(ref)
520                 self.setRoot(ref, justSet)
521
522         def pathUp(self, justSet=False):
523                 if self.mode == MODE_TV:
524                         prev = self.servicePathTV.pop()
525                         length = len(self.servicePathTV)
526                         if length:
527                                 current = self.servicePathTV[length-1]
528                 else:
529                         prev = self.servicePathRadio.pop()
530                         length = len(self.servicePathRadio)
531                         if length:
532                                 current = self.servicePathRadio[length-1]
533                 self.setRoot(current, justSet)
534                 if not justSet:
535                         self.setCurrentSelection(prev)
536                 return prev
537
538         def isBasePathEqual(self, ref):
539                 if self.mode == MODE_RADIO and len(self.servicePathRadio) > 1 and self.servicePathRadio[0] == ref:
540                         return True
541                 elif self.mode == MODE_TV and len(self.servicePathTV) > 1 and self.servicePathTV[0] == ref:
542                         return True
543                 return False
544
545         def isPrevPathEqual(self, ref):
546                 path = self.servicePathRadio
547                 if self.mode == MODE_TV:
548                         path = self.servicePathTV
549                 length = len(path)
550                 if length > 1 and path[length-2] == ref:
551                         return True
552                 return False
553
554         def preEnterPath(self, refstr):
555                 return False
556
557         def showAllServices(self):
558                 if not self.pathChangedDisabled:
559                         refstr = '%s ORDER BY name'%(self.service_types)
560                         if not self.preEnterPath(refstr):
561                                 ref = eServiceReference(refstr)
562                                 currentRoot = self.getRoot()
563                                 if currentRoot is None or currentRoot != ref:
564                                         self.clearPath()
565                                         self.enterPath(ref)
566
567         def showSatellites(self):
568                 if not self.pathChangedDisabled:
569                         refstr = '%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types)
570                         if not self.preEnterPath(refstr):
571                                 ref = eServiceReference(refstr)
572                                 justSet=False
573                                 prev = None
574
575                                 if self.isBasePathEqual(ref):
576                                         if self.isPrevPathEqual(ref):
577                                                 justSet=True
578                                         prev = self.pathUp(justSet)
579                                 else:
580                                         currentRoot = self.getRoot()
581                                         if currentRoot is None or currentRoot != ref:
582                                                 justSet=True
583                                                 self.clearPath()
584                                                 self.enterPath(ref, True)
585                                 if justSet:
586                                         serviceHandler = eServiceCenter.getInstance()
587                                         servicelist = serviceHandler.list(ref)
588                                         if not servicelist is None:
589                                                 while True:
590                                                         service = servicelist.getNext()
591                                                         if not service.valid(): #check if end of list
592                                                                 break
593                                                         orbpos = service.getData(4) >> 16
594                                                         if service.getPath().find("FROM PROVIDER") != -1:
595                                                                 service_name = _("Providers")
596                                                         else:
597                                                                 service_name = _("Services")
598                                                         try:
599                                                                 service_name += str(' - %s'%(nimmanager.getSatDescription(orbpos)))
600                                                                 service.setName(service_name) # why we need this cast?
601                                                         except:
602                                                                 if orbpos > 1800: # west
603                                                                         service.setName("%s (%3.1f" + _("W") + ")" %(str, (0 - (orbpos - 3600)) / 10.0))
604                                                                 else:
605                                                                         service.setName("%s (%3.1f" + _("E") + ")" % (str, orbpos / 10.0))
606                                                         self.servicelist.addService(service)
607                                                         self.servicelist.finishFill()
608                                                         if prev is not None:
609                                                                 self.setCurrentSelection(prev)
610
611         def showProviders(self):
612                 if not self.pathChangedDisabled:
613                         refstr = '%s FROM PROVIDERS ORDER BY name'%(self.service_types)
614                         if not self.preEnterPath(refstr):
615                                 ref = eServiceReference(refstr)
616                                 if self.isBasePathEqual(ref):
617                                         self.pathUp()
618                                 else:
619                                         currentRoot = self.getRoot()
620                                         if currentRoot is None or currentRoot != ref:
621                                                 self.clearPath()
622                                                 self.enterPath(ref)
623
624         def changeBouquet(self, direction):
625                 if not self.pathChangedDisabled:
626                         if self.isBasePathEqual(self.bouquet_root):
627                                 self.pathUp()
628                                 if direction < 0:
629                                         self.moveUp()
630                                 else:
631                                         self.moveDown()
632                                 ref = self.getCurrentSelection()
633                                 self.enterPath(ref)
634
635         def nextBouquet(self):
636                 self.changeBouquet(+1)
637
638         def prevBouquet(self):
639                 self.changeBouquet(-1)
640
641         def showFavourites(self):
642                 if not self.pathChangedDisabled:
643                         if not self.preEnterPath(self.bouquet_rootstr):
644                                 if self.isBasePathEqual(self.bouquet_root):
645                                         self.pathUp()
646                                 else:
647                                         currentRoot = self.getRoot()
648                                         if currentRoot is None or currentRoot != self.bouquet_root:
649                                                 self.clearPath()
650                                                 self.enterPath(self.bouquet_root)
651
652         def keyNumberGlobal(self, number):
653                 char = self.numericalTextInput.getKey(number)
654                 self.servicelist.moveToChar(char)
655
656         def getRoot(self):
657                 return self.servicelist.getRoot()
658
659         def getCurrentSelection(self):
660                 return self.servicelist.getCurrent()
661
662         def setCurrentSelection(self, service):
663                 servicepath = service.getPath()
664                 pos = servicepath.find(" FROM BOUQUET")
665                 if pos != -1:
666                         if self.mode == MODE_TV:
667                                 servicepath = '(type == 1)' + servicepath[pos:]
668                         else:
669                                 servicepath = '(type == 2)' + servicepath[pos:]
670                         service.setPath(servicepath)
671                 self.servicelist.setCurrent(service)
672
673         def getBouquetList(self):
674                 serviceCount=0
675                 bouquets = [ ]
676                 serviceHandler = eServiceCenter.getInstance()
677                 list = serviceHandler.list(self.bouquet_root)
678                 if not list is None:
679                         while True:
680                                 s = list.getNext()
681                                 if not s.valid():
682                                         break
683                                 if ((s.flags & eServiceReference.flagDirectory) == eServiceReference.flagDirectory):
684                                         info = serviceHandler.info(s)
685                                         if not info is None:
686                                                 bouquets.append((info.getName(s), s))
687                                 else:
688                                         serviceCount += 1
689                         if len(bouquets) == 0 and serviceCount > 0:
690                                 info = serviceHandler.info(self.bouquet_root)
691                                 if not info is None:
692                                         bouquets.append((info.getName(self.bouquet_root), self.bouquet_root))
693                         return bouquets
694                 return None
695
696 class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG):
697         def __init__(self, session):
698                 ChannelSelectionBase.__init__(self,session)
699                 ChannelSelectionEdit.__init__(self)
700                 ChannelSelectionEPG.__init__(self)
701
702                 #config for lastservice
703                 config.tv = ConfigSubsection();
704                 config.tv.lastservice = configElement("config.tv.lastservice", configText, "", 0);
705                 config.tv.lastroot = configElement("config.tv.lastroot", configText, "", 0);
706                 config.tv.prevservice = configElement("config.tv.prevservice", configText, "", 0);
707                 config.tv.prevroot = configElement("config.tv.prevroot", configText, "", 0);
708
709                 self["actions"] = ActionMap(["OkCancelActions"],
710                         {
711                                 "cancel": self.cancel,
712                                 "ok": self.channelSelected,
713                         })
714                 self.onShown.append(self.__onShown)
715
716                 self.lastChannelRootTimer = eTimer()
717                 self.lastChannelRootTimer.timeout.get().append(self.__onCreate)
718                 self.lastChannelRootTimer.start(100,True)
719
720         def __onCreate(self):
721                 self.setTvMode()
722                 self.servicePathTV = [ ]
723                 self.restoreRoot()
724                 lastservice=eServiceReference(config.tv.lastservice.value)
725                 if lastservice.valid():
726                         self.setCurrentSelection(lastservice)
727                         self.session.nav.playService(lastservice)
728
729         def __onShown(self):
730                 self.recallBouquetMode()
731                 ref = self.session.nav.getCurrentlyPlayingServiceReference()
732                 if ref is not None and ref.valid() and ref.getPath() == "":
733                         self.servicelist.setPlayableIgnoreService(ref)
734                 else:
735                         self.servicelist.setPlayableIgnoreService(eServiceReference())
736
737         def channelSelected(self):
738                 ref = self.getCurrentSelection()
739                 if self.movemode:
740                         self.toggleMoveMarked()
741                 elif (ref.flags & 7) == 7:
742                         self.enterPath(ref)
743                 elif self.bouquet_mark_edit:
744                         self.doMark()
745                 else:
746                         self.zap()
747                         self.close(ref)
748
749         #called from infoBar and channelSelected
750         def zap(self):
751                 ref = self.session.nav.getCurrentlyPlayingServiceReference()
752                 if ref is None or ref != self.getCurrentSelection():
753                         self.session.nav.playService(self.getCurrentSelection())
754                 self.saveRoot()
755                 self.saveChannel()
756
757         def saveRoot(self):
758                 path = ''
759                 for i in self.servicePathTV:
760                         path += i.toString()
761                         path += ';'
762                 if config.tv.prevroot.value != config.tv.lastroot.value:
763                         config.tv.prevroot.value = config.tv.lastroot.value
764                         config.tv.prevroot.save()
765                 if len(path) and path != config.tv.lastroot.value:
766                         config.tv.lastroot.value = path
767                         config.tv.lastroot.save()
768
769         def restoreRoot(self):
770                 self.servicePathTV = [ ]
771                 re = compile('.+?;')
772                 tmp = re.findall(config.tv.lastroot.value)
773                 cnt = 0
774                 for i in tmp:
775                         self.servicePathTV.append(eServiceReference(i[:len(i)-1]))
776                         cnt += 1
777                 if cnt:
778                         path = self.servicePathTV.pop()
779                         self.enterPath(path)
780                 else:
781                         self.showFavourites()
782                         self.saveRoot()
783
784         def preEnterPath(self, refstr):
785                 if len(self.servicePathTV) and self.servicePathTV[0] != eServiceReference(refstr):
786                         pathstr = config.tv.lastroot.value
787                         if pathstr is not None and pathstr.find(refstr) == 0:
788                                 self.restoreRoot()
789                                 lastservice=eServiceReference(config.tv.lastservice.value)
790                                 if lastservice is not None:
791                                         self.setCurrentSelection(lastservice)
792                                 return True
793                 return False
794
795         def saveChannel(self):
796                 ref = self.session.nav.getCurrentlyPlayingServiceReference()
797                 if ref is not None:
798                         refstr = ref.toString()
799                 else:
800                         refstr = ""
801                 if refstr != config.tv.lastservice.value:
802                         config.tv.prevservice.value = config.tv.lastservice.value
803                         config.tv.prevservice.save()
804                         config.tv.lastservice.value = refstr
805                         config.tv.lastservice.save()
806
807         def recallPrevService(self):
808                 if len(config.tv.prevservice.value) and len(config.tv.prevroot.value):
809                         if config.tv.lastroot.value != config.tv.prevroot.value:
810                                 tmp = config.tv.lastroot.value
811                                 config.tv.lastroot.value = config.tv.prevroot.value
812                                 config.tv.lastroot.save()
813                                 config.tv.prevroot.value = tmp
814                                 config.tv.prevroot.save()
815                                 self.restoreRoot()
816                         if config.tv.lastservice.value != config.tv.prevservice.value:
817                                 tmp = config.tv.lastservice.value
818                                 config.tv.lastservice.value = config.tv.prevservice.value
819                                 config.tv.lastservice.save()
820                                 config.tv.prevservice.value = tmp
821                                 config.tv.prevservice.save()
822                                 lastservice=eServiceReference(config.tv.lastservice.value)
823                                 self.session.nav.playService(lastservice)
824                                 self.setCurrentSelection(lastservice)
825
826         def cancel(self):
827                 self.close(None)
828                 self.restoreRoot()
829                 lastservice=eServiceReference(config.tv.lastservice.value)
830                 if lastservice.valid() and self.getCurrentSelection() != lastservice:
831                         self.setCurrentSelection(lastservice)
832
833 from Screens.InfoBarGenerics import InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord
834
835 class RadioInfoBar(Screen, InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord):
836         def __init__(self, session):
837                 Screen.__init__(self, session)
838                 InfoBarEvent.__init__(self)
839                 InfoBarServiceName.__init__(self)
840                 InfoBarInstantRecord.__init__(self)
841                 self["Clock"] = Clock()
842
843 class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG):
844         def __init__(self, session):
845                 ChannelSelectionBase.__init__(self, session)
846                 ChannelSelectionEdit.__init__(self)
847                 ChannelSelectionEPG.__init__(self)
848
849                 config.radio = ConfigSubsection();
850                 config.radio.lastservice = configElement("config.radio.lastservice", configText, "", 0);
851                 config.radio.lastroot = configElement("config.radio.lastroot", configText, "", 0);
852                 self.onLayoutFinish.append(self.onCreate)
853
854                 self.info = session.instantiateDialog(RadioInfoBar)
855
856                 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
857                         {
858                                 "keyTV": self.closeRadio,
859                                 "keyRadio": self.closeRadio,
860                                 "cancel": self.closeRadio,
861                                 "ok": self.channelSelected,
862                         })
863
864         def saveRoot(self):
865                 path = ''
866                 for i in self.servicePathRadio:
867                         path += i.toString()
868                         path += ';'
869                 if len(path) and path != config.radio.lastroot.value:
870                         config.radio.lastroot.value = path
871                         config.radio.lastroot.save()
872
873         def restoreRoot(self):
874                 self.servicePathRadio = [ ]
875                 re = compile('.+?;')
876                 tmp = re.findall(config.radio.lastroot.value)
877                 cnt = 0
878                 for i in tmp:
879                         self.servicePathRadio.append(eServiceReference(i[:len(i)-1]))
880                         cnt += 1
881                 if cnt:
882                         path = self.servicePathRadio.pop()
883                         self.enterPath(path)
884                 else:
885                         self.showFavourites()
886                         self.saveRoot()
887
888         def preEnterPath(self, refstr):
889                 if len(self.servicePathRadio) and self.servicePathRadio[0] != eServiceReference(refstr):
890                         pathstr = config.radio.lastroot.value
891                         if pathstr is not None and pathstr.find(refstr) == 0:
892                                 self.restoreRoot()
893                                 lastservice=eServiceReference(config.radio.lastservice.value)
894                                 if lastservice is not None:
895                                         self.setCurrentSelection(lastservice)
896                                 return True
897                 return False
898
899         def onCreate(self):
900                 self.setRadioMode()
901                 self.restoreRoot()
902                 lastservice=eServiceReference(config.radio.lastservice.value)
903                 if lastservice.valid():
904                         self.servicelist.setCurrent(lastservice)
905                         self.session.nav.playService(lastservice)
906                         self.servicelist.setPlayableIgnoreService(lastservice)
907                 self.info.show()
908
909         def channelSelected(self): # just return selected service
910                 ref = self.getCurrentSelection()
911                 if self.movemode:
912                         self.toggleMoveMarked()
913                 elif (ref.flags & 7) == 7:
914                         self.enterPath(ref)
915                 elif self.bouquet_mark_edit:
916                         self.doMark()
917                 else:
918                         playingref = self.session.nav.getCurrentlyPlayingServiceReference()
919                         if playingref is None or playingref != ref:
920                                 self.session.nav.playService(ref)
921                                 self.servicelist.setPlayableIgnoreService(ref)
922                                 config.radio.lastservice.value = ref.toString()
923                                 config.radio.lastservice.save()
924                         self.saveRoot()
925
926         def closeRadio(self):
927                 self.info.hide()
928                 #set previous tv service
929                 lastservice=eServiceReference(config.tv.lastservice.value)
930                 self.session.nav.playService(lastservice)
931                 self.close(None)
932
933 class SimpleChannelSelection(ChannelSelectionBase):
934         def __init__(self, session, title):
935                 ChannelSelectionBase.__init__(self, session)
936                 self.title = title
937                 self.onShown.append(self.__onExecCallback)
938
939                 self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
940                         {
941                                 "cancel": self.cancel,
942                                 "ok": self.channelSelected,
943                                 "keyRadio": self.setModeRadio,
944                                 "keyTV": self.setModeTv,
945                         })
946
947         def __onExecCallback(self):
948                 self.session.currentDialog.instance.setTitle(self.title)
949                 self.setModeTv()
950
951         def channelSelected(self): # just return selected service
952                 ref = self.getCurrentSelection()
953                 if (ref.flags & 7) == 7:
954                         self.enterPath(ref)
955                 else:
956                         ref = self.getCurrentSelection()
957                         self.close(ref)
958
959         def setModeTv(self):
960                 self.setTvMode()
961                 self.showFavourites()
962
963         def setModeRadio(self):
964                 self.setRadioMode()
965                 self.showFavourites()