~wicd-devel/wicd/verypluggablebackends

« back to all changes in this revision

Viewing changes to wicd/wicd-client.py

  • Committer: Adam Blackburn
  • Date: 2008-12-17 13:51:45 UTC
  • Revision ID: compwiz18@gmail.com-20081217135145-17mwsb0ni8rk405z
Added a network-manager style tray icon (only wireless network support for now)
Add more methods to the wireless interface

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!/usr/bin/env python
2
 
 
3
 
""" wicd - wireless connection daemon frontend implementation
4
 
 
5
 
This module implements a usermode frontend for wicd.  It updates connection
6
 
information, provides an (optional) tray icon, and allows for launching of 
7
 
the wicd GUI and Wired Profile Chooser.
8
 
 
9
 
class TrayIcon() -- Parent class of TrayIconGUI and IconConnectionInfo.
10
 
    class TrayConnectionInfo() -- Child class of TrayIcon which provides
11
 
        and updates connection status.
12
 
    class TrayIconGUI() -- Child class of TrayIcon which implements the tray.
13
 
        icon itself.  Parent class of StatusTrayIconGUI and EggTrayIconGUI.
14
 
    class StatusTrayIconGUI() -- Implements the tray icon using a 
15
 
                                 gtk.StatusIcon.
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
 
 
20
 
"""
21
 
 
22
 
#
23
 
#   Copyright (C) 2007 - 2008 Adam Blackburn
24
 
#   Copyright (C) 2007 - 2008 Dan O'Reilly
25
 
#
26
 
#   This program is free software; you can redistribute it and/or modify
27
 
#   it under the terms of the GNU General Public License Version 2 as
28
 
#   published by the Free Software Foundation.
29
 
#
30
 
#   This program is distributed in the hope that it will be useful,
31
 
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
32
 
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
33
 
#   GNU General Public License for more details.
34
 
#
35
 
#   You should have received a copy of the GNU General Public License
36
 
#   along with this program.  If not, see <http://www.gnu.org/licenses/>.
37
 
#
38
 
 
39
 
import sys
40
 
import gtk
41
 
import gobject
42
 
import getopt
43
 
import os
44
 
import pango
45
 
import time
46
 
from dbus import DBusException
47
 
from dbus import version as dbus_version
48
 
 
49
 
# Wicd specific imports
50
 
from wicd import wpath
51
 
from wicd import misc
52
 
from wicd import gui
53
 
from wicd.dbusmanager import DBusManager
54
 
import logging
55
 
 
56
 
# Import egg.trayicon if we're using an older gtk version
57
 
if not (gtk.gtk_version[0] >= 2 and gtk.gtk_version[1] >= 10):
58
 
    try:
59
 
        import egg.trayicon
60
 
        USE_EGG = True
61
 
    except ImportError:
62
 
        logging.debug( 'Unable to load wicd.py: Missing egg.trayicon module.' )
63
 
        sys.exit(1)
64
 
else:
65
 
    USE_EGG = False
66
 
 
67
 
if not dbus_version or (dbus_version < (0, 80, 0)):
68
 
    import dbus.glib
69
 
else:
70
 
    from dbus.mainloop.glib import DBusGMainLoop
71
 
    DBusGMainLoop(set_as_default=True)
72
 
 
73
 
misc.RenameProcess("wicd-client")
74
 
 
75
 
if __name__ == '__main__':
76
 
    wpath.chdir(__file__)
77
 
 
78
 
dbus_manager = None
79
 
daemon = None
80
 
wireless = None
81
 
wired = None
82
 
wired = None
83
 
 
84
 
language = misc.get_language_list_tray()
85
 
 
86
 
class NetworkMenuItem(gtk.ImageMenuItem):
87
 
    def __init__(self, lbl, is_active=False):
88
 
        gtk.ImageMenuItem.__init__(self)
89
 
        self.label = gtk.Label(lbl)
90
 
        if is_active:
91
 
            atrlist = pango.AttrList()
