From d1846cb6279835c1281ca706d0b127cbd76b7184 Mon Sep 17 00:00:00 2001 From: Andrew Psaltis Date: Fri, 9 Jan 2009 20:42:12 -0500 Subject: [PATCH 1/3] curses/curses_misc.py: Refactored some ComboBox internals Renamed show_first to focus in ComboBox Added callback support curses/netentry_curses.py: Renamed NetEntryBase to AdvancedSettingsDialog, and WirelessNetEntry to WirelessSettingsDialog The "WirelessSettingsDialog" is complete. :-) Raise it by pressing "C" on a wireless network. Much of the code was taken from netentry.py. The buttons aren't pretty like they are in the Preferences Dialog, but they are fully functional. curses/prefs_curses.py: Refactored to accommodate the ComboBox changes Added a warning about changing backends curses/wicd-curses.py: Refactored to accommodate changes to the rest of the program Added a constantly displayed message saying how to exit the program, other than ctrl+c curses/TODO: Removed a bunch of stuff that is already implemented, added some stuff that needs to be implemented curses/README: Added/clearified some things --- curses/README | 25 ++--- curses/TODO | 17 +--- curses/curses_misc.py | 38 ++++---- curses/netentry_curses.py | 188 +++++++++++++++++++++++++++++--------- curses/prefs_curses.py | 10 +- curses/wicd-curses.py | 15 ++- in/man=wicd-curses.8.in | 12 ++- 7 files changed, 210 insertions(+), 95 deletions(-) diff --git a/curses/README b/curses/README index d443845..bf4aebd 100644 --- a/curses/README +++ b/curses/README @@ -2,30 +2,33 @@ This is a curses-based client for wicd. It is designed to imitate wicd-client as much as can be done with a console-based interface. It is written using the Urwid (http://excess.org/urwid) toolkit, and thus requires it. -That's all there is to it, really. It installs unless you disable when you -call setup.py +That's all there is to it, really. It installs unless you disable it when you +call setup.py. Right now, it lists current available networks, and whether you are connected -to anything or not, all of which is updated in real time. It will actually -connect you to networks now. Global preferences are now configurable from the -console. Per-network settings is a work in progress. +to anything or not, all of which is updated in real time. Other features +include the ability to connect to networks, global preferences controls, and +per-network settings for wireless networks. + +All features that I plan on implementing (that are not mentioned above) are +listed the TODO file in this same directory. If you want any other features, +ask me. I try to be on the #wicd Freenode IRC channel most of the time. Controls: F5 : refresh wireless networks F8 or Q: quit -D : disconnect from active network +D : disconnect from all active networks ESC : if connecting to a network, stop doing so ENTER : Attempt connection to selected network P : Display preferences dialog -C : Display network configuration for selected network +C : Display network configuration for selected network (only works for + wireless at the moment) A : Display "About" dialog -IN DIALOGS: +IN DIALOGS (Meta usually is "Alt"): ESC or Q: Quit dialog without saving information (if present) -Meta+Left/Right: Change tabs Left/Right +Meta+Left/Right: Change tabs Left/Right (if tabs present) Meta+Enter : Quit dialog and save information - - ~NaCl diff --git a/curses/TODO b/curses/TODO index 1c80fde..56eb346 100644 --- a/curses/TODO +++ b/curses/TODO @@ -1,17 +1,10 @@ Things to do (in no particular order): -* Make a network config dialog for both wireless and wired interfaces -* Make an about dialog +* Make a network config dialog for wired interfaces * Implement a keyhandler function for the overall frame * Make keystrokes customizable * Make color schemes customizable -* Integrate this with the my local copy of the experimental branch -* Give some indication of activity during the connection process -* Make a man page for the UI. - -Oh, and most importantly: - -* Tell people how they can quit the app in the app (F8 or Q, until I do all of - that stuff) :-) - -Anything else? That's all I can think of now. +* Implement a "scan for hidden networks" dialog +* Implement a "make an ad-hoc network" dialog +* Implement a "help" dialog +* Perform a mass code cleanup diff --git a/curses/curses_misc.py b/curses/curses_misc.py index 06bfb77..dfbfd84 100644 --- a/curses/curses_misc.py +++ b/curses/curses_misc.py @@ -261,7 +261,7 @@ class ComboBox(urwid.WidgetWrap): #def get_size(self): - def __init__(self,label='',list=[],attrs=('body','editnfc'),focus_attr='focus',use_enter=True,show_first=0): + def __init__(self,label='',list=[],attrs=('body','editnfc'),focus_attr='focus',use_enter=True,focus=0,callback=None,user_args=None): """ label : bit of text that preceeds the combobox. If it is "", then ignore it @@ -269,13 +269,16 @@ class ComboBox(urwid.WidgetWrap): body : parent widget ui : the screen row : where this object is to be found onscreen - show_first: index of the element in the list to pick first + focus : index of the element in the list to pick first + callback : function that takes (combobox,sel_index,user_args=None) + user_args : user_args in the callback """ self.label = urwid.Text(label) self.attrs = attrs self.focus_attr = focus_attr self.list = list + str,trash = self.label.get_text() self.overlay = None @@ -290,26 +293,27 @@ class ComboBox(urwid.WidgetWrap): # We need this to pick our keypresses self.use_enter = use_enter - - # Set the focus at the beginning to 0 - self.show_first = show_first - + # The Focus + self.focus = focus + # The callback and friends + self.callback = callback + self.user_args = user_args def set_list(self,list): self.list = list - def set_show_first(self,show_first): - self.show_first = show_first + def set_focus(self,index): + self.focus = index def build_combobox(self,body,ui,row): str,trash = self.label.get_text() - self.cbox = DynWrap(SelText([self.list[self.show_first]+' vvv']),attrs=self.attrs,focus_attr=self.focus_attr) + self.cbox = DynWrap(SelText([self.list[self.focus]+' 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, + self.overlay = self.ComboSpace(self.list,body,ui,self.focus, pos=(len(str)+1,row)) else: w = urwid.Columns([self.cbox]) - self.overlay = self.ComboSpace(self.list,body,ui,self.show_first, + self.overlay = self.ComboSpace(self.list,body,ui,self.focus, pos=(0,row)) self.set_w(w) @@ -328,16 +332,18 @@ class ComboBox(urwid.WidgetWrap): retval = self.overlay.show(self.ui,self.body) if retval != None: self.cbox.set_w(SelText(retval+' vvv')) + if self.callback != None: + self.callback(self,self.overlay._listbox.get_focus()[1],self.user_args) return self._w.keypress(size,key) - # Most obvious thing ever. :-) def selectable(self): 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_focus(self): + if self.overlay: + return self.overlay._listbox.get_focus() + else: + return None,self.focus def get_sensitive(self): return self.cbox.get_sensitive() diff --git a/curses/netentry_curses.py b/curses/netentry_curses.py index 71f0d18..79f3703 100644 --- a/curses/netentry_curses.py +++ b/curses/netentry_curses.py @@ -31,13 +31,13 @@ def error(ui,parent,message): # /\ # /!!\ # /____\ - dialog = Dialog(message,[OK],('body','body','focus'),40,6) + dialog = Dialog([('important','ERROR: '),message],['OK'],('body','body','focus'),40,6,parent) keys = True dim = ui.get_cols_rows() while True: if keys: - ui.draw_screen(dim, about.render(dim, True)) + ui.draw_screen(dim, dialog.render(dim, True)) keys = ui.get_input() if "window resize" in keys: @@ -61,10 +61,13 @@ def dbus_init(dbus_ifaces): 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): +# 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']+':') @@ -78,7 +81,7 @@ class NetEntryBase(urwid.WidgetWrap): dns2_t = ('editcp',language['dns']+ ' ' + language['2']+':'+' '*8) dns3_t = ('editcp',language['dns']+ ' ' + language['3']+':'+' '*8) - cancel_t = 'cancel' + cancel_t = 'Cancel' ok_t = 'OK' self.static_ip_cb = urwid.CheckBox(static_ip_t, @@ -102,6 +105,12 @@ class NetEntryBase(urwid.WidgetWrap): _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, @@ -113,11 +122,20 @@ class NetEntryBase(urwid.WidgetWrap): 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) @@ -139,7 +157,7 @@ class NetEntryBase(urwid.WidgetWrap): # 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(): + 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())) @@ -148,17 +166,17 @@ class NetEntryBase(urwid.WidgetWrap): 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(): + 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.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('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: @@ -198,24 +216,35 @@ class NetEntryBase(urwid.WidgetWrap): ######################################## -class WirelessNetEntry(NetEntryBase): +class WirelessSettingsDialog(AdvancedSettingsDialog): def __init__(self,networkID): - NetEntryBase.__init__(self) + 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() + 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. """ @@ -238,9 +267,9 @@ class WirelessNetEntry(NetEntryBase): #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'))) + '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") @@ -248,14 +277,19 @@ class WirelessNetEntry(NetEntryBase): 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() + 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. """ @@ -265,15 +299,85 @@ class WirelessNetEntry(NetEntryBase): """ 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, 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, 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 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) + #self.change_encrypt_method() + #self._w.body.body.append(self.pile_encrypt) keys = True while True: @@ -281,15 +385,15 @@ class WirelessNetEntry(NetEntryBase): ui.draw_screen(dim, overlay.render(dim, True)) keys = ui.get_input() + for k in keys: + #Send key to underlying widget: + overlay.keypress(dim, k) 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 + if "meta enter" in keys or self.OK_PRESSED: + if self.save_settings(self.networkID): + return True + if self.CANCEL_PRESSED: + return False diff --git a/curses/prefs_curses.py b/curses/prefs_curses.py index 4f19361..c771798 100755 --- a/curses/prefs_curses.py +++ b/curses/prefs_curses.py @@ -109,6 +109,7 @@ class PrefsDialog(urwid.WidgetWrap): 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'] @@ -207,6 +208,7 @@ class PrefsDialog(urwid.WidgetWrap): 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) @@ -218,7 +220,7 @@ class PrefsDialog(urwid.WidgetWrap): advancedLB = urwid.ListBox([self.wpa_cat, self.wpa_cbox,self.wpa_warn,_blank, self.backend_cat, - self.backend_cbox,_blank, + self.backend_cbox,self.backend_warn,_blank, self.debug_cat, self.debug_mode_checkb, _blank, self.wless_cat, @@ -315,7 +317,7 @@ class PrefsDialog(urwid.WidgetWrap): # Pick where to begin first: def_driver = daemon.GetWPADriver() try: - self.wpa_cbox.set_show_first(self.wpadrivers.index(def_driver)) + self.wpa_cbox.set_focus(self.wpadrivers.index(def_driver)) except ValueError: pass # It defaults to 0 anyway @@ -326,9 +328,9 @@ class PrefsDialog(urwid.WidgetWrap): self.backend_cbox.set_list(self.thebackends) cur_backend = daemon.GetSavedBackend() try: - self.backend_cbox.set_show_first(self.thebackends.index(cur_backend)) + self.backend_cbox.set_focus(self.thebackends.index(cur_backend)) except ValueError: - self.backend_cbox.set_show_first(0) + self.backend_cbox.set_focus(0) # Two last checkboxes self.debug_mode_checkb.set_state(daemon.GetDebugMode()) diff --git a/curses/wicd-curses.py b/curses/wicd-curses.py index fc483aa..cedecc2 100644 --- a/curses/wicd-curses.py +++ b/curses/wicd-curses.py @@ -56,7 +56,7 @@ from time import sleep from curses_misc import SelText,ComboBox,Dialog from prefs_curses import PrefsDialog import netentry_curses -from netentry_curses import WirelessNetEntry +from netentry_curses import WirelessSettingsDialog language = misc.get_language_list_gui() @@ -303,7 +303,7 @@ class WiredComboBox(ComboBox): wiredL.append(theString) id+=1 self.__super.__init__(list=wiredL,use_enter=False) - self.set_show_first(theList.index(wired.GetDefaultWiredProfile())) + self.set_focus(theList.index(wired.GetDefaultWiredProfile())) def keypress(self,size,key): self.__super.keypress(size,key) @@ -503,8 +503,9 @@ class appGUI(): def idle_incr(self): theText = "" if self.connecting: - theText = "-- Connecting -- Press ESC to cancel" - self.footer1 = urwid.Text(str(self.incr) + ' '+theText) + theText = "-- Connecting -- Press ESC to cancel " + quit_note = "-- Press F8 or Q to quit." + self.footer1 = urwid.Text(str(self.incr) + ' '+theText+quit_note) self.incr+=1 return True @@ -585,12 +586,10 @@ class appGUI(): focus = self.thePile.get_focus() if focus == self.wiredCB: pass - #self.connect("wired",0) else: - # wless list only other option + # wireless list only other option wid,pos = self.thePile.get_focus().get_focus() - WirelessNetEntry(pos).run(ui,self.size,self.frame) - #self.connect("wireless",pos) + WirelessSettingsDialog(pos).run(ui,self.size,self.frame) #self.netentry = NetEntryBase(dbusmanager.get_dbus_ifaces()) #self.netentry.run(ui,self.size,self.frame) diff --git a/in/man=wicd-curses.8.in b/in/man=wicd-curses.8.in index 670b37d..5913828 100644 --- a/in/man=wicd-curses.8.in +++ b/in/man=wicd-curses.8.in @@ -39,11 +39,19 @@ The following is a work in progress and might not be fully functional as of yet. .BR C Bring up network configuration controller for the selected network .PP -The following is not implemented yet: +The following are not implemented yet: .TP .BR S Bring up the script selector for the selected network (requires superuser privileges) - +.TP +.BR I +Bring up hidden network scanning dialog +.TP +.BR R +Bring up script selector "dialog." +.TP +.BR H +Bring up a rather simplistic help dialog. Of course, it mentions this man page first. :-) .SH "FILES" These are not used yet. .TP From 84cb49a6fc9ca5aac15c8539d88421c7b156b382 Mon Sep 17 00:00:00 2001 From: Andrew Psaltis Date: Sun, 11 Jan 2009 13:05:01 -0500 Subject: [PATCH 2/3] curses/prefs_curses.py: Finished refactoring to accommodate the ComboBox changes curses/wicd-curses.py: Moved some of the keybinding code around in/other=WHEREAREMYFILES.in: ADDED. File telling the user where the wicd config files are. Usually symlinked to ~/.wicd/WHEREAREMYFILES and installed to the documentation directory in/scripts=wicd-client.in: Make ~/.wicd and link WHEREAREMYFILES if it has not been done so already. Start wicd-curses if there is no X server on this console (determined by the presence of $DISPLAY), and add a file detailing this man/wicd-client.1: Added note about wicd-client starting wicd-curses setup.py: Install WHEREAREMYFILES along with the rest of the documentation --- curses/prefs_curses.py | 4 ++-- curses/wicd-curses.py | 12 +++++----- in/other=WHEREAREMYFILES.in | 14 ++++++++++++ in/scripts=wicd-client.in | 45 +++++++++++++++++++++++++++++++++++++ man/wicd-client.1 | 2 ++ setup.py | 5 +++-- 6 files changed, 72 insertions(+), 10 deletions(-) create mode 100644 in/other=WHEREAREMYFILES.in diff --git a/curses/prefs_curses.py b/curses/prefs_curses.py index c771798..49737e0 100755 --- a/curses/prefs_curses.py +++ b/curses/prefs_curses.py @@ -345,7 +345,7 @@ class PrefsDialog(urwid.WidgetWrap): 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_selected()[1]]) + 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()) @@ -357,7 +357,7 @@ class PrefsDialog(urwid.WidgetWrap): else: daemon.SetWiredAutoConnectMethod(1) - daemon.SetBackend(self.backends[self.backend_cbox.get_selected()[1]]) + daemon.SetBackend(self.backends[self.backend_cbox.get_focus()[1]]) # External Programs Tab if self.dhcp0.get_state(): diff --git a/curses/wicd-curses.py b/curses/wicd-curses.py index cedecc2..10eaecf 100644 --- a/curses/wicd-curses.py +++ b/curses/wicd-curses.py @@ -576,12 +576,6 @@ class appGUI(): self.update_ui() if "A" in keys: about_dialog(self.frame) - for k in keys: - if k == "window resize": - self.size = ui.get_cols_rows() - continue - self.frame.keypress( self.size, k ) - if "C" in keys: focus = self.thePile.get_focus() if focus == self.wiredCB: @@ -593,6 +587,12 @@ class appGUI(): #self.netentry = NetEntryBase(dbusmanager.get_dbus_ifaces()) #self.netentry.run(ui,self.size,self.frame) + for k in keys: + if k == "window resize": + self.size = ui.get_cols_rows() + continue + self.frame.keypress( self.size, k ) + if " " in keys: focus = self.thePile.get_focus() if focus == self.wiredCB: diff --git a/in/other=WHEREAREMYFILES.in b/in/other=WHEREAREMYFILES.in new file mode 100644 index 0000000..61363e9 --- /dev/null +++ b/in/other=WHEREAREMYFILES.in @@ -0,0 +1,14 @@ +If you are reading this, you are probably wondering why your Wicd configuration +files are not here. What follows is a summary of the folders that wicd uses. + +For a more detailed (and complete) description what is in each directory, consult the +man pages for wicd(8) and wicd-curses(8). + +~/.wicd + User-dependent configuration files, only used by wicd-curses + +%ETC% + Global configuration files + +%NETWORKS% + Individual network configurations diff --git a/in/scripts=wicd-client.in b/in/scripts=wicd-client.in index d79a061..f535254 100755 --- a/in/scripts=wicd-client.in +++ b/in/scripts=wicd-client.in @@ -1,2 +1,47 @@ #!/bin/bash +BOLD=`tput bold` +BLUE=`tput setaf 4` +NC=`tput sgr0` +# check_firstrun() +if [ ! -d ~/.wicd ]; then + mkdir ~/.wicd +fi +# Make sure the user knows WHEREAREMYFILES ;-) +if [ -e %DOCDIR%WHEREAREMYFILES ] && [ ! -L ~/.wicd/WHEREAREMYFILES ]; then + ln -s %DOCDIR%WHEREAREMYFILES ~/.wicd/WHEREAREMYFILES +fi +if [ "$DISPLAY" = "" ] && [ -x "%BIN%wicd-curses" ]; then + if [ ! -f ~/.wicd/CLIENT_CURSES_WARNING ]; then + echo "NOTICE: We see that you don't have an X server active on this console." + echo "We will now be starting ${BOLD}${BLUE}wicd-curses${NC}. If you desire" + echo "more information about what is happening here, please read:" + echo + echo "man wicd-client" + echo "-or-" + echo "man wicd-curses" + echo + echo "We apologize for any inconvenience. This message will not be displayed again." + echo "Please press enter to continue..." + + read junk + cat >>~/.wicd/CLIENT_CURSES_WARNING< Date: Sun, 11 Jan 2009 19:40:29 -0500 Subject: [PATCH 3/3] Progress is being made, apparently 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 --- curses/README | 1 + curses/TODO | 1 - curses/curses_misc.py | 181 ++++++++++++++++++++++++-------------- curses/netentry_curses.py | 39 ++++---- curses/prefs_curses.py | 5 ++ curses/wicd-curses.py | 121 +++++++++++++++++-------- in/man=wicd-curses.8.in | 6 +- man/wicd-client.1 | 2 +- 8 files changed, 228 insertions(+), 128 deletions(-) diff --git a/curses/README b/curses/README index bf4aebd..3faa1c8 100644 --- a/curses/README +++ b/curses/README @@ -25,6 +25,7 @@ P : Display preferences dialog C : Display network configuration for selected network (only works for wireless at the moment) A : Display "About" dialog +I : Raise up the "Scan for hidden networks" dialog IN DIALOGS (Meta usually is "Alt"): ESC or Q: Quit dialog without saving information (if present) diff --git a/curses/TODO b/curses/TODO index 56eb346..6c81304 100644 --- a/curses/TODO +++ b/curses/TODO @@ -4,7 +4,6 @@ Things to do (in no particular order): * Implement a keyhandler function for the overall frame * Make keystrokes customizable * Make color schemes customizable -* Implement a "scan for hidden networks" dialog * Implement a "make an ad-hoc network" dialog * Implement a "help" dialog * Perform a mass code cleanup diff --git a/curses/curses_misc.py b/curses/curses_misc.py index dfbfd84..f26d4c6 100644 --- a/curses/curses_misc.py +++ b/curses/curses_misc.py @@ -350,73 +350,124 @@ class ComboBox(urwid.WidgetWrap): 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 -class Dialog(urwid.WidgetWrap): - """ - Creates a BoxWidget that displays a message +# This is a h4x3d copy of some of the code in Ian Ward's dialog.py example. +class DialogExit(Exception): + pass - Attributes: - - b_pressed -- Contains the label of the last button pressed or None if no - button has been pressed. - edit_text -- After a button is pressed, this contains the text the user - has entered in the edit field - """ +class Dialog2(urwid.WidgetWrap): + def __init__(self, text, height,width, body=None ): + self.width = int(width) + if width <= 0: + self.width = ('relative', 80) + self.height = int(height) + if height <= 0: + self.height = ('relative', 80) + + self.body = body + if body is None: + # fill space with nothing + body = urwid.Filler(urwid.Divider(),'top') - b_pressed = None - edit_text = None - - _blank = urwid.Text("") - _edit_widget = None - _mode = None - - def __init__(self, msg, buttons, attr, width, height, body, ): - """ - msg -- content of the message widget, one of: - plain string -- string is displayed - (attr, markup2) -- markup2 is given attribute attr - [markupA, markupB, ... ] -- list items joined together - buttons -- a list of strings with the button labels - attr -- a tuple (background, button, active_button) of attributes - width -- width of the message widget - height -- height of the message widget - body -- widget displayed beneath the message widget - """ - - # Text widget containing the message: - msg_widget = urwid.Padding(urwid.Text(msg), 'center', width - 4) - - # GridFlow widget containing all the buttons: - button_widgets = [] - - for button in buttons: - button_widgets.append(urwid.AttrWrap( - urwid.Button(button, self._action), attr[1], attr[2])) - - button_grid = urwid.GridFlow(button_widgets, 12, 2, 1, 'center') - - # Combine message widget and button widget: - widget_list = [msg_widget, self._blank, button_grid] - self._combined = urwid.AttrWrap(urwid.Filler( - urwid.Pile(widget_list, 2)), attr[0]) - - # This was the real thing I added to this class - self._linebox = urwid.LineBox(self._combined) - # Place the dialog widget on top of body: - # Width and height are increased to accomidate the linebox - overlay = urwid.Overlay(self._linebox, body, 'center', width+2, - 'middle', height+2) + self.frame = urwid.Frame( body, focus_part='footer') + if text is not None: + self.frame.header = urwid.Pile( [urwid.Text(text), + urwid.Divider()] ) + w = self.frame + self.view = w - urwid.WidgetWrap.__init__(self, overlay) + # pad area around listbox + #w = urwid.Padding(w, ('fixed left',2), ('fixed right',2)) + #w = urwid.Filler(w, ('fixed top',1), ('fixed bottom',1)) + #w = urwid.AttrWrap(w, 'body') + # buttons: tuple of name,exitcode + def add_buttons(self, buttons): + l = [] + for name, exitcode in buttons: + b = urwid.Button( name, self.button_press ) + b.exitcode = exitcode + b = urwid.AttrWrap( b, 'body','focus' ) + l.append( b ) + self.buttons = urwid.GridFlow(l, 10, 3, 1, 'center') + self.frame.footer = urwid.Pile( [ urwid.Divider(), + self.buttons ], focus_item = 1) + + def button_press(self, button): + raise DialogExit(button.exitcode) + + def run(self,ui,parent): + ui.set_mouse_tracking() + size = ui.get_cols_rows() + overlay = urwid.Overlay(urwid.LineBox(self.view), parent, 'center', self.width, + 'middle', self.height) + try: + while True: + canvas = overlay.render( size, focus=True ) + ui.draw_screen( size, canvas ) + keys = None + while not keys: + keys = ui.get_input() + for k in keys: + if urwid.is_mouse_event(k): + event, button, col, row = k + overlay.mouse_event( size, + event, button, col, row, + focus=True) + if k == 'window resize': + size = ui.get_cols_rows() + k = self.view.keypress( size, k ) + if k == 'esc': + raise DialogExit(-1) + if k: + self.unhandled_key( size, k) + except DialogExit, e: + return self.on_exit( e.args[0] ) + + def on_exit(self, exitcode): + return exitcode, "" + + def unhandled_key(self, size, key): + pass + +class TextDialog(Dialog2): + def __init__(self, text, height, width, header=None): + l = [] + # read the whole file (being slow, not lazy this time) + #for line in open(file).readlines(): + # l.append( urwid.Text( line.rstrip() )) + l = [urwid.Text(text)] + body = urwid.ListBox(l) + body = urwid.AttrWrap(body, 'body') + + Dialog2.__init__(self, header, height+2, width+2, body) + self.add_buttons([('OK',1)]) - def _action(self, button): - """ - Function called when a button is pressed. - Should not be called manually. - """ - - self.b_pressed = button.get_label() - if self._edit_widget: - self.edit_text = self._edit_widget.get_edit_text() + def unhandled_key(self, size, k): + if k in ('up','page up','down','page down'): + self.frame.set_focus('body') + self.view.keypress( size, k ) + self.frame.set_focus('footer') + +class InputDialog(Dialog2): + def __init__(self, text, height, width,ok_name='OK'): + self.edit = urwid.Edit(wrap='clip') + body = urwid.ListBox([self.edit]) + body = urwid.AttrWrap(body, 'editbx','editfc') + + Dialog2.__init__(self, text, height, width, body) + + self.frame.set_focus('body') + self.add_buttons([(ok_name,0),('Cancel',-1)]) + + def unhandled_key(self, size, k): + if k in ('up','page up'): + self.frame.set_focus('body') + if k in ('down','page down'): + self.frame.set_focus('footer') + if k == 'enter': + # pass enter to the "ok" button + self.frame.set_focus('footer') + self.view.keypress( size, k ) + + def on_exit(self, exitcode): + return exitcode, self.edit.get_edit_text() diff --git a/curses/netentry_curses.py b/curses/netentry_curses.py index 79f3703..09fa7f8 100644 --- a/curses/netentry_curses.py +++ b/curses/netentry_curses.py @@ -22,7 +22,7 @@ # MA 02110-1301, USA. import urwid -from curses_misc import Dialog,DynWrap,MaskingEdit,ComboBox +from curses_misc import TextDialog,DynWrap,MaskingEdit,ComboBox import wicd.misc as misc from wicd.misc import noneToString, stringToNone, noneToBlankString, to_bool @@ -31,23 +31,9 @@ def error(ui,parent,message): # /\ # /!!\ # /____\ - dialog = Dialog([('important','ERROR: '),message],['OK'],('body','body','focus'),40,6,parent) + dialog = TextDialog(message,40,6,('important',"ERROR")) + return dialog.run(ui,parent) - keys = True - dim = ui.get_cols_rows() - 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: - return False - for k in keys: - dialog.keypress(dim, k) - if dialog.b_pressed == 'OK': - return False language = misc.get_language_list_gui() @@ -310,13 +296,13 @@ class WirelessSettingsDialog(AdvancedSettingsDialog): 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, language['encrypt_info_missing']) + 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, language['enable_encryption']) + error(self.ui, self.overlay, language['enable_encryption']) return False else: #print 'encryption is ' + str(wireless.GetWirelessProperty(networkid, @@ -372,27 +358,34 @@ class WirelessSettingsDialog(AdvancedSettingsDialog): def run(self,ui,dim,display): self.ui = ui + self.parent = display width,height = ui.get_cols_rows() - overlay = urwid.Overlay(self, display, ('fixed left', 0),width + self.overlay = urwid.Overlay(self, display, ('fixed left', 0),width , ('fixed top',1), height-3) - self.encryption_combo.build_combobox(overlay,ui,14) + 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, overlay.render(dim, True)) + ui.draw_screen(dim, self.overlay.render(dim, True)) keys = ui.get_input() for k in keys: #Send key to underlying widget: - overlay.keypress(dim, k) + 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: diff --git a/curses/prefs_curses.py b/curses/prefs_curses.py index 49737e0..b5d1ef9 100755 --- a/curses/prefs_curses.py +++ b/curses/prefs_curses.py @@ -425,6 +425,11 @@ class PrefsDialog(urwid.WidgetWrap): 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: diff --git a/curses/wicd-curses.py b/curses/wicd-curses.py index 10eaecf..637b34b 100644 --- a/curses/wicd-curses.py +++ b/curses/wicd-curses.py @@ -53,10 +53,10 @@ import sys from time import sleep # Curses UIs for other stuff -from curses_misc import SelText,ComboBox,Dialog +from curses_misc import SelText,ComboBox,TextDialog,InputDialog from prefs_curses import PrefsDialog import netentry_curses -from netentry_curses import WirelessSettingsDialog +from netentry_curses import WirelessSettingsDialog, error language = misc.get_language_list_gui() @@ -80,6 +80,19 @@ class wrap_exceptions: ui.stop() print "\nTerminated by user." raise + except DBusException: + gobject.source_remove(redraw_tag) + # Quit the loop + loop.quit() + # Zap the screen + ui.stop() + print "" + print "DBus failiure!" + print "This is most likely caused by the wicd daemon stopping" + print "while wicd-curses is running." + print "" + print "Please restart the daemon, and restart wicd-curses." + raise except : # If the UI isn't inactive (redraw_tag wouldn't normally be # set), then don't try to stop it, just gracefully die. @@ -212,23 +225,8 @@ def about_dialog(body): " ___|+|___ Dan O'Reilly (wicd)\n", " |---------| Andrew Psaltis (this ui)\n", "---------------------------------------------------"] - about = Dialog(theText,['OK'],('body','body','focus'),55,14,body) - - 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: - about.keypress(dim, k) - if about.b_pressed == 'OK': - return False + about = TextDialog(theText,55,14) + about.run(ui,body) ######################################## ##### URWID SUPPORT CLASSES @@ -335,6 +333,7 @@ class appGUI(): # for networks. :-) # Will need a translation sooner or later self.screen_locker = urwid.Filler(urwid.Text(('important',"Scanning networks... stand by..."), align='center')) + self.no_wlan = urwid.Filler(urwid.Text(('important',"No wireless networks found."), align='center')) self.TITLE = 'Wicd Curses Interface' #wrap1 = urwid.AttrWrap(txt, 'black') @@ -344,8 +343,10 @@ class appGUI(): self.wiredH=urwid.Filler(urwid.Text("Wired Network(s)")) self.wlessH=urwid.Filler(urwid.Text("Wireless Network(s)")) + #if wireless.GetNumberOfNetworks() == 0: + # wireless.Scan() wiredL,wlessL = gen_network_list() - self.wiredCB = urwid.Filler(ComboBox(list=wiredL)) + self.wiredCB = urwid.Filler(ComboBox(list=wiredL,use_enter=False)) self.wlessLB = urwid.ListBox(wlessL) # Stuff I used to simulate large lists #spam = SelText('spam') @@ -383,6 +384,8 @@ class appGUI(): self.screen_locked = False #self.always_show_wired = daemon.GetAlwaysShowWiredInterface() + self.focusloc = (1,0) + self.pref = None self.update_status() @@ -395,18 +398,46 @@ class appGUI(): self.screen_locked = True def unlock_screen(self): - self.update_netlist(force_check=True) self.frame.set_body(self.thePile) self.screen_locked = False # I'm hoping that this will get rid of Adam's problem with the ListBox not # redisplaying itself immediately upon completion. + self.update_netlist(force_check=True) self.update_ui() + def raise_hidden_network_dialog(self): + dialog = InputDialog(('header','Select Hidden Network ESSID'),7,30,'Scan') + exitcode,hidden = dialog.run(ui,self.frame) + if exitcode != -1: + # That dialog will sit there for a while if I don't get rid of it + self.update_ui() + wireless.SetHiddenNetworkESSID(misc.noneToString(hidden)) + wireless.Scan() + wireless.SetHiddenNetworkESSID("") + + def update_focusloc(self): + # Location of last known focus is remapped to current location. + # This might need to be cleaned up later. + + if self.thePile.get_focus() is self.wiredCB: + wlessorwired = 1 + else : + wlessorwired = 3 + if self.thePile.get_focus() == self.no_wlan: + where = 0 + elif self.thePile.get_focus() == self.wiredCB: + where = self.thePile.get_focus().get_body().get_focus()[1] + else: + where = self.thePile.get_focus().get_focus()[1] + + self.focusloc = (wlessorwired,where) + # Be clunky until I get to a later stage of development. # Update the list of networks. Usually called by DBus. # TODO: Preserve current focus when updating the list. @wrap_exceptions() def update_netlist(self,state=None, x=None, force_check=False): + self.update_focusloc() """ Updates the overall network list.""" if not state: state, x = daemon.GetConnectionStatus() @@ -416,17 +447,28 @@ class appGUI(): # use_enter=False)) self.wiredCB.get_body().set_list(wiredL) self.wiredCB.get_body().build_combobox(self.frame,ui,3) - self.wlessLB.body = urwid.SimpleListWalker(wlessL) - + if len(wlessL) != 0: + self.wlessLB.body = urwid.SimpleListWalker(wlessL) + else: + self.wlessLB.body = urwid.SimpleListWalker([self.no_wlan]) if daemon.GetAlwaysShowWiredInterface() or wired.CheckPluggedIn(): #if daemon.GetAlwaysShowWiredInterface(): self.thePile = urwid.Pile([('fixed',1,self.wiredH), ('fixed',1,self.wiredCB), ('fixed',1,self.wlessH), self.wlessLB] ) + #self.focusloc = (self.thePile.get_focus(), + # self.thePile.get_focus().get_focus()[1]) + self.thePile.set_focus(self.focusloc[0]) + if self.focusloc[0] == 1: + self.thePile.get_focus().get_body().set_focus(self.focusloc[1]) + else: + self.thePile.get_focus().set_focus(self.focusloc[1]) else: self.thePile = urwid.Pile([('fixed',1,self.wlessH),self.wlessLB] ) self.frame.body = self.thePile + if self.focusloc[0] == self.wlessLB: + self.wlessLB.set_focus(self.focusloc[1]) #self.always_show_wired = not self.always_show_wired self.prev_state = state @@ -512,19 +554,20 @@ class appGUI(): # Yeah, I'm copying code. Anything wrong with that? #@wrap_exceptions() def dbus_scan_finished(self): - # I'm pretty sure that I'll need this later. - #if not self.connecting: - #self.refresh_networks(fresh=False) - self.unlock_screen() - # I'm hoping that this will resolve Adam's problem with the screen lock - # remaining onscreen until a key is pressed. It goes away perfectly well - # here. - self.update_ui() + # I'm pretty sure that I'll need this later. + #if not self.connecting: + # gobject.idle_add(self.refresh_networks, None, False, None) + self.unlock_screen() + # I'm hoping that this will resolve Adam's problem with the screen lock + # remaining onscreen until a key is pressed. It goes away perfectly well + # here. + self.update_ui() # Same, same, same, same, same, same #@wrap_exceptions() def dbus_scan_started(self): self.lock_screen() + self.update_ui() # Redraw the screen @wrap_exceptions() @@ -554,7 +597,7 @@ class appGUI(): # references to self.frame lying around. ^_^ if "enter" in keys: focus = self.thePile.get_focus() - if focus == self.wiredCB: + if focus is self.wiredCB: self.connect("wired",0) else: # wless list only other option @@ -586,8 +629,15 @@ class appGUI(): WirelessSettingsDialog(pos).run(ui,self.size,self.frame) #self.netentry = NetEntryBase(dbusmanager.get_dbus_ifaces()) #self.netentry.run(ui,self.size,self.frame) + if "I" in keys: + self.raise_hidden_network_dialog() for k in keys: + if urwid.is_mouse_event(k): + event, button, col, row = k + self.frame.mouse_event( self.size, + event, button, col, row, + focus=True) if k == "window resize": self.size = ui.get_cols_rows() continue @@ -597,7 +647,7 @@ class appGUI(): focus = self.thePile.get_focus() if focus == self.wiredCB: #self.set_status('space pressed on wiredCB!') - wid,pos = self.wiredCB.get_body().get_selected() + wid,pos = self.wiredCB.get_body().get_focus() text,attr = wid.get_text() wired.ReadWiredNetworkProfile(text) # Make sure our internal reference to the combobox matches the @@ -629,14 +679,14 @@ def main(): misc.RenameProcess('wicd-curses') ui = urwid.curses_display.Screen() - # Color scheme. + # Default Color scheme. # Other potential color schemes can be found at: # http://excess.org/urwid/wiki/RecommendedPalette # Note: the current palette below is optimized for the linux console. # For example, this looks particularly bad on a default-colored XTerm. # NB: To find current terminal background use variable COLORFGBG ui.register_palette([ - ('body','light gray','default'), + ('body','default','default'), ('focus','dark magenta','light gray'), ('header','light blue','default'), ('important','light red','default'), @@ -658,6 +708,7 @@ def main(): def run(): global loop,redraw_tag + ui.set_mouse_tracking() redraw_tag = -1 app = appGUI() diff --git a/in/man=wicd-curses.8.in b/in/man=wicd-curses.8.in index 5913828..7d81ba9 100644 --- a/in/man=wicd-curses.8.in +++ b/in/man=wicd-curses.8.in @@ -33,6 +33,9 @@ Refresh the network list .TP .BR P Bring up the preferences controller +.TP +.BR I +Bring up hidden network scanning dialog .PP The following is a work in progress and might not be fully functional as of yet. .TP @@ -44,9 +47,6 @@ The following are not implemented yet: .BR S Bring up the script selector for the selected network (requires superuser privileges) .TP -.BR I -Bring up hidden network scanning dialog -.TP .BR R Bring up script selector "dialog." .TP diff --git a/man/wicd-client.1 b/man/wicd-client.1 index 99d5a7c..115217c 100644 --- a/man/wicd-client.1 +++ b/man/wicd-client.1 @@ -4,7 +4,7 @@ wicd-client \- manual page for wicd-client .SH DESCRIPTION wireless (and wired) connection daemon front\-end. -If wicd-curses(8) is instaled, and you attempt to run wicd-client without an active X server on the current terminal, wicd-client will attempt to run wicd-curses(8). It will warn you the first time this happens. +If wicd-curses(8) is instaled, and you attempt to run wicd-client without an active X server on the current terminal, wicd-client will attempt to run wicd-curses(8) instead. It will warn you the first time this happens. .SS "Arguments:" .TP \fB\-n\fR \fB\-\-no\-tray\fR