From 11e8a966773b1cb8bedc56b41e273ac76700615b Mon Sep 17 00:00:00 2001 From: David Paleino Date: Sun, 6 May 2012 17:16:15 +0200 Subject: [PATCH] New feature: dialogs to "forget" saved networks --- curses/curses_misc.py | 9 ++++-- curses/wicd-curses.py | 62 ++++++++++++++++++++++++++++++++++++++++- data/wicd.ui | 14 ++++++++++ gtk/gui.py | 61 ++++++++++++++++++++++++++++++++++++++++ in/man=wicd-curses.8.in | 3 ++ po/wicd.pot | 22 ++++++++++++++- wicd/wicd-daemon.py | 22 +++++++++++++++ 7 files changed, 188 insertions(+), 5 deletions(-) diff --git a/curses/curses_misc.py b/curses/curses_misc.py index 9278b2b..6674545 100644 --- a/curses/curses_misc.py +++ b/curses/curses_misc.py @@ -511,14 +511,17 @@ class Dialog2(urwid.WidgetWrap): # Simple dialog with text in it and "OK" class TextDialog(Dialog2): - def __init__(self, text, height, width, header=None,align='left'): + def __init__(self, text, height, width, header=None, align='left', + buttons=(_('OK'), 1)): 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)]) - + if type(buttons) == list: + self.add_buttons(buttons) + else: + self.add_buttons([buttons]) def unhandled_key(self, size, k): if k in ('up','page up','down','page down'): diff --git a/curses/wicd-curses.py b/curses/wicd-curses.py index 641aa52..491f076 100755 --- a/curses/wicd-curses.py +++ b/curses/wicd-curses.py @@ -221,6 +221,7 @@ _('For more detailed help, consult the wicd-curses(8) man page.')+"\n", ('bold',' I'),": "+_('Scan for hidden networks')+"\n", ('bold',' S'),": "+_('Select scripts')+"\n", ('bold',' O'),": "+_('Set up Ad-hoc network')+"\n", +('bold',' X'),": "+_('Remove settings for saved networks')+"\n", ('bold',' ->'),": "+_('Configure selected network')+"\n", ('bold',' A'),": "+_("Display 'about' dialog")+"\n", ('bold',' F8 q Q'),": "+_('Quit wicd-curses')+"\n", @@ -511,6 +512,54 @@ class AdHocDialog(Dialog2): self.key_edit.get_edit_text()) return exitcode, data +# TODO +class ForgetDialog(Dialog2): + def __init__(self): + self.to_remove = dict(essid=[], bssid=[]) + + header = urwid.AttrWrap(urwid.Text(' %20s %20s' % ('ESSID', 'BSSID')), 'listbar') + title = urwid.Text(_('Please select the networks to forget')) + l = [ title, header ] + for entry in wireless.GetSavedWirelessNetworks(): + label = '%20s %20s' + if entry[1] != 'None': + label = label % (entry[0], entry[1]) + data = entry + else: + label = label % (entry[0], 'global') + data = (entry[0], 'essid:' + entry[0]) + + cb = urwid.CheckBox(label, on_state_change=self.update_to_remove, user_data=data) + l.append(cb) + body = urwid.ListBox(l) + + header = ('header', _('List of saved networks')) + Dialog2.__init__(self, header, 15, 50, body) + self.add_buttons([(_('Remove'),1),(_('Cancel'),-1)]) + self.frame.set_focus('body') + + def update_to_remove(self, widget, checked, data): + if checked: + self.to_remove['essid'].append(data[0]) + self.to_remove['bssid'].append(data[1]) + else: + self.to_remove['essid'].remove(data[0]) + self.to_remove['bssid'].remove(data[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.buttons.set_focus(1) + self.view.keypress(size, k) + + def on_exit(self, exitcode): + return exitcode, self.to_remove + ######################################## ##### APPLICATION INTERFACE CLASS ######################################## @@ -892,7 +941,18 @@ class appGUI(): data[1], "WEP", data[5], data[4], False) - + if 'X' in keys: + exitcode, data = ForgetDialog().run(ui, self.frame) + if exitcode == 1: + text = _('Are you sure you want to discard settings for ' + + 'the selected networks?') + text += '\n\n' + '\n'.join(data['essid']) + confirm, useless = TextDialog(text, 20, 50, + buttons=[(_('OK'), 1), (_('Cancel'), -1)], + ).run(ui, self.frame) + if confirm == 1: + map(wireless.DeleteWirelessNetwork, data['bssid']) + for k in keys: if urwid.VERSION < (1, 0, 0): check_mouse_event = urwid.is_mouse_event diff --git a/data/wicd.ui b/data/wicd.ui index 3a77b20..8b94e57 100644 --- a/data/wicd.ui +++ b/data/wicd.ui @@ -60,6 +60,16 @@ + + + Forget network settings + True + Remove settings for saved networks + image3 + True + + + @@ -1732,5 +1742,9 @@ WPA supplicant driver. True gtk-find + + True + gtk-delete + diff --git a/gtk/gui.py b/gtk/gui.py index feec25c..aafd97e 100644 --- a/gtk/gui.py +++ b/gtk/gui.py @@ -180,6 +180,7 @@ class appGui(object): "preferences_clicked" : self.settings_dialog, "about_clicked" : self.about_dialog, "create_adhoc_clicked" : self.create_adhoc_network, + "forget_network_clicked" : self.forget_network, } self.wTree.connect_signals(dic) @@ -300,6 +301,66 @@ class appGui(object): False) #chkbox_use_ics.get_active()) dialog.destroy() + def forget_network(self, widget=None): + """ + Shows a dialog that lists saved wireless networks, and lets the user + delete them. + """ + wireless.ReloadConfig() + dialog = gtk.Dialog(title = _('List of saved networks'), + flags = gtk.DIALOG_MODAL, + buttons=(gtk.STOCK_DELETE, 1, gtk.STOCK_OK, 2)) + dialog.set_has_separator(True) + dialog.set_size_request(400, 200) + + networks = gtk.ListStore(str, str) + for entry in wireless.GetSavedWirelessNetworks(): + if entry[1] != 'None': + networks.append(entry) + else: + networks.append((entry[0], _('Global settings for this ESSID'))) + tree = gtk.TreeView(model=networks) + tree.get_selection().set_mode(gtk.SELECTION_MULTIPLE) + + cell = gtk.CellRendererText() + + column = gtk.TreeViewColumn(_('ESSID'), cell, text = 0) + tree.append_column(column) + + column = gtk.TreeViewColumn(_('BSSID'), cell, text = 1) + tree.append_column(column) + + scroll = gtk.ScrolledWindow() + scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + scroll.add(tree) + dialog.vbox.pack_start(scroll) + dialog.vbox.set_spacing(5) + dialog.show_all() + response = dialog.run() + if response == 1: + model, pathlist = tree.get_selection().get_selected_rows() + to_remove = dict(essid=[], bssid=[]) + if pathlist: + for row in pathlist: + iter = model.get_iter(path=row) + to_remove['essid'].append(misc.noneToString(model.get_value(iter, 0))) + to_remove['bssid'].append(model.get_value(iter, 1)) + + confirm = gtk.MessageDialog( + flags = gtk.DIALOG_MODAL, + type = gtk.MESSAGE_INFO, + buttons = gtk.BUTTONS_YES_NO, + message_format = _('Are you sure you want to discard' + + ' settings for the selected networks?') + ) + confirm.format_secondary_text('\n'.join(to_remove['essid'])) + response = confirm.run() + if response == gtk.RESPONSE_YES: + map(wireless.DeleteWirelessNetwork, to_remove['bssid']) + wireless.ReloadConfig() + confirm.destroy() + dialog.destroy() + def toggle_encrypt_check(self, widget=None): """ Toggles the encryption key entry box for the ad-hoc dialog. """ self.key_entry.set_sensitive(self.chkbox_use_encryption.get_active()) diff --git a/in/man=wicd-curses.8.in b/in/man=wicd-curses.8.in index a9467ec..f00883e 100644 --- a/in/man=wicd-curses.8.in +++ b/in/man=wicd-curses.8.in @@ -56,6 +56,9 @@ Bring up instructions on how to edit the scripts. I have implemented a way to d .TP .BR O Raise the Ad-Hoc network creation dialog +.TP +.BR X +Show the list of saved wireless networks, to be able to remove them .SH "FILES" .TP diff --git a/po/wicd.pot b/po/wicd.pot index 1c8f2d6..ec74267 100644 --- a/po/wicd.pot +++ b/po/wicd.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-05-04 00:29+0200\n" +"POT-Creation-Date: 2012-05-06 08:57+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -66,6 +66,10 @@ msgstr "" msgid "Always switch to wired connection when available" msgstr "" +#: gtk/gui.py:352 +msgid "Are you sure you want to discard settings for the selected networks?" +msgstr "" + #: wicd/translations.py:77 msgid "Authentication" msgstr "" @@ -88,6 +92,10 @@ msgstr "" msgid "Automatically reconnect on connection loss" msgstr "" +#: gtk/gui.py:329 +msgid "BSSID" +msgstr "" + #: curses/prefs_curses.py:113 curses/prefs_curses.py:114 msgid "Backend" msgstr "" @@ -364,6 +372,10 @@ msgstr "" msgid "Key index" msgstr "" +#: gtk/gui.py:309 +msgid "List of saved networks" +msgstr "" + #: curses/netentry_curses.py:51 gtk/netentry.py:76 msgid "Netmask" msgstr "" @@ -828,6 +840,14 @@ msgstr "" msgid "Enter a hidden network to try to locate." msgstr "" +#: data/wicd.ui:65 +msgid "Forget network settings" +msgstr "" + +#: data/wicd.ui:67 +msgid "Remove settings for saved networks" +msgstr "" + #: data/wicd.ui:79 msgid "_Switch Off Wi-Fi" msgstr "" diff --git a/wicd/wicd-daemon.py b/wicd/wicd-daemon.py index b8c3e5e..e510038 100644 --- a/wicd/wicd-daemon.py +++ b/wicd/wicd-daemon.py @@ -41,6 +41,7 @@ import getopt import signal import atexit from subprocess import Popen +from operator import itemgetter # DBUS import gobject @@ -1306,6 +1307,27 @@ class WirelessDaemon(dbus.service.Object): ''' Returns a list of wireless interfaces on the system. ''' return wnettools.GetWirelessInterfaces() + @dbus.service.method('org.wicd.daemon.wireless') + def GetSavedWirelessNetworks(self): + ''' Returns a list of saved wireless networks. ''' + ret = [] + for section in self.config.sections(): + if section.startswith('essid:'): + ret.append((section.replace('essid:', ''), 'None')) + else: + essid = self.config.get(section, 'essid') + ret.append((essid, section)) + return sorted(ret, key=itemgetter(0)) + + @dbus.service.method('org.wicd.daemon.wireless') + def DeleteWirelessNetwork(self, section): + """ Deletes a wireless network section. """ + section = misc.to_unicode(section) + print "Deleting wireless settings for %s (%s)" % \ + (self.config.get(section, 'essid'), str(section)) + self.config.remove_section(section) + self.config.write() + @dbus.service.signal(dbus_interface='org.wicd.daemon.wireless', signature='') def SendStartScanSignal(self): """ Emits a signal announcing a scan has started. """