mirror of
https://github.com/gryf/wicd.git
synced 2025-12-19 20:38:00 +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
489 lines
19 KiB
Python
Executable File
489 lines
19 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
# Copyright (C) 2008-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
|
|
import urwid.curses_display
|
|
|
|
from wicd import misc
|
|
from wicd import dbusmanager
|
|
from curses_misc import SelText,DynWrap,ComboBox,TabColumns
|
|
|
|
daemon = None
|
|
wireless = None
|
|
wired = None
|
|
# Will work for now, I guess.
|
|
language = misc.get_language_list_gui()
|
|
|
|
class PrefsDialog(urwid.WidgetWrap):
|
|
def __init__(self,body,pos,ui,dbus=None):
|
|
global daemon, wireless, wired
|
|
|
|
daemon = dbus['daemon']
|
|
wireless = dbus['wireless']
|
|
wired = dbus['wired']
|
|
|
|
width,height = ui.get_cols_rows()
|
|
height -= 3
|
|
#width = 80
|
|
#height = 20
|
|
# Stuff that goes at the top
|
|
|
|
header0_t = language["gen_settings"]
|
|
header1_t = language["ext_programs"]
|
|
header2_t = language["advanced_settings"]
|
|
self.header0 = urwid.AttrWrap(SelText(header0_t),'tab active','focus')
|
|
self.header1 = urwid.AttrWrap(SelText(header1_t),'body','focus')
|
|
self.header2 = urwid.AttrWrap(SelText(header2_t),'body','focus')
|
|
title = language['preferences']
|
|
|
|
# Blank line
|
|
_blank = urwid.Text('')
|
|
|
|
####
|
|
#### Text in the widgets
|
|
####
|
|
|
|
# General Settings
|
|
net_cat_t = ('header','Network Interfaces')
|
|
wired_t = ('editcp',language['wired_interface']+': ')
|
|
wless_t = ('editcp',language['wireless_interface']+':')
|
|
always_show_wired_t = 'Always show wired interface'
|
|
|
|
global_dns_cat_t = ('header','Global DNS Servers')
|
|
global_dns_t = ('editcp',language['use_global_dns'])
|
|
dns_dom_t = ('editcp',' DNS Domain: ')
|
|
search_dom_t = ('editcp',' Search domain:')
|
|
dns1_t = ('editcp',' DNS server 1: ')
|
|
dns2_t = ('editcp',' DNS server 2: ')
|
|
dns3_t = ('editcp',' DNS server 3: ')
|
|
|
|
|
|
wired_auto_cat_t= ('header','Wired Autoconnect Settings')
|
|
wired_auto_1_t = language['use_default_profile']
|
|
wired_auto_2_t = language['show_wired_list']
|
|
wired_auto_3_t = language['use_last_used_profile']
|
|
|
|
auto_reconn_cat_t = ('header','Automatic Reconnection')
|
|
auto_reconn_t = 'Automatically reconnect on connection loss'
|
|
|
|
#### External Programs
|
|
automatic_t = language['wicd_auto_config']
|
|
|
|
dhcp_header_t = ('header',language["dhcp_client"])
|
|
# Automatic
|
|
dhcp1_t = 'dhclient'
|
|
dhcp2_t = 'dhcpcd'
|
|
dhcp3_t = 'pump'
|
|
|
|
wired_detect_header_t = ('header',language["wired_detect"])
|
|
wired1_t = 'ethtool'
|
|
wired2_t = 'mii-tool'
|
|
|
|
flush_header_t = ('header',language["route_flush"])
|
|
flush1_t = 'ip'
|
|
flush2_t = 'route'
|
|
|
|
#### Advanced Settings
|
|
#wpa_t=('editcp',language['wpa_supplicant_driver']+':')
|
|
wpa_cat_t=('header','WPA_Supplicant')
|
|
wpa_t=('editcp','Driver:')
|
|
wpa_list = ['spam','double spam','triple spam','quadruple spam']
|
|
wpa_warn_t = ('important','You should almost always use wext as the WPA Supplicant Driver')
|
|
|
|
backend_cat_t = ('header',language['backend'])
|
|
backend_t = language['backend']+':'
|
|
backend_list = ['spam','double spam','triple spam','quadruple spam']
|
|
backend_warn_t = ('important','Changes to the backend (probably) requires a daemon restart')
|
|
|
|
debug_cat_t = ('header','Debugging')
|
|
debug_mode_t = language['use_debug_mode']
|
|
|
|
wless_cat_t = ('header','Wireless Interface')
|
|
use_dbm_t = language['display_type_dialog']
|
|
|
|
|
|
|
|
####
|
|
#### UI Widgets
|
|
####
|
|
|
|
# General Settings
|
|
self.net_cat = urwid.Text(net_cat_t)
|
|
self.wired_edit = urwid.AttrWrap(urwid.Edit(wired_t),'editbx','editfc')
|
|
self.wless_edit = urwid.AttrWrap(urwid.Edit(wless_t),'editbx','editfc')
|
|
|
|
self.global_dns_cat = urwid.Text(global_dns_cat_t)
|
|
# Default the global DNS settings to off. They will be reenabled later
|
|
# if so required.
|
|
global_dns_state = False
|
|
self.global_dns_checkb = urwid.CheckBox(global_dns_t,global_dns_state,
|
|
on_state_change=self.global_dns_trigger)
|
|
self.search_dom = DynWrap(urwid.Edit(search_dom_t),global_dns_state)
|
|
self.dns_dom = DynWrap(urwid.Edit(dns_dom_t),global_dns_state)
|
|
self.dns1 = DynWrap(urwid.Edit(dns1_t),global_dns_state)
|
|
self.dns2 = DynWrap(urwid.Edit(dns2_t),global_dns_state)
|
|
self.dns3 = DynWrap(urwid.Edit(dns3_t),global_dns_state)
|
|
|
|
|
|
self.always_show_wired_checkb = urwid.CheckBox(always_show_wired_t)
|
|
|
|
self.wired_auto_l = []
|
|
self.wired_auto_cat = urwid.Text(wired_auto_cat_t)
|
|
self.wired_auto_1 = urwid.RadioButton(self.wired_auto_l,wired_auto_1_t)
|
|
self.wired_auto_2 = urwid.RadioButton(self.wired_auto_l,wired_auto_2_t)
|
|
self.wired_auto_3 = urwid.RadioButton(self.wired_auto_l,wired_auto_3_t)
|
|
|
|
self.auto_reconn_cat = urwid.Text(auto_reconn_cat_t)
|
|
self.auto_reconn_checkb = urwid.CheckBox(auto_reconn_t)
|
|
generalLB = urwid.ListBox([self.net_cat,
|
|
self.wless_edit,#_blank,
|
|
self.wired_edit,
|
|
self.always_show_wired_checkb,_blank,
|
|
self.global_dns_cat,
|
|
self.global_dns_checkb,#_blank,
|
|
self.search_dom,self.dns_dom,
|
|
self.dns1,self.dns2,self.dns3,_blank,
|
|
self.wired_auto_cat,
|
|
self.wired_auto_1,
|
|
self.wired_auto_2,
|
|
self.wired_auto_3, _blank,
|
|
self.auto_reconn_cat,
|
|
self.auto_reconn_checkb
|
|
])
|
|
|
|
#### External Programs tab
|
|
automatic_t = language['wicd_auto_config']
|
|
|
|
self.dhcp_header = urwid.Text(dhcp_header_t)
|
|
self.dhcp_l = []
|
|
# Automatic
|
|
self.dhcp0 = urwid.RadioButton(self.dhcp_l,automatic_t)
|
|
self.dhcp1 = urwid.RadioButton(self.dhcp_l,dhcp1_t)
|
|
self.dhcp2 = urwid.RadioButton(self.dhcp_l,dhcp2_t)
|
|
self.dhcp3 = urwid.RadioButton(self.dhcp_l,dhcp3_t)
|
|
|
|
self.wired_l = []
|
|
self.wired_detect_header = urwid.Text(wired_detect_header_t)
|
|
self.wired0 = urwid.RadioButton(self.wired_l,automatic_t)
|
|
self.wired1 = urwid.RadioButton(self.wired_l,wired1_t)
|
|
self.wired2 = urwid.RadioButton(self.wired_l,wired2_t)
|
|
|
|
self.flush_l = []
|
|
self.flush_header = urwid.Text(flush_header_t)
|
|
self.flush0 = urwid.RadioButton(self.flush_l,automatic_t)
|
|
self.flush1 = urwid.RadioButton(self.flush_l,flush1_t)
|
|
self.flush2 = urwid.RadioButton(self.flush_l,flush2_t)
|
|
|
|
externalLB = urwid.ListBox([self.dhcp_header,
|
|
self.dhcp0,self.dhcp1,self.dhcp2,self.dhcp3,
|
|
_blank,
|
|
self.wired_detect_header,
|
|
self.wired0,self.wired1,self.wired2,
|
|
_blank,
|
|
self.flush_header,
|
|
self.flush0,self.flush1,self.flush2
|
|
])
|
|
|
|
|
|
#### Advanced settings
|
|
self.wpa_cat = urwid.Text(wpa_cat_t)
|
|
self.wpa_cbox = ComboBox(wpa_t)
|
|
self.wpa_warn = urwid.Text(wpa_warn_t)
|
|
|
|
self.backend_cat = urwid.Text(backend_cat_t)
|
|
self.backend_cbox = ComboBox(backend_t)
|
|
self.backend_warn = urwid.Text(backend_warn_t)
|
|
|
|
self.debug_cat = urwid.Text(debug_cat_t)
|
|
self.debug_mode_checkb = urwid.CheckBox(debug_mode_t)
|
|
|
|
self.wless_cat = urwid.Text(wless_cat_t)
|
|
self.use_dbm_checkb = urwid.CheckBox(use_dbm_t)
|
|
|
|
|
|
advancedLB = urwid.ListBox([self.wpa_cat,
|
|
self.wpa_cbox,self.wpa_warn,_blank,
|
|
self.backend_cat,
|
|
self.backend_cbox,self.backend_warn,_blank,
|
|
self.debug_cat,
|
|
self.debug_mode_checkb, _blank,
|
|
self.wless_cat,
|
|
self.use_dbm_checkb, _blank
|
|
])
|
|
|
|
|
|
headerList = [self.header0,self.header1,self.header2]
|
|
lbList = [generalLB,externalLB,advancedLB]
|
|
self.tab_map = {self.header0 : generalLB,
|
|
self.header1 : externalLB,
|
|
self.header2 : advancedLB}
|
|
#self.load_settings()
|
|
|
|
# Now for the buttons:
|
|
ok_t = 'OK'
|
|
cancel_t = 'Cancel'
|
|
|
|
ok_button = urwid.AttrWrap(urwid.Button('OK',self.ok_callback),'body','focus')
|
|
cancel_button = urwid.AttrWrap(urwid.Button('Cancel',self.cancel_callback),'body','focus')
|
|
# Variables set by the buttons' callback functions
|
|
self.CANCEL_PRESSED = False
|
|
self.OK_PRESSED = False
|
|
|
|
|
|
self.button_cols = urwid.Columns([ok_button,cancel_button],dividechars=1)
|
|
#self.active_tab = self.header0
|
|
|
|
#self.columns = urwid.Columns([('fixed',len(header0_t),self.header0),
|
|
# ('fixed',len(header1_t),self.header1),
|
|
# ('fixed',len(header2_t),self.header2),
|
|
# urwid.Text(('header',title),align='right')],
|
|
# dividechars=1)
|
|
|
|
#content = [self.columns,generalPile]
|
|
#self._label = urwid.AttrWrap(SelText(titles),attr[0],attr[1])
|
|
#self.walker = urwid.SimpleListWalker(content)
|
|
#self.listbox = urwid.ListBox(self.walker)
|
|
#self._linebox = urwid.LineBox(self._listbox)
|
|
self.tabs = TabColumns(headerList,lbList,'Preferences',self.button_cols)
|
|
#overlay = urwid.Overlay(self.tabs, body, ('fixed left', pos[0]),
|
|
# width, ('fixed top', pos[1]), height)
|
|
self.__super.__init__(self.tabs)
|
|
|
|
def load_settings(self):
|
|
# Reset the buttons
|
|
self.CANCEL_PRESSED = False
|
|
self.OK_PRESSED = False
|
|
|
|
### General Settings
|
|
# Urwid does not like dbus.Strings as text markups
|
|
wless_iface = unicode(daemon.GetWirelessInterface())
|
|
wired_iface = unicode(daemon.GetWiredInterface())
|
|
self.wless_edit.set_edit_text(wless_iface)
|
|
self.wired_edit.set_edit_text(wired_iface)
|
|
|
|
self.always_show_wired_checkb.set_state(
|
|
daemon.GetAlwaysShowWiredInterface())
|
|
|
|
# DNS
|
|
self.global_dns_checkb.set_state(daemon.GetUseGlobalDNS())
|
|
theDNS = daemon.GetGlobalDNSAddresses()
|
|
|
|
i = 0
|
|
for w in self.dns1,self.dns2,self.dns3,self.dns_dom,self.search_dom :
|
|
w.set_edit_text(misc.noneToBlankString(theDNS[i]))
|
|
i+=1
|
|
|
|
# Wired Automatic Connection
|
|
self.wired_auto_l[daemon.GetWiredAutoConnectMethod()-1]
|
|
|
|
self.auto_reconn_checkb.set_state(daemon.GetAutoReconnect())
|
|
|
|
### External Programs
|
|
dhcp_method = daemon.GetDHCPClient()
|
|
self.dhcp_l[dhcp_method].set_state(True)
|
|
|
|
wired_link_method = daemon.GetLinkDetectionTool()
|
|
self.wired_l[wired_link_method].set_state(True)
|
|
|
|
flush_method = daemon.GetFlushTool()
|
|
self.flush_l[flush_method].set_state(True)
|
|
|
|
### Advanced settings
|
|
# wpa_supplicant janx
|
|
self.wpadrivers = ["wext", "hostap", "madwifi", "atmel",
|
|
"ndiswrapper", "ipw"]
|
|
self.wpadrivers = wireless.GetWpaSupplicantDrivers(self.wpadrivers)
|
|
self.wpadrivers.append("ralink_legacy")
|
|
# Same as above with the dbus.String
|
|
self.thedrivers = [unicode(w) for w in self.wpadrivers]
|
|
self.wpa_cbox.set_list(self.thedrivers)
|
|
|
|
# Pick where to begin first:
|
|
def_driver = daemon.GetWPADriver()
|
|
try:
|
|
self.wpa_cbox.set_focus(self.wpadrivers.index(def_driver))
|
|
except ValueError:
|
|
pass # It defaults to 0 anyway
|
|
|
|
self.backends = daemon.GetBackendList()
|
|
# Remove the blank string b/c of some dbus mess
|
|
self.backends.remove('')
|
|
self.thebackends= [unicode(w) for w in self.backends]
|
|
self.backend_cbox.set_list(self.thebackends)
|
|
cur_backend = daemon.GetSavedBackend()
|
|
try:
|
|
self.backend_cbox.set_focus(self.thebackends.index(cur_backend))
|
|
except ValueError:
|
|
self.backend_cbox.set_focus(0)
|
|
|
|
# Two last checkboxes
|
|
self.debug_mode_checkb.set_state(daemon.GetDebugMode())
|
|
self.use_dbm_checkb.set_state(daemon.GetSignalDisplayType())
|
|
|
|
def save_results(self):
|
|
""" Pushes the selected settings to the daemon.
|
|
This exact order is found in prefs.py"""
|
|
daemon.SetUseGlobalDNS(self.global_dns_checkb.get_state())
|
|
daemon.SetGlobalDNS(self.dns1.get_edit_text(), self.dns2.get_edit_text(),
|
|
self.dns3.get_edit_text(), self.dns_dom.get_edit_text(),
|
|
self.search_dom.get_edit_text())
|
|
daemon.SetWirelessInterface(self.wless_edit.get_edit_text())
|
|
daemon.SetWiredInterface(self.wired_edit.get_edit_text())
|
|
daemon.SetWPADriver(self.wpadrivers[self.wpa_cbox.get_focus()[1]])
|
|
daemon.SetAlwaysShowWiredInterface(self.always_show_wired_checkb.get_state())
|
|
daemon.SetAutoReconnect(self.auto_reconn_checkb.get_state())
|
|
daemon.SetDebugMode(self.debug_mode_checkb.get_state())
|
|
daemon.SetSignalDisplayType(int(self.use_dbm_checkb.get_state()))
|
|
if self.wired_auto_2.get_state():
|
|
daemon.SetWiredAutoConnectMethod(2)
|
|
elif self.wired_auto_3.get_state():
|
|
daemon.SetWiredAutoConnectMethod(3)
|
|
else:
|
|
daemon.SetWiredAutoConnectMethod(1)
|
|
|
|
daemon.SetBackend(self.backends[self.backend_cbox.get_focus()[1]])
|
|
|
|
# External Programs Tab
|
|
if self.dhcp0.get_state():
|
|
dhcp_client = misc.AUTO
|
|
elif self.dhcp1.get_state():
|
|
dhcp_client = misc.DHCLIENT
|
|
elif self.dhcp2.get_state():
|
|
dhcp_client = misc.DHCPCD
|
|
else:
|
|
dhcp_client = misc.PUMP
|
|
daemon.SetDHCPClient(dhcp_client)
|
|
|
|
if self.wired0.get_state():
|
|
link_tool = misc.AUTO
|
|
elif self.wired1.get_state():
|
|
link_tool = misc.ETHTOOL
|
|
else:
|
|
link_tool = misc.MIITOOL
|
|
daemon.SetLinkDetectionTool(link_tool)
|
|
|
|
if self.flush0.get_state():
|
|
flush_tool = misc.AUTO
|
|
elif self.flush1.get_state():
|
|
flush_tool = misc.IP
|
|
else:
|
|
flush_tool = misc.ROUTE
|
|
daemon.SetFlushTool(flush_tool)
|
|
|
|
# DNS CheckBox callback
|
|
def global_dns_trigger(self,check_box,new_state,user_data=None):
|
|
for w in self.dns1,self.dns2,self.dns3,self.dns_dom,self.search_dom:
|
|
w.set_sensitive(new_state)
|
|
|
|
# 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 ready_comboboxes(self,ui,body):
|
|
self.wpa_cbox.build_combobox(body,ui,4)
|
|
self.backend_cbox.build_combobox(body,ui,8)
|
|
|
|
# Put the widget into an overlay, and run!
|
|
def run(self,ui, dim, display):
|
|
width,height = ui.get_cols_rows()
|
|
self.load_settings()
|
|
# TODO: The below, if things go 'well'
|
|
# If we are small, "tabbify" the interface
|
|
# Else, pile it together
|
|
|
|
overlay = urwid.Overlay(self.tabs, 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:
|
|
if urwid.is_mouse_event(k):
|
|
event, button, col, row = k
|
|
overlay.mouse_event( dim,
|
|
event, button, col, row,
|
|
focus=True)
|
|
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
|
|
|
|
|
|
###
|
|
### EXTERNAL ENTRY POINT STUFF
|
|
###
|
|
def run_it():
|
|
dialog = PrefsDialog(None,(0,0),ui,dbusmanager.get_dbus_ifaces())
|
|
keys = True
|
|
dim = ui.get_cols_rows()
|
|
dialog.load_settings()
|
|
dialog.ready_comboboxes(ui,dialog)
|
|
while True:
|
|
if keys:
|
|
ui.draw_screen(dim, dialog.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:
|
|
dialog.keypress(dim, k)
|
|
if dialog.CANCEL_PRESSED:
|
|
return False
|
|
if dialog.OK_PRESSED:
|
|
dialog.save_results()
|
|
return True
|
|
|
|
if __name__=='__main__':
|
|
try:
|
|
dbusmanager.connect_to_dbus()
|
|
except DBusException:
|
|
# I may need to be a little more verbose here.
|
|
# Suggestions as to what should go here
|
|
print "Can't connect to the daemon. Are you sure it is running?"
|
|
print "Please check the wicd log for error messages."
|
|
raise
|
|
ui = urwid.curses_display.Screen()
|
|
ui.register_palette([
|
|
('body','light gray','default'),
|
|
('focus','dark magenta','light gray'),
|
|
('header','light blue','default'),
|
|
('important','light red','default'),
|
|
('connected','dark green','default'),
|
|
('connected focus','default','dark green'),
|
|
('editcp', 'default', 'default', 'standout'),
|
|
('editbx', 'light gray', 'dark blue'),
|
|
('editfc', 'white','dark blue', 'bold'),
|
|
('tab active','dark green','light gray')])
|
|
ui.run_wrapper(run_it)
|