92
 
            atrlist.insert(pango.AttrWeight(pango.WEIGHT_BOLD, 0, 50))
93
 
            self.label.set_attributes(atrlist)
94
 
        self.label.set_justify(gtk.JUSTIFY_LEFT)
95
 
        self.label.set_alignment(0, 0)
96
 
        self.add(self.label)
97
 
        self.label.show()
98
 
        
99
 
 
100
 
class TrayIcon:
101
 
    """ Base Tray Icon class.
102
 
    
103
 
    Base Class for implementing a tray icon to display network status.
104
 
    
105
 
    """
106
 
    def __init__(self, use_tray, animate):
107
 
        if USE_EGG:
108
 
            self.tr = self.EggTrayIconGUI(use_tray)
109
 
        else:
110
 
            self.tr = self.StatusTrayIconGUI(use_tray)
111
 
        self.icon_info = self.TrayConnectionInfo(self.tr, use_tray, animate)
112
 
        
113
 
 
114
 
    class TrayConnectionInfo:
115
 
        """ Class for updating the tray icon status. """
116
 
        def __init__(self, tr, use_tray=True, animate=True):
117
 
            """ Initialize variables needed for the icon status methods. """
118
 
            self.last_strength = -2
119
 
            self.still_wired = False
120
 
            self.network = ''
121
 
            self.tried_reconnect = False
122
 
            self.connection_lost_counter = 0
123
 
            self.tr = tr
124
 
            self.use_tray = use_tray
125
 
            self.last_sndbytes = -1
126
 
            self.last_rcvbytes = -1
127
 
            self.max_snd_gain = 10000
128
 
            self.max_rcv_gain = 10000
129
 
            self.animate = animate
130
 
            self.update_tray_icon()
131
 
 
132
 
        def wired_profile_chooser(self):
133
 
            """ Launch the wired profile chooser. """
134
 
            gui.WiredProfileChooser()
135
 
            daemon.SetNeedWiredProfileChooser(False)
136
 
            
137
 
        def set_wired_state(self, info):
138
 
            """ Sets the icon info for a wired state. """
139
 
            wired_ip = info[0]
140
 
            self.tr.set_from_file(wpath.images + "wired.png")
141
 
            self.tr.set_tooltip(language['connected_to_wired'].replace('$A',
142
 
                                                                     wired_ip))
143
 
            
144
 
        def set_wireless_state(self, info):
145
 
            """ Sets the icon info for a wireless state. """
146
 
            lock = ''
147
 
            wireless_ip = info[0]
148
 
            self.network = info[1]
149
 
            strength = info[2]
150
 
            cur_net_id = int(info[3])
151
 
            sig_string = daemon.FormatSignalForPrinting(str(strength))
152
 
            
153
 
            if wireless.GetWirelessProperty(cur_net_id, "encryption"):
154
 
                lock = "-lock"
155
 
                
156
 
            self.tr.set_tooltip(language['connected_to_wireless']
157
 
                                .replace('$A', self.network)
158
 
                                .replace('$B', sig_string)
159
 
                                .replace('$C', str(wireless_ip)))
160
 
            self.set_signal_image(int(strength), lock)
161
 
            
162
 
        def set_connecting_state(self, info):
163
 
            """ Sets the icon info for a connecting state. """
164
 
            if info[0] == 'wired' and len(info) == 1:
165
 
                cur_network = language['wired']
166
 
            else:
167
 
                cur_network = info[1]
168
 
            self.tr.set_tooltip(language['connecting'] + " to " + 
169
 
                                cur_network + "...")
170
 
            self.tr.set_from_file(wpath.images + "no-signal.png")  
171
 
            
172
 
        def set_not_connected_state(self, info):
173
 
            """ Set the icon info for the not connected state. """
174
 
            self.tr.set_from_file(wpath.images + "no-signal.png")
175
 
            if wireless.GetKillSwitchEnabled():
176
 
                status = (language['not_connected'] + " (" + 
177
 
                         language['killswitch_enabled'] + ")")
