~ubuntu-branches/ubuntu/wily/wicd/wily

« back to all changes in this revision

Viewing changes to wicd/wicd-client.py

  • Committer: Bazaar Package Importer
  • Author(s): David Paleino
  • Date: 2009-06-22 17:59:27 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20090622175927-iax3alden0bmj6zg
Tags: 1.6.1-3
* debian/config, debian/templates updated:
  - only show users to add to netdev, skip those who are already
    members (Closes: #534138)
  - gracefully handle upgrades from previous broken versions, where
    debconf set a value of ${default} for wicd/users
    (Closes: #532112)

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
    class StatusTrayIconGUI() -- Implements the tray icon using a 
15
15
                                 gtk.StatusIcon.
16
16
    class EggTrayIconGUI() -- Implements the tray icon using egg.trayicon.
17
 
def usage() -- Prints usage information.
18
 
def main() -- Runs the wicd frontend main loop.
19
17
 
20
18
"""
21
19
 
22
20
#
23
 
#   Copyright (C) 2007 - 2008 Adam Blackburn
24
 
#   Copyright (C) 2007 - 2008 Dan O'Reilly
 
21
#   Copyright (C) 2007 - 2009 Adam Blackburn
 
22
#   Copyright (C) 2007 - 2009 Dan O'Reilly
25
23
#
26
24
#   This program is free software; you can redistribute it and/or modify
27
25
#   it under the terms of the GNU General Public License Version 2 as
39
37
import sys
40
38
import gtk
41
39
import gobject
42
 
import dbus
43
 
import dbus.service
44
40
import getopt
45
41
import os
 
42
import pango
 
43
import atexit
 
44
from dbus import DBusException
 
45
 
 
46
import pygtk
 
47
pygtk.require('2.0')
 
48
 
 
49
HAS_NOTIFY = True
 
50
try:
 
51
    import pynotify
 
52
    if not pynotify.init("Wicd"):
 
53
        HAS_NOTIFY = False
 
54
except ImportError:
 
55
    HAS_NOTIFY = False
46
56
 
47
57
# Wicd specific imports
48
 
import wicd.wpath as wpath
49
 
import wicd.misc as misc
50
 
import wicd.gui as gui
 
58
from wicd import wpath
 
59
from wicd import misc
 
60
from wicd import gui
 
61
from wicd import dbusmanager
 
62
from wicd.guiutil import error, can_use_notify
 
63
 
 
64
from wicd.translations import language
51
65
 
52
66
ICON_AVAIL = True
53
67
USE_EGG = False
57
71
        import egg.trayicon
58
72
        USE_EGG = True
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.'
61
75
        ICON_AVAIL = False
62
76
 
63
 
if getattr(dbus, 'version', (0, 0, 0)) < (0, 80, 0):
64
 
    import dbus.glib
65
 
else:
66
 
    from dbus.mainloop.glib import DBusGMainLoop
67
 
    DBusGMainLoop(set_as_default=True)
68
 
 
69
77
misc.RenameProcess("wicd-client")
70
78
 
71
79
if __name__ == '__main__':
72
80
    wpath.chdir(__file__)
73
 
 
74
 
bus = None
75
 
daemon = None
76
 
wireless = None
77
 
wired = None
78
 
wired = None
79
 
config = None
80
 
 
81
 
_ = misc.get_gettext()
82
 
language = {}
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')
89
 
 
 
81
    
 
82
daemon = wireless = wired = lost_dbus_id = None
 
83
DBUS_AVAIL = False
 
84
 
 
85
def catchdbus(func):
 
86
    def wrapper(*args, **kwargs):
 
87
        try:
 
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'])
 
92
                #raise
 
93
                raise DBusException(e)
 
94
            else:
 
95
                print "warning: ignoring exception %s" % e
 
96
            return None
 
97
    wrapper.__name__ = func.__name__
 
98
    wrapper.__module__ = func.__module__
 
99
    wrapper.__dict__ = func.__dict__
 
100
    wrapper.__doc__ = func.__doc__
 
101
    return wrapper
 
102
            
 
103
 
 
104
class NetworkMenuItem(gtk.ImageMenuItem):
 
105
    def __init__(self, lbl, is_active=False):
 
106
        gtk.ImageMenuItem.__init__(self)
 
107
        self.label = gtk.Label(lbl)
 
108
        if is_active:
 
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)
 
114
        self.add(self.label)
 
115
        self.label.show()
 
116
        
90
117
 
91
118
class TrayIcon(object):
92
119
    """ Base Tray Icon class.
94
121
    Base Class for implementing a tray icon to display network status.
95
122
    
96
123
    """
97
 
    def __init__(self, use_tray, animate):
 
124
    def __init__(self, animate):
98
125
        if USE_EGG:
99
 
            self.tr = self.EggTrayIconGUI(use_tray)
 
126
            self.tr = self.EggTrayIconGUI()
100
127
        else:
101
 
            self.tr = self.StatusTrayIconGUI(use_tray)
102
 
        self.icon_info = self.TrayConnectionInfo(self.tr, use_tray, animate)
 
128
            self.tr = self.StatusTrayIconGUI()
 
129
        self.icon_info = self.TrayConnectionInfo(self.tr, animate)
 
130
        self.tr.icon_info = self.icon_info
103
131
        
104
132
    def is_embedded(self):
105
133
        if USE_EGG:
106
 
            raise NotImplementedError
 
134
            raise NotImplementedError()
107
135
        else:
108
136
            return self.tr.is_embedded()
109
 
        
 
137
    
110
138
 
111
139
    class TrayConnectionInfo(object):
112
140
        """ Class for updating the tray icon status. """
113
 
        def __init__(self, tr, use_tray=True, animate=True):
 
141
        def __init__(self, tr, animate=True):
114
142
            """ Initialize variables needed for the icon status methods. """
115
143
            self.last_strength = -2
116
144
            self.still_wired = False
118
146
            self.tried_reconnect = False
119
147
            self.connection_lost_counter = 0
120
148
            self.tr = tr
121
 
            self.use_tray = use_tray
122
149
            self.last_sndbytes = -1
123
150
            self.last_rcvbytes = -1
124
151
            self.max_snd_gain = 10000
125
152
            self.max_rcv_gain = 10000
126
153
            self.animate = animate
127
 
            self.update_tray_icon()
128
 
 
 
154
 
 
155
            # keep track of the last state to provide appropriate
 
156
            # notifications
 
157
            self._last_bubble = None
 
158
            self.last_state = None
 
159
            self.should_notify = True
 
160
 
 
161
            if DBUS_AVAIL:
 
162
                self.update_tray_icon()
 
163
            else:
 
164
                handle_no_dbus()
 
165
                self.set_not_connected_state()
 
166
 
 
167
        def _show_notification(self, title, details, image=None):
 
168
            if self.should_notify:
 
169
                if not self._last_bubble:
 
170
                    self._last_bubble = pynotify.Notification(title, details,
 
171
                                                              image)
 
172
                    self._last_bubble.show()
 
173
                else:
 
174
                    self._last_bubble.clear_actions()
 
175
                    self._last_bubble.clear_hints()
 
176
                    self._last_bubble.update(title, details, image)
 
177
                    self._last_bubble.show()
 
178
 
 
179
                self.should_notify = False
 
180
 
 
181
        @catchdbus
129
182
        def wired_profile_chooser(self):
130
183
            """ Launch the wired profile chooser. """
131
184
            gui.WiredProfileChooser()
134
187
        def set_wired_state(self, info):
135
188
            """ Sets the icon info for a wired state. """
136
189
            wired_ip = info[0]
137
 
            self.tr.set_from_file(wpath.images + "wired.png")
138
 
            self.tr.set_tooltip(language['connected_to_wired'].replace('$A',
139
 
                                                                     wired_ip))
 
190
            self.tr.set_from_file(os.path.join(wpath.images, "wired.png"))
 
191
            status_string = language['connected_to_wired'].replace('$A',
 
192
                                                                     wired_ip)
 
193
            self.tr.set_tooltip(status_string)
 
194
            self._show_notification(language['wired_network'],
 
195
                                    language['connection_established'],
 
196
                                    'network-wired')
140
197
            
 
198
        @catchdbus
141
199
        def set_wireless_state(self, info):
142
200
            """ Sets the icon info for a wireless state. """
143
201
            lock = ''
149
207
            
150
208
            if wireless.GetWirelessProperty(cur_net_id, "encryption"):
151
209
                lock = "-lock"
152
 
                
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'],
 
218
                                    'network-wireless')
 
219
            
158
220
            
159
221
        def set_connecting_state(self, info):
160
222
            """ Sets the icon info for a connecting state. """
 
223
            wired = False
161
224
            if info[0] == 'wired' and len(info) == 1:
162
 
                cur_network = language['wired']
 
225
                cur_network = language['wired_network']
 
226
                wired = True
163
227
            else:
164
228
                cur_network = info[1]
165
 
            self.tr.set_tooltip(language['connecting'] + " to " + 
166
 
                                cur_network + "...")
167
 
            self.tr.set_from_file(wpath.images + "no-signal.png")  
 
229
            status_string = language['connecting'] + " to " + \
 
230
                                cur_network + "..."
 
231
            self.tr.set_tooltip(status_string)
 
232
            self.tr.set_from_file(os.path.join(wpath.images, "no-signal.png"))
 
233
            if wired:
 
234
                self._show_notification(cur_network,
 
235
                                    language['establishing_connection'],
 
236
                                        'network-wired')
 
237
            else:
 
238
                self._show_notification(cur_network,
 
239
                                        language['establishing_connection'],
 
240
                                        'network-wireless')
 
241
 
168
242
            
169
 
        def set_not_connected_state(self, info):
 
243
        @catchdbus
 
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():
 
247
            if not DBUS_AVAIL:
 
248
                status = language['no_daemon_tooltip']
 
249
            elif wireless.GetKillSwitchEnabled():
173
250
                status = (language['not_connected'] + " (" + 
174
251
                         language['killswitch_enabled'] + ")")
175
252
            else:
176
253
                status = language['not_connected']
177
254
            self.tr.set_tooltip(status)
 
255
            self._show_notification(language['disconnected'], None, 'stop')
178
256
 
 
257
        @catchdbus
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
182
261
 
183
262
            if not state or not info:
184
263
                [state, info] = daemon.GetConnectionStatus()
 
264
 
 
265
            # should this state change display a notification?
 
266
            self.should_notify = (can_use_notify() and 
 
267
                                  self.last_state != state)
 
268
 
 
269
            self.last_state = state
185
270
            
186
271
            if state == misc.WIRED:
187
272
                self.set_wired_state(info)
196
281
                return False
197
282
            return True
198
283
 
 
284
        @catchdbus
199
285
        def set_signal_image(self, wireless_signal, lock):
200
286
            """ Sets the tray icon image for an active wireless connection. """
201
287
            if self.animate:
202
288
                prefix = self.get_bandwidth_state()
203
289
            else:
204
 
                prefix = ''
 
290
                prefix = 'idle-'
205
291
            if daemon.GetSignalDisplayType() == 0:
206
292
                if wireless_signal > 75:
207
293
                    signal_img = "high-signal"
223
309
 
224
310
            img_file = ''.join([wpath.images, prefix, signal_img, lock, ".png"])
225
311
            self.tr.set_from_file(img_file)
226
 
            
 
312
        
 
313
        @catchdbus
227
314
        def get_bandwidth_state(self):
228
315
            """ Determines what network activity state we are in. """
229
316
            transmitting = False
303
390
        tray icons.
304
391
 
305
392
        """
306
 
        def __init__(self, use_tray):
 
393
        def __init__(self):
307
394
            menu = """
308
395
                    <ui>
309
 
                    <menubar name="Menubar">
310
 
                    <menu action="Menu">
311
 
                    <menuitem action="Connect"/>
312
 
                    <separator/>
313
 
                    <menuitem action="About"/>
314
 
                    <menuitem action="Quit"/>
315
 
                    </menu>
316
 
                    </menubar>
 
396
                        <menubar name="Menubar">
 
397
                            <menu action="Menu">
 
398
                                <menu action="Connect">
 
399
                                </menu>
 
400
                                <separator/>
 
401
                                <menuitem action="About"/>
 
402
                                <menuitem action="Quit"/>
 
403
                            </menu>
 
404
                        </menubar>
317
405
                    </ui>
318
406
            """
319
407
            actions = [
320
408
                    ('Menu',  None, 'Menu'),
321
 
                    ('Connect', gtk.STOCK_CONNECT, '_Connect...', None,
322
 
                     'Connect to network', self.on_preferences),
 
409
                    ('Connect', gtk.STOCK_CONNECT, "Connect"),
323
410
                    ('About', gtk.STOCK_ABOUT, '_About...', None,
324
411
                     'About wicd-tray-icon', self.on_about),
325
412
                    ('Quit',gtk.STOCK_QUIT,'_Quit',None,'Quit wicd-tray-icon',
334
421
                                                                  props.parent)
335
422
            self.gui_win = None
336
423
            self.current_icon_path = None
337
 
            self.use_tray = use_tray
338
 
 
 
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)
 
427
            
 
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()
 
433
            
 
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()
 
439
                
339
440
        def on_activate(self, data=None):
340
441
            """ Opens the wicd GUI. """
341
 
            self.toggle_wicd_gui()
 
442
            if DBUS_AVAIL:
 
443
                self.toggle_wicd_gui()
 
444
            else:
 
445
                # error(None, language["daemon_unavailable"])
 
446
                pass
342
447
 
343
448
        def on_quit(self, widget=None):
344
449
            """ Closes the tray icon. """
345
450
            sys.exit(0)
346
451
 
347
 
        def on_preferences(self, data=None):
348
 
            """ Opens the wicd GUI. """
349
 
            self.toggle_wicd_gui()
350
 
 
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')
355
 
            # VERSIONNUMBER
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')
359
459
            dialog.run()
360
460
            dialog.destroy()
361
 
 
 
461
        
 
462
        def _add_item_to_menu(self, net_menu, lbl, type_, n_id, is_connecting, 
 
463
                              is_active):
 
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__":
 
468
                    wired.ConnectWired()
 
469
                else:
 
470
                    wireless.ConnectWireless(net_id)
 
471
                    
 
472
            item = NetworkMenuItem(lbl, is_active)
 
473
            image = gtk.Image()
 
474
            
 
475
            if type_ == "__wired__":
 
476
                image.set_from_icon_name("network-wired", 2)
 
477
            else:
 
478
                pb = gtk.gdk.pixbuf_new_from_file_at_size(self._get_img(n_id),
 
479
                                                          20, 20)
 
480
                image.set_from_pixbuf(pb)
 
481
                del pb
 
482
            item.set_image(image)
 
483
            del image
 
484
            item.connect("activate", network_selected, type_, n_id)
 
485
            net_menu.append(item)
 
486
            item.show()
 
487
            if is_connecting:
 
488
                item.set_sensitive(False)  
 
489
            del item
 
490
                
 
491
        @catchdbus
 
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
 
497
            
 
498
            def get_prop(prop):
 
499
                return wireless.GetWirelessProperty(net_id, prop)
 
500
            
 
501
            strength = fix_strength(get_prop("quality"), -1)
 
502
            dbm_strength = fix_strength(get_prop('strength'), -100)
 
503
 
 
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'
 
512
                else:
 
513
                    signal_img = 'signal-25.png'
 
514
            else:
 
515
                if strength > 75:
 
516
                    signal_img = 'signal-100.png'
 
517
                elif strength > 50:
 
518
                    signal_img = 'signal-75.png'
 
519
                elif strength > 25:
 
520
                    signal_img = 'signal-50.png'
 
521
                else:
 
522
                    signal_img = 'signal-25.png'
 
523
            return wpath.images + signal_img
 
524
            
 
525
        def on_net_menu_activate(self, item):
 
526
            """ Trigger a background scan to populate the network menu. 
 
527
            
 
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.
 
531
            
 
532
            """
 
533
            if self._is_scanning:
 
534
                return True
 
535
            
 
536
            self.init_network_menu()
 
537
            gobject.timeout_add(800, self._trigger_scan_if_needed, item)
 
538
            
 
539
        @catchdbus
 
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():
 
543
                gtk.main_iteration()
 
544
            if item.state != gtk.STATE_PRELIGHT:
 
545
                return False
 
546
            wireless.Scan(False)
 
547
            return False
 
548
        
 
549
        @catchdbus
 
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)
 
554
 
 
555
            net_menuitem = self.manager.get_widget("/Menubar/Menu/Connect/")
 
556
            submenu = net_menuitem.get_submenu()
 
557
            self._clear_menu(submenu)
 
558
            if not DBUS_AVAIL:
 
559
                net_menuitem.show()
 
560
                return
 
561
 
 
562
            is_connecting = daemon.CheckIfConnecting()
 
563
            num_networks = wireless.GetNumberOfNetworks()
 
564
            [status, info] = daemon.GetConnectionStatus()
 
565
                
 
566
            if daemon.GetAlwaysShowWiredInterface() or \
 
567
               wired.CheckPluggedIn():
 
568
                if status == misc.WIRED:
 
569
                    is_active = True
 
570
                else:
 
571
                    is_active = False
 
572
                self._add_item_to_menu(submenu, "Wired Network", "__wired__", 0,
 
573
                                       is_connecting, is_active)
 
574
                sep = gtk.SeparatorMenuItem()
 
575
                submenu.append(sep)
 
576
                sep.show()
 
577
            
 
578
            if num_networks > 0:
 
579
                for x in range(0, num_networks):
 
580
                    essid = get_prop(x, "essid")
 
581
                    if status == misc.WIRELESS and info[1] == essid:
 
582
                        is_active = True
 
583
                    else:
 
584
                        is_active = False
 
585
                    self._add_item_to_menu(submenu, essid, "wifi", x,
 
586
                                           is_connecting, is_active)
 
587
            else:
 
588
                no_nets_item = gtk.MenuItem(language['no_wireless_networks_found'])
 
589
                no_nets_item.set_sensitive(False)
 
590
                no_nets_item.show()
 
591
                submenu.append(no_nets_item)
 
592
                    
 
593
            net_menuitem.show()
 
594
        
 
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)
 
