fixes
[enigma2.git] / lib / python / Plugins / Extensions / DVDPlayer / plugin.py
1 from os import path as os_path, remove as os_remove, listdir as os_listdir, system
2 from enigma import eTimer, iPlayableService, iServiceInformation, eServiceReference, iServiceKeys
3 from Screens.Screen import Screen
4 from Screens.MessageBox import MessageBox
5 from Screens.ChoiceBox import ChoiceBox
6 from Screens.HelpMenu import HelpableScreen
7 from Screens.InfoBarGenerics import InfoBarSeek, InfoBarPVRState, InfoBarCueSheetSupport, InfoBarShowHide, InfoBarNotifications
8 from Components.ActionMap import ActionMap, NumberActionMap, HelpableActionMap
9 from Components.Label import Label
10 from Components.FileList import FileList
11 from Components.MenuList import MenuList
12 from Components.ServiceEventTracker import ServiceEventTracker, InfoBarBase
13 from Components.config import config
14 from Tools.Directories import pathExists, fileExists
15
16 import servicedvd # load c++ part of dvd player plugin
17
18 lastpath = ""
19
20 class FileBrowser(Screen):
21         skin = """
22         <screen name="FileBrowser" position="100,100" size="520,376" title="DVD File Browser" >
23                 <widget name="filelist" position="0,0" size="520,376" scrollbarMode="showOnDemand" />
24         </screen>"""
25         def __init__(self, session, dvd_filelist = [ ]):
26                 Screen.__init__(self, session)
27
28                 self.dvd_filelist = dvd_filelist
29                 if len(dvd_filelist):   
30                         self["filelist"] = MenuList(self.dvd_filelist)
31                 else:
32                         global lastpath
33                         if lastpath is not None:
34                                 currDir = lastpath + "/"
35                         else:
36                                 currDir = "/media/dvd/"
37                         if not pathExists(currDir):
38                                 currDir = "/"
39
40                         self.filelist = FileList(currDir, matchingPattern = "(?i)^.*\.(iso)", useServiceRef = True)
41                         self["filelist"] = self.filelist
42
43                 self["FilelistActions"] = ActionMap(["OkCancelActions"],
44                         {
45                                 "ok": self.ok,
46                                 "cancel": self.exit
47                         })
48
49         def ok(self):
50                 if len(self.dvd_filelist):
51                         print "OK " + self["filelist"].getCurrent()
52                         self.close(self["filelist"].getCurrent())
53                 else:
54                         global lastpath
55                         filename = self["filelist"].getFilename()
56                         if filename is not None:
57                                 if filename.upper().endswith("VIDEO_TS/"):
58                                         print "dvd structure found, trying to open..."
59                                         dvdpath = filename[0:-9]
60                                         lastpath = (dvdpath.rstrip("/").rsplit("/",1))[0]
61                                         print "lastpath video_ts/=", lastpath
62                                         self.close(dvdpath)
63                                         return
64                         if self["filelist"].canDescent(): # isDir
65                                 self["filelist"].descent()
66                                 pathname = self["filelist"].getCurrentDirectory() or ""
67                                 if fileExists(pathname+"VIDEO_TS.IFO"):
68                                         print "dvd structure found, trying to open..."
69                                         lastpath = (pathname.rstrip("/").rsplit("/",1))[0]
70                                         print "lastpath video_ts.ifo=", lastpath
71                                         self.close(pathname)
72                         else:
73                                 lastpath = filename[0:filename.rfind("/")]
74                                 print "lastpath directory=", lastpath
75                                 self.close(filename)
76
77         def exit(self):
78                 self.close(None)
79
80 class DVDSummary(Screen):
81         skin = """
82         <screen position="0,0" size="132,64">
83                 <widget source="session.CurrentService" render="Label" position="5,4" size="120,28" font="Regular;12" transparent="1" >
84                         <convert type="ServiceName">Name</convert>
85                 </widget>
86                 <widget name="DVDPlayer" position="5,30" size="66,16" font="Regular;12" transparent="1" />
87                 <widget name="Chapter" position="72,30" size="54,16" font="Regular;12" transparent="1" halign="right" />
88                 <widget source="session.CurrentService" render="Label" position="66,46" size="60,18" font="Regular;16" transparent="1" halign="right" >
89                         <convert type="ServicePosition">Position</convert>
90                 </widget>
91                 <widget source="session.CurrentService" render="Progress" position="6,46" size="60,18" borderWidth="1" >
92                         <convert type="ServicePosition">Position</convert>
93                 </widget>
94         </screen>"""
95
96         def __init__(self, session, parent):
97                 Screen.__init__(self, session, parent)
98
99                 self["DVDPlayer"] = Label("DVD Player")
100                 self["Title"] = Label("")
101                 self["Time"] = Label("")
102                 self["Chapter"] = Label("")
103
104         def updateChapter(self, chapter):
105                 self["Chapter"].setText(chapter)
106
107         def setTitle(self, title):
108                 self["Title"].setText(title)
109
110 class DVDOverlay(Screen):
111         skin = """<screen name="DVDOverlay" position="0,0" size="720,576" flags="wfNoBorder" zPosition="-1" backgroundColor="transparent" />"""
112         def __init__(self, session, args = None):
113                 Screen.__init__(self, session)
114                 
115 class ChapterZap(Screen):
116         skin = """
117         <screen name="ChapterZap" position="235,255" size="250,60" title="Chapter" >
118                 <widget name="chapter" position="35,15" size="110,25" font="Regular;23" />
119                 <widget name="number" position="145,15" size="80,25" halign="right" font="Regular;23" />
120         </screen>"""
121         
122         def quit(self):
123                 self.Timer.stop()
124                 self.close(0)
125
126         def keyOK(self):
127                 self.Timer.stop()
128                 self.close(int(self["number"].getText()))
129
130         def keyNumberGlobal(self, number):
131                 self.Timer.start(3000, True)            #reset timer
132                 self.field = self.field + str(number)
133                 self["number"].setText(self.field)
134                 if len(self.field) >= 4:
135                         self.keyOK()
136
137         def __init__(self, session, number):
138                 Screen.__init__(self, session)
139                 self.field = str(number)
140
141                 self["chapter"] = Label(_("Chapter:"))
142
143                 self["number"] = Label(self.field)
144
145                 self["actions"] = NumberActionMap( [ "SetupActions" ],
146                         {
147                                 "cancel": self.quit,
148                                 "ok": self.keyOK,
149                                 "1": self.keyNumberGlobal,
150                                 "2": self.keyNumberGlobal,
151                                 "3": self.keyNumberGlobal,
152                                 "4": self.keyNumberGlobal,
153                                 "5": self.keyNumberGlobal,
154                                 "6": self.keyNumberGlobal,
155                                 "7": self.keyNumberGlobal,
156                                 "8": self.keyNumberGlobal,
157                                 "9": self.keyNumberGlobal,
158                                 "0": self.keyNumberGlobal
159                         })
160
161                 self.Timer = eTimer()
162                 self.Timer.callback.append(self.keyOK)
163                 self.Timer.start(3000, True)
164
165 class DVDPlayer(Screen, InfoBarBase, InfoBarNotifications, InfoBarSeek, InfoBarPVRState, InfoBarShowHide, HelpableScreen, InfoBarCueSheetSupport):
166 #       ALLOW_SUSPEND = True
167         ENABLE_RESUME_SUPPORT = True
168         
169         skin = """
170         <screen name="DVDPlayer" flags="wfNoBorder" position="0,380" size="720,160" title="InfoBar" backgroundColor="transparent" >
171                 <!-- Background -->
172                 <ePixmap position="0,0" zPosition="-2" size="720,160" pixmap="skin_default/info-bg_mp.png" alphatest="off" />
173                 <ePixmap position="29,40" zPosition="0" size="665,104" pixmap="skin_default/screws_mp.png" alphatest="on" transparent="1" />
174                 <!-- colorbuttons -->
175                 <ePixmap position="48,70" zPosition="0" size="108,13" pixmap="skin_default/icons/mp_buttons.png" alphatest="on" />
176                 <!-- Servicename -->
177                 <ePixmap pixmap="skin_default/icons/icon_event.png" position="207,78" zPosition="1" size="15,10" alphatest="on" />
178                 <widget source="session.CurrentService" render="Label" position="230,73" size="300,22" font="Regular;20" backgroundColor="#263c59" shadowColor="#1d354c" shadowOffset="-1,-1" transparent="1" noWrap="1">
179                         <convert type="ServiceName">Name</convert>
180                 </widget>
181                 <!-- Chapter info -->
182                 <widget name="chapterLabel" position="230,96" size="360,22" font="Regular;20" foregroundColor="#c3c3c9" backgroundColor="#263c59" transparent="1" />
183                 <!-- Audio track info -->
184                 <ePixmap pixmap="skin_default/icons/icon_dolby.png" position="540,73" zPosition="1" size="26,16" alphatest="on"/>
185                 <widget name="audioLabel" position="570,73" size="130,22" font="Regular;18" backgroundColor="#263c59" shadowColor="#1d354c" shadowOffset="-1,-1" transparent="1" />
186                 <!-- Subtitle track info -->
187                 <widget source="session.CurrentService" render="Pixmap" pixmap="skin_default/icons/icon_txt.png" position="540,96" zPosition="1" size="26,16" alphatest="on" >
188                         <convert type="ServiceInfo">HasTelext</convert>
189                         <convert type="ConditionalShowHide" />
190                 </widget>
191                 <widget name="subtitleLabel" position="570,96" size="130,22" font="Regular;18" backgroundColor="#263c59" shadowColor="#1d354c" shadowOffset="-1,-1" transparent="1" />
192                 <!-- Elapsed time -->
193                 <widget source="session.CurrentService" render="Label" position="205,129" size="100,20" font="Regular;18" halign="center" valign="center" backgroundColor="#06224f" shadowColor="#1d354c" shadowOffset="-1,-1" transparent="1" >
194                         <convert type="ServicePosition">Position,ShowHours</convert>
195                 </widget>
196                 <!-- Progressbar (movie position)-->
197                 <widget source="session.CurrentService" render="PositionGauge" position="300,133" size="270,10" zPosition="2" pointer="skin_default/position_pointer.png:540,0" transparent="1" >
198                         <convert type="ServicePosition">Gauge</convert>
199                 </widget>
200                 <!-- Remaining time -->
201                 <widget source="session.CurrentService" render="Label" position="576,129" size="100,20" font="Regular;18" halign="center" valign="center" backgroundColor="#06224f" shadowColor="#1d354c" shadowOffset="-1,-1" transparent="1" >
202                         <convert type="ServicePosition">Remaining,Negate,ShowHours</convert>
203                 </widget>
204         </screen>"""
205
206         def save_infobar_seek_config(self):
207                 self.saved_config_speeds_forward = config.seek.speeds_forward.value
208                 self.saved_config_speeds_backward = config.seek.speeds_backward.value
209                 self.saved_config_enter_forward = config.seek.enter_forward.value
210                 self.saved_config_enter_backward = config.seek.enter_backward.value
211                 self.saved_config_seek_stepwise_minspeed = config.seek.stepwise_minspeed.value
212                 self.saved_config_seek_stepwise_repeat = config.seek.stepwise_repeat.value
213                 self.saved_config_seek_on_pause = config.seek.on_pause.value
214                 self.saved_config_seek_speeds_slowmotion = config.seek.speeds_slowmotion.value
215
216         def change_infobar_seek_config(self):
217                 config.seek.speeds_forward.value = [2, 4, 8, 16, 32, 64]
218                 config.seek.speeds_backward.value = [8, 16, 32, 64]
219                 config.seek.speeds_slowmotion.value = [ ]
220                 config.seek.enter_forward.value = "2"
221                 config.seek.enter_backward.value = "2"
222                 config.seek.stepwise_minspeed.value = "Never"
223                 config.seek.stepwise_repeat.value = "3"
224                 config.seek.on_pause.value = "play"
225
226         def restore_infobar_seek_config(self):
227                 config.seek.speeds_forward.value = self.saved_config_speeds_forward
228                 config.seek.speeds_backward.value = self.saved_config_speeds_backward
229                 config.seek.speeds_slowmotion.value = self.saved_config_seek_speeds_slowmotion
230                 config.seek.enter_forward.value = self.saved_config_enter_forward
231                 config.seek.enter_backward.value = self.saved_config_enter_backward
232                 config.seek.stepwise_minspeed.value = self.saved_config_seek_stepwise_minspeed
233                 config.seek.stepwise_repeat.value = self.saved_config_seek_stepwise_repeat
234                 config.seek.on_pause.value = self.saved_config_seek_on_pause
235
236         def __init__(self, session, dvd_device = None, dvd_filelist = [ ], args = None):
237                 Screen.__init__(self, session)
238                 InfoBarBase.__init__(self)
239                 InfoBarNotifications.__init__(self)
240                 InfoBarCueSheetSupport.__init__(self, actionmap = "MediaPlayerCueSheetActions")
241                 InfoBarShowHide.__init__(self)
242                 HelpableScreen.__init__(self)
243                 self.save_infobar_seek_config()
244                 self.change_infobar_seek_config()
245                 InfoBarSeek.__init__(self, useSeekBackHack=False)
246                 InfoBarPVRState.__init__(self)
247                 self.dvdScreen = self.session.instantiateDialog(DVDOverlay)
248
249                 self.oldService = self.session.nav.getCurrentlyPlayingServiceReference()
250                 self.session.nav.stopService()
251                 self["audioLabel"] = Label("n/a")
252                 self["subtitleLabel"] = Label("")
253                 self["chapterLabel"] = Label("")
254                 self.last_audioTuple = None
255                 self.last_subtitleTuple = None
256                 self.totalChapters = 0
257                 self.currentChapter = 0
258                 self.totalTitles = 0
259                 self.currentTitle = 0
260
261                 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
262                         {
263                                 iPlayableService.evStopped: self.__serviceStopped,
264                                 iPlayableService.evUser: self.__timeUpdated,
265                                 iPlayableService.evUser+1: self.__statePlay,
266                                 iPlayableService.evUser+2: self.__statePause,
267                                 iPlayableService.evUser+3: self.__osdFFwdInfoAvail,
268                                 iPlayableService.evUser+4: self.__osdFBwdInfoAvail,
269                                 iPlayableService.evUser+5: self.__osdStringAvail,
270                                 iPlayableService.evUser+6: self.__osdAudioInfoAvail,
271                                 iPlayableService.evUser+7: self.__osdSubtitleInfoAvail,
272                                 iPlayableService.evUser+8: self.__chapterUpdated,
273                                 iPlayableService.evUser+9: self.__titleUpdated,
274                                 iPlayableService.evUser+11: self.__menuOpened,
275                                 iPlayableService.evUser+12: self.__menuClosed
276                         })
277
278                 self["DVDPlayerDirectionActions"] = HelpableActionMap(self, "DirectionActions",
279                         {
280                                 #MENU KEY DOWN ACTIONS
281                                 "left": (self.keyLeft, _("DVD left key")),
282                                 "right": (self.keyRight, _("DVD right key")),
283                                 "up": (self.keyUp, _("DVD up key")),
284                                 "down": (self.keyDown, _("DVD down key")),
285
286                                 #MENU KEY REPEATED ACTIONS
287                                 "leftRepeated": self.doNothing,
288                                 "rightRepeated": self.doNothing,
289                                 "upRepeated": self.doNothing,
290                                 "downRepeated": self.doNothing,
291
292                                 #MENU KEY UP ACTIONS
293                                 "leftUp": self.doNothing,
294                                 "rightUp": self.doNothing,
295                                 "upUp": self.doNothing,
296                                 "downUp": self.doNothing,
297                         }, -2)
298
299                 self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions",
300                         {
301                                 "ok": (self.keyOk, _("DVD ENTER key")),
302                                 "cancel": self.keyCancel,
303                         }, -2)
304
305                 self["DVDPlayerPlaybackActions"] = HelpableActionMap(self, "DVDPlayerActions",
306                         {
307                                 #PLAYER ACTIONS
308                                 "dvdMenu": (self.enterDVDMenu, _("show DVD main menu")),
309                                 "toggleInfo": (self.toggleInfo, _("toggle time, chapter, audio, subtitle info")),
310                                 "nextChapter": (self.nextChapter, _("forward to the next chapter")),
311                                 "prevChapter": (self.prevChapter, _("rewind to the previous chapter")),
312                                 "nextTitle": (self.nextTitle, _("jump forward to the next title")),
313                                 "prevTitle": (self.prevTitle, _("jump back to the previous title")),
314                                 "tv": (self.askLeavePlayer, _("exit DVD player or return to file browser")),
315                                 "dvdAudioMenu": (self.enterDVDAudioMenu, _("(show optional DVD audio menu)")),
316                                 "nextAudioTrack": (self.nextAudioTrack, _("switch to the next audio track")),
317                                 "nextSubtitleTrack": (self.nextSubtitleTrack, _("switch to the next subtitle language")),
318                                 "seekBeginning": (self.seekBeginning, _("Jump to video title 1 (play movie from start)")),
319                         }, -2)
320                         
321                 self["NumberActions"] = NumberActionMap( [ "NumberActions"],
322                         {
323                                 "1": self.keyNumberGlobal,
324                                 "2": self.keyNumberGlobal,
325                                 "3": self.keyNumberGlobal,
326                                 "4": self.keyNumberGlobal,
327                                 "5": self.keyNumberGlobal,
328                                 "6": self.keyNumberGlobal,
329                                 "7": self.keyNumberGlobal,
330                                 "8": self.keyNumberGlobal,
331                                 "9": self.keyNumberGlobal,
332                                 "0": self.keyNumberGlobal,
333                         })
334
335                 self.onClose.append(self.__onClose)
336
337                 if dvd_device:
338                                 self.dvd_device = dvd_device
339                                 self.physicalDVD = True
340                 else:
341                         if fileExists("/dev/cdroms/cdrom0"):
342                                 print "physical dvd found (/dev/cdroms/cdrom0)"
343                                 self.dvd_device = "/dev/cdroms/cdrom0"
344                                 self.physicalDVD = True
345                         else:
346                                 self.dvd_device = None
347                                 self.physicalDVD = False
348
349                 self.dvd_filelist = dvd_filelist
350                 self.onFirstExecBegin.append(self.showFileBrowser)
351                 self.service = None
352                 self.in_menu = False
353                 self.old_aspect = open("/proc/stb/video/aspect", "r").read()
354                 self.old_policy = open("/proc/stb/video/policy", "r").read()
355                 self.old_wss = open("/proc/stb/denc/0/wss", "r").read()
356
357         def keyNumberGlobal(self, number):
358                 print "You pressed number " + str(number)
359                 self.session.openWithCallback(self.numberEntered, ChapterZap, number)
360
361         def numberEntered(self, retval):
362 #               print self.servicelist
363                 if retval > 0:
364                         self.zapToNumber(retval)
365
366         def __serviceStopped(self):
367                 self.dvdScreen.hide()
368                 self.service.subtitle().disableSubtitles(self.session.current_dialog.instance)
369
370         def serviceStarted(self): #override InfoBarShowHide function
371                 self.dvdScreen.show()
372                 self.service.subtitle().enableSubtitles(self.dvdScreen.instance, None)
373
374         def doEofInternal(self, playing):
375                 if self.in_menu:
376                         self.hide()
377
378         def __menuOpened(self):
379                 self.hide()
380                 self.in_menu = True
381                 self["NumberActions"].setEnabled(False)
382
383         def __menuClosed(self):
384                 self.show()
385                 self.in_menu = False
386                 self["NumberActions"].setEnabled(True)
387
388         def setChapterLabel(self):
389                 chapterLCD = "Menu"
390                 chapterOSD = "DVD Menu"
391                 if self.currentTitle > 0:
392                         chapterLCD = "%s %d" % (_("Chap."), self.currentChapter)
393                         chapterOSD = "DVD %s %d/%d" % (_("Chapter"), self.currentChapter, self.totalChapters)
394                         chapterOSD += " (%s %d/%d)" % (_("Title"), self.currentTitle, self.totalTitles)
395                 self["chapterLabel"].setText(chapterOSD)
396                 try:
397                         self.session.summary.updateChapter(chapterLCD)
398                 except:
399                         pass
400
401         def doNothing(self):
402                 pass
403
404         def toggleInfo(self):
405                 if not self.in_menu:
406                         self.toggleShow()
407                         print "toggleInfo"
408
409         def __timeUpdated(self):
410                 print "timeUpdated"
411
412         def __statePlay(self):
413                 print "statePlay"
414
415         def __statePause(self):
416                 print "statePause"
417
418         def __osdFFwdInfoAvail(self):
419                 self.setChapterLabel()
420                 print "FFwdInfoAvail"
421
422         def __osdFBwdInfoAvail(self):
423                 self.setChapterLabel()
424                 print "FBwdInfoAvail"
425
426         def __osdStringAvail(self):
427                 print "StringAvail"
428
429         def __osdAudioInfoAvail(self):
430                 audioTuple = self.service.info().getInfoObject(iServiceInformation.sUser+6)
431                 print "AudioInfoAvail ", repr(audioTuple)
432                 if audioTuple:
433                         audioString = "%d: %s (%s)" % (audioTuple[0],audioTuple[1],audioTuple[2])
434                         self["audioLabel"].setText(audioString)
435                         if audioTuple != self.last_audioTuple and not self.in_menu:
436                                 self.doShow()
437                         self.last_audioTuple = audioTuple
438
439         def __osdSubtitleInfoAvail(self):
440                 subtitleTuple = self.service.info().getInfoObject(iServiceInformation.sUser+7)
441                 print "SubtitleInfoAvail ", repr(subtitleTuple)
442                 if subtitleTuple:
443                         subtitleString = ""
444                         if subtitleTuple[0] is not 0:
445                                 subtitleString = "%d: %s" % (subtitleTuple[0],subtitleTuple[1])
446                         self["subtitleLabel"].setText(subtitleString)
447                         if subtitleTuple != self.last_subtitleTuple and not self.in_menu:
448                                 self.doShow()
449                         self.last_subtitleTuple = subtitleTuple
450
451         def __chapterUpdated(self):
452                 self.currentChapter = self.service.info().getInfo(iServiceInformation.sCurrentChapter)
453                 self.totalChapters = self.service.info().getInfo(iServiceInformation.sTotalChapters)
454                 self.setChapterLabel()
455                 print "__chapterUpdated: %d/%d" % (self.currentChapter, self.totalChapters)
456
457         def __titleUpdated(self):
458                 self.currentTitle = self.service.info().getInfo(iServiceInformation.sCurrentTitle)
459                 self.totalTitles = self.service.info().getInfo(iServiceInformation.sTotalTitles)
460                 self.setChapterLabel()
461                 print "__titleUpdated: %d/%d" % (self.currentTitle, self.totalTitles)
462                 if not self.in_menu:
463                         self.doShow()
464                 
465         def askLeavePlayer(self):
466                 choices = [(_("Continue playing"), "play"), (_("Exit"), "exit")]
467                 if not self.physicalDVD:
468                         choices.insert(1,(_("Return to file browser"), "browser"))                      
469                 self.session.openWithCallback(self.exitCB, ChoiceBox, title=_("Leave DVD Player?"), list = choices)
470
471         def nextAudioTrack(self):
472                 if self.service:
473                         self.service.keys().keyPressed(iServiceKeys.keyUser)
474
475         def nextSubtitleTrack(self):
476                 if self.service:
477                         self.service.keys().keyPressed(iServiceKeys.keyUser+1)
478
479         def enterDVDAudioMenu(self):
480                 if self.service:
481                         self.service.keys().keyPressed(iServiceKeys.keyUser+2)
482
483         def nextChapter(self):
484                 if self.service:
485                         self.service.keys().keyPressed(iServiceKeys.keyUser+3)
486
487         def prevChapter(self):
488                 if self.service:
489                         self.service.keys().keyPressed(iServiceKeys.keyUser+4)
490
491         def nextTitle(self):
492                 if self.service:
493                         self.service.keys().keyPressed(iServiceKeys.keyUser+5)
494
495         def prevTitle(self):
496                 if self.service:
497                         self.service.keys().keyPressed(iServiceKeys.keyUser+6)
498
499         def enterDVDMenu(self):
500                 if self.service:
501                         self.service.keys().keyPressed(iServiceKeys.keyUser+7)
502
503         def seekBeginning(self):
504                 if self.service:
505                         seekable = self.getSeek()
506                         if seekable is not None:
507                                 seekable.seekTo(0)
508
509         def zapToNumber(self, number):
510                 if self.service:
511                         seekable = self.getSeek()
512                         if seekable is not None:
513                                 print "seek to chapter %d" % number
514                                 seekable.seekChapter(number)
515
516 #       MENU ACTIONS
517         def keyRight(self):
518                 if self.service:
519                         self.service.keys().keyPressed(iServiceKeys.keyRight)
520
521         def keyLeft(self):
522                 if self.service:
523                         self.service.keys().keyPressed(iServiceKeys.keyLeft)
524
525         def keyUp(self):
526                 if self.service:
527                         self.service.keys().keyPressed(iServiceKeys.keyUp)
528
529         def keyDown(self):
530                 if self.service:
531                         self.service.keys().keyPressed(iServiceKeys.keyDown)
532
533         def keyOk(self):
534                 if self.service:
535                         if not self.in_menu:
536                                 self.toggleInfo()
537                         self.service.keys().keyPressed(iServiceKeys.keyOk)
538
539         def keyCancel(self):
540                 self.askLeavePlayer()
541
542         def showFileBrowser(self):
543                 if self.physicalDVD and len(self.dvd_filelist) == 0:
544                         if self.dvd_device == "/dev/cdroms/cdrom0":
545                                 self.session.openWithCallback(self.DVDdriveCB, MessageBox, text=_("Do you want to play DVD in drive?"), timeout=5 )
546                         else:
547                                 self.DVDdriveCB(True)
548                 elif len(self.dvd_filelist) == 1:
549                         self.FileBrowserClosed(self.dvd_filelist[0])
550                 else:
551                         self.session.openWithCallback(self.FileBrowserClosed, FileBrowser, self.dvd_filelist)
552         
553         def DVDdriveCB(self, answer):
554                 if answer == True:
555                         self.FileBrowserClosed(self.dvd_device)
556                 else:
557                         self.session.openWithCallback(self.FileBrowserClosed, FileBrowser)
558                         self.physicalDVD = False
559
560         def FileBrowserClosed(self, val):
561                 curref = self.session.nav.getCurrentlyPlayingServiceReference()
562                 print "FileBrowserClosed", val
563                 if val is None:
564                         self.askLeavePlayer()
565                 else:
566                         newref = eServiceReference(4369, 0, val)
567                         print "play", newref.toString()
568                         if curref is None or curref != newref:
569                                 self.session.nav.playService(newref)
570                                 self.service = self.session.nav.getCurrentService()
571                                 print "self.service", self.service
572                                 print "cur_dlg", self.session.current_dialog
573
574         def exitCB(self, answer):
575                 if answer is not None:
576                         if answer[1] == "exit":
577                                 if self.service:
578                                         self.service = None
579                                 self.close()
580                         if answer[1] == "browser":
581                                 #TODO check here if a paused dvd playback is already running... then re-start it...
582                                 #else
583                                 if self.service:
584                                         self.service = None
585                                 self.showFileBrowser()
586                         else:
587                                 pass
588
589         def __onClose(self):
590                 for i in (("/proc/stb/video/aspect", self.old_aspect), ("/proc/stb/video/policy", self.old_policy), ("/proc/stb/denc/0/wss", self.old_wss)):
591                         try:
592                                 open(i[0], "w").write(i[1])
593                         except IOError:
594                                 print "restore", i[0], "failed"
595                 self.restore_infobar_seek_config()
596                 self.session.nav.playService(self.oldService)
597
598         def playLastCB(self, answer): # overwrite infobar cuesheet function
599                 print "playLastCB", answer, self.resume_point
600                 if self.service:
601                         seek = self.service.seek()
602                         if answer == True:
603                                 seek.seekTo(self.resume_point)
604                         pause = self.service.pause()
605                         pause.unpause()
606                 self.hideAfterResume()
607
608         def showAfterCuesheetOperation(self):
609                 if not self.in_menu:
610                         self.show()
611
612         def createSummary(self):
613                 return DVDSummary
614
615 #override some InfoBarSeek functions
616         def doEof(self):
617                 self.setSeekState(self.SEEK_STATE_PLAY)
618
619         def calcRemainingTime(self):
620                 return 0
621
622 def main(session, **kwargs):
623         session.open(DVDPlayer)
624
625 def menu(menuid, **kwargs):
626         if menuid == "mainmenu":
627                 return [(_("DVD Player"), main, "dvd_player", 46)]
628         return []
629
630 from Plugins.Plugin import PluginDescriptor
631
632 def filescan_open(list, session, **kwargs):
633         if len(list) == 1 and list[0].mimetype == "video/x-dvd":
634                 splitted = list[0].path.split('/')
635                 print "splitted", splitted
636                 if len(splitted) > 2:
637                         if splitted[1] == 'autofs':
638                                 session.open(DVDPlayer, dvd_device="/dev/%s" %(splitted[2]))
639                                 return
640                         else:
641                                 print "splitted[0]", splitted[1]
642         else:
643                 dvd_filelist = []
644                 for x in list:
645                         if x.mimetype == "video/x-dvd-iso":
646                                 dvd_filelist.append(x.path)
647                         if x.mimetype == "video/x-dvd":
648                                 dvd_filelist.append(x.path.rsplit('/',1)[0])                    
649                 session.open(DVDPlayer, dvd_filelist=dvd_filelist)
650
651 def filescan(**kwargs):
652         from Components.Scanner import Scanner, ScanPath
653
654         # Overwrite checkFile to only detect local
655         class LocalScanner(Scanner):
656                 def checkFile(self, file):
657                         return fileExists(file.path)
658
659         return [
660                 LocalScanner(mimetypes = ["video/x-dvd","video/x-dvd-iso"],
661                         paths_to_scan =
662                                 [
663                                         ScanPath(path = "video_ts", with_subdirs = False),
664                                         ScanPath(path = "", with_subdirs = False),
665                                 ],
666                         name = "DVD",
667                         description = "Play DVD",
668                         openfnc = filescan_open,
669                 )]              
670
671 def Plugins(**kwargs):
672         return [PluginDescriptor(name = "DVDPlayer", description = "Play DVDs", where = PluginDescriptor.WHERE_MENU, fnc = menu),
673                         PluginDescriptor(where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)]