3
""" gui -- The main wicd GUI module.
5
Module containing the code for the main wicd GUI.
10
# Copyright (C) 2007-2009 Adam Blackburn
11
# Copyright (C) 2007-2009 Dan O'Reilly
13
# This program is free software; you can redistribute it and/or modify
14
# it under the terms of the GNU General Public License Version 2 as
15
# published by the Free Software Foundation.
17
# This program is distributed in the hope that it will be useful,
18
# but WITHOUT ANY WARRANTY; without even the implied warranty of
19
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
# GNU General Public License for more details.
22
# You should have received a copy of the GNU General Public License
23
# along with this program. If not, see <http://www.gnu.org/licenses/>.
33
from itertools import chain
34
from dbus import DBusException
37
from wicd import wpath
38
from wicd import dbusmanager
39
from wicd.misc import noneToString
41
from prefs import PreferencesDialog
43
from netentry import WiredNetworkEntry, WirelessNetworkEntry
44
from guiutil import error, LabelEntry
45
from wicd.translations import language
47
if __name__ == '__main__':
50
proxy_obj = daemon = wireless = wired = bus = None
53
def setup_dbus(force=True):
54
global bus, daemon, wireless, wired, DBUS_AVAIL
56
dbusmanager.connect_to_dbus()
59
print "Can't connect to the daemon, trying to start it automatically..."
60
if not misc.PromptToStartDaemon():
61
print "Failed to find a graphical sudo program, cannot continue."
64
dbusmanager.connect_to_dbus()
66
error(None, "Could not connect to wicd's D-Bus interface. " +
67
"Check the wicd log for error messages.")
73
bus = dbusmanager.get_bus()
74
dbus_ifaces = dbusmanager.get_dbus_ifaces()
75
daemon = dbus_ifaces['daemon']
76
wireless = dbus_ifaces['wireless']
77
wired = dbus_ifaces['wired']
82
def handle_no_dbus(from_tray=False):
85
if from_tray: return False
86
print "Wicd daemon is shutting down!"
87
error(None, language['lost_dbus'], block=False)
91
class WiredProfileChooser:
92
""" Class for displaying the wired profile chooser. """
94
""" Initializes and runs the wired profile chooser. """
95
# Import and init WiredNetworkEntry to steal some of the
96
# functions and widgets it uses.
97
wired_net_entry = WiredNetworkEntry()
99
dialog = gtk.Dialog(title = language['wired_network_found'],
100
flags = gtk.DIALOG_MODAL,
101
buttons = (gtk.STOCK_CONNECT, 1,
102
gtk.STOCK_CANCEL, 2))
103
dialog.set_has_separator(False)
104
dialog.set_size_request(400, 150)
105
instruct_label = gtk.Label(language['choose_wired_profile'] + ':\n')
106
stoppopcheckbox = gtk.CheckButton(language['stop_showing_chooser'])
108
wired_net_entry.is_full_gui = False
109
instruct_label.set_alignment(0, 0)
110
stoppopcheckbox.set_active(False)
112
# Remove widgets that were added to the normal WiredNetworkEntry
113
# so that they can be added to the pop-up wizard.
114
wired_net_entry.vbox_top.remove(wired_net_entry.hbox_temp)
115
wired_net_entry.vbox_top.remove(wired_net_entry.profile_help)
117
dialog.vbox.pack_start(instruct_label, fill=False, expand=False)
118
dialog.vbox.pack_start(wired_net_entry.profile_help, False, False)
119
dialog.vbox.pack_start(wired_net_entry.hbox_temp, False, False)
120
dialog.vbox.pack_start(stoppopcheckbox, False, False)
123
wired_profiles = wired_net_entry.combo_profile_names
124
wired_net_entry.profile_help.hide()
125
if wired_net_entry.profile_list != None:
126
wired_profiles.set_active(0)
127
print "wired profiles found"
129
print "no wired profiles found"
130
wired_net_entry.profile_help.show()
132
response = dialog.run()
134
print 'reading profile ', wired_profiles.get_active_text()
135
wired.ReadWiredNetworkProfile(wired_profiles.get_active_text())
138
if stoppopcheckbox.get_active():
139
daemon.SetForcedDisconnect(True)
143
class appGui(object):
144
""" The main wicd GUI class. """
145
def __init__(self, standalone=False, tray=None):
146
""" Initializes everything needed for the GUI. """
151
gladefile = os.path.join(wpath.gtk, "wicd.glade")
152
self.wTree = gtk.glade.XML(gladefile)
153
self.window = self.wTree.get_widget("window1")
154
self.window.set_icon_name("wicd-gtk")
155
size = daemon.ReadWindowSize("main")
158
if width > -1 and height > -1:
159
self.window.resize(int(width), int(height))
161
width = int(gtk.gdk.screen_width() / 2)
164
self.window.resize(width, int(gtk.gdk.screen_height() / 1.7))
166
dic = { "refresh_clicked" : self.refresh_clicked,
167
"quit_clicked" : self.exit,
168
"disconnect_clicked" : self.disconnect_all,
169
"main_exit" : self.exit,
170
"cancel_clicked" : self.cancel_connect,
171
"hidden_clicked" : self.connect_hidden,
172
"preferences_clicked" : self.settings_dialog,
173
"about_clicked" : self.about_dialog,
174
"create_adhoc_clicked" : self.create_adhoc_network,
176
self.wTree.signal_autoconnect(dic)
178
# Set some strings in the GUI - they may be translated
179
label_instruct = self.wTree.get_widget("label_instructions")
180
label_instruct.set_label(language['select_a_network'])
182
probar = self.wTree.get_widget("progressbar")
183
probar.set_text(language['connecting'])
185
self.all_network_list = self.wTree.get_widget("network_list_vbox")
186
self.all_network_list.show_all()
187
self.wired_network_box = gtk.VBox(False, 0)
188
self.wired_network_box.show_all()
189
self.network_list = gtk.VBox(False, 0)
190
self.all_network_list.pack_start(self.wired_network_box, False, False)
191
self.all_network_list.pack_start(self.network_list, True, True)
192
self.network_list.show_all()
193
self.status_area = self.wTree.get_widget("connecting_hbox")
194
self.status_bar = self.wTree.get_widget("statusbar")
195
menu = self.wTree.get_widget("menu1")
197
self.status_area.hide_all()
199
if os.path.exists(os.path.join(wpath.images, "wicd.png")):
200
self.window.set_icon_from_file(os.path.join(wpath.images, "wicd.png"))
202
self.first_dialog_load = True
203
self.is_visible = True
204
self.pulse_active = False
206
self.standalone = standalone
207
self.wpadrivercombo = None
208
self.connecting = False
209
self.refreshing = False
210
self.prev_state = None
211
self.update_cb = None
212
self.network_list.set_sensitive(False)
213
label = gtk.Label("%s..." % language['scanning'])
214
self.network_list.pack_start(label)
216
self.wait_for_events(0.2)
217
self.window.connect('delete_event', self.exit)
218
self.window.connect('key-release-event', self.key_event)
219
daemon.SetGUIOpen(True)
220
bus.add_signal_receiver(self.dbus_scan_finished, 'SendEndScanSignal',
221
'org.wicd.daemon.wireless')
222
bus.add_signal_receiver(self.dbus_scan_started, 'SendStartScanSignal',
223
'org.wicd.daemon.wireless')
224
bus.add_signal_receiver(self.update_connect_buttons, 'StatusChanged',
226
bus.add_signal_receiver(self.handle_connection_results,
227
'ConnectResultsSent', 'org.wicd.daemon')
228
bus.add_signal_receiver(lambda: setup_dbus(force=False),
229
"DaemonStarting", "org.wicd.daemon")
230
bus.add_signal_receiver(self._do_statusbar_update, 'StatusChanged',
233
bus.add_signal_receiver(handle_no_dbus, "DaemonClosing",
236
self._do_statusbar_update(*daemon.GetConnectionStatus())
237
self.wait_for_events(0.1)
238
self.update_cb = misc.timeout_add(2, self.update_statusbar)
239
self.refresh_clicked()
241
def handle_connection_results(self, results):
242
if results not in ['Success', 'aborted'] and self.is_visible:
243
error(self.window, language[results], block=False)
245
def create_adhoc_network(self, widget=None):
246
""" Shows a dialog that creates a new adhoc network. """
247
print "Starting the Ad-Hoc Network Creation Process..."
248
dialog = gtk.Dialog(title = language['create_adhoc_network'],
249
flags = gtk.DIALOG_MODAL,
250
buttons=(gtk.STOCK_CANCEL, 2, gtk.STOCK_OK, 1))
251
dialog.set_has_separator(False)
252
dialog.set_size_request(400, -1)
253
self.chkbox_use_encryption = gtk.CheckButton(language['use_wep_encryption'])
254
self.chkbox_use_encryption.set_active(False)
255
ip_entry = LabelEntry(language['ip'] + ':')
256
essid_entry = LabelEntry(language['essid'] + ':')
257
channel_entry = LabelEntry(language['channel'] + ':')
258
self.key_entry = LabelEntry(language['key'] + ':')
259
self.key_entry.set_auto_hidden(True)
260
self.key_entry.set_sensitive(False)
262
chkbox_use_ics = gtk.CheckButton(language['use_ics'])
264
self.chkbox_use_encryption.connect("toggled",
265
self.toggle_encrypt_check)
266
channel_entry.entry.set_text('3')
267
essid_entry.entry.set_text('My_Adhoc_Network')
268
ip_entry.entry.set_text('169.254.12.10') # Just a random IP
270
vbox_ah = gtk.VBox(False, 0)
271
self.wired_network_box = gtk.VBox(False, 0)
272
vbox_ah.pack_start(self.chkbox_use_encryption, False, False)
273
vbox_ah.pack_start(self.key_entry, False, False)
275
dialog.vbox.pack_start(essid_entry)
276
dialog.vbox.pack_start(ip_entry)
277
dialog.vbox.pack_start(channel_entry)
278
dialog.vbox.pack_start(chkbox_use_ics)
279
dialog.vbox.pack_start(vbox_ah)
280
dialog.vbox.set_spacing(5)
282
response = dialog.run()
284
wireless.CreateAdHocNetwork(essid_entry.entry.get_text(),
285
channel_entry.entry.get_text(),
286
ip_entry.entry.get_text().strip(),
288
self.key_entry.entry.get_text(),
289
self.chkbox_use_encryption.get_active(),
290
False) #chkbox_use_ics.get_active())
293
def toggle_encrypt_check(self, widget=None):
294
""" Toggles the encryption key entry box for the ad-hoc dialog. """
295
self.key_entry.set_sensitive(self.chkbox_use_encryption.get_active())
297
def disconnect_all(self, widget=None):
298
""" Disconnects from any active network. """
300
gobject.idle_add(self.all_network_list.set_sensitive, True)
302
self.all_network_list.set_sensitive(False)
303
daemon.Disconnect(reply_handler=handler, error_handler=handler)
305
def about_dialog(self, widget, event=None):
306
""" Displays an about dialog. """
307
dialog = gtk.AboutDialog()
308
dialog.set_name("Wicd")
309
dialog.set_version(daemon.Hello())
310
dialog.set_authors([ "Adam Blackburn", "Dan O'Reilly", "Andrew Psaltis" ])
311
dialog.set_website("http://wicd.sourceforge.net")
315
def key_event (self, widget, event=None):
316
""" Handle key-release-events. """
317
if event.state & gtk.gdk.CONTROL_MASK and \
318
gtk.gdk.keyval_name(event.keyval) in ["w", "q"]:
321
def settings_dialog(self, widget, event=None):
322
""" Displays a general settings dialog. """
324
self.pref = PreferencesDialog(self, self.wTree)
326
self.pref.load_preferences_diag()
327
if self.pref.run() == 1:
328
self.pref.save_results()
331
def connect_hidden(self, widget):
332
""" Prompts the user for a hidden network, then scans for it. """
333
dialog = gtk.Dialog(title=language['hidden_network'],
334
flags=gtk.DIALOG_MODAL,
335
buttons=(gtk.STOCK_CONNECT, 1, gtk.STOCK_CANCEL, 2))
336
dialog.set_has_separator(False)
337
lbl = gtk.Label(language['hidden_network_essid'])
338
textbox = gtk.Entry()
339
dialog.vbox.pack_start(lbl)
340
dialog.vbox.pack_start(textbox)
342
button = dialog.run()
344
answer = textbox.get_text()
346
self.refresh_networks(None, True, answer)
350
def cancel_connect(self, widget):
351
""" Alerts the daemon to cancel the connection process. """
352
#should cancel a connection if there
354
cancel_button = self.wTree.get_widget("cancel_button")
355
cancel_button.set_sensitive(False)
356
daemon.CancelConnect()
357
# Prevents automatic reconnecting if that option is enabled
358
daemon.SetForcedDisconnect(True)
360
def pulse_progress_bar(self):
361
""" Pulses the progress bar while connecting to a network. """
362
if not self.pulse_active:
364
if not self.is_visible:
367
gobject.idle_add(self.wTree.get_widget("progressbar").pulse)
372
def update_statusbar(self):
373
""" Triggers a status update in wicd-monitor. """
374
if not self.is_visible:
379
# If we're connecting, don't wait for the monitor to send
380
# us a signal, since it won't until the connection is made.
381
self._do_statusbar_update(*daemon.GetConnectionStatus())
384
def _do_statusbar_update(self, state, info):
385
if not self.is_visible:
388
if state == misc.WIRED:
389
return self.set_wired_state(info)
390
elif state == misc.WIRELESS:
391
return self.set_wireless_state(info)
392
elif state == misc.CONNECTING:
393
return self.set_connecting_state(info)
394
elif state in (misc.SUSPENDED, misc.NOT_CONNECTED):
395
return self.set_not_connected_state(info)
398
def set_wired_state(self, info):
400
# Adjust our state from connecting->connected.
401
self._set_not_connecting_state()
402
self.set_status(language['connected_to_wired'].replace('$A', info[0]))
405
def set_wireless_state(self, info):
407
# Adjust our state from connecting->connected.
408
self._set_not_connecting_state()
409
self.set_status(language['connected_to_wireless'].replace
410
('$A', info[1]).replace
411
('$B', daemon.FormatSignalForPrinting(info[2])).replace
415
def set_not_connected_state(self, info):
417
# Adjust our state from connecting->not-connected.
418
self._set_not_connecting_state()
419
self.set_status(language['not_connected'])
422
def _set_not_connecting_state(self):
425
gobject.source_remove(self.update_cb)
426
self.update_cb = misc.timeout_add(2, self.update_statusbar)
427
self.connecting = False
428
if self.pulse_active:
429
self.pulse_active = False
430
gobject.idle_add(self.all_network_list.set_sensitive, True)
431
gobject.idle_add(self.status_area.hide_all)
433
gobject.idle_add(self.status_bar.remove, 1, self.statusID)
435
def set_connecting_state(self, info):
436
if not self.connecting:
438
gobject.source_remove(self.update_cb)
439
self.update_cb = misc.timeout_add(500, self.update_statusbar,
441
self.connecting = True
442
if not self.pulse_active:
443
self.pulse_active = True
444
misc.timeout_add(100, self.pulse_progress_bar, milli=True)
445
gobject.idle_add(self.all_network_list.set_sensitive, False)
446
gobject.idle_add(self.status_area.show_all)
448
gobject.idle_add(self.status_bar.remove, 1, self.statusID)
449
if info[0] == "wireless":
450
gobject.idle_add(self.set_status, str(info[1]) + ': ' +
451
language[str(wireless.CheckWirelessConnectingMessage())])
452
elif info[0] == "wired":
453
gobject.idle_add(self.set_status, language['wired_network'] + ': ' +
454
language[str(wired.CheckWiredConnectingMessage())])
457
def update_connect_buttons(self, state=None, x=None, force_check=False):
458
""" Updates the connect/disconnect buttons for each network entry.
460
If force_check is given, update the buttons even if the
461
current network state is the same as the previous.
464
if not DBUS_AVAIL: return
466
state, x = daemon.GetConnectionStatus()
468
if self.prev_state != state or force_check:
469
apbssid = wireless.GetApBssid()
470
for entry in chain(self.network_list, self.wired_network_box):
471
if hasattr(entry, "update_connect_button"):
472
entry.update_connect_button(state, apbssid)
473
self.prev_state = state
475
def set_status(self, msg):
476
""" Sets the status bar message for the GUI. """
477
self.statusID = self.status_bar.push(1, msg)
479
def dbus_scan_finished(self):
480
""" Calls for a non-fresh update of the gui window.
482
This method is called after a wireless scan is completed.
485
if not DBUS_AVAIL: return
486
gobject.idle_add(self.refresh_networks, None, False, None)
488
def dbus_scan_started(self):
489
""" Called when a wireless scan starts. """
490
if not DBUS_AVAIL: return
491
self.network_list.set_sensitive(False)
493
def _remove_items_from_vbox(self, vbox):
500
def refresh_clicked(self, widget=None):
501
""" Kick off an asynchronous wireless scan. """
502
if not DBUS_AVAIL or self.connecting: return
503
self.refreshing = True
505
# Remove stuff already in there.
506
self._remove_items_from_vbox(self.wired_network_box)
507
self._remove_items_from_vbox(self.network_list)
508
label = gtk.Label("%s..." % language['scanning'])
509
self.network_list.pack_start(label)
510
self.network_list.show_all()
511
if wired.CheckPluggedIn() or daemon.GetAlwaysShowWiredInterface():
512
printLine = True # In this case we print a separator.
513
wirednet = WiredNetworkEntry()
514
self.wired_network_box.pack_start(wirednet, False, False)
515
wirednet.connect_button.connect("clicked", self.connect,
516
"wired", 0, wirednet)
517
wirednet.disconnect_button.connect("clicked", self.disconnect,
518
"wired", 0, wirednet)
519
wirednet.advanced_button.connect("clicked",
520
self.edit_advanced, "wired", 0,
522
state, x = daemon.GetConnectionStatus()
523
wirednet.update_connect_button(state)
525
self._wired_showing = True
527
self._wired_showing = False
531
def refresh_networks(self, widget=None, fresh=True, hidden=None):
532
""" Refreshes the network list.
534
If fresh=True, scans for wireless networks and displays the results.
535
If a ethernet connection is available, or the user has chosen to,
536
displays a Wired Network entry as well.
537
If hidden isn't None, will scan for networks after running
538
iwconfig <wireless interface> essid <hidden>.
543
wireless.SetHiddenNetworkESSID(noneToString(hidden))
544
self.refresh_clicked()
546
print "refreshing..."
547
self.network_list.set_sensitive(False)
548
self._remove_items_from_vbox(self.network_list)
549
self.wait_for_events()
550
printLine = False # We don't print a separator by default.
551
if self._wired_showing:
553
num_networks = wireless.GetNumberOfNetworks()
554
instruct_label = self.wTree.get_widget("label_instructions")
556
instruct_label.show()
557
for x in range(0, num_networks):
559
sep = gtk.HSeparator()
560
self.network_list.pack_start(sep, padding=10, fill=False,
565
tempnet = WirelessNetworkEntry(x)
566
self.network_list.pack_start(tempnet, False, False)
567
tempnet.connect_button.connect("clicked",
568
self.connect, "wireless", x,
570
tempnet.disconnect_button.connect("clicked",
571
self.disconnect, "wireless",
573
tempnet.advanced_button.connect("clicked",
574
self.edit_advanced, "wireless",
577
instruct_label.hide()
578
if wireless.GetKillSwitchEnabled():
579
label = gtk.Label(language['killswitch_enabled'] + ".")
581
label = gtk.Label(language['no_wireless_networks_found'])
582
self.network_list.pack_start(label)
584
self.update_connect_buttons(force_check=True)
585
self.network_list.set_sensitive(True)
586
self.refreshing = False
588
def save_settings(self, nettype, networkid, networkentry):
589
""" Verifies and saves the settings for the network entry. """
590
entry = networkentry.advanced_dialog
594
# First make sure all the Addresses entered are valid.
595
if entry.chkbox_static_ip.get_active():
596
req_entlist = [entry.txt_ip, entry.txt_netmask]
597
opt_entlist = [entry.txt_gateway]
599
if entry.chkbox_static_dns.get_active() and \
600
not entry.chkbox_global_dns.get_active():
601
for ent in [entry.txt_dns_1, entry.txt_dns_2, entry.txt_dns_3]:
602
opt_entlist.append(ent)
605
for lblent in req_entlist:
606
lblent.set_text(lblent.get_text().strip())
607
if not misc.IsValidIP(lblent.get_text()):
608
error(self.window, language['invalid_address'].
609
replace('$A', lblent.label.get_label()))
612
# Optional entries, only check for validity if they're entered.
613
for lblent in opt_entlist:
614
lblent.set_text(lblent.get_text().strip())
615
if lblent.get_text() and not misc.IsValidIP(lblent.get_text()):
616
error(self.window, language['invalid_address'].
617
replace('$A', lblent.label.get_label()))
620
# Now save the settings.
621
if nettype == "wireless":
622
if not networkentry.save_wireless_settings(networkid):
625
elif nettype == "wired":
626
if not networkentry.save_wired_settings():
631
def edit_advanced(self, widget, ttype, networkid, networkentry):
632
""" Display the advanced settings dialog.
634
Displays the advanced settings dialog and saves any changes made.
635
If errors occur in the settings, an error message will be displayed
636
and the user won't be able to save the changes until the errors
640
dialog = networkentry.advanced_dialog
644
if self.run_settings_dialog(dialog, ttype, networkid, networkentry):
648
def run_settings_dialog(self, dialog, nettype, networkid, networkentry):
649
""" Runs the settings dialog.
651
Runs the settings dialog and returns True if settings are saved
652
successfully, and false otherwise.
655
result = dialog.run()
656
if result == gtk.RESPONSE_ACCEPT:
657
if self.save_settings(nettype, networkid, networkentry):
663
def check_encryption_valid(self, networkid, entry):
664
""" Make sure that encryption settings are properly filled in. """
665
# Make sure no entries are left blank
666
if entry.chkbox_encryption.get_active():
667
encryption_info = entry.encryption_info
668
for entry_info in encryption_info.itervalues():
669
if entry_info[0].entry.get_text() == "" and \
670
entry_info[1] == 'required':
671
error(self.window, "%s (%s)" % (language['encrypt_info_missing'],
672
entry_info[0].label.get_label())
675
# Make sure the checkbox is checked when it should be
676
elif not entry.chkbox_encryption.get_active() and \
677
wireless.GetWirelessProperty(networkid, "encryption"):
678
error(self.window, language['enable_encryption'])
682
def _wait_for_connect_thread_start(self):
683
self.wTree.get_widget("progressbar").pulse()
684
if not self._connect_thread_started:
687
misc.timeout_add(2, self.update_statusbar)
688
self.update_statusbar()
691
def connect(self, widget, nettype, networkid, networkentry):
692
""" Initiates the connection process in the daemon. """
694
self._connect_thread_started = True
696
def setup_interface_for_connection():
697
cancel_button = self.wTree.get_widget("cancel_button")
698
cancel_button.set_sensitive(True)
699
self.all_network_list.set_sensitive(False)
701
gobject.idle_add(self.status_bar.remove, 1, self.statusID)
702
gobject.idle_add(self.set_status, language["disconnecting_active"])
703
gobject.idle_add(self.status_area.show_all)
704
self.wait_for_events()
705
self._connect_thread_started = False
707
if nettype == "wireless":
708
if not self.check_encryption_valid(networkid,
709
networkentry.advanced_dialog):
710
self.edit_advanced(None, nettype, networkid, networkentry)
712
setup_interface_for_connection()
713
wireless.ConnectWireless(networkid, reply_handler=handler,
714
error_handler=handler)
715
elif nettype == "wired":
716
setup_interface_for_connection()
717
wired.ConnectWired(reply_handler=handler, error_handler=handler)
719
gobject.source_remove(self.update_cb)
720
misc.timeout_add(100, self._wait_for_connect_thread_start, milli=True)
722
def disconnect(self, widget, nettype, networkid, networkentry):
723
""" Disconnects from the given network.
726
widget -- The disconnect button that was pressed.
728
nettype -- "wired" or "wireless", depending on the network entry type.
730
networkentry -- The NetworkEntry containing the disconnect button.
734
gobject.idle_add(self.all_network_list.set_sensitive, True)
735
gobject.idle_add(self.network_list.set_sensitive, True)
738
networkentry.connect_button.show()
739
daemon.SetForcedDisconnect(True)
740
self.network_list.set_sensitive(False)
741
if nettype == "wired":
742
wired.DisconnectWired(reply_handler=handler, error_handler=handler)
744
wireless.DisconnectWireless(reply_handler=handler,
745
error_handler=handler)
747
def wait_for_events(self, amt=0):
748
""" Wait for any pending gtk events to finish before moving on.
751
amt -- a number specifying the number of ms to wait before checking
756
while gtk.events_pending():
759
def exit(self, widget=None, event=None):
760
""" Hide the wicd GUI.
762
This method hides the wicd GUI and writes the current window size
763
to disc for later use. This method normally does NOT actually
764
destroy the GUI, it just hides it.
768
gobject.source_remove(self.update_cb)
769
bus.remove_signal_receiver(self._do_statusbar_update, 'StatusChanged',
771
[width, height] = self.window.get_size()
773
daemon.WriteWindowSize(width, height, "main")
774
daemon.SetGUIOpen(False)
775
except DBusException:
781
self.is_visible = False
785
""" Brings the GUI out of the hidden state.
787
Method to show the wicd GUI, alert the daemon that it is open,
788
and refresh the network list.
791
self.window.present()
792
self.wait_for_events()
793
self.is_visible = True
794
daemon.SetGUIOpen(True)
795
self.wait_for_events(0.1)
796
gobject.idle_add(self.refresh_clicked)
797
self._do_statusbar_update(*daemon.GetConnectionStatus())
798
bus.add_signal_receiver(self._do_statusbar_update, 'StatusChanged',
800
self.update_cb = misc.timeout_add(2, self.update_statusbar)
803
if __name__ == '__main__':
805
app = appGui(standalone=True)
806
mainloop = gobject.MainLoop()