4.2.0r15
[enigma2.git] / usr / lib / enigma2 / python / Plugins / SystemPlugins / NetworkManager / NetworkConfig.py
1 # -*- coding: utf-8 -*-
2 from enigma import eNetworkManager, eNetworkService, eNetworkServicePtr, StringList, StringMap
3
4 from Components.Label import Label
5 from Components.ActionMap import ActionMap
6 from Components.config import getConfigListEntry, ConfigIP, ConfigOnOff, ConfigIP6, ConfigSelection
7 from Components.ConfigList import ConfigListScreen
8 from Components.Sources.List import List
9 from Components.Sources.StaticText import StaticText
10 from Screens.Screen import Screen
11
12 from Tools.BoundFunction import boundFunction
13 from Tools.Directories import resolveFilename, SCOPE_CURRENT_SKIN
14 from Tools.Log import Log
15 from Tools.LoadPixmap import LoadPixmap
16
17 from netaddr import IPAddress
18
19 def toIP4List(value):
20         return [ int(v) for v in str(value).split(".") ]
21
22 def toIP4String(cfg):
23         return cfg.tostring(cfg.value)
24
25 NETWORK_STATE_MAP = {
26                         "idle" : _("Idle"),
27                         "failure" : _("Failure"),
28                         "association" : _("Association"),
29                         "configuration" : _("Configuration"),
30                         "ready" : _("Connected"),
31                         "disconnect" : _("Disconnect"),
32                         "online" : _("Online"),
33                 }
34
35 def translateState(state):
36         return NETWORK_STATE_MAP.get(state, state)
37
38 class NetworkConfigGeneral(object):
39         def __init__(self):
40                 self._nm = eNetworkManager.getInstance()
41                 self._nm_conn = [
42                                 self._nm.technologiesChanged.connect(self._technologiesChanged),
43                                 self._nm.stateChanged.connect(self._servicesChanged),
44                                 self._nm.servicesChanged.connect(self._servicesChanged),
45                         ]
46                 self._tech_conn = []
47                 self._services = List([], enableWrapAround = True)
48                 self._services.buildfunc = self._buildServiceListEntry
49
50         def _getCurrentService(self):
51                 service = self._services.getCurrent()
52                 if service:
53                         return service[1]
54                 return None
55         _currentService = property(_getCurrentService)
56
57         def _technologiesChanged(self):
58                 pass
59
60         def _techPoweredChanged(self, powered):
61                 if powered:
62                         self._rescan()
63
64         def _setTechPowered(self, cfg):
65                 tech = cfg.tech
66                 powered = not tech.powered()
67                 tech.setPowered(powered)
68
69         def _scanFinished(self, tech):
70                 pass
71
72         def _rescan(self, tech=None):
73                 if tech is not None and  tech.type() == eNetworkService.TYPE_WIFI and tech.powered():
74                         Log.i("Triggering rescan for '%s'" %tech.name())
75                         tech.scan()
76                         return True
77
78                 res = False
79                 for tech in self._nm.getTechnologies():
80                         if tech.type() == eNetworkService.TYPE_WIFI and tech.powered():
81                                 Log.i("Triggering rescan for '%s'" %tech.name())
82                                 tech.scan()
83                                 res = True
84                 return res
85
86         def _removeService(self):
87                 service = self._currentService
88                 if isinstance(service, eNetworkServicePtr):
89                         Log.i("Removing %s" %service.name())
90                         service.setAutoConnect(False)
91                         service.remove()
92
93         def getTechnologyConfig(self):
94                 l = []
95                 techs = self._nm.getTechnologies()
96                 self._tech_conn = []
97                 for tech in techs:
98                         cfg = ConfigOnOff(default=tech.powered())
99                         cfg.tech = tech
100                         cfg.addNotifier(self._setTechPowered, initial_call=False)
101                         self._tech_conn.append(tech.poweredChanged.connect(self._techPoweredChanged))
102                         self._tech_conn.append(tech.scanFinished.connect(boundFunction(self._scanFinished, tech)))
103                         title = "%s (%s)" %(tech.name(), tech.type())
104                         l.append(getConfigListEntry(title, cfg))
105                 Log.w(l)
106                 return l
107
108         def _servicesChanged(self, *args):
109                 pass
110
111         def getServiceList(self, unified=False):
112                 l = []
113                 services = self._nm.getServices()
114                 techs = self._nm.getTechnologies()
115                 self._tech_conn = []
116                 if unified:
117                         for tech in techs:
118                                 self._tech_conn.append(tech.poweredChanged.connect(self._techPoweredChanged))
119                                 self._tech_conn.append(tech.scanFinished.connect(boundFunction(self._scanFinished, tech)))
120                                 l.append( (tech.path(), tech,) )
121                                 for service in services:
122                                         if service.type() == tech.type():
123                                                 l.append( (service.path(), service,) )
124                 else:
125                         for service in services:
126                                 l.append( (service.path(), service,) )
127                 return l
128
129         def _buildListEntry(self, path, instance):
130                 if isinstance(instance, eNetworkServicePtr):
131                         return self._buildServiceListEntry(path, instance)
132                 else:
133                         return self._buildTechnologyListEntry(path, instance)
134
135         def _buildTechnologyListEntry(self, techpath, tech):
136                 #Log.i("technology: %s/%s" %(tech.name(), tech.type()))
137                 enabled = _("on") if tech.powered() else _("off")
138                 name = tech.name()
139                 if tech.isScanning():
140                         name = "%s - scanning..." %name
141                 return (tech.path(), None, enabled, None, None, None, name)
142
143         def _buildServiceListEntry(self, svcpath, service):
144                 #Log.i("service: %s/%s/%s" %(service.name(), service.type(), service.strength()))
145                 strength = ""
146                 if service.type() == eNetworkService.TYPE_ETHERNET:
147                         if service.connected():
148                                 interfacepng = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/icons/network_wired-active.png"))
149                         else:
150                                 if service.state() != eNetworkManager.STATE_IDLE:
151                                         interfacepng = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/icons/network_wired.png"))
152                                 else:
153                                         interfacepng = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/icons/network_wired-inactive.png"))
154                 elif service.type() == eNetworkService.TYPE_WIFI:
155                         strength = str( service.strength() )
156                         if service.connected():
157                                 interfacepng = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/icons/network_wireless-active.png"))
158                         else:
159                                 if service.state() != eNetworkManager.STATE_IDLE:
160                                         interfacepng = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/icons/network_wireless.png"))
161                                 else:
162                                         interfacepng = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/icons/network_wireless-inactive.png"))
163                 ip = ""
164                 if service.connected():
165                         ip = service.ipv4().get(eNetworkService.KEY_ADDRESS, "")
166                         if not ip:
167                                 ip = service.ipv6().get(eNetworkService.KEY_ADDRESS, "")
168
169                 return (service.path(), interfacepng, strength, service.name(), ip, translateState(service.state()), None)
170
171 class NetworkServiceConfig(Screen, NetworkConfigGeneral):
172         skin = """
173                 <screen name="NetworkServiceConfig" position="center,center" size="560,500" title="Network Configuration" zPosition="0">
174                         <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
175                         <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
176                         <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on" />
177                         <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" alphatest="on" />
178
179                         <widget name="key_red" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
180                         <widget name="key_green" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
181                         <widget name="key_yellow" position="280,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
182                         <widget name="key_blue" position="420,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
183
184                         <widget source="list" render="Listbox" position="5,50" size="550,420" scrollbarMode="showOnDemand" zPosition="1">
185                                 <convert type="TemplatedMultiContent">
186                                         {"template":[
187                                                         MultiContentEntryPixmapAlphaTest(pos = (0, 0), size = (50, 50), png = 1), #type icon
188                                                         MultiContentEntryText(pos = (500, 0), size = (50, 50), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 2), #signal strength
189                                                         MultiContentEntryText(pos = (55, 0), size = (440, 24), font=0, flags = RT_HALIGN_LEFT, text = 3), #service name
190                                                         MultiContentEntryText(pos = (55, 30), size = (220, 18), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 4), #ip
191                                                         MultiContentEntryText(pos = (275, 30), size = (220, 18), font=1, flags = RT_HALIGN_RIGHT|RT_VALIGN_CENTER, text = 5), #state
192                                                         MultiContentEntryText(pos = (5, 0), size = (490, 50), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 6), #technology name
193                                                 ],
194                                         "itemHeight": 50,
195                                         "fonts": [gFont("Regular", 22), gFont("Regular", 16)]
196                                         }
197                                 </convert>
198                         </widget>
199                         <widget name="hint" position="5,480" zPosition="1" size="560,20" font="Regular;16" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
200                 </screen>"""
201
202         def __init__(self, session):
203                 Screen.__init__(self, session)
204                 NetworkConfigGeneral.__init__(self)
205
206                 self["key_red"] = Label(_("Reset"))
207                 self["key_green"] = Label(_("Scan"))
208                 self["key_yellow"] = Label(_("IP"))
209                 self["key_blue"] = Label(_("DNS"))
210                 self["hint"] = Label(_("Press OK to connect"))
211                 self["OkCancelActions"] = ActionMap(["OkCancelActions", "ColorActions"],
212                 {
213                         "cancel": self.close,
214                         "ok" : self._ok,
215                         "green": self._rescan,
216                         "red": self._removeService
217                 }, -3)
218                 self["ServiceActions"] = ActionMap(["ColorActions"],
219                 {
220                         "yellow": self._configIP,
221                         "blue": self._configDNS,
222                 }, -2)
223
224                 self["list"] = self._services
225                 self._hasWireless = False
226
227                 self._services.buildfunc = self._buildListEntry
228                 self._services.onSelectionChanged.append(self._selectionChanged)
229
230                 self._addNotifiers()
231                 self._createSetup()
232
233                 self.onClose.append(self._onClose)
234                 self.onLayoutFinish.append(self.layoutFinished)
235
236         def _rescan(self):
237                 if isinstance(self._currentService, eNetworkServicePtr):
238                         return
239                 if self._currentService.type() != eNetworkService.TYPE_WIFI:
240                         return
241                 if NetworkConfigGeneral._rescan(self, self._currentService):
242                         self._createSetup()
243
244         def _scanFinished(self, tech):
245                 Log.i("finished!")
246                 self._createSetup()
247
248         def _removeService(self):
249                 NetworkConfigGeneral._removeService(self)
250                 self._createSetup()
251
252         def _selectionChanged(self):
253                 self._checkButtons()
254
255         def _checkButtons(self):
256                 self["hint"].setText("")
257                 if isinstance(self._currentService, eNetworkServicePtr): #a service
258                         self["key_green"].hide()
259                         if self._currentService.connected():
260                                 self["hint"].setText(_("Press OK to disconnect"))
261                         else:
262                                 self["hint"].setText(_("Press OK to connect"))
263                         if self._currentService.favorite():
264                                 self["key_red"].show()
265                         else:
266                                 self["key_red"].hide()
267                         self["key_yellow"].show()
268                         self["key_blue"].show()
269                         self["ServiceActions"].setEnabled(True)
270                 else: #a technology
271                         if self._currentService and self._currentService.type() == eNetworkService.TYPE_WIFI:
272                                 self["key_green"].show()
273                         else:
274                                 self["key_green"].hide()
275                         self["key_red"].hide()
276                         if self._currentService:
277                                 if self._currentService.powered():
278                                         self["hint"].setText(_("Press OK to disable"))
279                                 else:
280                                         self["hint"].setText(_("Press OK to enable"))
281                         else:
282                                 self["hint"].setText("")
283                         self["key_yellow"].hide()
284                         self["key_blue"].hide()
285                         self["ServiceActions"].setEnabled(False)
286
287         def _configChanged(self, *args, **kwargs):
288                 self._createSetup()
289
290         def _configIP(self):
291                 service = self._currentService
292                 if service:
293                         self.session.open(NetworkServiceIPConfig, service)
294
295         def _configDNS(self):
296                 service = self._currentService
297                 if service:
298                         self.session.open(NetworkServiceNSConfig, service)
299
300         def _technologiesChanged(self):
301                 self._createSetup()
302
303         def _servicesChanged(self, *args):
304                 self._createSetup()
305
306         def _addNotifiers(self):
307                 pass
308
309         def _removeNotifiers(self):
310                 pass
311
312         def _onClose(self):
313                 self._removeNotifiers()
314
315         def keyLeft(self):
316                 ConfigListScreen.keyLeft(self)
317
318         def keyRight(self):
319                 ConfigListScreen.keyRight(self)
320
321         def _ok(self):
322                 item = self._currentService
323                 if not item:
324                         return
325                 if isinstance(item, eNetworkServicePtr):
326                         state = item.state()
327                         Log.i(state)
328                         if state == eNetworkManager.STATE_IDLE or state == eNetworkManager.STATE_FAILURE:
329                                 item.requestDisconnect()
330                                 item.requestConnect()
331                                 item.setAutoConnect(True)
332                         else:
333                                 item.requestDisconnect()
334                 else:
335                         item.setPowered(not item.powered())
336
337         def _createSetup(self):
338                 self._hasWireless = False
339                 for tech in self._nm.getTechnologies():
340                         if tech.type() == eNetworkService.TYPE_WIFI and tech.powered():
341                                 self._hasWireless = True
342                 self._services.updateList(self.getServiceList(unified=True))
343                 self._checkButtons()
344
345         def _techPoweredChanged(self, powered):
346                 if powered:
347                         self._rescan()
348                 self._createSetup()
349
350         def layoutFinished(self):
351                 self.setTitle(_("Network Config"))
352                 self._checkButtons()
353
354 class ServiceBoundConfiguration(object):
355         def __init__(self, service):
356                 self._service = service
357                 nm = eNetworkManager.getInstance()
358                 self._svcRemovedConn = nm.serviceRemoved.connect(self.__onServiceRemoved)
359                 self._isServiceRemoved = False
360
361         def __onServiceRemoved(self, svcpath):
362                 if svcpath == self._service.path():
363                         Log.i("Service '%s' removed. Closing..." %svcpath)
364                         self._isServiceRemoved = True
365                         #TODO show a messagebox! The user will be VERY confused otherwise!
366                         self.close()
367
368 class ServiceIPConfiguration(object):
369         def __init__(self, service):
370                 self._service = service
371                 self.onChanged = []
372                 method_choices_ip4 = {eNetworkService.METHOD_DHCP : "dhcp", eNetworkService.METHOD_MANUAL : _("manual"), eNetworkService.METHOD_OFF : _("off")}
373                 #IPv4
374                 self._config_ip4_method = ConfigSelection(method_choices_ip4, default=eNetworkService.METHOD_DHCP)
375                 self._config_ip4_address = ConfigIP(default=[0,0,0,0])
376                 self._config_ip4_mask = ConfigIP(default=[0,0,0,0])
377                 self._config_ip4_gw = ConfigIP(default=[0,0,0,0])
378                 #IPv6
379                 method_choices_ip6 = {eNetworkService.METHOD_AUTO : _("auto"), eNetworkService.METHOD_6TO4 : "6to4", eNetworkService.METHOD_MANUAL : _("manual"), eNetworkService.METHOD_OFF : _("off")}
380                 choices_privacy_ip6 = {eNetworkService.IPV6_PRIVACY_DISABLED : _("Disabled"), eNetworkService.IPV6_PRIVACY_ENABLED : _("Enabled"), eNetworkService.IPV6_PRIVACY_PREFERRED : _("Preferred")}
381                 self._config_ip6_method = ConfigSelection(method_choices_ip6, default=eNetworkService.METHOD_DHCP)
382                 self._config_ip6_address = ConfigIP6()
383                 self._config_ip6_mask = ConfigIP6()
384                 self._config_ip6_gw = ConfigIP6()
385                 self._config_ip6_privacy = ConfigSelection(choices_privacy_ip6, default="disabled")
386
387                 self._isReloading = False
388                 self._ipv4Changed = False
389                 self._ipv6Changed = False
390                 self._addNotifiers()
391                 self._service_conn = [
392                         self._service.ipv4Changed.connect(self._serviceChanged),
393                         self._service.ipv6Changed.connect(self._serviceChanged),
394                         self._service.ipv4ConfigChanged.connect(self._serviceChanged),
395                         self._service.ipv6ConfigChanged.connect(self._serviceChanged),
396                 ]
397
398         def _serviceChanged(self, *args):
399                 self.reload(force=False)
400
401         def _addNotifiers(self):
402                 #Setup refresh
403                 self._config_ip4_method.addNotifier(self._changed, initial_call=False)
404                 self._config_ip6_method.addNotifier(self._changed, initial_call=False)
405
406                 #change tracking
407                 #ipv4
408                 self._config_ip4_method.addNotifier(self._changedIP4, initial_call=False)
409                 self._config_ip4_address.addNotifier(self._changedIP4, initial_call=False)
410                 self._config_ip4_mask.addNotifier(self._changedIP4, initial_call=False)
411                 self._config_ip4_gw.addNotifier(self._changedIP4, initial_call=False)
412                 #ipv6
413                 self._config_ip6_method.addNotifier(self._changedIP6, initial_call=False)
414                 self._config_ip6_address.addNotifier(self._changedIP6, initial_call=False)
415                 self._config_ip6_mask.addNotifier(self._changedIP6, initial_call=False)
416                 self._config_ip6_gw.addNotifier(self._changedIP6, initial_call=False)
417                 self._config_ip6_privacy.addNotifier(self._changedIP6, initial_call=False)
418
419         def _changedIP4(self, element):
420                 if not self._isReloading:
421                         self._ipv4Changed = True
422                 self._changed(element)
423
424         def _changedIP6(self, element):
425                 if not self._isReloading:
426                         self._ipv6Changed = True
427                 self._changed(element)
428
429         def _changed(self, element):
430                 if not self._isReloading:
431                         Log.i()
432                         for fnc in self.onChanged:
433                                 fnc()
434
435         def reload(self, force=True):
436                 self._isReloading = True
437                 if force:
438                         self._ipv4Changed = False
439                         self._ipv6Changed = False
440                 if not self._ipv6Changed:
441                         ip4 = self._service.ipv4()
442                         if not dict(ip4):
443                                 ip6 = self._service.ipv4Config()
444                         self._config_ip4_method.value = ip4.get(eNetworkService.KEY_METHOD, eNetworkService.METHOD_OFF)
445                         self._config_ip4_address.value = toIP4List( ip4.get("Address", "0.0.0.0") )
446                         self._config_ip4_mask.value = toIP4List( ip4.get(eNetworkService.KEY_NETMASK, "0.0.0.0") )
447                         self._config_ip4_gw.value = toIP4List( ip4.get(eNetworkService.KEY_GATEWAY, "0.0.0.0") )
448                 if not self._ipv6Changed:
449                         ip6 = self._service.ipv6()
450                         Log.i("%s / %s" %(dict(ip6), dict(self._service.ipv6Config())) )
451                         if not dict(ip6):
452                                 ip6 = self._service.ipv6Config()
453                         self._config_ip6_method.value = ip6.get(eNetworkService.KEY_METHOD, eNetworkService.METHOD_OFF)
454                         self._config_ip6_address.value = ip6.get(eNetworkService.KEY_ADDRESS, "::")
455                         self._config_ip6_mask.value = ip6.get(eNetworkService.KEY_NETMASK, "::")
456                         self._config_ip6_gw.value = ip6.get(eNetworkService.KEY_GATEWAY, "::")
457                         self._config_ip6_privacy.value = ip6.get(eNetworkService.KEY_PRIVACY, eNetworkService.IPV6_PRIVACY_DISABLED)
458                 self._isReloading = False
459                 self._changed(None)
460
461         def getList(self):
462                 l = [ getConfigListEntry(_("Method (IPv4)"), self._config_ip4_method), ]
463                 if self._config_ip4_method.value != eNetworkService.METHOD_OFF:
464                         l.extend([
465                                 getConfigListEntry(_("Address (IPv4)"), self._config_ip4_address),
466                                 getConfigListEntry(_("Mask (IPv4)"), self._config_ip4_mask),
467                                 getConfigListEntry(_("Gateway (IPv4)"), self._config_ip4_gw),
468                         ])
469                 l.append( getConfigListEntry(_("Method (IPv6)"), self._config_ip6_method))
470                 if self._config_ip6_method.value != eNetworkService.METHOD_OFF:
471                         l.extend([
472                                 getConfigListEntry(_("Address (IPv6)"), self._config_ip6_address),
473                                 getConfigListEntry(_("Mask (IPv6)"), self._config_ip6_mask),
474                                 getConfigListEntry(_("Gateway (IPv6)"), self._config_ip6_gw),
475                         ])
476                 if self._config_ip6_method.value in (eNetworkService.METHOD_AUTO, eNetworkService.METHOD_6TO4):
477                         l.append( getConfigListEntry(_("Privacy (IPv6)"), self._config_ip6_privacy) )
478                 return l
479
480         def save(self):
481                 if self._ipv4Changed:
482                         Log.i("IPv4 Changed, saving!")
483                         if self._config_ip4_method.value == eNetworkService.METHOD_MANUAL:
484                                 ip4_config = {
485                                                 eNetworkService.KEY_METHOD : self._config_ip4_method.value,
486                                                 eNetworkService.KEY_ADDRESS : toIP4String(self._config_ip4_address),
487                                                 eNetworkService.KEY_NETMASK : toIP4String(self._config_ip4_mask),
488                                                 eNetworkService.KEY_GATEWAY : toIP4String(self._config_ip4_gw),
489                                         }
490                         else:
491                                 ip4_config = { eNetworkService.KEY_METHOD : self._config_ip4_method.value }
492                         Log.i(ip4_config)
493                         self._service.setIpv4Config(StringMap(ip4_config))
494
495                 if self._ipv6Changed:
496                         Log.i("IPv6 Changed, saving!")
497                         if self._config_ip6_method.value == eNetworkService.METHOD_MANUAL:
498                                 ip6_config = {
499                                                 eNetworkService.KEY_METHOD : self._config_ip6_method.value,
500                                                 eNetworkService.KEY_ADDRESS : self._config_ip6_address.value,
501                                                 eNetworkService.KEY_NETMASK : self._config_ip6_mask.value,
502                                                 eNetworkService.KEY_GATEWAY : self._config_ip6_gw.value,
503                                                 eNetworkService.KEY_PRIVACY : self._config_ip6_privacy.value,
504                                         }
505                         else:
506                                 val = self._config_ip6_method.value #avoid config element overhead here
507                                 #one can not configure 6to4, it will automatically be applied by connman if applicable -> change it to auto
508                                 if val == eNetworkService.METHOD_6TO4:
509                                         val = eNetworkService.METHOD_AUTO
510
511                                 ip6_config = { eNetworkService.KEY_METHOD : val }
512                                 if val != eNetworkService.METHOD_OFF:
513                                         ip6_config[eNetworkService.KEY_PRIVACY] = self._config_ip6_privacy.value
514                         Log.i(ip6_config)
515                         self._service.setIpv6Config(StringMap(ip6_config))
516
517 class NetworkServiceIPConfig(ConfigListScreen, Screen, ServiceBoundConfiguration):
518         skin = """
519                 <screen name="NetworkServiceIPConfig" position="center,center" size="560,400" title="Network: Service configuration">
520                         <!--
521                         <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
522                         <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
523                         <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on" />
524                         -->
525                         <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" alphatest="on" />
526                         <!--
527                         <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
528                         <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
529                         <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
530                         -->
531                         <widget source="key_blue" render="Label" position="420,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
532                         <widget name="config" position="5,50" size="550,360" scrollbarMode="showOnDemand" zPosition="1"/>
533                 </screen>"""
534
535         def __init__(self, session, service):
536                 Screen.__init__(self, session)
537                 ConfigListScreen.__init__(self, [], session=session)
538                 ServiceBoundConfiguration.__init__(self, service)
539
540                 self["key_blue"] = StaticText(_("Reset"))
541                 self["setupActions"] = ActionMap(["SetupActions", "ColorActions"],
542                 {
543                         "blue": self._reload,
544                         "save": self.close,
545                         "cancel": self.close,
546                         "ok" : self.close,
547                 }, -2)
548
549                 self._ipconfig = ServiceIPConfiguration(self._service)
550                 self._ipconfig.onChanged.append(self._createSetup)
551                 self._noSave = False
552
553                 self._reload()
554                 self.onClose.append(self.__onClose)
555
556         def __onClose(self):
557                 self._ipconfig.onChanged.remove(self._createSetup)
558                 self._apply()
559                 del self._ipconfig
560
561         def _apply(self):
562                 if self._isServiceRemoved:
563                         return
564                 self._ipconfig.save()
565
566         def _reload(self):
567                 self._ipconfig.reload()
568                 self._createSetup()
569
570         def _createSetup(self):
571                 self["config"].list = self._ipconfig.getList()
572
573 class ServiceNSConfiguration(object):
574         def __init__(self, service):
575                 self._service = service
576                 self.onChanged = []
577                 self._nameservers = []
578
579         def reload(self):
580                 self._nameservers = []
581                 ns = self._service.nameserversConfig()
582                 for n in ns:
583                         ip = IPAddress(n)
584                         if ip.version == 4:
585                                 cfg = ConfigIP( default=toIP4List(ip.format()))
586                                 self._nameservers.append(cfg)
587                         elif ip.version == 6:
588                                 cfg = ConfigIP6(default=ip.format())
589                                 self._nameservers.append(cfg)
590
591         def getList(self):
592                 return [ getConfigListEntry("Nameserver", ns) for ns in self._nameservers ]
593
594         def add4(self):
595                 self._nameservers.append(ConfigIP([0,0,0,0]))
596
597         def add6(self):
598                 self._nameservers.append(ConfigIP6())
599
600         def remove(self, cfg):
601                 self._nameservers.remove(cfg)
602
603         def save(self):
604                 servers = []
605                 for nscfg in self._nameservers:
606                         if isinstance(nscfg, ConfigIP):
607                                 servers.append(toIP4String(nscfg))
608                         elif isinstance(nscfg, ConfigIP6):
609                                 servers.append(nscfg.value)
610                 self._service.setNameserversConfig(StringList(servers))
611
612 class NetworkServiceNSConfig(ConfigListScreen, Screen, ServiceBoundConfiguration):
613         skin = """
614                 <screen name="NetworkServiceNSConfig" position="center,center" size="560,400" title="Service: Nameserver configuration">
615                         <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
616                         <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
617                         <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on" />
618                         <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" alphatest="on" />
619                         <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
620                         <widget source="key_green"
621                          render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
622                         <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
623                         <widget source="key_blue" render="Label" position="420,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
624                         <widget name="config" position="5,50" size="550,360" scrollbarMode="showOnDemand" zPosition="1"/>
625                 </screen>"""
626
627         def __init__(self, session, service):
628                 Screen.__init__(self, session)
629                 ConfigListScreen.__init__(self, [], session=session)
630                 ServiceBoundConfiguration.__init__(self, service)
631
632                 self["key_red"] = StaticText(_("Delete"))
633                 self["key_green"] = StaticText(_("New (IPv4)"))
634                 self["key_yellow"] = StaticText(_("New (IPv6)"))
635                 self["key_blue"] = StaticText(_("Reset"))
636                 self["setupActions"] = ActionMap(["OkCancelActions", "ColorActions"],
637                 {
638                         "red": self._remove,
639                         "green": self._add4,
640                         "yellow": self._add6,
641                         "blue": self._reload,
642                         "save": self.close,
643                         "cancel": self.close,
644                         "ok" : self.close,
645                 }, -2)
646
647                 self._nsconfig = ServiceNSConfiguration(self._service)
648                 self._reload()
649                 self.onClose.append(self.__onClose)
650                 self.onLayoutFinish.append(self._layoutFinished)
651
652         def _layoutFinished(self):
653                 self.setTitle(_("%s Network - Nameservers" %self._service.name()))
654
655         def _remove(self):
656                 cfg = self["config"].getCurrent()
657                 if cfg:
658                         self._nsconfig.remove(cfg[1])
659                         self._createSetup()
660
661         def _add4(self):
662                 self._nsconfig.add4()
663                 self._createSetup()
664
665         def _add6(self):
666                 self._nsconfig.add6()
667                 self._createSetup()
668
669         def __onClose(self):
670                 if self._isServiceRemoved:
671                         return
672                 self._nsconfig.save()
673
674         def _reload(self):
675                 self._nsconfig.reload()
676                 self._createSetup()
677
678         def _createSetup(self):
679                 self["config"].setList( self._nsconfig.getList() )