178
 
            else:
179
 
                status = language['not_connected']
180
 
            self.tr.set_tooltip(status)
181
 
 
182
 
        def update_tray_icon(self, state=None, info=None):
183
 
            """ Updates the tray icon and current connection status. """
184
 
            if not self.use_tray: return False
185
 
 
186
 
            if not state or not info:
187
 
                [state, info] = daemon.GetConnectionStatus()
188
 
            
189
 
            if state == misc.WIRED:
190
 
                self.set_wired_state(info)
191
 
            elif state == misc.WIRELESS:
192
 
                self.set_wireless_state(info)
193
 
            elif state == misc.CONNECTING:
194
 
                self.set_connecting_state(info)
195
 
            elif state in (misc.SUSPENDED, misc.NOT_CONNECTED):
196
 
                self.set_not_connected_state(info)
197
 
            else:
198
 
                logging.debug( 'Invalid state returned!!!' )
199
 
                return False
200
 
            return True
201
 
 
202
 
        def set_signal_image(self, wireless_signal, lock):
203
 
            """ Sets the tray icon image for an active wireless connection. """
204
 
            if self.animate:
205
 
                prefix = self.get_bandwidth_state()
206
 
            else:
207
 
                prefix = 'idle-'
208
 
            if daemon.GetSignalDisplayType() == 0:
209
 
                if wireless_signal > 75:
210
 
                    signal_img = "high-signal"
211
 
                elif wireless_signal > 50:
212
 
                    signal_img = "good-signal"
213
 
                elif wireless_signal > 25:
214
 
                    signal_img = "low-signal"
215
 
                else:
216
 
                    signal_img = "bad-signal"
217
 
            else:
218
 
                if wireless_signal >= -60:
219
 
                    signal_img = "high-signal"
220
 
                elif wireless_signal >= -70:
221
 
                    signal_img = "good-signal"
222
 
                elif wireless_signal >= -80:
223
 
                    signal_img = "low-signal"
224
 
                else:
225
 
                    signal_img = "bad-signal"
226
 
 
227
 
            img_file = ''.join([wpath.images, prefix, signal_img, lock, ".png"])
228
 
            self.tr.set_from_file(img_file)
229
 
            
230
 
        def get_bandwidth_state(self):
231
 
            """ Determines what network activity state we are in. """
232
 
            transmitting = False
233
 
            receiving = False
234
 
                    
235
 
            dev_dir = '/sys/class/net/'
236
 
            wiface = daemon.GetWirelessInterface()
237
 
            for fldr in os.listdir(dev_dir):
238
 
                if fldr == wiface:
239
 
                    dev_dir = dev_dir + fldr + "/statistics/"
240
 
                    break
241
 
            try:
242
 
                rcvbytes = int(open(dev_dir + "rx_bytes", "r").read().strip())
243
 
                sndbytes = int(open(dev_dir + "tx_bytes", "r").read().strip())
244
 
            except IOError:
245
 
                sndbytes = None
246
 
                rcvbytes = None
247
 
                
248
 
            if not rcvbytes or not sndbytes:
249
 
                return 'idle-'
250
 
                    
251
 
            # Figure out receiving data info.
252
 
            activity = self.is_network_active(rcvbytes, self.max_rcv_gain,
253
 
                                              self.last_rcvbytes)
254
 
            receiving = activity[0]
255
 
            self.max_rcv_gain = activity[1]
256
 
            self.last_rcvbytes = activity[2]
257
 
                    
258
 
            # Figure out out transmitting data info.
259
 
            activity = self.is_network_active(sndbytes, self.max_snd_gain,
260
 
                                              self.last_sndbytes)
261
 
            transmitting = activity[0]
262
 
            self.max_snd_gain = activity[1]
263
 
            self.last_sndbytes = activity[2]
264
 
                    
265
 
            if transmitting and receiving:
266
 
                return 'both-'
267
 
            elif transmitting:
268
 
                return 'transmitting-'
