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