Configuration of tv-norm and video resolution is now intuitive
[enigma2-plugins.git] / vlcplayer / src / VlcServerConfig.py
1 # -*- coding: ISO-8859-1 -*-
2 #===============================================================================
3 # VLC Player Plugin by A. Lätsch 2007
4 #                   modified by Volker Christian 2008
5 #
6 # This is free software; you can redistribute it and/or modify it under
7 # the terms of the GNU General Public License as published by the Free
8 # Software Foundation; either version 2, or (at your option) any later
9 # version.
10 #===============================================================================
11
12
13 from Components.ActionMap import ActionMap
14 from Components.Button import Button
15 from Components.ConfigList import ConfigListScreen
16 from Components.config import ConfigElement
17 from Components.config import ConfigIP
18 from Components.config import ConfigInteger
19 from Components.config import ConfigSelection
20 from Components.config import ConfigSubList
21 from Components.config import ConfigSubsection
22 from Components.config import ConfigSlider
23 from Components.config import ConfigText
24 from Components.config import ConfigYesNo
25 from Components.config import config
26 from Components.config import getConfigListEntry
27 from Screens.Screen import Screen
28 from VlcServer import VlcServer
29 from . import _
30
31 class ConfigMutable(ConfigElement):
32         def __init__(self, configElementDict, defaultKey):
33                 ConfigElement.__init__(self)
34                 self.configElementDict = configElementDict
35                 if self.configElementDict.has_key(defaultKey):
36                         self.currentConfig = self.configElementDict[defaultKey]
37                         self.currentKey = defaultKey
38                         self.defaultKey = self.currentKey
39
40         def addConfigElement(self, key, configElement):
41                 self.elements[key] = configElement
42
43         def setAsCurrent(self, key):
44                 if self.configElementDict.has_key(key):
45                         self.currentConfig = self.configElementDict[key]
46                         self.currentKey = key
47                         self.saved_value = self.currentConfig.saved_value
48                         
49         def setValue(self, val):
50                 self.currentConfig.value = val
51                 self.changed()
52
53         def set_Value(self, val):
54                 self.currentConfig._value = val
55                 self.changed()
56
57         def getValue(self):
58                 return self.currentConfig.value
59         
60         def get_Value(self):
61                 return self.currentConfig._value
62
63         _value = property(get_Value, set_Value)
64         
65         def fromstring(self, value):
66                 return self.currentConfig.fromstring(value)
67
68         def load(self):
69                 self.currentConfig.saved_value = self.saved_value
70                 self.currentConfig.load()
71
72         def tostring(self, value):
73                 return self.currentConfig.tostring(value)
74
75         def save(self):
76                 self.currentConfig.save()
77                 self.defaultKey = self.currentKey
78                 self.saved_value = self.currentConfig.saved_value
79
80         def cancel(self):
81                 self.setAsCurrent(self.defaultKey)
82                 self.load()
83                 
84         def isChanged(self):
85                 return self.currentConfig.isChanged()
86
87         def changed(self):
88                 for x in self.notifiers:
89                         x(self)
90                         
91         def addNotifier(self, notifier, initial_call = True):
92                 assert callable(notifier), "notifiers must be callable"
93                 self.notifiers.append(notifier)
94                 if initial_call:
95                         notifier(self)
96
97         def disableSave(self):
98                 self.currentConfig.disableSave()
99
100         def __call__(self, selected):
101                 return self.currentConfig(selected)
102
103         def onSelect(self, session):
104                 self.currentConfig.onSelect(session)
105
106         def onDeselect(self, session):
107                 self.currentConfig.onDeselect(session)
108
109         def handleKey(self, key):
110                 self.currentConfig.handleKey(key)
111
112         def getHTML(self, id):
113                 return self.currentConfig.getHTML(id)
114
115         def genText(self):
116                 return self.currentConfig.genText()
117
118         def getText(self):
119                 return self.currentConfig.getText()
120
121         def getMulti(self, selected):
122                 return self.currentConfig.getMulti(selected)
123
124
125 class ConfigSelectionExtended(ConfigSelection):
126         def __init__(self, choices, default = None):
127                 ConfigSelection.__init__(self, choices, default)
128
129         def deleteNotifier(self, notifier):
130                 self.notifiers.remove(notifier)
131
132
133 class __VlcServerConfig():
134         def __init__(self):
135                 self.serverlist = []
136                 config.plugins.vlcplayer = ConfigSubsection()
137                 config.plugins.vlcplayer.servercount = ConfigInteger(0)
138                 config.plugins.vlcplayer.servers = ConfigSubList()
139                 config.plugins.vlcplayer.defaultserver = ConfigText("", False)
140                 for servernum in range(0, config.plugins.vlcplayer.servercount.value):
141                         self.new()
142
143         # Add a new server or load a configsection if existing
144         def new(self):
145                 newServerConfigSubsection = ConfigSubsection()
146                 config.plugins.vlcplayer.servers.append(newServerConfigSubsection)
147                 newServerConfigSubsection.name = ConfigText("Server " + str(self.__getServerCount()), False)
148                 if newServerConfigSubsection.name.value == newServerConfigSubsection.name.default:
149                         newServerConfigSubsection.name.default = ""
150                 newServerConfigSubsection.addressType = ConfigSelectionExtended([("FQDN", "FQDN"), ("IP", "IP-Address")], "IP")
151                 newServerConfigSubsection.hostip = ConfigMutable({"IP": ConfigIP([192,168,1,1]), "FQDN": ConfigText("fqdname", False)},
152                                                                                         newServerConfigSubsection.addressType.value)
153                 newServerConfigSubsection.httpport = ConfigInteger(8080, (0,65535))
154                 newServerConfigSubsection.basedir = ConfigText("/", False)
155                 newServerConfigSubsection.dvdPath = ConfigText("", False)
156                 newServerConfigSubsection.transcodeVideo = ConfigYesNo()
157                 newServerConfigSubsection.transcodeAudio = ConfigYesNo(True)
158                 newServerConfigSubsection.videocodec = ConfigSelection([("mp1v", "MPEG1"), ("mp2v", "MPEG2")], "mp2v")
159                 newServerConfigSubsection.videobitrate = ConfigInteger(1000, (100, 9999))
160                 newServerConfigSubsection.audiocodec = ConfigSelection([("mpga", "MP1"), ("mp2a", "MP2"), ("mp3", "MP3")], "mp2a")
161                 newServerConfigSubsection.audiobitrate = ConfigInteger(128, (64, 320))
162                 newServerConfigSubsection.samplerate = ConfigSelection([("0", "as Input"), ("44100", "44100"), ("48000", "48000")], "44100")
163                 newServerConfigSubsection.audiochannels = ConfigInteger(2, (1, 9))
164                 newServerConfigSubsection.videonorm = ConfigSelection(
165                                 [("720,576,4:3,25,i", "720 x 576 (4:3) @ 25fps (PAL)"),
166                                  ("720,576,16:9,25,i", "720 x 576 (16:9) @ 25fps (PAL)"),
167                                  ("704,576,4:3,25,i", "704 x 576 (4:3) @ 25fps (PAL)"),
168                                  ("704,576,16:9,25,i", "704 x 576 (16:9) @ 25fps (PAL)"),
169                                  ("544,576,4:3,25,i", "544 x 576 (4:3) @ 25fps (PAL)"),
170                                  ("544,576,16:9,25,i", "544 x 576 (16:9) @ 25fps (PAL)"),
171                                  ("480,576,4:3,25,i", "480 x 576 (4:3) @ 25fps (PAL)"),
172                                  ("480,576,16:9,25,i", "480 x 576 (16:9) @ 25fps (PAL)"),
173                                  ("480,288,4:3,25,i", "480 x 288 (4:3) @ 25fps (PAL)"),
174                                  ("480,288,16:9,25,i", "480 x 288 (16:9) @ 25fps (PAL)"),
175                                  ("352,576,4:3,25,i", "352 x 576 (4:3) @ 25fps (PAL)"),
176                                  ("352,576,16:9,25,i", "352 x 576 (16:9) @ 25fps (PAL)"),
177                                  ("352,288,4:3,25,i", "352 x 288 (4:3) @ 25fps (PAL)"),
178                                  ("352,288,16:9,25,i", "352 x 288 (16:9) @ 25fps (PAL)"),
179                                  ("720,480,4:3,30,i", "720 x 480 (4:3) @ 30fps (NTSC)"),
180                                  ("720,480,16:9,30,i", "720 x 480 (16:9) @ 30fps (NTSC)"),
181                                  ("640,480,4:3,30,i", "640 x 480 (4:3) @ 30fps (NTSC)"),
182                                  ("640,480,16:9,30,i", "640 x 480 (16:9) @ 30fps (NTSC)"),
183                                  ("544,480,4:3,30,i", "544 x 480 (4:3) @ 30fps (NTSC)"),
184                                  ("544,480,16:9,30,i", "544 x 480 (16:9) @ 30fps (NTSC)"),
185                                  ("480,480,4:3,30,i", "480 x 480 (4:3) @ 30fps (NTSC)"),
186                                  ("480,480,16:9,30,i", "480 x 480 (16:9) @ 30fps (NTSC)"),
187                                  ("480,240,4:3,30,i", "480 x 240 (4:3) @ 30fps (NTSC)"),
188                                  ("480,240,16:9,30,i", "480 x 240 (16:9) @ 30fps (NTSC)"),
189                                  ("353,480,4:3,30,i", "353 x 480 (4:3) @ 30fps (NTSC)"),
190                                  ("353,480,16:9,30,i", "353 x 480 (16:9) @ 30fps (NTSC)"),
191                                  ("352,240,4:3,30,i", "352 x 240 (4:3) @ 30fps (NTSC)"),
192                                  ("352,240,16:9,30,i", "352 x 240 (16:9) @ 30fps (NTSC)"),
193                                  ("1920,1080,16:9,50,p", "1920 x 1080 (16:9) @ 50p (HTDV)"),
194                                  ("1920,1080,16:9,25,p", "1920 x 1080 (16:9) @ 25p (HTDV)"),
195                                  ("1920,1080,16:9,25,i", "1920 x 1080 (16:9) @ 25i (HTDV)"),
196                                  ("1440,1080,16:9,25,p", "1440 x 1080 (16:9) @ 25p (HTDV)"),
197                                  ("1440,1080,16:9,25,i", "1440 x 1080 (16:9) @ 25i (HTDV)"),
198                                  ("1280,720,16:9,50,p", "1280 x 720 (16:9) @ 50p (HDTV)"),
199                                  ("1280,720,16:9,25,p", "1280 x 720 (16:9) @ 25p (HDTV)"),
200                                  ("720,576,16:9,50,p", "720 x 576 (16:9) @ 50p (HDTV)")
201                                 ], "352,288,4:3,25,i")
202                 newServerConfigSubsection.overscancorrection = ConfigInteger(0, (0, 100))
203                 newServerConfigSubsection.soverlay = ConfigYesNo()
204                 newServer = VlcServer(newServerConfigSubsection)
205
206                 self.serverlist.append(newServer)
207
208                 return newServer
209
210         # Add was canceled or existing server should be removed
211         def delete(self, server):
212                 config.plugins.vlcplayer.servers.remove(server.getCfg())
213                 self.serverlist.remove(server)
214                 self.__save()
215
216         # Edit or Add should complete
217         def save(self, server):
218                 server.getCfg().save()
219                 self.__save()
220
221         # Edit has been canceled
222         def cancel(self, server):
223                 for element in server.getCfg().dict().values():
224                         element.cancel()
225
226         def getServerlist(self):
227                 return self.serverlist
228
229         def getServerByName(self, name):
230                 for server in self.serverlist:
231                         if server.getName() == name:
232                                 return server
233                 return None
234
235         def getDefaultServer(self):
236                 return self.getServerByName(config.plugins.vlcplayer.defaultserver.value)
237
238         def setAsDefault(self, defaultServer):
239                 if defaultServer is not None:
240                         config.plugins.vlcplayer.defaultserver.value = defaultServer.getName()
241                         config.plugins.vlcplayer.defaultserver.save()
242
243         def __save(self):
244                 config.plugins.vlcplayer.servercount.value = self.__getServerCount()
245                 config.plugins.vlcplayer.servercount.save()
246
247         def __getServerCount(self):
248                 return len(config.plugins.vlcplayer.servers)
249
250
251 vlcServerConfig = __VlcServerConfig()
252
253
254 class VlcServerConfigScreen(Screen, ConfigListScreen):
255         skin = """
256                 <screen name="VlcServerConfigScreen" position="80,100" size="560,320" title="Edit VLC Server">
257                         <widget name="config" position="10,10" size="540,250" scrollbarMode="showOnDemand" />
258                         <ePixmap name="red"    position="0,280"   zPosition="4" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
259                         <ePixmap name="green"  position="140,280" zPosition="4" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
260                         <ePixmap name="yellow" position="280,280" zPosition="4" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
261                         <ePixmap name="blue"   position="420,280" zPosition="4" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" />
262                         <widget name="key_red" position="0,280" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
263                         <widget name="key_green" position="140,280" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
264                         <widget name="key_yellow" position="280,280" zPosition="5" size="140,40" valign="center" halign="center"  font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
265                         <widget name="key_blue" position="420,280" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
266                 </screen>"""
267
268         def __init__(self, session, server):
269                 Screen.__init__(self, session)
270                 self.server = server
271                 self["actions"] = ActionMap(["SetupActions", "ColorActions"],
272                 {
273                         "green": self.keySave,
274                         "red": self.keyCancel,
275                         "cancel": self.keyCancel
276                 }, -2)
277
278                 self["key_red"] = Button(_("Cancel"))
279                 self["key_green"] = Button(_("OK"))
280                 self["key_yellow"] = Button("")
281                 self["key_blue"] = Button("")
282
283                 cfglist = []
284                 cfglist.append(getConfigListEntry(_("Server Profile Name"), server.name()))
285                 cfglist.append(getConfigListEntry(_("Enter VLC-Server as FQDN or IP-Address"), server.addressType()))
286                 self.hostConfigListEntry = getConfigListEntry(_("Server Address"), server.host())
287                 cfglist.append(self.hostConfigListEntry)
288                 cfglist.append(getConfigListEntry(_("HTTP Port"), server.httpPort()))
289                 cfglist.append(getConfigListEntry(_("Movie Directory"), server.basedir()))
290                 cfglist.append(getConfigListEntry(_("DVD Device (leave empty for default)"), server.dvdPath()))
291
292                 cfglist.append(getConfigListEntry(_("Transcode MPEG/DVD Video"), server.transcodeVideo()))
293                 cfglist.append(getConfigListEntry(_("Video Codec"), server.videoCodec()))
294                 cfglist.append(getConfigListEntry(_("Video Bitrate"), server.videoBitrate()))
295                 cfglist.append(getConfigListEntry(_("Video Norm"), server.videoNorm()))
296                 cfglist.append(getConfigListEntry(_("Overscan Correction [in % of Video width]"), server.overscanCorrection()))
297                 cfglist.append(getConfigListEntry(_("Subtitle overlay"), server.sOverlay()))
298
299                 cfglist.append(getConfigListEntry(_("Transcode MPEG/DVD Audio"), server.transcodeAudio()))
300                 cfglist.append(getConfigListEntry(_("Audio Codec"), server.audioCodec()))
301                 cfglist.append(getConfigListEntry(_("Audio Bitrate"), server.audioBitrate()))
302                 cfglist.append(getConfigListEntry(_("Audio Samplerate"), server.samplerate()))
303                 cfglist.append(getConfigListEntry(_("Audio Channels"), server.audioChannels()))
304
305                 ConfigListScreen.__init__(self, cfglist, session)
306
307                 server.addressType().addNotifier(self.switchAddressType, False)
308                 
309                 self.onClose.append(self.__onClose)
310                 
311         def __onClose(self):
312                 self.server.addressType().deleteNotifier(self.switchAddressType)
313
314         def switchAddressType(self, configElement):
315                 self.server.host().setAsCurrent(configElement.value)
316                 self["config"].invalidate(self.hostConfigListEntry)
317
318         def keySave(self):
319                 self.close(True, self.server)
320
321         def keyCancel(self):
322                 self.close(False, self.server)