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