600
 
 
601
            loading_item = gtk.MenuItem(language['scanning'] + "...")
 
602
            loading_item.set_sensitive(False)
 
603
            loading_item.show()
 
604
            submenu.append(loading_item)
 
605
            net_menuitem.show()
 
606
            
 
607
        def _clear_menu(self, menu):
 
608
            """ Clear the right-click menu. """
 
609
            for item in menu.get_children():
 
610
                menu.remove(item)
 
611
                item.destroy()
 
612
            
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,
367
 
                                        'SendEndScanSignal',
368
 
                                        'org.wicd.daemon')
369
 
                bus.add_signal_receiver(self.gui_win.dbus_scan_started,
370
 
                                        'SendStartScanSignal',
371
 
                                        'org.wicd.daemon')
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()
376
619
            else:
377
620
                self.gui_win.exit()
378
621
                return True
379
 
        
 
622
    
 
623
 
380
624
    if USE_EGG:
381
625
        class EggTrayIconGUI(TrayIconGUI):
382
626
            """ Tray Icon for gtk < 2.10.
386
630
            for machines running versions of GTK < 2.10.
387
631
            
388
632
            """
389
 
            def __init__(self, use_tray=True):
 
633
            def __init__(self):
390
634
                """Initializes the tray icon"""
391
 
                TrayIcon.TrayIconGUI.__init__(self, use_tray)