269
 
            elif receiving:
270
 
                return 'receiving-'
271
 
            else:
272
 
                return 'idle-'
273
 
            
274
 
        def is_network_active(self, bytes, max_gain, last_bytes):
275
 
            """ Determines if a network is active.
276
 
            
277
 
            Determines if a network is active by looking at the
278
 
            number of bytes sent since the previous check.  This method
279
 
            is generic, and can be used to determine activity in both
280
 
            the sending and receiving directions.
281
 
            
282
 
            Returns:
283
 
            A tuple containing three elements:
284
 
            1) a boolean specifying if the network is active.
285
 
            2) an int specifying the maximum gain the network has had.
286
 
            3) an int specifying the last recorded number of bytes sent.
287
 
            
288
 
            """
289
 
            active = False
290
 
            if last_bytes == -1:
291
 
                last_bytes = bytes
292
 
            elif bytes > (last_bytes + float(max_gain / 20.0)):
293
 
                last_bytes = bytes
294
 
                active = True
295
 
                
296
 
                gain = bytes - last_bytes
297
 
                if gain > max_gain:
298
 
                    max_gain = gain
299
 
            return (active, max_gain, last_bytes)
300
 
 
301
 
 
302
 
    class TrayIconGUI(object):
303
 
        """ Base Tray Icon UI class.
304
 
        
305
 
        Implements methods and variables used by both egg/StatusIcon
306
 
        tray icons.
307
 
 
308
 
        """
309
 
        def __init__(self, use_tray):
310
 
            menu = """
311
 
                    <ui>
312
 
                        <menubar name="Menubar">
313
 
                            <menu action="Menu">
314
 
                                <menu action="Connect">
315
 
                                </menu>
316
 
                                <separator/>
317
 
                                <menuitem action="About"/>
318
 
                                <menuitem action="Quit"/>
319
 
                            </menu>
320
 
                        </menubar>
321
 
                    </ui>
322
 
            """
323
 
            actions = [
324
 
                    ('Menu',  None, 'Menu'),
325
 
                    ('Connect', gtk.STOCK_CONNECT, "Connect"),
326
 
                    ('About', gtk.STOCK_ABOUT, '_About...', None,
327
 
                     'About wicd-tray-icon', self.on_about),
328
 
                    ('Quit',gtk.STOCK_QUIT,'_Quit',None,'Quit wicd-tray-icon',
329
 
                     self.on_quit),
330
 
                    ]
331
 
            actg = gtk.ActionGroup('Actions')
332
 
            actg.add_actions(actions)
333
 
            self.manager = gtk.UIManager()
334
 
            self.manager.insert_action_group(actg, 0)
335
 
            self.manager.add_ui_from_string(menu)
336
 
            self.menu = (self.manager.get_widget('/Menubar/Menu/About').
337
 
                                                                  props.parent)
338
 
            self.gui_win = None
339
 
            self.current_icon_path = None
340
 
            self.use_tray = use_tray
341
 
            self._is_scanning = False
342
 
            net_menuitem = self.manager.get_widget("/Menubar/Menu/Connect/")
343
 
            net_menuitem.connect("activate", self.on_net_menu_activate)
344
 
            
345
 
        def tray_scan_started(self):
346
 
            """ Callback for when a wireless scan is started. """
347
 
            self._is_scanning = True
348
 
            self.init_network_menu()
349
 
            
350
 
        def tray_scan_ended(self):
351
 
            """ Callback for when a wireless scan finishes. """
352
 
            self._is_scanning = False
353
 
            self.populate_network_menu()
354
 
                
355
 
        def on_activate(self, data=None):
356
 
            """ Opens the wicd GUI. """
357
 
            self.toggle_wicd_gui()
358
 
 
359
 
        def on_quit(self, widget=None):
360
 
            """ Closes the tray icon. """
361
 
            sys.exit(0)
362
 
 
363
 
        def on_about(self, data=None):
364
 
            """ Opens the About Dialog. """
