[RecordTimer] fix repeat timer issue.
[vuplus_dvbapp] / lib / python / Screens / AudioSelection.py
1 from Screen import Screen
2 from Screens.Setup import getConfigMenuItem
3 from Components.ServiceEventTracker import ServiceEventTracker
4 from Components.ActionMap import NumberActionMap
5 from Components.ConfigList import ConfigListScreen
6 from Components.ChoiceList import ChoiceList, ChoiceEntryComponent
7 from Components.config import config, ConfigSubsection, getConfigListEntry, ConfigNothing, ConfigSelection, ConfigOnOff
8 from Components.Label import Label
9 from Components.MultiContent import MultiContentEntryText
10 from Components.Sources.List import List
11 from Components.Sources.Boolean import Boolean
12 from Components.SystemInfo import SystemInfo
13
14 from enigma import iPlayableService, eTimer, eSize
15
16 from Tools.ISO639 import LanguageCodes
17 from Tools.BoundFunction import boundFunction
18 FOCUS_CONFIG, FOCUS_STREAMS = range(2)
19 [PAGE_AUDIO, PAGE_SUBTITLES] = ["audio", "subtitles"]
20
21 class AudioSelection(Screen, ConfigListScreen):
22         def __init__(self, session, infobar=None, page=PAGE_AUDIO):
23                 Screen.__init__(self, session)
24
25                 self["streams"] = List([])
26                 self["key_red"] = Boolean(False)
27                 self["key_green"] = Boolean(False)
28                 self["key_yellow"] = Boolean(True)
29                 self["key_blue"] = Boolean(False)
30                 
31                 ConfigListScreen.__init__(self, [])
32                 self.infobar = infobar or self.session.infobar
33
34                 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
35                         {
36                                 iPlayableService.evUpdatedInfo: self.__updatedInfo
37                         })
38                 self.cached_subtitle_checked = False
39                 self.__selected_subtitle = None
40         
41                 self["actions"] = NumberActionMap(["ColorActions", "SetupActions", "DirectionActions"],
42                 {
43                         "red": self.keyRed,
44                         "green": self.keyGreen,
45                         "yellow": self.keyYellow,
46                         "blue": self.keyBlue,
47                         "ok": self.keyOk,
48                         "cancel": self.cancel,
49                         "up": self.keyUp,
50                         "down": self.keyDown,
51                         "1": self.keyNumberGlobal,
52                         "2": self.keyNumberGlobal,
53                         "3": self.keyNumberGlobal,
54                         "4": self.keyNumberGlobal,
55                         "5": self.keyNumberGlobal,
56                         "6": self.keyNumberGlobal,
57                         "7": self.keyNumberGlobal,
58                         "8": self.keyNumberGlobal,
59                         "9": self.keyNumberGlobal,
60                 }, -2)
61
62                 self.settings = ConfigSubsection()
63                 choicelist = [(PAGE_AUDIO,_("audio tracks")), (PAGE_SUBTITLES,_("Subtitles"))]
64                 self.settings.menupage = ConfigSelection(choices = choicelist, default=page)
65                 self.onLayoutFinish.append(self.__layoutFinished)
66
67         def __layoutFinished(self):
68                 self["config"].instance.setSelectionEnable(False)
69                 self.focus = FOCUS_STREAMS
70                 self.settings.menupage.addNotifier(self.fillList)
71
72         def fillList(self, arg=None):
73                 streams = []
74                 conflist = []
75                 selectedidx = 0
76
77                 if self.settings.menupage.getValue() == PAGE_AUDIO:
78                         self.setTitle(_("Select audio track"))
79                         service = self.session.nav.getCurrentService()
80                         self.audioTracks = audio = service and service.audioTracks()
81                         n = audio and audio.getNumberOfTracks() or 0
82                         if SystemInfo["CanDownmixAC3"]:
83                                 self.settings.downmix = ConfigOnOff(default=config.av.downmix_ac3.value)
84                                 self.settings.downmix.addNotifier(self.changeAC3Downmix, initial_call = False)
85                                 conflist.append(getConfigListEntry(_("Dolby Digital / DTS downmix"), self.settings.downmix))
86                                 self["key_red"].setBoolean(True)
87
88                         if n > 0:
89                                 self.audioChannel = service.audioChannel()
90                                 if self.audioChannel:
91                                         choicelist = [("0",_("left")), ("1",_("stereo")), ("2", _("right"))]
92                                         self.settings.channelmode = ConfigSelection(choices = choicelist, default = str(self.audioChannel.getCurrentChannel()))
93                                         self.settings.channelmode.addNotifier(self.changeMode, initial_call = False)
94                                         conflist.append(getConfigListEntry(_("Channel"), self.settings.channelmode))
95                                         self["key_green"].setBoolean(True)
96                                 else:
97                                         conflist.append(('',))
98                                         self["key_green"].setBoolean(False)
99                                 selectedAudio = self.audioTracks.getCurrentTrack()
100                                 for x in range(n):
101                                         number = str(x + 1)
102                                         i = audio.getTrackInfo(x)
103                                         languages = i.getLanguage().split('/')
104                                         description = i.getDescription() or _("<unknown>")
105                                         selected = ""
106                                         language = ""
107
108                                         if selectedAudio == x:
109                                                 selected = _("Running")
110                                                 selectedidx = x
111
112                                         cnt = 0
113                                         for lang in languages:
114                                                 if cnt:
115                                                         language += ' / '
116                                                 if LanguageCodes.has_key(lang):
117                                                         language += LanguageCodes[lang][0]
118                                                 elif lang == "und":
119                                                         _("<unknown>")
120                                                 else:
121                                                         language += lang
122                                                 cnt += 1
123
124                                         streams.append((x, "", number, description, language, selected))
125
126                         else:
127                                 streams = []
128                                 conflist.append(('',))
129                                 self["key_green"].setBoolean(False)
130
131                 elif self.settings.menupage.getValue() == PAGE_SUBTITLES:
132                         self.setTitle(_("Subtitle selection"))
133                         conflist.append(('',))
134                         self["key_red"].setBoolean(False)
135                         if self.infobar.selected_subtitle:
136                                 conflist.append(getConfigListEntry(_("Subtitle Quickmenu"), ConfigNothing()))
137                                 self["key_green"].setBoolean(True)
138                         else:
139                                 conflist.append(('',))
140                                 self["key_green"].setBoolean(False)
141
142                         if self.subtitlesEnabled():
143                                 sel = self.infobar.selected_subtitle
144                         else:
145                                 sel = None
146
147                         idx = 0
148                         
149                         subtitlelist = self.getSubtitleList()
150
151                         if len(subtitlelist):
152                                 for x in subtitlelist:
153                                         number = str(x[1])
154                                         description = "?"
155                                         language = _("<unknown>")
156                                         selected = ""
157
158                                         if sel and x == sel:
159                                                 selected = _("Running")
160                                                 selectedidx = idx
161                                         
162                                         if x[4] != "und":
163                                                 if LanguageCodes.has_key(x[4]):
164                                                         language = LanguageCodes[x[4]][0]
165                                                 else:
166                                                         language = x[4]
167
168                                         if x[0] == 0:
169                                                 description = "DVB"
170                                                 number = "%x" % (x[1])
171
172                                         elif x[0] == 1:
173                                                 description = "TTX"
174                                                 number = "%x%02x" % (x[3],x[2])
175
176                                         elif x[0] == 2:
177                                                 types = (_("<unknown>"), "UTF-8 text", "SSA", "AAS", ".SRT file", "VOB", "PGS (unsupported)")
178                                                 description = types[x[2]]
179
180                                         streams.append((x, "", number, description, language, selected))
181                                         idx += 1
182                         
183                         else:
184                                 streams = []
185
186                 conflist.append(getConfigListEntry(_("Menu"), self.settings.menupage))
187                 
188                 from Components.PluginComponent import plugins
189                 from Plugins.Plugin import PluginDescriptor
190                 
191                 if hasattr(self.infobar, "runPlugin"):
192                         class PluginCaller:
193                                 def __init__(self, fnc, *args):
194                                         self.fnc = fnc
195                                         self.args = args
196                                 def __call__(self, *args, **kwargs):
197                                         self.fnc(*self.args)
198
199                         Plugins = [ (p.name, PluginCaller(self.infobar.runPlugin, p)) for p in plugins.getPlugins(where = PluginDescriptor.WHERE_AUDIOMENU) ]
200
201                         if len(Plugins):
202                                 self["key_blue"].setBoolean(True)
203                                 conflist.append(getConfigListEntry(Plugins[0][0], ConfigNothing()))
204                                 self.plugincallfunc = Plugins[0][1]
205                         if len(Plugins) > 1:
206                                 print "plugin(s) installed but not displayed in the dialog box:", Plugins[1:]
207
208                 self["config"].list = conflist
209                 self["config"].l.setList(conflist)
210
211                 self["streams"].list = streams
212                 self["streams"].setIndex(selectedidx)
213
214         def __updatedInfo(self):
215                 self.fillList()
216
217         def getSubtitleList(self):
218                 s = self.infobar and self.infobar.getCurrentServiceSubtitle()
219                 l = s and s.getSubtitleList() or [ ]
220                 return l
221
222         def subtitlesEnabled(self):
223                 return self.infobar.subtitles_enabled
224
225         def enableSubtitle(self, subtitles):
226                 if self.infobar.selected_subtitle != subtitles:
227                         self.infobar.subtitles_enabled = False
228                         self.infobar.selected_subtitle = subtitles
229                         if subtitles:
230                                 self.infobar.subtitles_enabled = True
231
232         def changeAC3Downmix(self, downmix):
233                 if downmix.getValue() == True:
234                         config.av.downmix_ac3.value = True
235                 else:
236                         config.av.downmix_ac3.value = False
237                 config.av.downmix_ac3.save()
238
239         def changeMode(self, mode):
240                 if mode is not None and self.audioChannel:
241                         self.audioChannel.selectChannel(int(mode.getValue()))
242
243         def changeAudio(self, audio):
244                 track = int(audio)
245                 if isinstance(track, int):
246                         if self.session.nav.getCurrentService().audioTracks().getNumberOfTracks() > track:
247                                 self.audioTracks.selectTrack(track)
248
249         def keyLeft(self):
250                 if self.focus == FOCUS_CONFIG:
251                         ConfigListScreen.keyLeft(self)
252                 elif self.focus == FOCUS_STREAMS:
253                         self["streams"].setIndex(0)
254
255         def keyRight(self, config = False):
256                 if config or self.focus == FOCUS_CONFIG:
257                         if self["config"].getCurrentIndex() < 3:
258                                 if self["config"].getCurrentIndex() == 1 and self.settings.menupage.getValue() == PAGE_SUBTITLES and self.infobar.selected_subtitle:
259                                         self.session.open(QuickSubtitlesConfigMenu, self.infobar)
260                                 else:
261                                         ConfigListScreen.keyRight(self)
262                         elif hasattr(self, "plugincallfunc"):
263                                 self.plugincallfunc()
264                 if self.focus == FOCUS_STREAMS and self["streams"].count() and config == False:
265                         self["streams"].setIndex(self["streams"].count()-1)
266
267         def keyRed(self):
268                 if self["key_red"].getBoolean():
269                         self.colorkey(0)
270
271         def keyGreen(self):
272                 if self["key_green"].getBoolean():
273                         self.colorkey(1)
274
275         def keyYellow(self):
276                 if self["key_yellow"].getBoolean():
277                         self.colorkey(2)
278
279         def keyBlue(self):
280                 if self["key_blue"].getBoolean():
281                         self.colorkey(3)
282
283         def colorkey(self, idx):
284                 self["config"].setCurrentIndex(idx)
285                 self.keyRight(True)
286
287         def keyUp(self):
288                 if self.focus == FOCUS_CONFIG:
289                         self["config"].instance.moveSelection(self["config"].instance.moveUp)
290                 elif self.focus == FOCUS_STREAMS:
291                         if self["streams"].getIndex() == 0:
292                                 self["config"].instance.setSelectionEnable(True)
293                                 self["streams"].style = "notselected"
294                                 self["config"].setCurrentIndex(len(self["config"].getList())-1)
295                                 self.focus = FOCUS_CONFIG
296                         else:
297                                 self["streams"].selectPrevious()
298
299         def keyDown(self):
300                 if self.focus == FOCUS_CONFIG:
301                         if self["config"].getCurrentIndex() < len(self["config"].getList())-1:
302                                 self["config"].instance.moveSelection(self["config"].instance.moveDown)
303                         else:
304                                 self["config"].instance.setSelectionEnable(False)
305                                 self["streams"].style = "default"
306                                 self.focus = FOCUS_STREAMS
307                 elif self.focus == FOCUS_STREAMS:
308                         self["streams"].selectNext()
309
310         def keyNumberGlobal(self, number):
311                 if number <= len(self["streams"].list):
312                         self["streams"].setIndex(number-1)
313                         self.keyOk()
314
315         def keyOk(self):
316                 if self.focus == FOCUS_STREAMS and self["streams"].list:
317                         cur = self["streams"].getCurrent()
318                         if self.settings.menupage.getValue() == PAGE_AUDIO and cur[0] is not None:
319                                 self.changeAudio(cur[0])
320                                 self.__updatedInfo()
321                         if self.settings.menupage.getValue() == PAGE_SUBTITLES and cur[0] is not None:
322                                 if self.infobar.selected_subtitle == cur[0]:
323                                         self.enableSubtitle(None)
324                                         selectedidx = self["streams"].getIndex()
325                                         self.__updatedInfo()
326                                         self["streams"].setIndex(selectedidx)
327                                 else:
328                                         self.enableSubtitle(cur[0])
329                                         self.__updatedInfo()
330                         self.close(0)
331                 elif self.focus == FOCUS_CONFIG:
332                         self.keyRight()
333
334         def cancel(self):
335                 self.close(0)
336
337 class SubtitleSelection(AudioSelection):
338         def __init__(self, session, infobar=None):
339                 AudioSelection.__init__(self, session, infobar, page=PAGE_SUBTITLES)
340                 self.skinName = ["AudioSelection"]
341
342 class QuickSubtitlesConfigMenu(ConfigListScreen, Screen):
343         skin = """
344         <screen position="50,80" size="480,425" title="Subtitle settings">
345                 <widget name="config" position="5,5" size="470,395" scrollbarMode="showOnDemand" />
346                 <widget name="videofps" position="5,405" size="470,25" zPosition="10" font="Regular;20" backgroundColor="#25062748" transparent="1" />
347         </screen>"""
348
349         def __init__(self, session, infobar):
350                 Screen.__init__(self, session)
351                 self.skin = QuickSubtitlesConfigMenu.skin
352                 self.infobar = infobar or self.session.infobar
353
354                 self.wait = eTimer()
355                 self.wait.timeout.get().append(self.resyncSubtitles)
356
357                 self["videofps"] = Label("")
358
359                 sub = self.infobar.selected_subtitle
360                 if sub[0] == 0:  # dvb
361                         menu = [
362                                 getConfigMenuItem("config.subtitles.subtitle_fontcolor"),
363                                 getConfigMenuItem("config.subtitles.dvb_subtitles_centered"),
364                                 getConfigMenuItem("config.subtitles.subtitle_bgopacity"),
365                                 getConfigMenuItem("config.subtitles.subtitle_original_position"),
366                                 getConfigMenuItem("config.subtitles.subtitle_position"),
367                                 getConfigMenuItem("config.subtitles.subtitle_bad_timing_delay"),
368                                 getConfigMenuItem("config.subtitles.subtitle_noPTSrecordingdelay"),
369                         ]
370                 elif sub[0] == 1: # teletext
371                         menu = [
372                                 getConfigMenuItem("config.subtitles.subtitle_fontcolor"),
373                                 getConfigMenuItem("config.subtitles.subtitle_fontsize"),
374                                 getConfigMenuItem("config.subtitles.subtitle_opacity"),
375                                 getConfigMenuItem("config.subtitles.subtitle_bgcolor"),
376                                 getConfigMenuItem("config.subtitles.subtitle_bgopacity"),
377                                 getConfigMenuItem("config.subtitles.subtitle_edgestyle"),
378                                 getConfigMenuItem("config.subtitles.subtitle_edgestyle_level"),
379                                 getConfigMenuItem("config.subtitles.subtitle_original_position"),
380                                 getConfigMenuItem("config.subtitles.subtitle_alignment"),
381                                 getConfigMenuItem("config.subtitles.subtitle_position"),
382                                 getConfigMenuItem("config.subtitles.subtitle_rewrap"),
383                                 getConfigMenuItem("config.subtitles.subtitle_bad_timing_delay"),
384                                 getConfigMenuItem("config.subtitles.subtitle_noPTSrecordingdelay"),
385                         ]
386                 else:           # pango
387                         menu = [
388                                 getConfigMenuItem("config.subtitles.subtitle_fontcolor"),
389                                 getConfigMenuItem("config.subtitles.subtitle_fontsize"),
390                                 getConfigMenuItem("config.subtitles.subtitle_opacity"),
391                                 getConfigMenuItem("config.subtitles.subtitle_bgcolor"),
392                                 getConfigMenuItem("config.subtitles.subtitle_bgopacity"),
393                                 getConfigMenuItem("config.subtitles.subtitle_edgestyle"),
394                                 getConfigMenuItem("config.subtitles.subtitle_edgestyle_level"),
395                                 getConfigMenuItem("config.subtitles.subtitle_original_position"),
396                                 getConfigMenuItem("config.subtitles.subtitle_alignment"),
397                                 getConfigMenuItem("config.subtitles.subtitle_position"),
398                                 getConfigMenuItem("config.subtitles.pango_subtitle_fontswitch"),
399                                 getConfigMenuItem("config.subtitles.colourise_dialogs"),
400                                 getConfigMenuItem("config.subtitles.subtitle_rewrap"),
401                                 getConfigMenuItem("config.subtitles.pango_subtitles_delay"),
402                                 getConfigMenuItem("config.subtitles.pango_subtitles_fps"),
403                         ]
404                         self["videofps"].setText(_("Video: %s fps") % (self.getFps().rstrip(".000")))
405
406                 ConfigListScreen.__init__(self, menu, self.session, on_change = self.changedEntry)
407
408                 self["actions"] = NumberActionMap(["SetupActions"],
409                 {
410                         "cancel": self.cancel,
411                         "ok": self.ok,
412                 },-2)
413
414                 self.onLayoutFinish.append(self.layoutFinished)
415
416         def layoutFinished(self):
417                 if not self["videofps"].text:
418                         self.instance.resize(eSize(self.instance.size().width(), self["config"].l.getItemSize().height()*len(self["config"].getList()) + 10))
419
420         def changedEntry(self):
421                 if self["config"].getCurrent() in [getConfigMenuItem("config.subtitles.pango_subtitles_delay"),getConfigMenuItem("config.subtitles.pango_subtitles_fps")]:
422                         self.wait.start(500, True)
423
424         def resyncSubtitles(self):
425                 self.infobar.setSeekState(self.infobar.SEEK_STATE_PAUSE)
426                 self.infobar.setSeekState(self.infobar.SEEK_STATE_PLAY)
427
428         def getFps(self):
429                 from enigma import iServiceInformation
430                 service = self.session.nav.getCurrentService()
431                 info = service and service.info()
432                 if not info:
433                         return ""
434                 fps = info.getInfo(iServiceInformation.sFrameRate)
435                 if fps > 0:
436                         return "%6.3f" % (fps/1000.)
437                 return ""
438
439         def cancel(self):
440                 self.close()
441
442         def ok(self):
443                 config.subtitles.save()
444                 self.close()