57
71
import egg.trayicon
59
73
except ImportError:
60
print 'Unable to load tray icon: Missing egg.trayicon module.'
74
print 'Unable to load tray icon: Missing both egg.trayicon and gtk.StatusIcon modules.'
63
if getattr(dbus, 'version', (0, 0, 0)) < (0, 80, 0):
66
from dbus.mainloop.glib import DBusGMainLoop
67
DBusGMainLoop(set_as_default=True)
69
77
misc.RenameProcess("wicd-client")
71
79
if __name__ == '__main__':
72
80
wpath.chdir(__file__)
81
_ = misc.get_gettext()
83
language['connected_to_wireless'] = _('Connected to $A at $B (IP: $C)')
84
language['connected_to_wired'] = _('Connected to wired network (IP: $A)')
85
language['not_connected'] = _('Not connected')
86
language['killswitch_enabled'] = _('Wireless Kill Switch Enabled')
87
language['connecting'] = _('Connecting')
88
language['wired'] = _('Wired Network')
82
daemon = wireless = wired = lost_dbus_id = None
86
def wrapper(*args, **kwargs):
88
return func(*args, **kwargs)
89
except DBusException, e:
90
if e.get_dbus_name() != None and "DBus.Error.AccessDenied" in e.get_dbus_name():
91
error(None, language['access_denied'])
93
raise DBusException(e)
95
print "warning: ignoring exception %s" % e
97
wrapper.__name__ = func.__name__
98
wrapper.__module__ = func.__module__
99
wrapper.__dict__ = func.__dict__
100
wrapper.__doc__ = func.__doc__
104
class NetworkMenuItem(gtk.ImageMenuItem):
105
def __init__(self, lbl, is_active=False):
106
gtk.ImageMenuItem.__init__(self)
107
self.label = gtk.Label(lbl)
109
atrlist = pango.AttrList()
110
atrlist.insert(pango.AttrWeight(pango.WEIGHT_BOLD, 0, 50))
111
self.label.set_attributes(atrlist)
112
self.label.set_justify(gtk.JUSTIFY_LEFT)
113
self.label.set_alignment(0, 0)
91
118
class TrayIcon(object):
92
119
""" Base Tray Icon class.
150
208
if wireless.GetWirelessProperty(cur_net_id, "encryption"):
153
self.tr.set_tooltip(language['connected_to_wireless']
210
status_string = (language['connected_to_wireless']
154
211
.replace('$A', self.network)
155
212
.replace('$B', sig_string)
156
.replace('$C', str(wireless_ip)))
213
.replace('$C', str(wireless_ip)))
214
self.tr.set_tooltip(status_string)
157
215
self.set_signal_image(int(strength), lock)
216
self._show_notification(self.network,
217
language['connection_established'],
159
221
def set_connecting_state(self, info):
160
222
""" Sets the icon info for a connecting state. """
161
224
if info[0] == 'wired' and len(info) == 1:
162
cur_network = language['wired']
225
cur_network = language['wired_network']
164
228
cur_network = info[1]
165
self.tr.set_tooltip(language['connecting'] + " to " +
167
self.tr.set_from_file(wpath.images + "no-signal.png")
229
status_string = language['connecting'] + " to " + \
231
self.tr.set_tooltip(status_string)
232
self.tr.set_from_file(os.path.join(wpath.images, "no-signal.png"))
234
self._show_notification(cur_network,
235
language['establishing_connection'],
238
self._show_notification(cur_network,
239
language['establishing_connection'],
169
def set_not_connected_state(self, info):
244
def set_not_connected_state(self, info=None):
170
245
""" Set the icon info for the not connected state. """
171
246
self.tr.set_from_file(wpath.images + "no-signal.png")
172
if wireless.GetKillSwitchEnabled():
248
status = language['no_daemon_tooltip']
249
elif wireless.GetKillSwitchEnabled():
173
250
status = (language['not_connected'] + " (" +
174
251
language['killswitch_enabled'] + ")")
176
253
status = language['not_connected']
177
254
self.tr.set_tooltip(status)
255
self._show_notification(language['disconnected'], None, 'stop')
179
258
def update_tray_icon(self, state=None, info=None):
180
259
""" Updates the tray icon and current connection status. """
181
if not self.use_tray: return False
260
if not DBUS_AVAIL: return False
183
262
if not state or not info:
184
263
[state, info] = daemon.GetConnectionStatus()
265
# should this state change display a notification?
266
self.should_notify = (can_use_notify() and
267
self.last_state != state)
269
self.last_state = state
186
271
if state == misc.WIRED:
187
272
self.set_wired_state(info)
335
422
self.gui_win = None
336
423
self.current_icon_path = None
337
self.use_tray = use_tray
424
self._is_scanning = False
425
net_menuitem = self.manager.get_widget("/Menubar/Menu/Connect/")
426
net_menuitem.connect("activate", self.on_net_menu_activate)
428
def tray_scan_started(self):
429
""" Callback for when a wireless scan is started. """
430
if not DBUS_AVAIL: return
431
self._is_scanning = True
432
self.init_network_menu()
434
def tray_scan_ended(self):
435
""" Callback for when a wireless scan finishes. """
436
if not DBUS_AVAIL: return
437
self._is_scanning = False
438
self.populate_network_menu()
339
440
def on_activate(self, data=None):
340
441
""" Opens the wicd GUI. """
341
self.toggle_wicd_gui()
443
self.toggle_wicd_gui()
445
# error(None, language["daemon_unavailable"])
343
448
def on_quit(self, widget=None):
344
449
""" Closes the tray icon. """
347
def on_preferences(self, data=None):
348
""" Opens the wicd GUI. """
349
self.toggle_wicd_gui()
351
452
def on_about(self, data=None):
352
453
""" Opens the About Dialog. """
353
454
dialog = gtk.AboutDialog()
354
dialog.set_name('wicd tray icon')
356
dialog.set_version('1.5.9')
455
dialog.set_name('Wicd Tray Icon')
456
dialog.set_version('2.0')
357
457
dialog.set_comments('An icon that shows your network connectivity')
358
458
dialog.set_website('http://wicd.net')
462
def _add_item_to_menu(self, net_menu, lbl, type_, n_id, is_connecting,
464
""" Add an item to the network list submenu. """
465
def network_selected(widget, net_type, net_id):
466
""" Callback method for a menu item selection. """
467
if net_type == "__wired__":
470
wireless.ConnectWireless(net_id)
472
item = NetworkMenuItem(lbl, is_active)
475
if type_ == "__wired__":
476
image.set_from_icon_name("network-wired", 2)
478
pb = gtk.gdk.pixbuf_new_from_file_at_size(self._get_img(n_id),
480
image.set_from_pixbuf(pb)
482
item.set_image(image)
484
item.connect("activate", network_selected, type_, n_id)
485
net_menu.append(item)
488
item.set_sensitive(False)
492
def _get_img(self, net_id):
493
""" Determines which image to use for the wireless entries. """
494
def fix_strength(val, default):
495
""" Assigns given strength to a default value if needed. """
496
return val and int(val) or default
499
return wireless.GetWirelessProperty(net_id, prop)
501
strength = fix_strength(get_prop("quality"), -1)
502
dbm_strength = fix_strength(get_prop('strength'), -100)
504
if daemon.GetWPADriver() == 'ralink legacy' or \
505
daemon.GetSignalDisplayType() == 1:
506
if dbm_strength >= -60:
507
signal_img = 'signal-100.png'
508
elif dbm_strength >= -70:
509
signal_img = 'signal-75.png'
510
elif dbm_strength >= -80:
511
signal_img = 'signal-50.png'
513
signal_img = 'signal-25.png'
516
signal_img = 'signal-100.png'
518
signal_img = 'signal-75.png'
520
signal_img = 'signal-50.png'
522
signal_img = 'signal-25.png'
523
return wpath.images + signal_img
525
def on_net_menu_activate(self, item):
526
""" Trigger a background scan to populate the network menu.
528
Clear the network menu, and schedule a method to be
529
called in .8 seconds to trigger a scan if the menu
530
is still being moused over.
533
if self._is_scanning:
536
self.init_network_menu()
537
gobject.timeout_add(800, self._trigger_scan_if_needed, item)
540
def _trigger_scan_if_needed(self, item):
541
""" Trigger a scan if the network menu is being hovered over. """
542
while gtk.events_pending():
544
if item.state != gtk.STATE_PRELIGHT:
550
def populate_network_menu(self, data=None):
551
""" Populates the network list submenu. """
552
def get_prop(net_id, prop):
553
return wireless.GetWirelessProperty(net_id, prop)
555
net_menuitem = self.manager.get_widget("/Menubar/Menu/Connect/")
556
submenu = net_menuitem.get_submenu()
557
self._clear_menu(submenu)
562
is_connecting = daemon.CheckIfConnecting()
563
num_networks = wireless.GetNumberOfNetworks()
564
[status, info] = daemon.GetConnectionStatus()
566
if daemon.GetAlwaysShowWiredInterface() or \
567
wired.CheckPluggedIn():
568
if status == misc.WIRED:
572
self._add_item_to_menu(submenu, "Wired Network", "__wired__", 0,
573
is_connecting, is_active)
574
sep = gtk.SeparatorMenuItem()
579
for x in range(0, num_networks):
580
essid = get_prop(x, "essid")
581
if status == misc.WIRELESS and info[1] == essid:
585
self._add_item_to_menu(submenu, essid, "wifi", x,
586
is_connecting, is_active)
588
no_nets_item = gtk.MenuItem(language['no_wireless_networks_found'])
589
no_nets_item.set_sensitive(False)
591
submenu.append(no_nets_item)
595
def init_network_menu(self):
596
""" Set the right-click network menu to the scanning state. """
597
net_menuitem = self.manager.get_widget("/Menubar/Menu/Connect/")
598
submenu = net_menuitem.get_submenu()
599
self._clear_menu(submenu)
601
loading_item = gtk.MenuItem(language['scanning'] + "...")
602
loading_item.set_sensitive(False)
604
submenu.append(loading_item)
607
def _clear_menu(self, menu):
608
""" Clear the right-click menu. """
609
for item in menu.get_children():
362
613
def toggle_wicd_gui(self):
363
614
""" Toggles the wicd GUI. """
364
615
if not self.gui_win:
365
self.gui_win = gui.appGui()
366
bus.add_signal_receiver(self.gui_win.dbus_scan_finished,
369
bus.add_signal_receiver(self.gui_win.dbus_scan_started,
370
'SendStartScanSignal',
372
bus.add_signal_receiver(self.gui_win.update_connect_buttons,
373
'StatusChanged', 'org.wicd.daemon')
616
self.gui_win = gui.appGui(tray=self)
374
617
elif not self.gui_win.is_visible:
375
618
self.gui_win.show_win()
377
620
self.gui_win.exit()
381
625
class EggTrayIconGUI(TrayIconGUI):
382
626
""" Tray Icon for gtk < 2.10.
386
630
for machines running versions of GTK < 2.10.
389
def __init__(self, use_tray=True):
390
634
"""Initializes the tray icon"""
391
TrayIcon.TrayIconGUI.__init__(self, use_tray)
392
self.use_tray = use_tray
394
self.toggle_wicd_gui()
635
TrayIcon.TrayIconGUI.__init__(self)
397
636
self.tooltip = gtk.Tooltips()
398
637
self.eb = gtk.EventBox()
399
638
self.tray = egg.trayicon.TrayIcon("WicdTrayIcon")
400
639
self.pic = gtk.Image()
401
640
self.tooltip.set_tip(self.eb, "Initializing wicd...")
402
self.pic.set_from_file("images/no-signal.png")
641
self.pic.set_from_file(wpath.images + "no-signal.png")
404
643
self.eb.connect('button_press_event', self.tray_clicked)
405
644
self.eb.add(self.pic)
406
645
self.tray.add(self.eb)
407
646
self.tray.show_all()
409
648
def tray_clicked(self, widget, event):
410
649
""" Handles tray mouse click events. """
411
650
if event.button == 1:
412
651
self.toggle_wicd_gui()
413
652
elif event.button == 3:
653
self.init_network_menu()
414
654
self.menu.popup(None, None, None, event.button, event.time)
416
656
def set_from_file(self, val=None):
417
657
""" Calls set_from_file on the gtk.Image for the tray icon. """
418
if not self.use_tray: return
419
658
self.pic.set_from_file(val)
421
660
def set_tooltip(self, val):
422
661
""" Set the tooltip for this tray icon.
424
663
Sets the tooltip for the gtk.ToolTips associated with this
428
if not self.use_tray: return
429
667
self.tooltip.set_tip(self.eb, val)
431
670
if hasattr(gtk, "StatusIcon"):
432
671
class StatusTrayIconGUI(gtk.StatusIcon, TrayIconGUI):
433
672
""" Class for creating the wicd tray icon on gtk > 2.10.
435
674
Uses gtk.StatusIcon to implement a tray icon.
438
def __init__(self, use_tray=True):
439
TrayIcon.TrayIconGUI.__init__(self, use_tray)
440
self.use_tray = use_tray
442
self.toggle_wicd_gui()
678
TrayIcon.TrayIconGUI.__init__(self)
445
679
gtk.StatusIcon.__init__(self)
447
681
self.current_icon_path = ''
448
682
self.set_visible(True)
449
683
self.connect('activate', self.on_activate)
450
684
self.connect('popup-menu', self.on_popup_menu)
451
685
self.set_from_file(wpath.images + "no-signal.png")
452
686
self.set_tooltip("Initializing wicd...")
454
688
def on_popup_menu(self, status, button, timestamp):
455
689
""" Opens the right click menu for the tray icon. """
690
self.init_network_menu()
456
691
self.menu.popup(None, None, None, button, timestamp)
458
def set_from_file(self, path = None):
693
def set_from_file(self, path=None):
459
694
""" Sets a new tray icon picture. """
460
if not self.use_tray: return
461
695
if path != self.current_icon_path:
462
696
self.current_icon_path = path
463
697
gtk.StatusIcon.set_from_file(self, path)
468
701
""" Print usage information. """
471
704
wireless (and wired) connection daemon front-end.
474
707
\t-n\t--no-tray\tRun wicd without the tray icon.
475
708
\t-h\t--help\t\tPrint this help information.
476
709
\t-a\t--no-animate\tRun the tray without network traffic tray animations.
479
def connect_to_dbus():
480
global bus, daemon, wireless, wired, config
481
# Connect to the daemon
482
bus = dbus.SystemBus()
712
def setup_dbus(force=True):
713
global daemon, wireless, wired, DBUS_AVAIL, lost_dbus_id
714
print "Connecting to daemon..."
484
print 'Attempting to connect tray to daemon...'
485
proxy_obj = bus.get_object('org.wicd.daemon', '/org/wicd/daemon')
487
except dbus.DBusException:
488
print "Can't connect to the daemon, trying to start it automatically..."
489
misc.PromptToStartDaemon()
491
print 'Attempting to connect tray to daemon...'
492
proxy_obj = bus.get_object('org.wicd.daemon', '/org/wicd/daemon')
494
except dbus.DBusException:
495
gui.error(None, "Could not connect to wicd's D-Bus interface. " +
496
"Make sure the daemon is started.")
499
daemon = dbus.Interface(proxy_obj, 'org.wicd.daemon')
500
wireless = dbus.Interface(proxy_obj, 'org.wicd.daemon.wireless')
501
wired = dbus.Interface(proxy_obj, 'org.wicd.daemon.wired')
502
config = dbus.Interface(proxy_obj, 'org.wicd.daemon.config')
716
dbusmanager.connect_to_dbus()
717
except DBusException:
719
print "Can't connect to the daemon, trying to start it automatically..."
720
misc.PromptToStartDaemon()
722
dbusmanager.connect_to_dbus()
723
except DBusException:
724
error(None, "Could not connect to wicd's D-Bus interface. " +
725
"Check the wicd log for error messages.")
731
gobject.source_remove(lost_dbus_id)
733
dbus_ifaces = dbusmanager.get_dbus_ifaces()
734
daemon = dbus_ifaces['daemon']
735
wireless = dbus_ifaces['wireless']
736
wired = dbus_ifaces['wired']
744
daemon.SetGUIOpen(False)
745
except DBusException:
748
def handle_no_dbus():
749
""" Called when dbus announces its shutting down. """
750
global DBUS_AVAIL, lost_dbus_id
752
gui.handle_no_dbus(from_tray=True)
753
print "Wicd daemon is shutting down!"
754
lost_dbus_id = misc.timeout_add(5, lambda:error(None, language['lost_dbus'],
506
760
""" The main frontend program.
535
788
print 'Loading...'
790
atexit.register(on_exit)
538
792
if not use_tray or not ICON_AVAIL:
539
the_gui = gui.appGui()
540
the_gui.standalone = True
793
the_gui = gui.appGui(standalone=True)
541
794
mainloop = gobject.MainLoop()
545
798
# Set up the tray icon GUI and backend
546
tray_icon = TrayIcon(use_tray, animate)
799
tray_icon = TrayIcon(animate)
548
801
# Check to see if wired profile chooser was called before icon
549
802
# was launched (typically happens on startup or daemon restart).
550
if daemon.GetNeedWiredProfileChooser():
803
if DBUS_AVAIL and daemon.GetNeedWiredProfileChooser():
551
804
daemon.SetNeedWiredProfileChooser(False)
552
805
tray_icon.icon_info.wired_profile_chooser()
807
bus = dbusmanager.get_bus()
554
808
bus.add_signal_receiver(tray_icon.icon_info.wired_profile_chooser,
555
809
'LaunchChooser', 'org.wicd.daemon')
557
810
bus.add_signal_receiver(tray_icon.icon_info.update_tray_icon,
558
811
'StatusChanged', 'org.wicd.daemon')
812
bus.add_signal_receiver(tray_icon.tr.tray_scan_ended, 'SendEndScanSignal',
813
'org.wicd.daemon.wireless')
814
bus.add_signal_receiver(tray_icon.tr.tray_scan_started,
815
'SendStartScanSignal', 'org.wicd.daemon.wireless')
816
bus.add_signal_receiver(lambda: (handle_no_dbus() or
817
tray_icon.icon_info.set_not_connected_state()),
818
"DaemonClosing", 'org.wicd.daemon')
819
bus.add_signal_receiver(lambda: setup_dbus(force=False), "DaemonStarting",
821
print 'Done loading.'
560
822
mainloop = gobject.MainLoop()