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 class InfoBar(InfoBarBase, InfoBarShowHide,
35 InfoBarNumberZap, InfoBarChannelSelection, InfoBarMenu, InfoBarEPG, InfoBarRdsDecoder,
36 InfoBarInstantRecord, InfoBarAudioSelection, InfoBarRedButton, InfoBarTimerButton, InfoBarVmodeButton,
37 HelpableScreen, InfoBarAdditionalInfo, InfoBarNotifications, InfoBarDish, InfoBarUnhandledKey,
38 InfoBarSubserviceSelection, InfoBarTimeshift, InfoBarSeek, InfoBarCueSheetSupport, InfoBarBuffer,
39 InfoBarSummarySupport, InfoBarTimeshiftState, InfoBarTeletextPlugin, InfoBarExtensions,
40 InfoBarPiP, InfoBarPlugins, InfoBarSubtitleSupport, InfoBarServiceErrorPopupSupport, InfoBarJobman, InfoBarPowersaver,
41 InfoBarHDMI, InfoBarHotkey, Screen):
46 def __init__(self, session):
47 Screen.__init__(self, session)
48 self["actions"] = HelpableActionMap(self, "InfobarActions",
50 "showMovies": (self.showMovies, _("Play recorded movies...")),
51 "showRadio": (self.showRadio, _("Show the radio player...")),
52 "showTv": (self.showTv, _("Show the tv player...")),
57 for x in HelpableScreen, \
58 InfoBarBase, InfoBarShowHide, \
59 InfoBarNumberZap, InfoBarChannelSelection, InfoBarMenu, InfoBarEPG, InfoBarRdsDecoder, \
60 InfoBarInstantRecord, InfoBarAudioSelection, InfoBarRedButton, InfoBarTimerButton, InfoBarUnhandledKey, InfoBarVmodeButton,\
61 InfoBarAdditionalInfo, InfoBarNotifications, InfoBarDish, InfoBarSubserviceSelection, InfoBarBuffer, \
62 InfoBarTimeshift, InfoBarSeek, InfoBarCueSheetSupport, InfoBarSummarySupport, InfoBarTimeshiftState, \
63 InfoBarTeletextPlugin, InfoBarExtensions, InfoBarPiP, InfoBarSubtitleSupport, InfoBarJobman, InfoBarPowersaver, \
64 InfoBarPlugins, InfoBarServiceErrorPopupSupport, InfoBarHotkey:
67 self.helpList.append((self["actions"], "InfobarActions", [("showMovies", _("Watch recordings..."))]))
68 self.helpList.append((self["actions"], "InfobarActions", [("showRadio", _("Listen to the radio..."))]))
70 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
72 enigma.iPlayableService.evUpdatedEventInfo: self.__eventInfoChanged
75 self.current_begin_time=0
76 assert InfoBar.instance is None, "class InfoBar is a singleton class and just one instance of this class is allowed!"
77 InfoBar.instance = self
80 InfoBar.instance = None
82 def __eventInfoChanged(self):
84 service = self.session.nav.getCurrentService()
85 old_begin_time = self.current_begin_time
86 info = service and service.info()
87 ptr = info and info.getEvent(0)
88 self.current_begin_time = ptr and ptr.getBeginTime() or 0
89 if config.usage.show_infobar_on_event_change.value:
90 if old_begin_time and old_begin_time != self.current_begin_time:
93 def __checkServiceStarted(self):
94 self.__serviceStarted(True)
95 self.onExecBegin.remove(self.__checkServiceStarted)
97 def serviceStarted(self): #override from InfoBarShowHide
98 new = self.servicelist.newServicePlayed()
100 InfoBarShowHide.serviceStarted(self)
101 self.current_begin_time=0
102 elif not self.__checkServiceStarted in self.onShown and new:
103 self.onShown.append(self.__checkServiceStarted)
105 def __checkServiceStarted(self):
106 self.serviceStarted()
107 self.onShown.remove(self.__checkServiceStarted)
110 self.showTvChannelList(True)
113 if config.usage.e1like_radio_mode.value:
114 self.showRadioChannelList(True)
116 self.rds_display.hide() # in InfoBarRdsDecoder
117 from Screens.ChannelSelection import ChannelSelectionRadio
118 self.session.openWithCallback(self.ChannelSelectionRadioClosed, ChannelSelectionRadio, self)
120 def ChannelSelectionRadioClosed(self, *arg):
121 self.rds_display.show() # in InfoBarRdsDecoder
122 self.servicelist.correctChannelNumber()
124 def showMovies(self, defaultRef=None):
125 self.lastservice = self.session.nav.getCurrentlyPlayingServiceOrGroup()
126 self.session.openWithCallback(self.movieSelected, Screens.MovieSelection.MovieSelection, defaultRef or eServiceReference(config.usage.last_movie_played.value), timeshiftEnabled = self.timeshiftEnabled())
128 def movieSelected(self, service):
129 ref = self.lastservice
132 if ref and not self.session.nav.getCurrentlyPlayingServiceOrGroup():
133 self.session.nav.playService(ref)
135 from Components.ParentalControl import parentalControl
136 if parentalControl.isServicePlayable(service, self.openMoviePlayer):
137 self.openMoviePlayer(service)
139 def openMoviePlayer(self, ref):
140 self.session.open(MoviePlayer, ref, slist=self.servicelist, lastservice=self.session.nav.getCurrentlyPlayingServiceOrGroup(), infobar=self)
142 class MoviePlayer(InfoBarBase, InfoBarShowHide, InfoBarMenu, InfoBarSeek, InfoBarShowMovies, InfoBarInstantRecord,
143 InfoBarAudioSelection, HelpableScreen, InfoBarNotifications, InfoBarServiceNotifications, InfoBarPVRState,
144 InfoBarCueSheetSupport, InfoBarMoviePlayerSummarySupport, InfoBarSubtitleSupport, Screen, InfoBarTeletextPlugin,
145 InfoBarServiceErrorPopupSupport, InfoBarExtensions, InfoBarPlugins, InfoBarPiP, InfoBarHDMI, InfoBarHotkey):
147 ENABLE_RESUME_SUPPORT = True
150 def __init__(self, session, service, slist=None, lastservice=None, infobar=None):
151 Screen.__init__(self, session)
153 self["actions"] = HelpableActionMap(self, "MoviePlayerActions",
155 "leavePlayer": (self.leavePlayer, _("leave movie player...")),
156 "leavePlayerOnExit": (self.leavePlayerOnExit, _("leave movie player...")),
157 "channelUp": (self.channelUp, _("when PiPzap enabled zap channel up...")),
158 "channelDown": (self.channelDown, _("when PiPzap enabled zap channel down...")),
161 self["DirectionActions"] = HelpableActionMap(self, "DirectionActions",
169 for x in HelpableScreen, InfoBarShowHide, InfoBarMenu, \
170 InfoBarBase, InfoBarSeek, InfoBarShowMovies, InfoBarInstantRecord, \
171 InfoBarAudioSelection, InfoBarNotifications, \
172 InfoBarServiceNotifications, InfoBarPVRState, InfoBarCueSheetSupport, \
173 InfoBarMoviePlayerSummarySupport, InfoBarSubtitleSupport, \
174 InfoBarTeletextPlugin, InfoBarServiceErrorPopupSupport, InfoBarExtensions, \
175 InfoBarPlugins, InfoBarPiP, InfoBarHotkey:
178 self.servicelist = slist
179 self.infobar = infobar
180 self.lastservice = lastservice or session.nav.getCurrentlyPlayingServiceOrGroup()
181 session.nav.playService(service)
182 self.cur_service = service
183 self.returning = False
184 self.onClose.append(self.__onClose)
187 from Screens.MovieSelection import playlist
189 if not config.movielist.stop_service.value:
190 Screens.InfoBar.InfoBar.instance.callServiceStarted()
191 self.session.nav.playService(self.lastservice)
192 config.usage.last_movie_played.value = self.cur_service.toString()
193 config.usage.last_movie_played.save()
195 def handleLeave(self, how):
196 self.is_closing = True
198 if config.usage.setup_level.index < 2: # -expert
201 (_("No"), "continue")
206 (_("Yes, returning to movie list"), "movielist"),
207 (_("Yes, and delete this movie"), "quitanddelete"),
208 (_("Yes, delete this movie and return to movie list"), "deleteandmovielist"),
209 (_("No"), "continue"),
210 (_("No, but restart from begin"), "restart")
213 from Screens.ChoiceBox import ChoiceBox
214 self.session.openWithCallback(self.leavePlayerConfirmed, ChoiceBox, title=_("Stop playing this movie?"), list = list)
216 self.leavePlayerConfirmed([True, how])
218 def leavePlayer(self):
219 setResumePoint(self.session)
220 self.handleLeave(config.usage.on_movie_stop.value)
222 def leavePlayerOnExit(self):
225 elif self.session.pipshown and "popup" in config.usage.pip_hideOnExit.value:
226 if config.usage.pip_hideOnExit.value == "popup":
227 self.session.openWithCallback(self.hidePipOnExitCallback, MessageBox, _("Disable Picture in Picture"), simple=True)
229 self.hidePipOnExitCallback(True)
230 elif config.usage.leave_movieplayer_onExit.value == "popup":
231 self.session.openWithCallback(self.leavePlayerOnExitCallback, MessageBox, _("Exit movie player?"), simple=True)
232 elif config.usage.leave_movieplayer_onExit.value == "without popup":
233 self.leavePlayerOnExitCallback(True)
235 def leavePlayerOnExitCallback(self, answer):
237 setResumePoint(self.session)
238 self.handleLeave("quit")
240 def hidePipOnExitCallback(self, answer):
244 def deleteConfirmed(self, answer):
246 self.leavePlayerConfirmed((True, "quitanddeleteconfirmed"))
248 def deleteAndMovielistConfirmed(self, answer):
250 self.leavePlayerConfirmed((True, "deleteandmovielistconfirmed"))
252 def movielistAgain(self):
253 from Screens.MovieSelection import playlist
255 self.leavePlayerConfirmed((True, "movielist"))
257 def leavePlayerConfirmed(self, answer):
258 answer = answer and answer[1]
261 if answer in ("quitanddelete", "quitanddeleteconfirmed", "deleteandmovielist", "deleteandmovielistconfirmed"):
262 ref = self.session.nav.getCurrentlyPlayingServiceOrGroup()
263 serviceHandler = enigma.eServiceCenter.getInstance()
264 if answer in ("quitanddelete", "deleteandmovielist"):
266 if config.usage.movielist_trashcan.value:
267 import Tools.Trashcan
269 trash = Tools.Trashcan.createTrashFolder(ref.getPath())
270 Screens.MovieSelection.moveServiceFiles(ref, trash)
271 # Moved to trash, okay
272 if answer == "quitanddelete":
275 self.movielistAgain()
278 print "[InfoBar] Failed to move to .Trash folder:", e
279 msg = _("Cannot move to trash can") + "\n" + str(e) + "\n"
280 info = serviceHandler.info(ref)
281 name = info and info.getName(ref) or _("this recording")
282 msg += _("Do you really want to delete %s?") % name
283 if answer == "quitanddelete":
284 self.session.openWithCallback(self.deleteConfirmed, MessageBox, msg)
285 elif answer == "deleteandmovielist":
286 self.session.openWithCallback(self.deleteAndMovielistConfirmed, MessageBox, msg)
289 elif answer in ("quitanddeleteconfirmed", "deleteandmovielistconfirmed"):
290 offline = serviceHandler.offlineOperations(ref)
291 if offline.deleteFromDisk(0):
292 self.session.openWithCallback(self.close, MessageBox, _("You cannot delete this!"), MessageBox.TYPE_ERROR)
293 if answer == "deleteandmovielistconfirmed":
294 self.movielistAgain()
297 if answer in ("quit", "quitanddeleteconfirmed"):
299 elif answer in ("movielist", "deleteandmovielistconfirmed"):
300 ref = self.session.nav.getCurrentlyPlayingServiceOrGroup()
301 self.returning = True
302 self.session.openWithCallback(self.movieSelected, Screens.MovieSelection.MovieSelection, ref)
303 self.session.nav.stopService()
304 if not config.movielist.stop_service.value:
305 self.session.nav.playService(self.lastservice)
306 elif answer == "restart":
308 self.setSeekState(self.SEEK_STATE_PLAY)
309 elif answer in ("playlist","playlistquit","loop"):
310 ( next_service, item , lenght ) = self.getPlaylistServiceInfo(self.cur_service)
311 if next_service is not None:
312 if config.usage.next_movie_msg.value:
313 self.displayPlayedName(next_service, item, lenght)
314 self.session.nav.playService(next_service)
315 self.cur_service = next_service
317 if answer == "playlist":
318 self.leavePlayerConfirmed([True,"movielist"])
319 elif answer == "loop" and lenght > 0:
320 self.leavePlayerConfirmed([True,"loop"])
322 self.leavePlayerConfirmed([True,"quit"])
323 elif answer in ("repeatcurrent"):
324 if config.usage.next_movie_msg.value:
325 (item, lenght) = self.getPlaylistServiceInfo(self.cur_service)
326 self.displayPlayedName(self.cur_service, item, lenght)
327 self.session.nav.stopService()
328 self.session.nav.playService(self.cur_service)
330 def doEofInternal(self, playing):
335 ref = self.session.nav.getCurrentlyPlayingServiceOrGroup()
338 self.handleLeave(config.usage.on_movie_eof.value)
341 slist = self.servicelist
342 if self.servicelist and self.servicelist.dopipzap:
343 if config.usage.oldstyle_zap_controls.value:
346 self.switchChannelUp()
351 if self.servicelist and self.servicelist.dopipzap:
352 if config.usage.oldstyle_zap_controls.value:
355 self.switchChannelDown()
360 if self.servicelist and self.servicelist.dopipzap:
361 if config.usage.oldstyle_zap_controls.value:
362 self.switchChannelDown()
366 InfoBarSeek.seekFwd(self)
369 if self.servicelist and self.servicelist.dopipzap:
370 if config.usage.oldstyle_zap_controls.value:
371 self.switchChannelUp()
375 InfoBarSeek.seekBack(self)
378 if config.usage.zap_with_ch_buttons.value and self.servicelist.dopipzap:
383 def channelDown(self):
384 if config.usage.zap_with_ch_buttons.value and self.servicelist.dopipzap:
389 def switchChannelDown(self):
390 if "keep" not in config.usage.servicelist_cursor_behavior.value:
391 self.servicelist.moveDown()
392 self.session.execDialog(self.servicelist)
394 def switchChannelUp(self):
395 if "keep" not in config.usage.servicelist_cursor_behavior.value:
396 self.servicelist.moveUp()
397 self.session.execDialog(self.servicelist)
400 slist = self.servicelist
401 if slist.inBouquet():
402 prev = slist.getCurrentSelection()
404 prev = prev.toString()
406 if config.usage.quickzap_bouquet_change.value:
410 cur = slist.getCurrentSelection()
412 playable = not (cur.flags & (64|8)) and hasattr(self.session, "pip") and self.session.pip.isPlayableForPipService(cur)
413 if cur.toString() == prev or playable:
417 slist.zap(enable_pipzap = True)
420 slist = self.servicelist
421 if slist.inBouquet():
422 prev = slist.getCurrentSelection()
424 prev = prev.toString()
426 if config.usage.quickzap_bouquet_change.value and slist.atEnd():
430 cur = slist.getCurrentSelection()
432 playable = not (cur.flags & (64|8)) and hasattr(self.session, "pip") and self.session.pip.isPlayableForPipService(cur)
433 if cur.toString() == prev or playable:
437 slist.zap(enable_pipzap = True)
440 slist = self.servicelist
441 if self.session.pipshown:
442 if slist and slist.dopipzap:
444 if self.session.pipshown:
446 self.session.pipshown = False
448 from Screens.PictureInPicture import PictureInPicture
449 self.session.pip = self.session.instantiateDialog(PictureInPicture)
450 self.session.pip.show()
451 if self.session.pip.playService(slist.getCurrentSelection()):
452 self.session.pipshown = True
453 self.session.pip.servicePath = slist.getCurrentServicePath()
455 self.session.pipshown = False
459 if self.session.pipshown:
460 InfoBarPiP.movePiP(self)
465 def showDefaultEPG(self):
466 self.infobar and self.infobar.showMultiEPG()
468 def openEventView(self):
469 self.infobar and self.infobar.showDefaultEPG()
471 def showEventInfoPlugins(self):
472 self.infobar and self.infobar.showEventInfoPlugins()
474 def showEventGuidePlugins(self):
475 self.infobar and self.infobar.showEventGuidePlugins()
477 def openSingleServiceEPG(self):
478 self.infobar and self.infobar.openSingleServiceEPG()
480 def openMultiServiceEPG(self):
481 self.infobar and self.infobar.openMultiServiceEPG()
483 def showMovies(self):
484 ref = self.session.nav.getCurrentlyPlayingServiceOrGroup()
485 self.playingservice = ref # movie list may change the currently playing
486 self.session.openWithCallback(self.movieSelected, Screens.MovieSelection.MovieSelection, ref)
488 def movieSelected(self, service):
489 if service is not None:
490 self.cur_service = service
491 self.is_closing = False
492 self.session.nav.playService(service)
493 self.returning = False
497 self.is_closing = False
498 ref = self.playingservice
499 del self.playingservice
500 # no selection? Continue where we left off
501 if ref and not self.session.nav.getCurrentlyPlayingServiceOrGroup():
502 self.session.nav.playService(ref)
504 def getPlaylistServiceInfo(self, service):
505 from MovieSelection import playlist
506 for i, item in enumerate(playlist):
508 if config.usage.on_movie_eof.value == "repeatcurrent":
509 return (i+1, len(playlist))
511 if i < len(playlist):
512 return (playlist[i], i+1, len(playlist))
513 elif config.usage.on_movie_eof.value == "loop":
514 return (playlist[0], 1, len(playlist))
515 return ( None, 0, 0 )
517 def displayPlayedName(self, ref, index, n):
518 from Tools import Notifications
519 Notifications.AddPopup(text = _("%s/%s: %s") % (index, n, self.ref2HumanName(ref)), type = MessageBox.TYPE_INFO, timeout = 5)
521 def ref2HumanName(self, ref):
522 return enigma.eServiceCenter.getInstance().info(ref).getName(ref)