365
 
            dialog = gtk.AboutDialog()
366
 
            dialog.set_name('Wicd Tray Icon')
367
 
            dialog.set_version('2.0')
368
 
            dialog.set_comments('An icon that shows your network connectivity')
369
 
            dialog.set_website('http://wicd.net')
370
 
            dialog.run()
371
 
            dialog.destroy()
372
 
        
373
 
        def _add_item_to_menu(self, net_menu, lbl, type_, n_id, is_connecting, 
374
 
                              is_active):
375
 
            """ Add an item to the network list submenu. """
376
 
            def network_selected(widget, net_type, net_id):
377
 
                """ Callback method for a menu item selection. """
378
 
                if net_type == "__wired__":
379
 
                    wired.ConnectWired()
380
 
                else:
381
 
                    wireless.ConnectWireless(net_id)
382
 
                    
383
 
            item = NetworkMenuItem(lbl, is_active)
384
 
            image = gtk.Image()
385
 
            
386
 
            if type_ == "__wired__":
387
 
                image.set_from_icon_name("network-wired", 2)
388
 
            else:
389
 
                pb = gtk.gdk.pixbuf_new_from_file_at_size(self._get_img(n_id),
390
 
                                                          20, 20)
391
 
                image.set_from_pixbuf(pb)
392
 
                del pb
393
 
            item.set_image(image)
394
 
            del image
395
 
            item.connect("activate", network_selected, type_, n_id)
396
 
            net_menu.append(item)
397
 
            item.show()
398
 
            if is_connecting:
399
 
                item.set_sensitive(False)  
400
 
            del item
401
 
                
402
 
        def _get_img(self, net_id):
403
 
            """ Determines which image to use for the wireless entries. """
404
 
            def fix_strength(val, default):
405
 
                """ Assigns given strength to a default value if needed. """
406
 
                return val is not None and int(val) or default
407
 
            
408
 
            def get_prop(prop):
409
 
                return wireless.GetWirelessProperty(net_id, prop)
410
 
            
411
 
            strength = fix_strength(get_prop("quality"), -1)
412
 
            dbm_strength = fix_strength(get_prop('strength'), -100)
413
 
 
414
 
            if daemon.GetWPADriver() == 'ralink legacy' or \
415
 
               daemon.GetSignalDisplayType() == 1:
416
 
                if dbm_strength >= -60:
417
 
                    signal_img = 'signal-100.png'
418
 
                elif dbm_strength >= -70:
419
 
                    signal_img = 'signal-75.png'
420
 
                elif dbm_strength >= -80:
421
 
                    signal_img = 'signal-50.png'
422
 
                else:
423
 
                    signal_img = 'signal-25.png'
424
 
            else:
425
 
                if strength > 75:
426
 
                    signal_img = 'signal-100.png'
427
 
                elif strength > 50:
428
 
                    signal_img = 'signal-75.png'
429
 
                elif strength > 25:
430
 
                    signal_img = 'signal-50.png'
431
 
                else:
432
 
                    signal_img = 'signal-25.png'
433
 
            return wpath.images + signal_img
434
 
            
435
 
        def on_net_menu_activate(self, item):
436
 
            """ Trigger a background scan to populate the network menu. 
437
 
            
438
 
            Called when the network submenu is moused over.  We
439
 
            sleep briefly, clear pending gtk events, and if
440
 
            we're still being moused over we trigger a scan.
441
 
            This is to prevent scans when the user is just
442
 
            mousing past the menu to select another menu item.
443
 
            
444
 
            """
445
 
            def dummy(x=None): pass
446
 
            
447
 
            if self._is_scanning:
448
 
                return True
449
 
            
450
 
            self.init_network_menu()
451
 
            time.sleep(.4)
452
 
            while gtk.events_pending():
453
 
                gtk.main_iteration()
454
 
            if item.state != gtk.STATE_PRELIGHT:
455
 
                return True
456
 
            wireless.Scan(reply_handler=dummy, error_handler=dummy)
