1
0
mirror of https://github.com/gryf/wicd.git synced 2025-12-19 04:20:22 +01:00

Checkpoint in WirelessNetEntry development

curses/curses_misc.py:
  Refactored some DynWrap internals
  Added MaskingEdit, a password edit
  Modified ComboBox to use a DynWrap internally instead of an AttrWrap
curses/netentry_curses.py:
  Added most of the WirelessNetEntry.  It doesn't save information yet, but it does
    load most of it.  Support for viewing the templated network settings is not
    implemented yet.
curses/wicd-curses.py:
  Activated support for the WirelessNetEntry configurator.  The wired one is not
    implemented yet.
This commit is contained in:
Andrew Psaltis
2009-01-06 19:02:27 -05:00
parent 2eaa3e3694
commit 4ab56b1183
4 changed files with 289 additions and 44 deletions

View File

@@ -5,7 +5,7 @@
wicd-curses.
"""
# Copyright (C) 2008-9 Andrew Psaltis
# 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
@@ -53,7 +53,7 @@ class DynWrap(urwid.AttrWrap):
"""
def __init__(self,w,sensitive=True,attrs=('editbx','editnfc'),focus_attr='editfc'):
self.attrs=attrs
self._attrs=attrs
self._sensitive = sensitive
cur_attr = attrs[0] if sensitive else attrs[1]
@@ -63,22 +63,78 @@ class DynWrap(urwid.AttrWrap):
def get_sensitive(self):
return self._sensitive
def set_sensitive(self,state):
if state :
self.set_attr(self.attrs[0])
if state:
self.set_attr(self._attrs[0])
else:
self.set_attr(self.attrs[1])
self.set_attr(self._attrs[1])
self._sensitive = state
property(get_sensitive,set_sensitive)
def get_attrs(self):
return self._attrs
def set_attrs(self,attrs):
self.attrs = attrs
self._attrs = attrs
property(get_attrs,set_attrs)
def selectable(self):
return self._sensitive
class MaskingEditException(Exception):
pass
# Password-style edit
class MaskingEdit(urwid.Edit):
"""
mask_mode = one of:
"always" : everything is a '*' all of the time
"on_focus" : everything is a '*' only when not in focus
"off" : everything is always unmasked
mask_char = the single character that masks all other characters in the field
"""
def __init__(self, caption = "", edit_text = "", multiline = False,
align = 'left', wrap = 'space', allow_tab = False,
edit_pos = None, layout=None, mask_mode="masked",mask_char='*'):
self.mask_mode = mask_mode
if len(mask_char) > 1:
raise MaskingEditException('Masks of more than one character are not supported!')
self.mask_char = mask_char
self.__super.__init__(caption,edit_text,multiline,align,wrap,allow_tab,edit_pos,layout)
def get_mask_mode(self):
return self.mask_mode
def set_mask_mode(self,mode):
self.mask_mode = mode
def get_masked_text(self):
return self.mask_char*len(self.get_edit_text())
def render(self,(maxcol,), focus=False):
"""
Render edit widget and return canvas. Include cursor when in
focus.
"""
# If we aren't masking anything ATM, then act like an Edit. No problems.
if self.mask_mode == "off" or (self.mask_mode == 'on_focus' and focus == True):
canv = self.__super.render((maxcol,),focus)
# The cache messes this thing up, because I am totally changing what is
# displayed.
self._invalidate()
return canv
# Else, we have a slight mess to deal with...
self._shift_view_to_cursor = not not focus # force bool
text, attr = self.get_text()
text = text[:len(self.caption)]+self.get_masked_text()
trans = self.get_line_translation( maxcol, (text,attr) )
canv = urwid.canvas.apply_text_layout(text, attr, trans, maxcol)
if focus:
canv = urwid.CompositeCanvas(canv)
canv.cursor = self.get_cursor_coords((maxcol,))
return canv
# Tabbed interface, mostly for use in the Preferences Dialog
class TabColumns(urwid.WidgetWrap):
"""
@@ -146,6 +202,9 @@ class ComboBoxException(Exception):
# A "combo box" of SelTexts
# I based this off of the code found here:
# http://excess.org/urwid/browser/contrib/trunk/rbreu_menus.py
# This is a hack. It isn't without quirks, but it more or less works.
# We need to wait for changes in urwid's Canvas controls before we can actually
# make a real ComboBox.
class ComboBox(urwid.WidgetWrap):
"""A ComboBox of text objects"""
class ComboSpace(urwid.WidgetWrap):
@@ -202,7 +261,7 @@ class ComboBox(urwid.WidgetWrap):
#def get_size(self):
def __init__(self,label='',list=[],attr=('body','focus'),use_enter=True,show_first=0):
def __init__(self,label='',list=[],attrs=('body','editnfc'),focus_attr='focus',use_enter=True,show_first=0):
"""
label : bit of text that preceeds the combobox. If it is "", then
ignore it
@@ -214,13 +273,14 @@ class ComboBox(urwid.WidgetWrap):
"""
self.label = urwid.Text(label)
self.attr = attr
self.attrs = attrs
self.focus_attr = focus_attr
self.list = list
str,trash = self.label.get_text()
self.overlay = None
self.cbox = urwid.AttrWrap(SelText(' vvv'),attr[0],attr[1])
#w,sensitive=True,attrs=('editbx','editnfc'),focus_attr='editfc')
self.cbox = DynWrap(SelText(' vvv'),attrs=attrs,focus_attr=focus_attr)
# Unicode will kill me sooner or later. ^_^
if label != '':
w = urwid.Columns([('fixed',len(str),self.label),self.cbox],dividechars=1)
@@ -242,8 +302,7 @@ class ComboBox(urwid.WidgetWrap):
def build_combobox(self,body,ui,row):
str,trash = self.label.get_text()
self.cbox = urwid.AttrWrap(SelText([self.list[self.show_first]+' vvv']),
self.attr[0],self.attr[1])
self.cbox = DynWrap(SelText([self.list[self.show_first]+' vvv']),attrs=self.attrs,focus_attr=self.focus_attr)
if str != '':
w = urwid.Columns([('fixed',len(str),self.label),self.cbox],dividechars=1)
self.overlay = self.ComboSpace(self.list,body,ui,self.show_first,
@@ -273,13 +332,17 @@ class ComboBox(urwid.WidgetWrap):
# Most obvious thing ever. :-)
def selectable(self):
return True
return self.cbox.selectable()
# Return the index of the selected element
def get_selected(self):
wid,pos = self.overlay._listbox.get_focus()
return (wid,pos)
def get_sensitive(self):
return self.cbox.get_sensitive()
def set_sensitive(self,state):
self.cbox.set_sensitive(state)
# Almost completely ripped from rbreu_filechooser.py:
# http://excess.org/urwid/browser/contrib/trunk/rbreu_menus.py

View File

@@ -1,4 +1,8 @@
#!/usr/bin/env python
"""
netentry_curses -- everyone's favorite networks settings dialogs... in text
form!
"""
# Copyright (C) 2009 Andrew Psaltis
@@ -18,14 +22,49 @@
# MA 02110-1301, USA.
import urwid
from curses_misc import Dialog,DynWrap
from curses_misc import Dialog,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 = Dialog(message,[OK],('body','body','focus'),40,6)
keys = True
dim = ui.get_cols_rows()
while True:
if keys:
ui.draw_screen(dim, about.render(dim, True))
keys = ui.get_input()
if "window resize" in keys:
dim = ui.get_cols_rows()
if "esc" in keys:
return False
for k in keys:
dialog.keypress(dim, k)
if dialog.b_pressed == 'OK':
return False
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 NetEntries some of the same fields.
# This will be used to produce the individual network settings
class NetEntryBase(urwid.WidgetWrap):
def __init__(self,dbus):
def __init__(self):
static_ip_t = language['use_static_ip']
ip_t = ('editcp',language['ip']+': ')
netmask_t = ('editcp',language['netmask']+':')
@@ -49,12 +88,12 @@ class NetEntryBase(urwid.WidgetWrap):
self.gateway_edit=DynWrap(urwid.Edit(gateway_t),False)
self.use_static_dns_cb = urwid.CheckBox(use_static_dns_t,
self.static_dns_cb = urwid.CheckBox(use_static_dns_t,
on_state_change=self.dns_toggle)
self.use_global_dns_cb = DynWrap(urwid.CheckBox(use_global_dns_t,
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.use_static_dns_cb,
self.use_global_dns_cb])
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)
@@ -63,39 +102,73 @@ class NetEntryBase(urwid.WidgetWrap):
_blank = urwid.Text('')
self._listbox = urwid.ListBox([self.static_ip_cb,
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.__super.__init__(self._listbox)
self._frame = urwid.Frame(self._listbox)
self.__super.__init__(self._frame)
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.use_static_dns_cb:
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.use_global_dns_cb.set_state(False,do_callback=False)
self.use_global_dns_cb.set_sensitive(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.use_global_dns_cb.get_w():
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)
# We need a network ID for this, and I am not sure how to get it yet.
# TODO: Implement this
#def load_settings(self):
# Code totally yanked from netentry.py
def save_settings(self):
""" Save settings common to wired and wireless settings dialogs. """
if self.chkbox_static_ip.get_active():
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.chkbox_static_dns.get_active() and \
not self.chkbox_global_dns.get_active():
self.set_net_prop('use_static_dns', True)
self.set_net_prop('use_global_dns', False)
self.set_net_prop('dns_domain', noneToString(self.txt_domain.get_text()))
self.set_net_prop("search_domain", noneToString(self.txt_search_dom.get_text()))
self.set_net_prop("dns1", noneToString(self.dns_1.get_text()))
self.set_net_prop("dns2", noneToString(self.dns_2.get_text()))
self.set_net_prop("dns3", noneToString(self.dns_3.get_text()))
elif self.chkbox_static_dns.get_active() and \
self.chkbox_global_dns.get_active():
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()
@@ -122,3 +195,101 @@ class NetEntryBase(urwid.WidgetWrap):
# return False
#if self.OK_PRESSED or 'meta enter' in keys:
# return True
########################################
class WirelessNetEntry(NetEntryBase):
def __init__(self,networkID):
NetEntryBase.__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()
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.encrypt_types = misc.LoadEncryptionMethods()
self.set_values()
def encryption_toggle(self,chkbox,new_state,user_data=None):
self.encryption_combo.set_sensitive(new_state)
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')))
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.combo_encryption.set_active(activeID)
#if activeID != -1:
# self.chkbox_encryption.set_active(True)
# self.combo_encryption.set_sensitive(True)
# self.vbox_encrypt_info.set_sensitive(True)
#else:
# self.combo_encryption.set_active(0)
#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))
def run(self,ui,dim,display):
width,height = ui.get_cols_rows()
list = []
for x, enc_type in enumerate(self.encrypt_types):
list.append(enc_type[0])
self.encryption_combo.set_list(list)
overlay = urwid.Overlay(self, display, ('fixed left', 0),width
, ('fixed top',1), height-3)
self.encryption_combo.build_combobox(overlay,ui,14)
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

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env python
# Copyright (C) 2008-9 Andrew Psaltis
# 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

View File

@@ -1,13 +1,13 @@
#!/usr/bin/env python
""" wicd-curses -- a (curses-based) console interface to wicd
""" wicd-curses. (curses/urwid-based) console interface to wicd
Provides the a console UI for wicd, so that people with broken X servers can
at least get a network connection. Or those who don't like using X. :-)
at least get a network connection. Or those who don't like using X. ;-)
"""
# Copyright (C) 2008-9 Andrew Psaltis
# 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
@@ -55,10 +55,10 @@ from time import sleep
# Curses UIs for other stuff
from curses_misc import SelText,ComboBox,Dialog
from prefs_curses import PrefsDialog
from netentry_curses import NetEntryBase
import netentry_curses
from netentry_curses import WirelessNetEntry
language = misc.get_language_list_gui()
# Whew. Now on to more interesting stuff:
########################################
##### SUPPORT CLASSES
@@ -582,8 +582,17 @@ class appGUI():
self.frame.keypress( self.size, k )
if "C" in keys:
self.netentry = NetEntryBase(dbusmanager.get_dbus_ifaces())
self.netentry.run(ui,self.size,self.frame)
focus = self.thePile.get_focus()
if focus == self.wiredCB:
pass
#self.connect("wired",0)
else:
# wless list only other option
wid,pos = self.thePile.get_focus().get_focus()
WirelessNetEntry(pos).run(ui,self.size,self.frame)
#self.connect("wireless",pos)
#self.netentry = NetEntryBase(dbusmanager.get_dbus_ifaces())
#self.netentry.run(ui,self.size,self.frame)
if " " in keys:
focus = self.thePile.get_focus()
@@ -678,7 +687,7 @@ def setup_dbus(force=True):
dbusmanager.connect_to_dbus()
except DBusException:
# I may need to be a little more verbose here.
# Suggestions as to what should go here
# Suggestions as to what should go here, please?
print "Can't connect to the daemon. Are you sure it is running?"
print "Please check the wicd log for error messages."
#raise
@@ -690,6 +699,8 @@ def setup_dbus(force=True):
wired = dbus_ifaces['wired']
DBUS_AVAIL = True
netentry_curses.dbus_init(dbus_ifaces)
return True
setup_dbus()