392
 
                self.use_tray = use_tray
393
 
                if not use_tray: 
394
 
                    self.toggle_wicd_gui()
395
 
                    return
396
 
    
 
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")
403
 
    
 
641
                self.pic.set_from_file(wpath.images + "no-signal.png")
 
642
 
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()
408
 
    
 
647
 
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)
415
 
    
 
655
 
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)
420
 
    
 
659
 
421
660
            def set_tooltip(self, val):
422
661
                """ Set the tooltip for this tray icon.
423
662
                
424
663
                Sets the tooltip for the gtk.ToolTips associated with this
425
664
                tray icon.
426
 
    
 
665
 
427
666
                """
428
 
                if not self.use_tray: return
429
667
                self.tooltip.set_tip(self.eb, val)
430
668
 
 
669
 
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.
436
675
            
437
676
            """
438
 
            def __init__(self, use_tray=True):
439
 
                TrayIcon.TrayIconGUI.__init__(self, use_tray)
440
 
                self.use_tray = use_tray
441
 
                if not use_tray: 
442
 
                    self.toggle_wicd_gui()
443
 
                    return
444
 
    
 
677
            def __init__(self):
 
678
                TrayIcon.TrayIconGUI.__init__(self)
445
679
                gtk.StatusIcon.__init__(self)
446
 
    
 
680
 
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...")
453
 
    
 
687
 
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)
457
 
    
458
 
            def set_from_file(self, path = None):
 
692
 
 
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)
464
698
 
465
699
 
466
700
def usage():
467
 
    # VERSIONNUMBER
468
701
    """ Print usage information. """
469
702
    print """