457
 
        
458
 
        def populate_network_menu(self, data=None):
459
 
            """ Populates the network list submenu. """
460
 
            def get_prop(net_id, prop):
461
 
                return wireless.GetWirelessProperty(net_id, prop)
462
 
 
463
 
            net_menuitem = self.manager.get_widget("/Menubar/Menu/Connect/")
464
 
            submenu = net_menuitem.get_submenu()
465
 
            self._clear_menu(submenu)
466
 
 
467
 
            is_connecting = daemon.CheckIfConnecting()
468
 
            num_networks = wireless.GetNumberOfNetworks()
469
 
            [status, info] = daemon.GetConnectionStatus()
470
 
                
471
 
            if daemon.GetAlwaysShowWiredInterface() or \
472
 
               wired.CheckPluggedIn():
473
 
                if status == misc.WIRED:
474
 
                    is_active = True
475
 
                else:
476
 
                    is_active = False
477
 
                self._add_item_to_menu(submenu, "Wired Network", "__wired__", 0,
478
 
                                       is_connecting, is_active)
479
 
                sep = gtk.SeparatorMenuItem()
480
 
                submenu.append(sep)
481
 
                sep.show()
482
 
            
483
 
            if num_networks > 0:
484
 
                for x in range(0, num_networks):
485
 
                    essid = get_prop(x, "essid")
486
 
                    if status == misc.WIRELESS and info[1] == essid:
487
 
                        is_active = True
488
 
                    else:
489
 
                        is_active = False
490
 
                    self._add_item_to_menu(submenu, essid, "wifi", x,
491
 
                                           is_connecting, is_active)
492
 
            else:
493
 
                no_nets_item = gtk.MenuItem(language['no_wireless_networks_found'])
494
 
                no_nets_item.set_sensitive(False)
495
 
                no_nets_item.show()
496
 
                submenu.append(no_nets_item)
497
 
                    
498
 
            net_menuitem.show()
499
 
        
500
 
        def init_network_menu(self):
501
 
            """ Set the right-click menu for to the scanning state. """
502
 
            net_menuitem = self.manager.get_widget("/Menubar/Menu/Connect/")
503
 
            submenu = net_menuitem.get_submenu()
504
 
            self._clear_menu(submenu)
505
 
 
506
 
            loading_item = gtk.MenuItem(language['scanning'] + "...")
507
 
            loading_item.set_sensitive(False)
508
 
            loading_item.show()
509
 
            submenu.append(loading_item)
510
 
            net_menuitem.show()
511
 
            
512
 
        def _clear_menu(self, menu):
513
 
            """ Clear the right-click menu. """
514
 
            for item in menu.get_children():
515
 
                menu.remove(item)
516
 
                item.destroy()
517
 
            
518
 
        def toggle_wicd_gui(self):
519
 
            """ Toggles the wicd GUI. """
520
 
            if not self.gui_win:
521
 
                self.gui_win = gui.appGui(dbus_manager)
522
 
                bus = dbus_manager.get_bus()
523
 
                bus.add_signal_receiver(self.gui_win.dbus_scan_finished,
524
 
                                        'SendEndScanSignal', 
525
 
                                        'org.wicd.daemon.wireless')
526
 
                bus.add_signal_receiver(self.gui_win.dbus_scan_started,
527
 
                                        'SendStartScanSignal',
528
 
                                        'org.wicd.daemon.wireless')
529
 
                bus.add_signal_receiver(self.gui_win.update_connect_buttons,
530
 
                                        'StatusChanged', 'org.wicd.daemon')
531
 
            elif not self.gui_win.is_visible:
532
 
                self.gui_win.show_win()
533
 
            else:
534
 
                self.gui_win.exit()
535
 
                return True
536
 
    
537
 
 
538
 
    class EggTrayIconGUI(TrayIconGUI):
