1 from Tools.Profile import profile
2 from Tools.BoundFunction import boundFunction
3 from enigma import eServiceReference
5 # workaround for required config entry dependencies.
6 import Screens.MovieSelection
8 from Screen import Screen
9 from Screens.MessageBox import MessageBox
11 profile("LOAD:enigma")
14 profile("LOAD:InfoBarGenerics")
15 from Screens.InfoBarGenerics import InfoBarShowHide, \
16 InfoBarNumberZap, InfoBarChannelSelection, InfoBarMenu, InfoBarRdsDecoder, \
17 InfoBarEPG, InfoBarSeek, InfoBarInstantRecord, InfoBarRedButton, InfoBarTimerButton, InfoBarVmodeButton, \
18 InfoBarAudioSelection, InfoBarAdditionalInfo, InfoBarNotifications, InfoBarDish, InfoBarUnhandledKey, \
19 InfoBarSubserviceSelection, InfoBarShowMovies, InfoBarTimeshift, \
20 InfoBarServiceNotifications, InfoBarPVRState, InfoBarCueSheetSupport, InfoBarBuffer, \
21 InfoBarSummarySupport, InfoBarMoviePlayerSummarySupport, InfoBarTimeshiftState, InfoBarTeletextPlugin, InfoBarExtensions, \
22 InfoBarSubtitleSupport, InfoBarPiP, InfoBarPlugins, InfoBarServiceErrorPopupSupport, InfoBarJobman, InfoBarPowersaver, \
23 InfoBarHDMI, setResumePoint, delResumePoint
24 from Screens.Hotkey import InfoBarHotkey
26 profile("LOAD:InitBar_Components")
27 from Components.ActionMap import HelpableActionMap
28 from Components.config import config
29 from Components.ServiceEventTracker import ServiceEventTracker, InfoBarBase
31 profile("LOAD:HelpableScreen")
32 from Screens.HelpMenu import HelpableScreen
34 from Screens.BpBlue import DeliteBp
35 from Screens.BpGreen import DeliteGp
37 class InfoBar(InfoBarBase, InfoBarShowHide,
38 InfoBarNumberZap, InfoBarChannelSelection, InfoBarMenu, InfoBarEPG, InfoBarRdsDecoder, DeliteBp, DeliteGp,
39 InfoBarInstantRecord, InfoBarAudioSelection, InfoBarRedButton, InfoBarTimerButton, InfoBarVmodeButton,
40 HelpableScreen, InfoBarAdditionalInfo, InfoBarNotifications, InfoBarDish, InfoBarUnhandledKey,
41 InfoBarSubserviceSelection, InfoBarTimeshift, InfoBarSeek, InfoBarCueSheetSupport, InfoBarBuffer,
42 InfoBarSummarySupport, InfoBarTimeshiftState, InfoBarTeletextPlugin, InfoBarExtensions,
43 InfoBarPiP, InfoBarPlugins, InfoBarSubtitleSupport, InfoBarServiceErrorPopupSupport, InfoBarJobman, InfoBarPowersaver,
44 InfoBarHDMI, InfoBarHotkey, Screen):
49 def __init__(self, session):
50 Screen.__init__(self, session)
51 self["actions"] = HelpableActionMap(self, "InfobarActions",
53 "showMovies": (self.showMovies, _("Play recorded movies...")),
54 "showRadio": (self.showRadio, _("Show the radio player...")),
55 "showTv": (self.showTv, _("Show the tv player...")),
60 for x in HelpableScreen, \
61 InfoBarBase, InfoBarShowHide, \
62 InfoBarNumberZap, InfoBarChannelSelection, InfoBarMenu, InfoBarEPG, InfoBarRdsDecoder, DeliteBp, DeliteGp, \
63 InfoBarInstantRecord, InfoBarAudioSelection, InfoBarRedButton, InfoBarTimerButton, InfoBarUnhandledKey, InfoBarVmodeButton,\
64 InfoBarAdditionalInfo, InfoBarNotifications, InfoBarDish, InfoBarSubserviceSelection, InfoBarBuffer, \
65 InfoBarTimeshift, InfoBarSeek, InfoBarCueSheetSupport, InfoBarSummarySupport, InfoBarTimeshiftState, \
66 InfoBarTeletextPlugin, InfoBarExtensions, InfoBarPiP, InfoBarSubtitleSupport, InfoBarJobman, InfoBarPowersaver, \
67 InfoBarPlugins, InfoBarServiceErrorPopupSupport, InfoBarHotkey:
70 self.helpList.append((self["actions"], "InfobarActions", [("showMovies", _("Watch recordings..."))]))
71 self.helpList.append((self["actions"], "InfobarActions", [("showRadio", _("Listen to the radio..."))]))
73 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
75 enigma.iPlayableService.evUpdatedEventInfo: self.__eventInfoChanged
78 self.current_begin_time=0
79 assert InfoBar.instance is None, "class InfoBar is a singleton class and just one instance of this class is allowed!"
80 InfoBar.instance = self
83 InfoBar.instance = None
85 def __eventInfoChanged(self):
87 service = self.session.nav.getCurrentService()
88 old_begin_time = self.current_begin_time
89 info = service and service.info()
90 ptr = info and info.getEvent(0)
91 self.current_begin_time = ptr and ptr.getBeginTime() or 0
92 if config.usage.show_infobar_on_event_change.value:
93 if old_begin_time and old_begin_time != self.current_begin_time:
96 def __checkServiceStarted(self):
97 self.__serviceStarted(True)
98 self.onExecBegin.remove(self.__checkServiceStarted)
100 def serviceStarted(self): #override from InfoBarShowHide
101 new = self.servicelist.newServicePlayed()
103 InfoBarShowHide.serviceStarted(self)
104 self.current_begin_time=0
105 elif not self.__checkServiceStarted in self.onShown and new:
106 self.onShown.append(self.__checkServiceStarted)
108 def __checkServiceStarted(self):
109 self.serviceStarted()
110 self.onShown.remove(self.__checkServiceStarted)
113 self.showTvChannelList(True)
116 if config.usage.e1like_radio_mode.value:
117 self.showRadioChannelList(True)
119 self.rds_display.hide() # in InfoBarRdsDecoder
120 from Screens.ChannelSelection import ChannelSelectionRadio
121 self.session.openWithCallback(self.ChannelSelectionRadioClosed, ChannelSelectionRadio, self)
123 def ChannelSelectionRadioClosed(self, *arg):
124 self.rds_display.show() # in InfoBarRdsDecoder
125 self.servicelist.correctChannelNumber()
127 def showMovies(self, defaultRef=None):
128 self.lastservice = self.session.nav.getCurrentlyPlayingServiceOrGroup()
129 self.session.openWithCallback(self.movieSelected, Screens.MovieSelection.MovieSelection, defaultRef or eServiceReference(config.usage.last_movie_played.value), timeshiftEnabled = self.timeshiftEnabled())
131 def movieSelected(self, service):
132 ref = self.lastservice
135 if ref and not self.session.nav.getCurrentlyPlayingServiceOrGroup():
136 self.session.nav.playService(ref)
138 from Components.ParentalControl import parentalControl
139 if parentalControl.isServicePlayable(service, self.openMoviePlayer):
140 self.openMoviePlayer(service)
142 def openMoviePlayer(self, ref):
143 self.session.open(MoviePlayer, ref, slist=self.servicelist, lastservice=self.session.nav.getCurrentlyPlayingServiceOrGroup(), infobar=self)
145 class MoviePlayer(InfoBarBase, InfoBarShowHide, InfoBarMenu, InfoBarSeek, InfoBarShowMovies, InfoBarInstantRecord,
146 InfoBarAudioSelection, HelpableScreen, InfoBarNotifications, InfoBarServiceNotifications, InfoBarPVRState,
147 InfoBarCueSheetSupport, InfoBarMoviePlayerSummarySupport, InfoBarSubtitleSupport, Screen, InfoBarTeletextPlugin,
148 InfoBarServiceErrorPopupSupport, InfoBarExtensions, InfoBarPlugins, InfoBarPiP, InfoBarHDMI, InfoBarHotkey):
150 ENABLE_RESUME_SUPPORT = True
153 def __init__(self, session, service, slist=None, lastservice=None, infobar=None):
154 Screen.__init__(self, session)
156 self["actions"] = HelpableActionMap(self, "MoviePlayerActions",
158 "leavePlayer": (self.leavePlayer, _("leave movie player...")),
159 "leavePlayerOnExit": (self.leavePlayerOnExit, _("leave movie player...")),
160 "channelUp": (self.channelUp, _("when PiPzap enabled zap channel up...")),
161 "channelDown": (self.channelDown, _("when PiPzap enabled zap channel down...")),
164 self["DirectionActions"] = HelpableActionMap(self, "DirectionActions",
172 for x in HelpableScreen, InfoBarShowHide, InfoBarMenu, \
173 InfoBarBase, InfoBarSeek, InfoBarShowMovies, InfoBarInstantRecord, \
174 InfoBarAudioSelection, InfoBarNotifications, \
175 InfoBarServiceNotifications, InfoBarPVRState, InfoBarCueSheetSupport, \
176 InfoBarMoviePlayerSummarySupport, InfoBarSubtitleSupport, \
177 InfoBarTeletextPlugin, InfoBarServiceErrorPopupSupport, InfoBarExtensions, \
178 InfoBarPlugins, InfoBarPiP, InfoBarHotkey:
181 self.servicelist = slist
182 self.infobar = infobar
183 self.lastservice = lastservice or session.nav.getCurrentlyPlayingServiceOrGroup()
184 session.nav.playService(service)
185 self.cur_service = service
186 self.returning = False
187 self.onClose.append(self.__onClose)
188 config.misc.standbyCounter.addNotifier(self.standbyCountChanged, initial_call=False)
191 config.misc.standbyCounter.removeNotifier(self.standbyCountChanged)
192 from Screens.MovieSelection import playlist
194 if not config.movielist.stop_service.value:
195 Screens.InfoBar.InfoBar.instance.callServiceStarted()
196 self.session.nav.playService(self.lastservice)
197 config.usage.last_movie_played.value = self.cur_service.toString()
198 config.usage.last_movie_played.save()
200 def standbyCountChanged(self, value):
201 if config.ParentalControl.servicepinactive.value:
202 from Components.ParentalControl import parentalControl
203 if parentalControl.isProtected(self.cur_service):
206 def handleLeave(self, how):
207 self.is_closing = True
209 if config.usage.setup_level.index < 2: # -expert
212 (_("No"), "continue")
217 (_("Yes, returning to movie list"), "movielist"),
218 (_("Yes, and delete this movie"), "quitanddelete"),
219 (_("Yes, delete this movie and return to movie list"), "deleteandmovielist"),
220 (_("No"), "continue"),
221 (_("No, but restart from begin"), "restart")
224 from Screens.ChoiceBox import ChoiceBox
225 self.session.openWithCallback(self.leavePlayerConfirmed, ChoiceBox, title=_("Stop playing this movie?"), list = list)
227 self.leavePlayerConfirmed([True, how])
229 def leavePlayer(self):
230 setResumePoint(self.session)
231 self.handleLeave(config.usage.on_movie_stop.value)
233 def leavePlayerOnExit(self):
236 elif self.session.pipshown and "popup" in config.usage.pip_hideOnExit.value:
237 if config.usage.pip_hideOnExit.value == "popup":
238 self.session.openWithCallback(self.hidePipOnExitCallback, MessageBox, _("Disable Picture in Picture"), simple=True)
240 self.hidePipOnExitCallback(True)
241 elif config.usage.leave_movieplayer_onExit.value == "movielist":
243 elif config.usage.leave_movieplayer_onExit.value == "popup":
244 self.session.openWithCallback(self.leavePlayerOnExitCallback, MessageBox, _("Exit movie player?"), simple=True)
245 elif config.usage.leave_movieplayer_onExit.value == "without popup":
246 self.leavePlayerOnExitCallback(True)
248 def leavePlayerOnExitCallback(self, answer):
250 setResumePoint(self.session)
251 self.handleLeave("quit")
253 def hidePipOnExitCallback(self, answer):
257 def deleteConfirmed(self, answer):
259 self.leavePlayerConfirmed((True, "quitanddeleteconfirmed"))
261 def deleteAndMovielistConfirmed(self, answer):
263 self.leavePlayerConfirmed((True, "deleteandmovielistconfirmed"))
265 def movielistAgain(self):
266 from Screens.MovieSelection import playlist
268 self.leavePlayerConfirmed((True, "movielist"))
270 def leavePlayerConfirmed(self, answer):
271 answer = answer and answer[1]
274 if answer in ("quitanddelete", "quitanddeleteconfirmed", "deleteandmovielist", "deleteandmovielistconfirmed"):
275 ref = self.session.nav.getCurrentlyPlayingServiceOrGroup()
276 serviceHandler = enigma.eServiceCenter.getInstance()
277 if answer in ("quitanddelete", "deleteandmovielist"):
279 if config.usage.movielist_trashcan.value:
280 import Tools.Trashcan
282 trash = Tools.Trashcan.createTrashFolder(ref.getPath())
283 Screens.MovieSelection.moveServiceFiles(ref, trash)
284 # Moved to trash, okay
285 if answer == "quitanddelete":
288 self.movielistAgain()
291 print "[InfoBar] Failed to move to .Trash folder:", e
292 msg = _("Cannot move to trash can") + "\n" + str(e) + "\n"
293 info = serviceHandler.info(ref)
294 name = info and info.getName(ref) or _("this recording")
295 msg += _("Do you really want to delete %s?") % name
296 if answer == "quitanddelete":
297 self.session.openWithCallback(self.deleteConfirmed, MessageBox, msg)
298 elif answer == "deleteandmovielist":
299 self.session.openWithCallback(self.deleteAndMovielistConfirmed, MessageBox, msg)
302 elif answer in ("quitanddeleteconfirmed", "deleteandmovielistconfirmed"):
303 offline = serviceHandler.offlineOperations(ref)
304 if offline.deleteFromDisk(0):
305 self.session.openWithCallback(self.close, MessageBox, _("You cannot delete this!"), MessageBox.TYPE_ERROR)
306 if answer == "deleteandmovielistconfirmed":
307 self.movielistAgain()
310 if answer in ("quit", "quitanddeleteconfirmed"):
312 elif answer in ("movielist", "deleteandmovielistconfirmed"):
313 ref = self.session.nav.getCurrentlyPlayingServiceOrGroup()
314 self.returning = True
315 self.session.openWithCallback(self.movieSelected, Screens.MovieSelection.MovieSelection, ref)
316 self.session.nav.stopService()
317 if not config.movielist.stop_service.value:
318 self.session.nav.playService(self.lastservice)
319 elif answer == "restart":
321 self.setSeekState(self.SEEK_STATE_PLAY)
322 elif answer in ("playlist","playlistquit","loop"):
323 ( next_service, item , lenght ) = self.getPlaylistServiceInfo(self.cur_service)
324 if next_service is not None:
325 if config.usage.next_movie_msg.value:
326 self.displayPlayedName(next_service, item, lenght)
327 self.session.nav.playService(next_service)
328 self.cur_service = next_service
330 if answer == "playlist":
331 self.leavePlayerConfirmed([True,"movielist"])
332 elif answer == "loop" and lenght > 0:
333 self.leavePlayerConfirmed([True,"loop"])
335 self.leavePlayerConfirmed([True,"quit"])
336 elif answer in ("repeatcurrent"):
337 if config.usage.next_movie_msg.value:
338 (item, lenght) = self.getPlaylistServiceInfo(self.cur_service)
339 self.displayPlayedName(self.cur_service, item, lenght)
340 self.session.nav.stopService()
341 self.session.nav.playService(self.cur_service)
343 def doEofInternal(self, playing):
348 ref = self.session.nav.getCurrentlyPlayingServiceOrGroup()
351 self.handleLeave(config.usage.on_movie_eof.value)
354 if self.servicelist and self.servicelist.dopipzap:
355 if config.usage.oldstyle_zap_controls.value:
358 self.switchChannelUp()
363 if self.servicelist and self.servicelist.dopipzap:
364 if config.usage.oldstyle_zap_controls.value:
367 self.switchChannelDown()
372 if self.servicelist and self.servicelist.dopipzap:
373 if config.usage.oldstyle_zap_controls.value:
374 self.switchChannelDown()
378 InfoBarSeek.seekFwd(self)
381 if self.servicelist and self.servicelist.dopipzap:
382 if config.usage.oldstyle_zap_controls.value:
383 self.switchChannelUp()
387 InfoBarSeek.seekBack(self)
390 if config.usage.zap_with_ch_buttons.value and self.servicelist and self.servicelist.dopipzap:
395 def channelDown(self):
396 if config.usage.zap_with_ch_buttons.value and self.servicelist and self.servicelist.dopipzap:
401 def switchChannelDown(self):
403 if "keep" not in config.usage.servicelist_cursor_behavior.value:
404 self.servicelist.moveDown()
405 self.session.execDialog(self.servicelist)
407 def switchChannelUp(self):
409 if "keep" not in config.usage.servicelist_cursor_behavior.value:
410 self.servicelist.moveUp()
411 self.session.execDialog(self.servicelist)
414 slist = self.servicelist
416 if slist.inBouquet():
417 prev = slist.getCurrentSelection()
419 prev = prev.toString()
421 if config.usage.quickzap_bouquet_change.value:
425 cur = slist.getCurrentSelection()
427 playable = not (cur.flags & (64|8)) and hasattr(self.session, "pip") and self.session.pip.isPlayableForPipService(cur)
428 if cur.toString() == prev or playable:
432 slist.zap(enable_pipzap = True)
435 slist = self.servicelist
437 if slist.inBouquet():
438 prev = slist.getCurrentSelection()
440 prev = prev.toString()
442 if config.usage.quickzap_bouquet_change.value and slist.atEnd():
446 cur = slist.getCurrentSelection()
448 playable = not (cur.flags & (64|8)) and hasattr(self.session, "pip") and self.session.pip.isPlayableForPipService(cur)
449 if cur.toString() == prev or playable:
453 slist.zap(enable_pipzap = True)
456 slist = self.servicelist
457 if self.session.pipshown:
458 if slist and slist.dopipzap:
460 if self.session.pipshown:
462 self.session.pipshown = False
464 from Screens.PictureInPicture import PictureInPicture
465 self.session.pip = self.session.instantiateDialog(PictureInPicture)
466 self.session.pip.show()
467 if self.session.pip.playService(slist.getCurrentSelection()):
468 self.session.pipshown = True
469 self.session.pip.servicePath = slist.getCurrentServicePath()
471 self.session.pipshown = False
475 if self.session.pipshown:
476 InfoBarPiP.movePiP(self)
481 def showDefaultEPG(self):
482 self.infobar and self.infobar.showMultiEPG()
484 def openEventView(self):
485 self.infobar and self.infobar.showDefaultEPG()
487 def showEventInfoPlugins(self):
488 self.infobar and self.infobar.showEventInfoPlugins()
490 def showEventGuidePlugins(self):
491 self.infobar and self.infobar.showEventGuidePlugins()
493 def openSingleServiceEPG(self):
494 self.infobar and self.infobar.openSingleServiceEPG()
496 def openMultiServiceEPG(self):
497 self.infobar and self.infobar.openMultiServiceEPG()
499 def showMovies(self):
500 ref = self.session.nav.getCurrentlyPlayingServiceOrGroup()
501 self.playingservice = ref # movie list may change the currently playing
502 self.session.openWithCallback(self.movieSelected, Screens.MovieSelection.MovieSelection, ref)
504 def movieSelected(self, service):
505 if service is not None:
506 self.cur_service = service
507 self.is_closing = False
508 self.session.nav.playService(service)
509 self.returning = False
513 self.is_closing = False
514 ref = self.playingservice
515 del self.playingservice
516 # no selection? Continue where we left off
517 if ref and not self.session.nav.getCurrentlyPlayingServiceOrGroup():
518 self.session.nav.playService(ref)
520 def getPlaylistServiceInfo(self, service):
521 from MovieSelection import playlist
522 for i, item in enumerate(playlist):
524 if config.usage.on_movie_eof.value == "repeatcurrent":
525 return (i+1, len(playlist))
527 if i < len(playlist):
528 return (playlist[i], i+1, len(playlist))
529 elif config.usage.on_movie_eof.value == "loop":
530 return (playlist[0], 1, len(playlist))
531 return ( None, 0, 0 )
533 def displayPlayedName(self, ref, index, n):
534 from Tools import Notifications
535 Notifications.AddPopup(text = _("%s/%s: %s") % (index, n, self.ref2HumanName(ref)), type = MessageBox.TYPE_INFO, timeout = 5)
537 def ref2HumanName(self, ref):
538 return enigma.eServiceCenter.getInstance().info(ref).getName(ref)