470
 
wicd 1.5.9
 
703
wicd %s 
471
704
wireless (and wired) connection daemon front-end.
472
705
 
473
706
Arguments:
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.
477
 
"""
478
 
    
479
 
def connect_to_dbus():
480
 
    global bus, daemon, wireless, wired, config
481
 
    # Connect to the daemon
482
 
    bus = dbus.SystemBus()
 
710
""" % wpath.version
 
711
 
 
712
def setup_dbus(force=True):
 
713
    global daemon, wireless, wired, DBUS_AVAIL, lost_dbus_id
 
714
    print "Connecting to daemon..."
483
715
    try:
484
 
        print 'Attempting to connect tray to daemon...'
485
 
        proxy_obj = bus.get_object('org.wicd.daemon', '/org/wicd/daemon')
486
 
        print 'Success.'
487
 
    except dbus.DBusException:
488
 
        print "Can't connect to the daemon, trying to start it automatically..."
489
 
        misc.PromptToStartDaemon()
490
 
        try:
491
 
            print 'Attempting to connect tray to daemon...'
492
 
            proxy_obj = bus.get_object('org.wicd.daemon', '/org/wicd/daemon')
493
 
            print 'Success.'
494
 
        except dbus.DBusException:
495
 
            gui.error(None, "Could not connect to wicd's D-Bus interface.  " +
496
 
                      "Make sure the daemon is started.")