539
 
        """ Tray Icon for gtk < 2.10.
540
 
        
541
 
        Uses the deprecated egg.trayicon module to implement the tray icon.
542
 
        Since it relies on a deprecated module, this class is only used
543
 
        for machines running versions of GTK < 2.10.
544
 
        
545
 
        """
546
 
        def __init__(self, use_tray=True):
547
 
            """Initializes the tray icon"""
548
 
            TrayIcon.TrayIconGUI.__init__(self, use_tray)
549
 
            self.use_tray = use_tray
550
 
            if not use_tray: 
551
 
                self.toggle_wicd_gui()
552
 
                return
553
 
 
554
 
            self.tooltip = gtk.Tooltips()
555
 
            self.eb = gtk.EventBox()
556
 
            self.tray = egg.trayicon.TrayIcon("WicdTrayIcon")
557
 
            self.pic = gtk.Image()
558
 
            self.tooltip.set_tip(self.eb, "Initializing wicd...")
559
 
            self.pic.set_from_file("images/no-signal.png")
560
 
 
561
 
            self.eb.connect('button_press_event', self.tray_clicked)
562
 
            self.eb.add(self.pic)
563
 
            self.tray.add(self.eb)
564
 
            self.tray.show_all()
565
 
 
566
 
        def tray_clicked(self, widget, event):
567
 
            """ Handles tray mouse click events. """
568
 
            if event.button == 1:
569
 
                self.toggle_wicd_gui()
570
 
            elif event.button == 3:
571
 
                self.init_network_menu()
572
 
                self.menu.popup(None, None, None, event.button, event.time)
573
 
 
574
 
        def set_from_file(self, val=None):
575
 
            """ Calls set_from_file on the gtk.Image for the tray icon. """
576
 
            if not self.use_tray: return
577
 
            self.pic.set_from_file(val)
578
 
 
579
 
        def set_tooltip(self, val):
580
 
            """ Set the tooltip for this tray icon.
581
 
            
582
 
            Sets the tooltip for the gtk.ToolTips associated with this
583
 
            tray icon.
584
 
 
585
 
            """
586
 
            if not self.use_tray: return
587
 
            self.tooltip.set_tip(self.eb, val)
588
 
 
589
 
 
590
 
    class StatusTrayIconGUI(gtk.StatusIcon, TrayIconGUI):
591
 
        """ Class for creating the wicd tray icon on gtk > 2.10.
592
 
        
593
 
        Uses gtk.StatusIcon to implement a tray icon.
594
 
        
595
 
        """
596
 
        def __init__(self, use_tray=True):
597
 
            TrayIcon.TrayIconGUI.__init__(self, use_tray)
598
 
            self.use_tray = use_tray
599
 
            if not use_tray: 
600
 
                self.toggle_wicd_gui()
601
 
                return
602
 
 
603
 
            gtk.StatusIcon.__init__(self)
604
 
 
605
 
            self.current_icon_path = ''
606
 
            self.set_visible(True)
607
 
            self.connect('activate', self.on_activate)
608
 
            self.connect('popup-menu', self.on_popup_menu)
609
 
            self.set_from_file(wpath.images + "no-signal.png")
610
 
            self.set_tooltip("Initializing wicd...")
611
 
 
612
 
        def on_popup_menu(self, status, button, timestamp):
613
 
            """ Opens the right click menu for the tray icon. """
614
 
            self.init_network_menu()
615
 
            self.menu.popup(None, None, None, button, timestamp)
616
 
 
617
 
        def set_from_file(self, path = None):
618
 
            """ Sets a new tray icon picture. """
619
 
            if not self.use_tray: return
620
 
            if path != self.current_icon_path:
621
 
                self.current_icon_path = path
622
 
                gtk.StatusIcon.set_from_file(self, path)
623
 
 
624
 
 
625
 
def usage():
626
 
    """ Print usage information. """
627
 
    print """
628
 
wicd 1.50
629
 
wireless (and wired) connection daemon front-end.
630
 
 
631
 
Arguments:
632
 
\t-n\t--no-tray\tRun wicd without the tray icon.
633
 
\t-h\t--help\t\tPrint this help information.
634
 
\t-a\t--no-animate\tRun the tray without network traffic tray animations.
635
 
"""
636
 
    
637
 
