mirror of
https://github.com/gryf/wicd.git
synced 2025-12-19 04:20:22 +01:00
curses/curses_misc.py:
Made Dialog a bit more generic with the new Dialog2, also supports mouse events.
Included TextDialog and InputDialog as subclasses of Dialog2
curses/netentry_curses.py:
Changed error() to support Dialog2
Added support for mouse events
curses/prefs_curses.py:
Added support for mouse events
curses/wicd-curses.py:
Added support for wicd's hidden wireless-network functionality
(Really) finished refactoring for the changes in ComboBox
Made some transitions a bit more immediate by calling update_ui() manually
Refactored to about_dialog to support Dialog2
Added support for mouse events (clicking to select, mostly)
Added support for retaining current list netlist focus throughout screen updates
(Hopefully) Added support for handling an instance of 0 available wireless
networks
in/man=wicd-curses.8.in: Hidden network support is fully functional
man/wicd-client.1: Added a word. (You'll live.)
setup.py: From last commit: Added the python "shebang" to the top of the file
393 lines
17 KiB
Python
393 lines
17 KiB
Python
#!/usr/bin/env python
|
|
"""
|
|
netentry_curses -- everyone's favorite networks settings dialogs... in text
|
|
form!
|
|
"""
|
|
|
|
# Copyright (C) 2009 Andrew Psaltis
|
|
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
# MA 02110-1301, USA.
|
|
|
|
import urwid
|
|
from curses_misc import TextDialog,DynWrap,MaskingEdit,ComboBox
|
|
import wicd.misc as misc
|
|
from wicd.misc import noneToString, stringToNone, noneToBlankString, to_bool
|
|
|
|
def error(ui,parent,message):
|
|
"""Shows an error dialog (or something that resembles one)"""
|
|
# /\
|
|
# /!!\
|
|
# /____\
|
|
dialog = TextDialog(message,40,6,('important',"ERROR"))
|
|
return dialog.run(ui,parent)
|
|
|
|
|
|
language = misc.get_language_list_gui()
|
|
|
|
daemon = None
|
|
wired = None
|
|
wireless = None
|
|
# Call this first!
|
|
def dbus_init(dbus_ifaces):
|
|
global daemon,wired,wireless
|
|
daemon = dbus_ifaces['daemon']
|
|
wired = dbus_ifaces['wired']
|
|
wireless = dbus_ifaces['wireless']
|
|
|
|
# Both the wired and the wireless settings preferences dialogs use some of the
|
|
# same fields.
|
|
# This will be used to produce the individual network settings dialogs way far below
|
|
class AdvancedSettingsDialog(urwid.WidgetWrap):
|
|
def __init__(self):
|
|
self.ui=None
|
|
|
|
static_ip_t = language['use_static_ip']
|
|
ip_t = ('editcp',language['ip']+': ')
|
|
netmask_t = ('editcp',language['netmask']+':')
|
|
gateway_t = ('editcp',language['gateway']+':')
|
|
|
|
use_static_dns_t = language['use_static_dns']
|
|
use_global_dns_t = language['use_global_dns']
|
|
dns_dom_t = ('editcp',language['dns_domain']+': ')
|
|
search_dom_t = ('editcp',language['search_domain']+':')
|
|
dns1_t = ('editcp',language['dns']+ ' ' + language['1']+':'+' '*8)
|
|
dns2_t = ('editcp',language['dns']+ ' ' + language['2']+':'+' '*8)
|
|
dns3_t = ('editcp',language['dns']+ ' ' + language['3']+':'+' '*8)
|
|
|
|
cancel_t = 'Cancel'
|
|
ok_t = 'OK'
|
|
|
|
self.static_ip_cb = urwid.CheckBox(static_ip_t,
|
|
on_state_change=self.static_ip_set_state)
|
|
self.ip_edit =DynWrap(urwid.Edit(ip_t),False)
|
|
self.netmask_edit=DynWrap(urwid.Edit(netmask_t),False)
|
|
self.gateway_edit=DynWrap(urwid.Edit(gateway_t),False)
|
|
|
|
|
|
self.static_dns_cb = urwid.CheckBox(use_static_dns_t,
|
|
on_state_change=self.dns_toggle)
|
|
self.global_dns_cb = DynWrap(urwid.CheckBox(use_global_dns_t,
|
|
on_state_change=self.dns_toggle),False,('body','editnfc'),None)
|
|
checkb_cols = urwid.Columns([self.static_dns_cb,
|
|
self.global_dns_cb])
|
|
self.dns_dom_edit = DynWrap(urwid.Edit(dns_dom_t) ,False)
|
|
self.search_dom_edit = DynWrap(urwid.Edit(search_dom_t),False)
|
|
self.dns1 = DynWrap(urwid.Edit(dns1_t) ,False)
|
|
self.dns2 = DynWrap(urwid.Edit(dns2_t) ,False)
|
|
self.dns3 = DynWrap(urwid.Edit(dns3_t) ,False)
|
|
|
|
_blank = urwid.Text('')
|
|
|
|
# Buttons. These need to be added to the list in superclasses.
|
|
self.OK_PRESSED= False
|
|
self.CANCEL_PRESSED = False
|
|
self.ok_button = urwid.AttrWrap(urwid.Button('OK',self.ok_callback),'body','focus')
|
|
self.cancel_button = urwid.AttrWrap(urwid.Button('Cancel',self.cancel_callback),'body','focus')
|
|
self.button_cols = urwid.Columns([self.ok_button,self.cancel_button])
|
|
|
|
walker = urwid.SimpleListWalker([self.static_ip_cb,
|
|
self.ip_edit,
|
|
self.netmask_edit,
|
|
self.gateway_edit,
|
|
_blank,
|
|
checkb_cols,
|
|
self.dns_dom_edit,self.search_dom_edit,
|
|
self.dns1,self.dns2,self.dns3
|
|
])
|
|
|
|
|
|
|
|
self._listbox = urwid.ListBox(walker)
|
|
#self._frame = urwid.Frame(self._listbox)
|
|
self._frame = urwid.Frame(self._listbox)
|
|
self.__super.__init__(self._frame)
|
|
|
|
|
|
# Button callbacks
|
|
def ok_callback(self,button_object,user_data=None):
|
|
self.OK_PRESSED = True
|
|
def cancel_callback(self,button_object,user_data=None):
|
|
self.CANCEL_PRESSED = True
|
|
|
|
def static_ip_set_state(self,checkb,new_state,user_data=None):
|
|
for w in [ self.ip_edit,self.netmask_edit,self.gateway_edit ]:
|
|
w.set_sensitive(new_state)
|
|
|
|
def dns_toggle(self,checkb,new_state,user_data=None):
|
|
if checkb == self.static_dns_cb:
|
|
for w in [ self.dns_dom_edit,self.search_dom_edit,
|
|
self.dns1,self.dns2,self.dns3 ]:
|
|
w.set_sensitive(new_state)
|
|
if not new_state:
|
|
self.global_dns_cb.set_state(False,do_callback=False)
|
|
self.global_dns_cb.set_sensitive(new_state)
|
|
# use_global_dns_cb is DynWrapped
|
|
if checkb == self.global_dns_cb.get_w():
|
|
for w in [ self.dns_dom_edit,self.search_dom_edit,
|
|
self.dns1,self.dns2,self.dns3 ]:
|
|
w.set_sensitive(not new_state)
|
|
|
|
# Code totally yanked from netentry.py
|
|
def save_settings(self):
|
|
""" Save settings common to wired and wireless settings dialogs. """
|
|
if self.static_ip_cb.get_state():
|
|
self.set_net_prop("ip", noneToString(self.ip_edit.get_edit_text()))
|
|
self.set_net_prop("netmask", noneToString(self.netmask_edit.get_edit_text()))
|
|
self.set_net_prop("gateway", noneToString(self.gateway_edit.get_edit_text()))
|
|
else:
|
|
self.set_net_prop("ip", '')
|
|
self.set_net_prop("netmask", '')
|
|
self.set_net_prop("gateway", '')
|
|
|
|
if self.static_dns_cb.get_state() and \
|
|
not self.global_dns_cb.get_state():
|
|
self.set_net_prop('use_static_dns', True)
|
|
self.set_net_prop('use_global_dns', False)
|
|
self.set_net_prop('dns_domain', noneToString(self.dns_dom_edit.get_text()))
|
|
self.set_net_prop("search_domain", noneToString(self.search_dom_edit.get_text()))
|
|
self.set_net_prop("dns1", noneToString(self.dns1.get_text()))
|
|
self.set_net_prop("dns2", noneToString(self.dns2.get_text()))
|
|
self.set_net_prop("dns3", noneToString(self.dns3.get_text()))
|
|
elif self.static_dns_cb.get_state() and \
|
|
self.global_dns_cb.get_state():
|
|
self.set_net_prop('use_static_dns', True)
|
|
self.set_net_prop('use_global_dns', True)
|
|
else:
|
|
self.set_net_prop('use_static_dns', False)
|
|
self.set_net_prop('use_global_dns', False)
|
|
self.set_net_prop('dns_domain', '')
|
|
self.set_net_prop("search_domain", '')
|
|
self.set_net_prop("dns1", '')
|
|
self.set_net_prop("dns2", '')
|
|
self.set_net_prop("dns3", '')
|
|
|
|
def run(self,ui,dim,display):
|
|
width,height = ui.get_cols_rows()
|
|
|
|
overlay = urwid.Overlay(self, display, ('fixed left', 0),width
|
|
, ('fixed top',1), height-3)
|
|
#self.ready_comboboxes(ui,overlay)
|
|
|
|
keys = True
|
|
while True:
|
|
if keys:
|
|
ui.draw_screen(dim, overlay.render(dim, True))
|
|
keys = ui.get_input()
|
|
|
|
if "window resize" in keys:
|
|
dim = ui.get_cols_rows()
|
|
if "esc" in keys or 'Q' in keys:
|
|
return False
|
|
for k in keys:
|
|
#Send key to underlying widget:
|
|
overlay.keypress(dim, k)
|
|
# Check if buttons are pressed.
|
|
#if self.CANCEL_PRESSED:
|
|
# return False
|
|
#if self.OK_PRESSED or 'meta enter' in keys:
|
|
# return True
|
|
|
|
########################################
|
|
|
|
class WirelessSettingsDialog(AdvancedSettingsDialog):
|
|
def __init__(self,networkID):
|
|
global wireless, daemon
|
|
AdvancedSettingsDialog.__init__(self)
|
|
self.networkID = networkID
|
|
global_settings_t = language['global_settings']
|
|
encryption_t = language['use_encryption']
|
|
|
|
self.global_settings_chkbox = urwid.CheckBox(global_settings_t)
|
|
self.encryption_chkbox = urwid.CheckBox(encryption_t,on_state_change=self.encryption_toggle)
|
|
self.encryption_combo = ComboBox(callback=self.combo_on_change)
|
|
self.pile_encrypt = None
|
|
# _w is a Frame, _w.body is a ListBox, _w.body.body is the ListWalker :-)
|
|
self._w.body.body.append(self.global_settings_chkbox)
|
|
self._w.body.body.append(self.encryption_chkbox)
|
|
self._w.body.body.append(self.encryption_combo)
|
|
self._w.body.body.append(self.button_cols)
|
|
self.encrypt_types = misc.LoadEncryptionMethods()
|
|
self.set_values()
|
|
|
|
# Set the frame title so that people will always know what we're dealing with.
|
|
self._w.header = urwid.Text(('header',">Configuring preferences for wireless network \"%s\"" % wireless.GetWirelessProperty(networkID,'essid')),align='right' )
|
|
|
|
def encryption_toggle(self,chkbox,new_state,user_data=None):
|
|
self.encryption_combo.set_sensitive(new_state)
|
|
self.pile_encrypt.set_sensitive(new_state)
|
|
|
|
def combo_on_change(self,combobox,new_index,user_data=None):
|
|
self.change_encrypt_method()
|
|
|
|
def set_values(self):
|
|
""" Set the various network settings to the right values. """
|
|
networkID = self.networkID
|
|
self.ip_edit.set_edit_text(self.format_entry(networkID,"ip"))
|
|
self.netmask_edit.set_edit_text(self.format_entry(networkID,"netmask"))
|
|
self.gateway_edit.set_edit_text(self.format_entry(networkID,"gateway"))
|
|
|
|
self.global_dns_cb.set_state(bool(wireless.GetWirelessProperty(networkID,
|
|
'use_global_dns')))
|
|
self.static_dns_cb.set_state(bool(wireless.GetWirelessProperty(networkID,
|
|
'use_static_dns')))
|
|
|
|
self.dns1.set_edit_text(self.format_entry(networkID, "dns1"))
|
|
self.dns2.set_edit_text(self.format_entry(networkID, "dns2"))
|
|
self.dns3.set_edit_text(self.format_entry(networkID, "dns3"))
|
|
self.dns_dom_edit.set_edit_text(self.format_entry(networkID, "dns_domain"))
|
|
self.search_dom_edit.set_edit_text(self.format_entry(networkID, "search_domain"))
|
|
|
|
|
|
#self.reset_static_checkboxes()
|
|
self.encryption_chkbox.set_state(bool(wireless.GetWirelessProperty(networkID,
|
|
'encryption')),do_callback=False)
|
|
self.global_settings_chkbox.set_state(bool(wireless.GetWirelessProperty(networkID
|
|
,'use_settings_globally')))
|
|
|
|
activeID = -1 # Set the menu to this item when we are done
|
|
user_enctype = wireless.GetWirelessProperty(networkID, "enctype")
|
|
for x, enc_type in enumerate(self.encrypt_types):
|
|
if enc_type[1] == user_enctype:
|
|
activeID = x
|
|
|
|
self.encryption_combo.set_focus(activeID)
|
|
if activeID != -1:
|
|
self.encryption_chkbox.set_state(True,do_callback=False)
|
|
self.encryption_combo.set_sensitive(True)
|
|
#self.lbox_encrypt_info.set_sensitive(True)
|
|
else:
|
|
self.encryption_combo.set_focus(0)
|
|
# Throw the encryption stuff into a list
|
|
list = []
|
|
for x, enc_type in enumerate(self.encrypt_types):
|
|
list.append(enc_type[0])
|
|
self.encryption_combo.set_list(list)
|
|
self.change_encrypt_method()
|
|
|
|
def set_net_prop(self, option, value):
|
|
""" Sets the given option to the given value for this network. """
|
|
wireless.SetWirelessProperty(self.networkID, option, value)
|
|
|
|
def format_entry(self, networkid, label):
|
|
""" Helper method for fetching/formatting wireless properties. """
|
|
return noneToBlankString(wireless.GetWirelessProperty(networkid, label))
|
|
|
|
# Ripped from netentry.py
|
|
def save_settings(self, networkid):
|
|
# Check encryption info
|
|
if self.encryption_chkbox.get_state():
|
|
#print "setting encryption info..."
|
|
encryption_info = self.encryption_info
|
|
encrypt_methods = misc.LoadEncryptionMethods()
|
|
self.set_net_prop("enctype",
|
|
encrypt_methods[self.encryption_combo.get_focus()[1] ][1])
|
|
for x in encryption_info:
|
|
if encryption_info[x].get_edit_text() == "":
|
|
error(self.ui, self.overlay,language['encrypt_info_missing'])
|
|
return False
|
|
self.set_net_prop(x, noneToString(encryption_info[x].
|
|
get_edit_text()))
|
|
elif not self.encryption_chkbox.get_state() and \
|
|
wireless.GetWirelessProperty(networkid, "encryption"):
|
|
error(self.ui, self.overlay, language['enable_encryption'])
|
|
return False
|
|
else:
|
|
#print 'encryption is ' + str(wireless.GetWirelessProperty(networkid,
|
|
# "encryption"))
|
|
#print "no encryption specified..."
|
|
self.set_net_prop("enctype", "None")
|
|
AdvancedSettingsDialog.save_settings(self)
|
|
|
|
if self.global_settings_chkbox.get_state():
|
|
self.set_net_prop('use_settings_globally', True)
|
|
else:
|
|
self.set_net_prop('use_settings_globally', False)
|
|
wireless.RemoveGlobalEssidEntry(networkid)
|
|
|
|
wireless.SaveWirelessNetworkProfile(networkid)
|
|
return True
|
|
|
|
# More or less ripped from netentry.py
|
|
def change_encrypt_method(self):
|
|
#self.lbox_encrypt = urwid.ListBox()
|
|
wid,ID = self.encryption_combo.get_focus()
|
|
methods = misc.LoadEncryptionMethods()
|
|
self.encryption_info = {}
|
|
|
|
if self._w.body.body.__contains__(self.pile_encrypt):
|
|
self._w.body.body.pop(self._w.body.body.__len__()-2)
|
|
|
|
# If nothing is selected, select the first entry.
|
|
if ID == -1:
|
|
self.encryption_combo.set_active(0)
|
|
ID = 0
|
|
|
|
opts = methods[ID][2]
|
|
theList = []
|
|
for x in opts:
|
|
edit = None
|
|
if language.has_key(opts[x][0]):
|
|
edit = MaskingEdit(('editcp',language[opts[x][0].lower().replace(' ','_')]+': '),mask_mode='on_focus')
|
|
else:
|
|
edit = MaskingEdit(('editcp',opts[x][0].replace('_',' ')+': '),mask_mode='on_focus')
|
|
theList.append(edit)
|
|
# Add the data to any array, so that the information
|
|
# can be easily accessed by giving the name of the wanted
|
|
# data.
|
|
self.encryption_info[opts[x][1]] = edit
|
|
|
|
edit.set_edit_text(noneToBlankString(
|
|
wireless.GetWirelessProperty(self.networkID, opts[x][1])))
|
|
|
|
self.pile_encrypt = DynWrap(urwid.Pile(theList),attrs=('editbx','editnfc'))
|
|
self._w.body.body.insert(self._w.body.body.__len__()-1,self.pile_encrypt)
|
|
#self._w.body.body.append(self.pile_encrypt)
|
|
|
|
def run(self,ui,dim,display):
|
|
self.ui = ui
|
|
self.parent = display
|
|
width,height = ui.get_cols_rows()
|
|
self.overlay = urwid.Overlay(self, display, ('fixed left', 0),width
|
|
, ('fixed top',1), height-3)
|
|
self.encryption_combo.build_combobox(self.overlay,ui,14)
|
|
#self.change_encrypt_method()
|
|
#self._w.body.body.append(self.pile_encrypt)
|
|
|
|
keys = True
|
|
while True:
|
|
if keys:
|
|
ui.draw_screen(dim, self.overlay.render(dim, True))
|
|
keys = ui.get_input()
|
|
|
|
for k in keys:
|
|
#Send key to underlying widget:
|
|
if urwid.is_mouse_event(k):
|
|
event, button, col, row = k
|
|
self.overlay.mouse_event( dim,
|
|
event, button, col, row,
|
|
focus=True)
|
|
self.overlay.keypress(dim, k)
|
|
if "window resize" in keys:
|
|
dim = ui.get_cols_rows()
|
|
if "esc" in keys or 'Q' in keys:
|
|
return False
|
|
if "meta enter" in keys or self.OK_PRESSED:
|
|
self.OK_PRESSED = False
|
|
if self.save_settings(self.networkID):
|
|
return True
|
|
if self.CANCEL_PRESSED:
|
|
return False
|