497
 
            sys.exit(1)
498
 
    
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:
 
718
        if force:
 
719
            print "Can't connect to the daemon, trying to start it automatically..."
 
720
            misc.PromptToStartDaemon()
 
721
            try:
 
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.")
 
726
                return False
 
727
        else:  
 
728
            return False
 
729
                
 
730
    if lost_dbus_id:
 
731
        gobject.source_remove(lost_dbus_id)
 
732
        lost_dbus_id = None
 
733
    dbus_ifaces = dbusmanager.get_dbus_ifaces()
 
734
    daemon = dbus_ifaces['daemon']
 
735
    wireless = dbus_ifaces['wireless']
 
736
    wired = dbus_ifaces['wired']
 
737
    DBUS_AVAIL = True
 
738
    print "Connected."
503
739
    return True
504
740
 
 
741
def on_exit():
 
742
    if DBUS_AVAIL:
 
743
        try:
 
744
            daemon.SetGUIOpen(False)
 
745
        except DBusException:
 
746
            pass
 
747
 
 
748
def handle_no_dbus():
 
749
    """ Called when dbus announces its shutting down. """
 
750
    global DBUS_AVAIL, lost_dbus_id
 
751
    DBUS_AVAIL = False
 
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'], 
 
755
                                                    block=False))
 
