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