def setup_dbus():
638
 
    global bus, daemon, wireless, wired, dbus_manager
639
 
    
640
 
    dbus_manager = DBusManager()
641
 
    try:
642
 
        dbus_manager.connect_to_dbus()
643
 
    except DBusException:
644
 
        logging.debug( "Can't connect to the daemon, trying to start it automatically..." )
645
 
        misc.PromptToStartDaemon()
646
 
        try:
647
 
            dbus_manager.connect_to_dbus()
648
 
        except DBusException:
649
 
            gui.error(None, "Could not connect to wicd's D-Bus interface.  " +
650
 
                      "Make sure the daemon is started.")
651
 
            sys.exit(1)
652
 
    dbus_ifaces = dbus_manager.get_dbus_ifaces()
653
 
    daemon = dbus_ifaces['daemon']
654
 
    wireless = dbus_ifaces['wireless']
655
 
    wired = dbus_ifaces['wired']
656
 
    return True
657
 
 
658
 
def main(argv):
659
 
    """ The main frontend program.
660
 
 
661
 
    Keyword arguments:
662
 
    argv -- The arguments passed to the script.
663
 
 
664
 
    """
665
 
    use_tray = True
666
 
    animate = True
667
 
 
668
 
    try:
669
 
        opts, args = getopt.getopt(sys.argv[1:], 'nha', ['help', 'no-tray',
670
 
                                                         'no-animate'])
671
 
    except getopt.GetoptError:
672
 
        # Print help information and exit
673
 
        usage()
674
 
        sys.exit(2)
675
 
 
676
 
    for opt, a in opts:
677
 
        if opt in ('-h', '--help'):
678
 
            usage()
679
 
            sys.exit(0)
680
 
        elif opt in ('-n', '--no-tray'):
681
 
            use_tray = False
682
 
        elif opt in ('-a', '--no-animate'):
683
 
            animate = False
684
 
        else:
685
 
            usage()
686
 
            sys.exit(2)
687
 
    
688
 
    logging.debug( 'Loading...')
689
 
    setup_dbus()
690
 
 
691
 
    if not use_tray:
692
 
        the_gui = gui.appGui()
693
 
        the_gui.standalone = True
694
 
        mainloop = gobject.MainLoop()
695
 
        mainloop.run()
696
 
        sys.exit(0)
697
 
 
698
 
    # Set up the tray icon GUI and backend
699
 
    tray_icon = TrayIcon(use_tray, animate)
700
 
 
701
 
    # Check to see if wired profile chooser was called before icon
702
 
    # was launched (typically happens on startup or daemon restart).
703
 
    if daemon.GetNeedWiredProfileChooser():
704
 
        daemon.SetNeedWiredProfileChooser(False)
705
 
        tray_icon.icon_info.wired_profile_chooser()
706
 
        
707
 
    bus = dbus_manager.get_bus()
708
 
    bus.add_signal_receiver(tray_icon.icon_info.wired_profile_chooser,
709
 
                            'LaunchChooser', 'org.wicd.daemon')
710
 
    bus.add_signal_receiver(tray_icon.icon_info.update_tray_icon,
711
 
                            'StatusChanged', 'org.wicd.daemon')
712
 
    bus.add_signal_receiver(tray_icon.tr.tray_scan_ended, 'SendEndScanSignal',
713
 
                            'org.wicd.daemon.wireless')
714
 
    bus.add_signal_receiver(tray_icon.tr.tray_scan_started,
715
 
                            'SendStartScanSignal', 'org.wicd.daemon.wireless')
716
 
    logging.debug( 'Done.')
717
 
    mainloop = gobject.MainLoop()
718
 
    mainloop.run()
719
 
 
720
 
 
721
 
if __name__ == '__main__':
722
 
    main(sys.argv)