fd10d934c46ba04db6a6864ed51e049188e7f371
[openblackhole/openblackhole-enigma2.git] / lib / python / Screens / InfoBar.py
1 from Tools.Profile import profile
2
3 # workaround for required config entry dependencies.
4 import Screens.MovieSelection
5
6 from Screen import Screen
7
8 profile("LOAD:enigma")
9 from enigma import iPlayableService
10
11 profile("LOAD:InfoBarGenerics")
12 from Screens.InfoBarGenerics import InfoBarShowHide, \
13         InfoBarNumberZap, InfoBarChannelSelection, InfoBarMenu, InfoBarRdsDecoder, \
14         InfoBarEPG, InfoBarSeek, InfoBarInstantRecord, \
15         InfoBarAudioSelection, InfoBarAdditionalInfo, InfoBarNotifications, InfoBarDish, InfoBarUnhandledKey, \
16         InfoBarSubserviceSelection, InfoBarShowMovies, InfoBarTimeshift,  \
17         InfoBarServiceNotifications, InfoBarPVRState, InfoBarCueSheetSupport, InfoBarSimpleEventView, \
18         InfoBarSummarySupport, InfoBarMoviePlayerSummarySupport, InfoBarTimeshiftState, InfoBarTeletextPlugin, InfoBarExtensions, \
19         InfoBarSubtitleSupport, InfoBarPiP, InfoBarPlugins, InfoBarServiceErrorPopupSupport, InfoBarJobman
20
21 profile("LOAD:InitBar_Components")
22 from Components.ActionMap import HelpableActionMap
23 from Components.config import config
24 from Components.ServiceEventTracker import ServiceEventTracker, InfoBarBase
25
26 profile("LOAD:HelpableScreen")
27 from Screens.HelpMenu import HelpableScreen
28
29 class InfoBar(InfoBarBase, InfoBarShowHide,
30         InfoBarNumberZap, InfoBarChannelSelection, InfoBarMenu, InfoBarEPG, InfoBarRdsDecoder,
31         InfoBarInstantRecord, InfoBarAudioSelection, 
32         HelpableScreen, InfoBarAdditionalInfo, InfoBarNotifications, InfoBarDish, InfoBarUnhandledKey,
33         InfoBarSubserviceSelection, InfoBarTimeshift, InfoBarSeek,
34         InfoBarSummarySupport, InfoBarTimeshiftState, InfoBarTeletextPlugin, InfoBarExtensions,
35         InfoBarPiP, InfoBarPlugins, InfoBarSubtitleSupport, InfoBarServiceErrorPopupSupport, InfoBarJobman,
36         Screen):
37         
38         ALLOW_SUSPEND = True
39         instance = None
40
41         def __init__(self, session):
42                 Screen.__init__(self, session)
43                 self["actions"] = HelpableActionMap(self, "InfobarActions",
44                         {
45                                 "showMovies": (self.showMovies, _("Play recorded movies...")),
46                                 "showRadio": (self.showRadio, _("Show the radio player...")),
47                                 "showTv": (self.showTv, _("Show the tv player...")),
48                         }, prio=2)
49                 
50                 self.allowPiP = True
51                 
52                 for x in HelpableScreen, \
53                                 InfoBarBase, InfoBarShowHide, \
54                                 InfoBarNumberZap, InfoBarChannelSelection, InfoBarMenu, InfoBarEPG, InfoBarRdsDecoder, \
55                                 InfoBarInstantRecord, InfoBarAudioSelection, InfoBarUnhandledKey, \
56                                 InfoBarAdditionalInfo, InfoBarNotifications, InfoBarDish, InfoBarSubserviceSelection, \
57                                 InfoBarTimeshift, InfoBarSeek, InfoBarSummarySupport, InfoBarTimeshiftState, \
58                                 InfoBarTeletextPlugin, InfoBarExtensions, InfoBarPiP, InfoBarSubtitleSupport, InfoBarJobman, \
59                                 InfoBarPlugins, InfoBarServiceErrorPopupSupport:
60                         x.__init__(self)
61
62                 self.helpList.append((self["actions"], "InfobarActions", [("showMovies", _("view recordings..."))]))
63                 self.helpList.append((self["actions"], "InfobarActions", [("showRadio", _("hear radio..."))]))
64
65                 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
66                         {
67                                 iPlayableService.evUpdatedEventInfo: self.__eventInfoChanged
68                         })
69
70                 self.current_begin_time=0
71                 assert InfoBar.instance is None, "class InfoBar is a singleton class and just one instance of this class is allowed!"
72                 InfoBar.instance = self
73
74         def __onClose(self):
75                 InfoBar.instance = None
76
77         def __eventInfoChanged(self):
78                 if self.execing:
79                         service = self.session.nav.getCurrentService()
80                         old_begin_time = self.current_begin_time
81                         info = service and service.info()
82                         ptr = info and info.getEvent(0)
83                         self.current_begin_time = ptr and ptr.getBeginTime() or 0
84                         if config.usage.show_infobar_on_event_change.value:
85                                 if old_begin_time and old_begin_time != self.current_begin_time:
86                                         self.doShow()
87
88         def __checkServiceStarted(self):
89                 self.__serviceStarted(True)
90                 self.onExecBegin.remove(self.__checkServiceStarted)
91
92         def serviceStarted(self):  #override from InfoBarShowHide
93                 new = self.servicelist.newServicePlayed()
94                 if self.execing:
95                         InfoBarShowHide.serviceStarted(self)
96                         self.current_begin_time=0
97                 elif not self.__checkServiceStarted in self.onShown and new:
98                         self.onShown.append(self.__checkServiceStarted)
99
100         def __checkServiceStarted(self):
101                 self.serviceStarted()
102                 self.onShown.remove(self.__checkServiceStarted)
103
104         def showTv(self):
105                 self.showTvChannelList(True)
106
107         def showRadio(self):
108                 if config.usage.e1like_radio_mode.value:
109                         self.showRadioChannelList(True)
110                 else:
111                         self.rds_display.hide() # in InfoBarRdsDecoder
112                         from Screens.ChannelSelection import ChannelSelectionRadio
113                         self.session.openWithCallback(self.ChannelSelectionRadioClosed, ChannelSelectionRadio, self)
114
115         def ChannelSelectionRadioClosed(self, *arg):
116                 self.rds_display.show()  # in InfoBarRdsDecoder
117
118         def showMovies(self, defaultRef=None):
119                 self.lastservice = self.session.nav.getCurrentlyPlayingServiceReference()
120                 self.session.openWithCallback(self.movieSelected, Screens.MovieSelection.MovieSelection, defaultRef)
121
122         def movieSelected(self, service):
123                 ref = self.lastservice
124                 del self.lastservice
125                 if service is None:
126                         if ref and not self.session.nav.getCurrentlyPlayingServiceReference():
127                                 self.session.nav.playService(ref)
128                 else:
129                         self.session.open(MoviePlayer, service, slist = self.servicelist, lastservice = ref)
130
131 class MoviePlayer(InfoBarBase, InfoBarShowHide, \
132                 InfoBarMenu, \
133                 InfoBarSeek, InfoBarShowMovies, InfoBarAudioSelection, HelpableScreen, InfoBarNotifications,
134                 InfoBarServiceNotifications, InfoBarPVRState, InfoBarCueSheetSupport, InfoBarSimpleEventView,
135                 InfoBarMoviePlayerSummarySupport, InfoBarSubtitleSupport, Screen, InfoBarTeletextPlugin,
136                 InfoBarServiceErrorPopupSupport, InfoBarExtensions, InfoBarPlugins, InfoBarPiP):
137
138         ENABLE_RESUME_SUPPORT = True
139         ALLOW_SUSPEND = True
140                 
141         def __init__(self, session, service, slist = None, lastservice = None):
142                 Screen.__init__(self, session)
143                 
144                 self["actions"] = HelpableActionMap(self, "MoviePlayerActions",
145                         {
146                                 "leavePlayer": (self.leavePlayer, _("leave movie player..."))
147                         })
148
149                 self["DirectionActions"] = HelpableActionMap(self, "DirectionActions",
150                         {
151                                 "left": self.left,
152                                 "right": self.right
153                         }, prio = -2)
154
155                 self.allowPiP = True
156                 
157                 for x in HelpableScreen, InfoBarShowHide, InfoBarMenu, \
158                                 InfoBarBase, InfoBarSeek, InfoBarShowMovies, \
159                                 InfoBarAudioSelection, InfoBarNotifications, InfoBarSimpleEventView, \
160                                 InfoBarServiceNotifications, InfoBarPVRState, InfoBarCueSheetSupport, \
161                                 InfoBarMoviePlayerSummarySupport, InfoBarSubtitleSupport, \
162                                 InfoBarTeletextPlugin, InfoBarServiceErrorPopupSupport, InfoBarExtensions, \
163                                 InfoBarPlugins, InfoBarPiP:
164                         x.__init__(self)
165
166                 self.servicelist = slist
167                 self.lastservice = lastservice or session.nav.getCurrentlyPlayingServiceReference()
168                 session.nav.playService(service)
169                 self.returning = False
170                 self.onClose.append(self.__onClose)
171
172         def __onClose(self):
173                 self.session.nav.playService(self.lastservice)
174
175         def handleLeave(self, how):
176                 self.is_closing = True
177                 if how == "ask":
178                         if config.usage.setup_level.index < 2: # -expert
179                                 list = (
180                                         (_("Yes"), "quit"),
181                                         (_("No"), "continue")
182                                 )
183                         else:
184                                 list = (
185                                         (_("Yes"), "quit"),
186                                         (_("Yes, returning to movie list"), "movielist"),
187                                         (_("Yes, and delete this movie"), "quitanddelete"),
188                                         (_("No"), "continue"),
189                                         (_("No, but restart from begin"), "restart")
190                                 )
191
192                         from Screens.ChoiceBox import ChoiceBox
193                         self.session.openWithCallback(self.leavePlayerConfirmed, ChoiceBox, title=_("Stop playing this movie?"), list = list)
194                 else:
195                         self.leavePlayerConfirmed([True, how])
196
197         def leavePlayer(self):
198                 self.handleLeave(config.usage.on_movie_stop.value)
199
200         def deleteConfirmed(self, answer):
201                 if answer:
202                         self.leavePlayerConfirmed((True, "quitanddeleteconfirmed"))
203
204         def leavePlayerConfirmed(self, answer):
205                 answer = answer and answer[1]
206
207                 if answer in ("quitanddelete", "quitanddeleteconfirmed"):
208                         ref = self.session.nav.getCurrentlyPlayingServiceReference()
209                         from enigma import eServiceCenter
210                         serviceHandler = eServiceCenter.getInstance()
211                         if answer == "quitanddelete":
212                                 msg = ''
213                                 if config.usage.movielist_trashcan.value:
214                                         import Tools.Trashcan
215                                         try:
216                                                 trash = Tools.Trashcan.createTrashFolder()
217                                                 Screens.MovieSelection.moveServiceFiles(ref, trash)
218                                                 # Moved to trash, okay
219                                                 self.close()
220                                                 return
221                                         except Exception, e:
222                                                 print "[InfoBar] Failed to move to .Trash folder:", e
223                                                 msg = _("Cannot move to trash can") + "\n" + str(e) + "\n"
224                                 info = serviceHandler.info(ref)
225                                 name = info and info.getName(ref) or _("this recording")
226                                 msg += _("Do you really want to delete %s?") % name
227                                 from Screens.MessageBox import MessageBox
228                                 self.session.openWithCallback(self.deleteConfirmed, MessageBox, msg)
229                                 return
230
231                         elif answer == "quitanddeleteconfirmed":
232                                 offline = serviceHandler.offlineOperations(ref)
233                                 if offline.deleteFromDisk(0):
234                                         from Screens.MessageBox import MessageBox
235                                         self.session.openWithCallback(self.close, MessageBox, _("You cannot delete this!"), MessageBox.TYPE_ERROR)
236                                         return
237
238                 if answer in ("quit", "quitanddeleteconfirmed"):
239                         self.close()
240                 elif answer == "movielist":
241                         ref = self.session.nav.getCurrentlyPlayingServiceReference()
242                         self.returning = True
243                         self.session.openWithCallback(self.movieSelected, Screens.MovieSelection.MovieSelection, ref)
244                         self.session.nav.stopService()
245                 elif answer == "restart":
246                         self.doSeek(0)
247                         self.setSeekState(self.SEEK_STATE_PLAY)
248
249         def doEofInternal(self, playing):
250                 if not self.execing:
251                         return
252                 if not playing :
253                         return
254                 self.handleLeave(config.usage.on_movie_eof.value)
255
256         def up(self):
257                 slist = self.servicelist
258                 if slist and slist.dopipzap:
259                         slist.moveUp()
260                         self.session.execDialog(slist)
261                 else:
262                         self.showMovies()
263
264         def down(self):
265                 slist = self.servicelist
266                 if slist and slist.dopipzap:
267                         slist.moveDown()
268                         self.session.execDialog(slist)
269                 else:
270                         self.showMovies()
271
272         def right(self):
273                 # XXX: gross hack, we do not really seek if changing channel in pip :-)
274                 slist = self.servicelist
275                 if slist and slist.dopipzap:
276                         # XXX: We replicate InfoBarChannelSelection.zapDown here - we shouldn't do that
277                         if slist.inBouquet():
278                                 prev = slist.getCurrentSelection()
279                                 if prev:
280                                         prev = prev.toString()
281                                         while True:
282                                                 if config.usage.quickzap_bouquet_change.value and slist.atEnd():
283                                                         slist.nextBouquet()
284                                                 else:
285                                                         slist.moveDown()
286                                                 cur = slist.getCurrentSelection()
287                                                 if not cur or (not (cur.flags & 64)) or cur.toString() == prev:
288                                                         break
289                         else:
290                                 slist.moveDown()
291                         slist.zap(enable_pipzap = True)
292                 else:
293                         InfoBarSeek.seekFwd(self)
294
295         def left(self):
296                 slist = self.servicelist
297                 if slist and slist.dopipzap:
298                         # XXX: We replicate InfoBarChannelSelection.zapUp here - we shouldn't do that
299                         if slist.inBouquet():
300                                 prev = slist.getCurrentSelection()
301                                 if prev:
302                                         prev = prev.toString()
303                                         while True:
304                                                 if config.usage.quickzap_bouquet_change.value:
305                                                         if slist.atBegin():
306                                                                 slist.prevBouquet()
307                                                 slist.moveUp()
308                                                 cur = slist.getCurrentSelection()
309                                                 if not cur or (not (cur.flags & 64)) or cur.toString() == prev:
310                                                         break
311                         else:
312                                 slist.moveUp()
313                         slist.zap(enable_pipzap = True)
314                 else:
315                         InfoBarSeek.seekBack(self)
316
317         def showPiP(self):
318                 slist = self.servicelist
319                 if self.session.pipshown:
320                         if slist and slist.dopipzap:
321                                 slist.togglePipzap()
322                         del self.session.pip
323                         self.session.pipshown = False
324                 else:
325                         from Screens.PictureInPicture import PictureInPicture
326                         self.session.pip = self.session.instantiateDialog(PictureInPicture)
327                         self.session.pip.show()
328                         self.session.pipshown = True
329                         self.session.pip.playService(slist.getCurrentSelection())
330
331         def swapPiP(self):
332                 pass
333
334         def showMovies(self):
335                 ref = self.session.nav.getCurrentlyPlayingServiceReference()
336                 self.playingservice = ref # movie list may change the currently playing
337                 self.session.openWithCallback(self.movieSelected, Screens.MovieSelection.MovieSelection, ref)
338
339         def movieSelected(self, service):
340                 if service is not None:
341                         self.is_closing = False
342                         self.session.nav.playService(service)
343                         self.returning = False
344                 elif self.returning:
345                         self.close()
346                 else:
347                         self.is_closing = False
348                         ref = self.playingservice
349                         del self.playingservice
350                         # no selection? Continue where we left off
351                         if ref and not self.session.nav.getCurrentlyPlayingServiceReference():
352                                 self.session.nav.playService(ref)