enigma2 20130114 (master) -> 20130216 (master)
[enigma2.git] / usr / lib / enigma2 / python / Screens / InfoBar.py
1 from Tools.Profile import profile
2
3 # workaround for required config entry dependencies.
4 from Screens.MovieSelection import 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, InfoBarDish, InfoBarUnhandledKey, \
16         InfoBarSubserviceSelection, InfoBarShowMovies, InfoBarTimeshift,  \
17         InfoBarServiceNotifications, InfoBarPVRState, InfoBarCueSheetSupport, InfoBarSimpleEventView, \
18         InfoBarSummarySupport, InfoBarMoviePlayerSummarySupport, InfoBarTimeshiftState, InfoBarTeletextPlugin, InfobarHbbtvPlugin, InfoBarExtensions, InfoBarNotifications, \
19         InfoBarSubtitleSupport, InfoBarPiP, InfoBarPlugins, InfoBarServiceErrorPopupSupport, InfoBarJobman, InfoBarAutoSleepTimer
20
21 profile("LOAD:InitBar_Components")
22 from Components.ActionMap import HelpableActionMap
23 from Components.config import config, ConfigBoolean
24 from Components.ServiceEventTracker import ServiceEventTracker, InfoBarBase
25 from Components.PluginComponent import plugins
26 from Plugins.Plugin import PluginDescriptor
27
28 profile("LOAD:HelpableScreen")
29 from Screens.HelpMenu import HelpableScreen
30
31 config.misc.initialharddisknotification = ConfigBoolean(True)
32 config.misc.missingdefaultstoragenotification = ConfigBoolean(True)
33
34 from Tools import Notifications
35 Notifications.notificationQueue.registerDomain("InfoBar", _("InfoBar"), Notifications.ICON_DEFAULT)
36
37 class InfoBar(InfoBarBase, InfoBarShowHide,
38         InfoBarNumberZap, InfoBarChannelSelection, InfoBarMenu, InfoBarEPG, InfoBarRdsDecoder,
39         InfoBarInstantRecord, InfoBarAudioSelection,
40         HelpableScreen, InfoBarAdditionalInfo, InfoBarDish, InfoBarUnhandledKey,
41         InfoBarSubserviceSelection, InfoBarTimeshift, InfoBarSeek,
42         InfoBarSummarySupport, InfoBarTimeshiftState, InfoBarTeletextPlugin, InfobarHbbtvPlugin, InfoBarExtensions, InfoBarNotifications,
43         InfoBarPiP, InfoBarPlugins, InfoBarSubtitleSupport, InfoBarServiceErrorPopupSupport, InfoBarJobman, InfoBarAutoSleepTimer,
44         Screen):
45
46         ALLOW_SUSPEND = True
47         instance = None
48
49         def __init__(self, session):
50                 Screen.__init__(self, session)
51                 self["actions"] = HelpableActionMap(self, "InfobarActions",
52                         {
53                                 "showMovies": (self.showMovies, _("Play recorded movies...")),
54                                 "showRadio": (self.showRadio, _("Show the radio player...")),
55                                 "showTv": (self.showTv, _("Show the tv player...")),
56                         }, prio=2)
57
58                 self.allowPiP = True
59
60                 for x in HelpableScreen, \
61                                 InfoBarBase, InfoBarShowHide, \
62                                 InfoBarNumberZap, InfoBarChannelSelection, InfoBarMenu, InfoBarEPG, InfoBarRdsDecoder, \
63                                 InfoBarInstantRecord, InfoBarAudioSelection, InfoBarUnhandledKey, \
64                                 InfoBarAdditionalInfo, InfoBarDish, InfoBarSubserviceSelection, \
65                                 InfoBarTimeshift, InfoBarSeek, InfoBarSummarySupport, InfoBarTimeshiftState, \
66                                 InfoBarTeletextPlugin, InfobarHbbtvPlugin, InfoBarExtensions, InfoBarNotifications, InfoBarPiP, InfoBarSubtitleSupport, InfoBarJobman, \
67                                 InfoBarPlugins, InfoBarServiceErrorPopupSupport, InfoBarAutoSleepTimer \
68                                 :
69                         x.__init__(self)
70
71                 self.helpList.append((self["actions"], "InfobarActions", [("showMovies", _("view recordings..."))]))
72                 self.helpList.append((self["actions"], "InfobarActions", [("showRadio", _("hear radio..."))]))
73
74                 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
75                         {
76                                 iPlayableService.evUpdatedEventInfo: self.__eventInfoChanged
77                         })
78
79                 self.current_begin_time=0
80                 assert InfoBar.instance is None, "class InfoBar is a singleton class and just one instance of this class is allowed!"
81                 InfoBar.instance = self
82                 for fnc in plugins.getPlugins(PluginDescriptor.WHERE_INFOBAR):
83                         fnc(session)
84
85                 self.showHarddiskPopup()
86
87         def showHarddiskPopup(self, dev = None, media_state = None):
88                 from Components.Harddisk import harddiskmanager
89                 if not self.HDDDetectedCB in harddiskmanager.delayed_device_Notifier:
90                         harddiskmanager.delayed_device_Notifier.append(self.HDDDetectedCB)
91                 if config.misc.initialharddisknotification.value:
92                         from Screens.MessageBox import MessageBox
93                         if harddiskmanager.HDDCount() and not harddiskmanager.HDDEnabledCount():
94                                 Notifications.AddNotificationWithCallback(self.HDDDetectedAnswer, MessageBox, _("Unconfigured storage devices found!")  + "\n" \
95                                         + _("Please make sure to set up your storage devices with the storage management in menu -> setup -> system -> storage devices.") + "\n\n" \
96                                         + _("Set up your storage device now?"), type = MessageBox.TYPE_YESNO, timeout = 15, default = False, domain = "InfoBar")
97                                 config.misc.initialharddisknotification.value = False
98                                 config.misc.initialharddisknotification.save()
99                 elif config.misc.missingdefaultstoragenotification.value and not config.misc.initialharddisknotification.value:
100                         from Screens.ChoiceBox import ChoiceBox
101                         from Components.UsageConfig import defaultStorageDevice
102                         choices = [
103                                 (_("OK, do nothing"), "ok"),
104                                 (_("OK, and don't ask again"), "ok_always")
105                         ]
106                         if harddiskmanager.HDDCount():
107                                 choices.append((_("OK, and set up a new default storage device"), "ok_setup"))
108                         titletxt = _("Default storage device is not available!") + "\n"
109                         if dev is None and defaultStorageDevice() != "<undefined>" and harddiskmanager.isDefaultStorageDeviceActivebyUUID(defaultStorageDevice()) is False:
110                                 Notifications.AddNotificationWithCallback(self.missingDefaultHDDAnswer, ChoiceBox, title = titletxt \
111                                         + _("Please verify if your default storage device is attached or set up your default storage device in menu -> setup -> system -> storage devices.") + "\n", list = choices, domain = "InfoBar")
112                         elif dev is not None and defaultStorageDevice() != "<undefined>" and harddiskmanager.isDefaultStorageDeviceActivebyUUID(defaultStorageDevice()) is False:
113                                 part = harddiskmanager.getPartitionbyDevice(dev)
114                                 if part is not None and part.uuid is not None and media_state is not None and media_state == "remove_default":
115                                         titletxt = _("Default storage device was removed!") + "\n"
116                                         Notifications.AddNotificationWithCallback(self.missingDefaultHDDAnswer, ChoiceBox, title = titletxt \
117                                                 + _("Please verify if your default storage device is attached or set up your default storage device in menu -> setup -> system -> storage devices.") + "\n", list = choices, domain = "InfoBar")
118
119         def missingDefaultHDDAnswer(self, answer):
120                 answer = answer and answer[1]
121                 if answer is not None:
122                         if answer == "ok_always":
123                                 print answer
124                                 config.misc.missingdefaultstoragenotification.value = False
125                                 config.misc.missingdefaultstoragenotification.save()
126                         elif answer == "ok_setup":
127                                 print answer
128                                 from Screens.HarddiskSetup import HarddiskDriveSelection
129                                 self.session.open(HarddiskDriveSelection)
130
131         def HDDDetectedAnswer(self, answer):
132                 if answer is not None:
133                         if answer:
134                                 from Screens.HarddiskSetup import HarddiskDriveSelection
135                                 self.session.open(HarddiskDriveSelection)
136
137         def HDDDetectedCB(self, dev, media_state):
138                 if InfoBar.instance:
139                         if InfoBar.instance.execing:
140                                 self.showHarddiskPopup(dev, media_state)
141                         else:
142                                 print "HDDDetectedCB: main infobar is not execing... so we ignore hotplug event!"
143                 else:
144                                 print "HDDDetectedCB: hotplug event.. but no infobar"
145
146         def __onClose(self):
147                 InfoBar.instance = None
148
149         def __eventInfoChanged(self):
150                 if self.execing:
151                         service = self.session.nav.getCurrentService()
152                         old_begin_time = self.current_begin_time
153                         info = service and service.info()
154                         ptr = info and info.getEvent(0)
155                         self.current_begin_time = ptr and ptr.getBeginTime() or 0
156                         if config.usage.show_infobar_on_event_change.value:
157                                 if old_begin_time and old_begin_time != self.current_begin_time:
158                                         self.doShow()
159
160         def serviceStarted(self):  #override from InfoBarShowHide
161                 new = self.servicelist.newServicePlayed()
162                 if self.execing:
163                         InfoBarShowHide.serviceStarted(self)
164                         self.current_begin_time=0
165                 elif not self.__checkServiceStarted in self.onShown and new:
166                         self.onShown.append(self.__checkServiceStarted)
167
168         def __checkServiceStarted(self):
169                 self.serviceStarted()
170                 self.onShown.remove(self.__checkServiceStarted)
171
172         def showTv(self):
173                 self.showTvChannelList(True)
174
175         def showRadio(self):
176                 if config.usage.e1like_radio_mode.value:
177                         self.showRadioChannelList(True)
178                 else:
179                         self.rds_display.hide() # in InfoBarRdsDecoder
180                         from Screens.ChannelSelection import ChannelSelectionRadio
181                         self.session.openWithCallback(self.ChannelSelectionRadioClosed, ChannelSelectionRadio, self)
182
183         def ChannelSelectionRadioClosed(self, *arg):
184                 self.rds_display.show()  # in InfoBarRdsDecoder
185
186         def showMovies(self):
187                 from Screens.MovieSelection import MovieSelection
188                 self.session.openWithCallback(self.movieSelected, MovieSelection)
189
190         def movieSelected(self, service):
191                 if service is not None:
192                         self.session.open(MoviePlayer, service)
193
194 class MoviePlayer(InfoBarBase, InfoBarShowHide, \
195                 InfoBarMenu, \
196                 InfoBarSeek, InfoBarShowMovies, InfoBarAudioSelection, HelpableScreen,
197                 InfoBarServiceNotifications, InfoBarPVRState, InfoBarCueSheetSupport, InfoBarSimpleEventView,
198                 InfoBarMoviePlayerSummarySupport, InfoBarSubtitleSupport, Screen, InfoBarTeletextPlugin,
199                 InfoBarServiceErrorPopupSupport, InfoBarExtensions, InfoBarNotifications, InfoBarPlugins, InfoBarPiP):
200
201         ENABLE_RESUME_SUPPORT = True
202         ALLOW_SUSPEND = True
203
204         def __init__(self, session, service):
205                 from enigma import eServiceMP3
206                 Screen.__init__(self, session)
207
208                 self["actions"] = HelpableActionMap(self, "MoviePlayerActions",
209                         {
210                                 "leavePlayer": (self.leavePlayer, _("leave movie player..."))
211                         })
212
213                 self.allowPiP = False
214
215                 for x in HelpableScreen, InfoBarShowHide, InfoBarMenu, \
216                                 InfoBarBase, InfoBarSeek, InfoBarShowMovies, \
217                                 InfoBarAudioSelection, InfoBarSimpleEventView, \
218                                 InfoBarServiceNotifications, InfoBarPVRState, InfoBarCueSheetSupport, \
219                                 InfoBarMoviePlayerSummarySupport, InfoBarSubtitleSupport, \
220                                 InfoBarTeletextPlugin, InfoBarServiceErrorPopupSupport, InfoBarExtensions, InfoBarNotifications, \
221                                 InfoBarPlugins, InfoBarPiP:
222                         x.__init__(self)
223
224                 self.lastservice = session.nav.getCurrentlyPlayingServiceReference()
225                 session.nav.playService(service)
226                 self.returning = False
227                 self.onClose.append(self.__onClose)
228
229                 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
230                         {
231                                 eServiceMP3.evAudioDecodeError: self.__evAudioDecodeError,
232                                 eServiceMP3.evVideoDecodeError: self.__evVideoDecodeError,
233                                 eServiceMP3.evPluginError: self.__evPluginError,
234                                 eServiceMP3.evStreamingSrcError: self.__evStreamingSrcError
235                         })
236
237         def __evAudioDecodeError(self):
238                 from Screens.MessageBox import MessageBox
239                 from enigma import iServiceInformation
240                 currPlay = self.session.nav.getCurrentService()
241                 sTagAudioCodec = currPlay.info().getInfoString(iServiceInformation.sTagAudioCodec)
242                 print "[__evAudioDecodeError] audio-codec %s can't be decoded by hardware" % (sTagAudioCodec)
243                 self.session.open(MessageBox, _("This Dreambox can't decode %s streams!") % sTagAudioCodec, type = MessageBox.TYPE_INFO,timeout = 20 )
244
245         def __evVideoDecodeError(self):
246                 from Screens.MessageBox import MessageBox
247                 from enigma import iServiceInformation
248                 currPlay = self.session.nav.getCurrentService()
249                 sTagVideoCodec = currPlay.info().getInfoString(iServiceInformation.sTagVideoCodec)
250                 print "[__evVideoDecodeError] video-codec %s can't be decoded by hardware" % (sTagVideoCodec)
251                 self.session.open(MessageBox, _("This Dreambox can't decode %s streams!") % sTagVideoCodec, type = MessageBox.TYPE_INFO,timeout = 20 )
252
253         def __evPluginError(self):
254                 from Screens.MessageBox import MessageBox
255                 from enigma import iServiceInformation
256                 currPlay = self.session.nav.getCurrentService()
257                 message = currPlay.info().getInfoString(iServiceInformation.sUser+12)
258                 print "[__evPluginError]" , message
259                 self.session.open(MessageBox, message, type = MessageBox.TYPE_INFO,timeout = 20 )
260
261         def __evStreamingSrcError(self):
262                 from Screens.MessageBox import MessageBox
263                 from enigma import iServiceInformation
264                 currPlay = self.session.nav.getCurrentService()
265                 message = currPlay.info().getInfoString(iServiceInformation.sUser+12)
266                 print "[__evStreamingSrcError]", message
267                 self.session.open(MessageBox, _("Streaming error: %s") % message, type = MessageBox.TYPE_INFO,timeout = 20 )
268
269         def __onClose(self):
270                 self.session.nav.playService(self.lastservice)
271
272         def handleLeave(self, how):
273                 self.is_closing = True
274                 if how == "ask":
275                         if config.usage.setup_level.index < 2: # -expert
276                                 list = (
277                                         (_("Yes"), "quit"),
278                                         (_("No"), "continue")
279                                 )
280                         else:
281                                 list = (
282                                         (_("Yes"), "quit"),
283                                         (_("Yes, returning to movie list"), "movielist"),
284                                         (_("Yes, and delete this movie"), "quitanddelete"),
285                                         (_("No"), "continue"),
286                                         (_("No, but restart from begin"), "restart")
287                                 )
288
289                         from Screens.ChoiceBox import ChoiceBox
290                         self.session.openWithCallback(self.leavePlayerConfirmed, ChoiceBox, title=_("Stop playing this movie?"), list = list)
291                 else:
292                         self.leavePlayerConfirmed([True, how])
293
294         def leavePlayer(self):
295                 self.handleLeave(config.usage.on_movie_stop.value)
296
297         def deleteConfirmed(self, answer):
298                 if answer:
299                         self.leavePlayerConfirmed((True, "quitanddeleteconfirmed"))
300
301         def leavePlayerConfirmed(self, answer):
302                 answer = answer and answer[1]
303
304                 if answer in ("quitanddelete", "quitanddeleteconfirmed"):
305                         ref = self.session.nav.getCurrentlyPlayingServiceReference()
306                         from enigma import eServiceCenter
307                         serviceHandler = eServiceCenter.getInstance()
308                         info = serviceHandler.info(ref)
309                         name = info and info.getName(ref) or _("this recording")
310
311                         if answer == "quitanddelete":
312                                 from Screens.MessageBox import MessageBox
313                                 self.session.openWithCallback(self.deleteConfirmed, MessageBox, _("Do you really want to delete %s?") % name)
314                                 return
315
316                         elif answer == "quitanddeleteconfirmed":
317                                 offline = serviceHandler.offlineOperations(ref)
318                                 if offline.deleteFromDisk(0):
319                                         from Screens.MessageBox import MessageBox
320                                         self.session.openWithCallback(self.close, MessageBox, _("You cannot delete this!"), MessageBox.TYPE_ERROR)
321                                         return
322
323                 if answer in ("quit", "quitanddeleteconfirmed"):
324                         self.close()
325                 elif answer == "movielist":
326                         ref = self.session.nav.getCurrentlyPlayingServiceReference()
327                         self.returning = True
328                         from Screens.MovieSelection import MovieSelection
329                         self.session.openWithCallback(self.movieSelected, MovieSelection, ref)
330                         self.session.nav.stopService()
331                 elif answer == "restart":
332                         self.doSeek(0)
333                         self.setSeekState(self.SEEK_STATE_PLAY)
334
335         def doEofInternal(self, playing):
336                 if not self.execing:
337                         return
338                 if not playing :
339                         return
340                 self.handleLeave(config.usage.on_movie_eof.value)
341
342         def showMovies(self):
343                 ref = self.session.nav.getCurrentlyPlayingServiceReference()
344                 from Screens.MovieSelection import MovieSelection
345                 self.session.openWithCallback(self.movieSelected, MovieSelection, ref)
346
347         def movieSelected(self, service):
348                 if service is not None:
349                         self.is_closing = False
350                         self.session.nav.playService(service)
351                         self.returning = False
352                 elif self.returning:
353                         self.close()