756
    return False
 
757
 
 
758
@catchdbus
505
759
def main(argv):
506
760
    """ The main frontend program.
507
761
 
509
763
    argv -- The arguments passed to the script.
510
764
 
511
765
    """
512
 
    use_tray = True
513
 
    animate = True
514
 
 
515
766
    try:
516
767
        opts, args = getopt.getopt(sys.argv[1:], 'nha', ['help', 'no-tray',
517
768
                                                         'no-animate'])
520
771
        usage()
521
772
        sys.exit(2)
522
773
 
 
774
    use_tray = True
 
775
    animate = True
523
776
    for opt, a in opts:
524
777
        if opt in ('-h', '--help'):
525
778
            usage()
533
786
            sys.exit(2)
534
787
    
535
788
    print 'Loading...'
536
 
    connect_to_dbus()
537
 
 
 
789
    setup_dbus()
 
790
    atexit.register(on_exit)
 
791
    
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()
542
795
        mainloop.run()
543
796
        sys.exit(0)
544
797
 
545
798
    # Set up the tray icon GUI and backend
546
 
    tray_icon = TrayIcon(use_tray, animate)
 
799
    tray_icon = TrayIcon(animate)
547
800
 
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()
553
 
 
 
806
        
 
807
    bus = dbusmanager.get_bus()
554
808
    bus.add_signal_receiver(tray_icon.icon_info.wired_profile_chooser,
555
809
                            'LaunchChooser', 'org.wicd.daemon')
556
 
 
557
810
    bus.add_signal_receiver(tray_icon.icon_info.update_tray_icon,
558
811
                            'StatusChanged', 'org.wicd.daemon')
559
 
    print 'Done.'
 
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",
 
820
                            "org.wicd.daemon")
 
821
    print 'Done loading.'
560
822
    mainloop = gobject.MainLoop()
561
823
    mainloop.run()
562
824