~ubuntu-branches/ubuntu/lucid/knetworkmanager/lucid

« back to all changes in this revision

Viewing changes to knetworkmanager/src/knetworkmanager-tray.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2008-09-26 12:40:26 UTC
  • mfrom: (1.2.7 upstream)
  • Revision ID: james.westby@ubuntu.com-20080926124026-t5fr920l4lf2l6hz
Tags: 1:0.7svn864988-0ubuntu1
New upstream snapshot, now works with current NM API, 
closes LP: #259278

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/***************************************************************************
2
 
 *
3
 
 * knetworkmanager-tray.cpp - A NetworkManager frontend for KDE
4
 
 *
5
 
 * Copyright (C) 2005, 2006 Novell, Inc.
6
 
 *
7
 
 * Author: Timo Hoenig        <thoenig@suse.de>, <thoenig@nouse.net>
8
 
 *         Will Stephenson    <wstephenson@suse.de>, <wstephenson@kde.org>
9
 
 *         Valentine Sinitsyn <e_val@inbox.ru>
10
 
 *         Helmut Schaa       <hschaa@suse.de>, <helmut.schaa@gmx.de>
11
 
 *
12
 
 * This program is free software; you can redistribute it and/or modify
13
 
 * it under the terms of the GNU General Public License as published by
14
 
 * the Free Software Foundation; either version 2 of the License, or
15
 
 * (at your option) any later version.
16
 
 *
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.
21
 
 *
22
 
 * You should have received a copy of the GNU General Public License
23
 
 * along with this program; if not, write to the Free Software
24
 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25
 
 *
26
 
 **************************************************************************/
27
 
 
28
 
class WirelessDialog;
29
 
 
30
 
#include <qsignalmapper.h>
31
 
#include <qevent.h>
32
 
#include <qvbox.h>
33
 
#include <qlayout.h>
34
 
#include <qpushbutton.h>
35
 
#include <qpixmap.h>
36
 
#include <qpixmapcache.h>
37
 
#include <qpainter.h>
38
 
#include <qstyle.h>
39
 
#include <qvaluelist.h>
40
 
#include <dcopclient.h>
41
 
#include <dbus/qdbusobjectpath.h>
42
 
#include <kdebug.h>
43
 
#include <kdialogbase.h>
44
 
#include <knotifyclient.h>
45
 
#include <knotifydialog.h>
46
 
#include <klocale.h>
47
 
#include <kstdguiitem.h>
48
 
#include <khelpmenu.h>
49
 
#include <kprocess.h>
50
 
#include <kiconloader.h>
51
 
#include <kconfig.h>
52
 
#include <kmessagebox.h>
53
 
 
54
 
#include <NetworkManager.h>
55
 
 
56
 
#include <dbus/qdbuserror.h>
57
 
 
58
 
#include "vpn_tray_component.h"
59
 
#include "devicetraycomponent.h"
60
 
#include "knetworkmanager-cellular_device_tray.h"
61
 
#include "knetworkmanager-cellular_device.h"
62
 
#include "knetworkmanager-device.h"
63
 
#include "knetworkmanager-devicestore.h"
64
 
#include "knetworkmanager-tray.h"
65
 
#include "knetworkmanager-menu_subhead.h"
66
 
#include "knetworkmanager-nm_proxy.h"
67
 
#include "knetworkmanager-connection_setting_info.h"
68
 
#include "knetworkmanager-connection_settings_dialog.h"
69
 
#include "knetworkmanager-connection_store.h"
70
 
#include "knetworkmanager-vpn_connection.h"
71
 
#include "knetworkmanager-connection.h"
72
 
#include "knetworkmanager-storage.h"
73
 
#include "knetworkmanager-connection_editor.h"
74
 
#include "knetworkmanager-vpnauthenticationdialog.h"
75
 
#include "knetworkmanager-wired_device.h"
76
 
#include "knetworkmanager-wired_device_tray.h"
77
 
#include "knetworkmanager-wireless_device_tray.h"
78
 
#include "knetworkmanager-wireless_device.h"
79
 
 
80
 
#define KDED_NETWORK_NAME "NMNetwork"
81
 
 
82
 
class TrayPrivate
83
 
{
84
 
        public:
85
 
                TrayPrivate(QObject* parent)
86
 
                        : foregroundTrayComponent(0)
87
 
                  , signalMapper(parent, "signal_mapper")
88
 
                  , current_idx(0)
89
 
                {}
90
 
                ~TrayPrivate() {}
91
 
 
92
 
                static Tray* tray;
93
 
                QValueList<TrayComponent*> trayComponents;
94
 
                DeviceTrayComponent * foregroundTrayComponent;
95
 
                QSignalMapper signalMapper;
96
 
                QMap<int, QPair<ConnectionSettings::Connection*, Device*> > act_conn_map;
97
 
                int current_idx;
98
 
};
99
 
 
100
 
Tray* TrayPrivate::tray = NULL;
101
 
 
102
 
Tray* Tray::getInstance()
103
 
{
104
 
        if (TrayPrivate::tray)
105
 
                return TrayPrivate::tray;
106
 
        else return (TrayPrivate::tray = new Tray());
107
 
}
108
 
 
109
 
void Tray::slotEditConnections()
110
 
{
111
 
        ConnectionEditorImpl* dlg = new ConnectionEditorImpl(this);
112
 
        dlg->show();
113
 
}
114
 
 
115
 
void Tray::slotEnableWireless()
116
 
{
117
 
        NMProxy* nm = NMProxy::getInstance();
118
 
        QDBusError err;
119
 
        if (!nm) return;
120
 
 
121
 
        nm->setWirelessEnabled(true, err);
122
 
}
123
 
 
124
 
void Tray::slotDisableWireless()
125
 
{
126
 
        NMProxy* nm = NMProxy::getInstance();
127
 
        QDBusError err;
128
 
        if (!nm) return;
129
 
 
130
 
        nm->setWirelessEnabled(false, err);
131
 
}
132
 
 
133
 
void Tray::slotOfflineMode()
134
 
{
135
 
        NMProxy* nm = NMProxy::getInstance();
136
 
        QDBusError err;
137
 
        if (!nm) return;
138
 
 
139
 
        nm->Sleep(true, err);
140
 
}
141
 
 
142
 
void Tray::slotOnlineMode()
143
 
{
144
 
        NMProxy* nm = NMProxy::getInstance();
145
 
        QDBusError err;
146
 
        if (!nm) return;
147
 
 
148
 
        nm->Sleep(false, err);
149
 
}
150
 
 
151
 
void Tray::contextMenuAboutToShow (KPopupMenu* menu)
152
 
{
153
 
        QDBusError err;
154
 
        NMProxy* nm = NMProxy::getInstance();
155
 
 
156
 
        // clear menu
157
 
        menu->clear();
158
 
 
159
 
        if (nm->isNMRunning())
160
 
        {
161
 
 
162
 
    // actions for each Device
163
 
                for (QValueList<TrayComponent*>::Iterator it = d->trayComponents.begin();
164
 
                  it != d->trayComponents.end();
165
 
                ++it)
166
 
          {
167
 
              (*it)->addMenuItems(menu);
168
 
          }
169
 
 
170
 
                // New connection
171
 
                KAction * newConnAction = 0;
172
 
                int devices =  d->trayComponents.count();
173
 
                if ( devices > 1 ) {
174
 
                        newConnAction = actionCollection ()->action ("new_connection_menu");
175
 
                        KActionMenu* newConnActionMenu = static_cast<KActionMenu*>(newConnAction);
176
 
                        newConnActionMenu->popupMenu()->clear();
177
 
                        for (QValueList<TrayComponent*>::Iterator it = d->trayComponents.begin();
178
 
                                        it != d->trayComponents.end();
179
 
                                        ++it)
180
 
                        {
181
 
                                DeviceTrayComponent* dev_comp = dynamic_cast<DeviceTrayComponent*> (*it);
182
 
                                KAction * deviceNewConnAction = 0;
183
 
                                if (dev_comp)
184
 
                                {
185
 
                                        QString actionName = QString("new_connection_%1").arg(dev_comp->device()->getInterface());
186
 
                                        deviceNewConnAction = actionCollection ()->action (actionName);
187
 
                                        if (!deviceNewConnAction) {
188
 
                                                deviceNewConnAction = new KAction (dev_comp->device()->getInterface(), 0, (*it), SLOT(newConnection()), actionCollection(), actionName);
189
 
                                        }
190
 
                                        newConnActionMenu->insert(deviceNewConnAction);
191
 
                                }
192
 
                        }
193
 
                } else if ( devices == 1 ) {
194
 
                        newConnAction = actionCollection ()->action ("new_connection");
195
 
                        QObject::disconnect( newConnAction, SIGNAL(activated()) );
196
 
                        QObject::connect( newConnAction, SIGNAL(activated()), d->trayComponents[0], SLOT(newConnection()));
197
 
                }
198
 
                if (newConnAction) {
199
 
                        newConnAction->plug(menu);
200
 
                }
201
 
        
202
 
          // turn things off
203
 
                if (nm)
204
 
                {
205
 
                        KActionMenu* disableStuffActionMenu = static_cast<KActionMenu*>(actionCollection ()->action ("deactivate_menu") );
206
 
                        disableStuffActionMenu->popupMenu()->clear();
207
 
                        QValueList<QPair<ConnectionSettings::Connection*, Device*> > map = nm->getActiveConnectionsMap();
208
 
                        d->act_conn_map.clear();
209
 
        
210
 
                        for (QValueList<QPair<ConnectionSettings::Connection*, Device*> >::Iterator it = map.begin(); it != map.end(); ++it)
211
 
                        {
212
 
                                ConnectionSettings::GenericConnection* conn = dynamic_cast<ConnectionSettings::GenericConnection*>((*it).first);
213
 
                                Device* dev = (*it).second;
214
 
 
215
 
                                if (!conn)
216
 
                                        continue;
217
 
 
218
 
                                QString actionName = QString("disable_connection_%1_%2").arg(conn->getID()).arg(dev ? dev->getInterface() : "");
219
 
                                KAction * deviceNewConnAction = actionCollection ()->action (actionName);
220
 
                                QString actionText = conn->getInfoSetting()->getName();
221
 
                                if (dev)
222
 
                                        actionText += QString(" (%1)").arg(dev->getInterface());
223
 
 
224
 
                                if (!deviceNewConnAction) {
225
 
                                        deviceNewConnAction = new KAction (actionText, 0, &d->signalMapper, SLOT(map()), actionCollection(), actionName);
226
 
                                }
227
 
                                d->signalMapper.setMapping(deviceNewConnAction, d->current_idx);
228
 
                                d->act_conn_map.insert(d->current_idx, QPair<ConnectionSettings::Connection*, Device*> (conn, dev));
229
 
                                d->current_idx++;
230
 
                                disableStuffActionMenu->insert(deviceNewConnAction);    
231
 
                        }
232
 
 
233
 
                        // disable wireless
234
 
                        if (nm->getWirelessHardwareEnabled(err))
235
 
                        {
236
 
                                KAction* wireless = NULL;
237
 
                                if (nm->getWirelessEnabled(err)) {
238
 
                                        wireless = actionCollection ()->action ("disable_wireless");
239
 
                                } else {
240
 
                                        wireless = actionCollection ()->action ("enable_wireless");
241
 
                                }
242
 
                                disableStuffActionMenu->insert(wireless);
243
 
                        }
244
 
 
245
 
                        // offline vs. online mode
246
 
                        KAction* switch_mode = NULL;
247
 
                        if (nm->getState(err) != NM_STATE_ASLEEP) {
248
 
                                switch_mode = actionCollection ()->action ("offline_mode");
249
 
                        }
250
 
                        else {
251
 
                                switch_mode = actionCollection ()->action ("online_mode");
252
 
                        }
253
 
                        disableStuffActionMenu->insert(switch_mode);
254
 
 
255
 
                        disableStuffActionMenu->plug(menu);
256
 
                }
257
 
        }
258
 
        else
259
 
        {
260
 
                Subhead* subhead = new Subhead (menu, "subhead", i18n("NetworkManager is not running"), SmallIcon("stop", QIconSet::Automatic));
261
 
                menu->insertItem (subhead, -1, -1);
262
 
        }
263
 
 
264
 
        // Notifications
265
 
        KAction* notif = actionCollection()->action("configure_notifications");
266
 
        notif->plug(menu);
267
 
 
268
 
        // Connection Editor
269
 
        KAction* edit = actionCollection ()->action ("edit_connections");
270
 
        edit->plug(menu);
271
 
 
272
 
        // quit
273
 
        menu->insertSeparator ();
274
 
        KAction* quitAction = actionCollection ()->action (KStdAction::name (KStdAction::Quit));
275
 
        if (quitAction)
276
 
                quitAction->plug (menu);
277
 
}
278
 
 
279
 
void
280
 
Tray::slotStateChanged(Q_UINT32 state)
281
 
{
282
 
        NMState nm_state = (NMState) state;
283
 
        // change tray icon according to NM's state
284
 
        switch(nm_state)
285
 
        {
286
 
                case NM_STATE_UNKNOWN:
287
 
                case NM_STATE_ASLEEP:
288
 
                case NM_STATE_CONNECTING:
289
 
                case NM_STATE_DISCONNECTED:
290
 
                        setPixmap (loadIcon ("knetworkmanager_disabled"));
291
 
                        break;
292
 
                case NM_STATE_CONNECTED:
293
 
                        setPixmap (loadIcon ("knetworkmanager"));
294
 
                        break;
295
 
        }
296
 
}
297
 
 
298
 
void
299
 
Tray::enterEvent (QEvent* /*e*/)
300
 
{
301
 
        // show tooltip
302
 
        QToolTip::remove (this);
303
 
        QString tooltip = "";
304
 
 
305
 
        // build up the tooltip from all tray components
306
 
        for (QValueList<TrayComponent*>::Iterator it = d->trayComponents.begin(); it != d->trayComponents.end(); ++it)
307
 
        {
308
 
                TrayComponent* comp = *it;
309
 
                if (comp->getToolTipText().isEmpty())
310
 
                        continue;
311
 
                if (!tooltip.isEmpty())
312
 
                        tooltip += "\n\n";
313
 
                tooltip += comp->getToolTipText().join("\n");
314
 
        }
315
 
        if (!tooltip.isEmpty())
316
 
                QToolTip::add (this, tooltip);
317
 
}
318
 
 
319
 
void 
320
 
Tray::slotVPNSecretsNeeded(ConnectionSettings::Connection* connection, ConnectionSettings::ConnectionSetting* setting, const QStringList& hints, bool request_new)
321
 
{
322
 
#warning Implement Tray::slotVPNSecretsNeeded to handle parms properly
323
 
        Q_UNUSED(setting);
324
 
        Q_UNUSED(hints);
325
 
        Q_UNUSED(request_new);
326
 
 
327
 
        printf("Tray::slotVPNSecretsNeeded\n");
328
 
        ConnectionSettings::VPNConnection* conn = dynamic_cast<ConnectionSettings::VPNConnection*>(connection);
329
 
        VPNAuthenticationDialog* auth = new VPNAuthenticationDialog(conn, this, "vpnauth");
330
 
        auth->show();
331
 
}
332
 
 
333
 
void 
334
 
Tray::slotSecretsNeeded(ConnectionSettings::Connection* connection, ConnectionSettings::ConnectionSetting* setting, const QStringList& hints, bool request_new)
335
 
{
336
 
        Storage* storage = Storage::getInstance();
337
 
        bool hasSecretsStored = storage->hasSecretsStored(connection, setting);
338
 
 
339
 
        // FIXME ugly secrets handling for VPN
340
 
        if (connection->getType() == NM_SETTING_VPN_SETTING_NAME)
341
 
        {
342
 
                slotVPNSecretsNeeded(connection, setting, hints, request_new);
343
 
                return;
344
 
        }
345
 
 
346
 
        // default secrets handling for all other connection types
347
 
        // 1) if we have secrets stored, restore them and send them back to NM
348
 
        // 2) if NM requests new secrets we should allow the user to retry the
349
 
        //    connection or to edit it
350
 
 
351
 
        if (hasSecretsStored && !request_new)
352
 
        {
353
 
                // We have secrets stored, restore them
354
 
                if (storage->restoreSecrets(connection, setting))
355
 
                {
356
 
                        connection->slotSecretsProvided(setting);
357
 
                }
358
 
        }
359
 
        else
360
 
        {
361
 
                // NM wants completely new secrets
362
 
                // FIXME: not implemented yet
363
 
                connection->slotSecretsError();
364
 
 
365
 
                //ConnectionSettingsDialogImpl* dlg = new ConnectionSettingsDialogImpl(NULL, connection, setting, this, "connect_something", false, Qt::WDestructiveClose);
366
 
                //dlg->show();
367
 
        }
368
 
}
369
 
 
370
 
void Tray::slotAddDeviceTrayComponent(Device* dev)
371
 
{
372
 
        if (dev)
373
 
                createDeviceTrayComponent(dev);
374
 
}
375
 
 
376
 
void Tray::slotRemoveDeviceTrayComponent(Device* dev)
377
 
{
378
 
        for (QValueList<TrayComponent*>::Iterator it = d->trayComponents.begin(); it != d->trayComponents.end(); ++it)
379
 
        {
380
 
                DeviceTrayComponent* dev_comp = dynamic_cast<DeviceTrayComponent*>(*it);
381
 
                if (!dev_comp)
382
 
                        continue;
383
 
 
384
 
                if (dev_comp->device() == dev)
385
 
                {
386
 
                        if (d->foregroundTrayComponent && dev_comp->device() == d->foregroundTrayComponent->device() ) {
387
 
                                d->foregroundTrayComponent = 0;
388
 
                        }
389
 
 
390
 
                        // remove the appropriate action
391
 
                        QString actionName = QString("new_connection_%1").arg(dev_comp->device()->getInterface());
392
 
                        KAction * deviceNewConnAction = actionCollection ()->action (actionName);
393
 
                        
394
 
                        if (!deviceNewConnAction)
395
 
                        {
396
 
                                delete deviceNewConnAction;
397
 
                                deviceNewConnAction = NULL;
398
 
                        }
399
 
                        // remove device_tray and delete it
400
 
                        d->trayComponents.remove(it);
401
 
                        delete dev_comp;
402
 
 
403
 
                        if (contextMenu()->isVisible()) {
404
 
                                contextMenu()->hide();
405
 
                        }
406
 
 
407
 
                        break;
408
 
                }
409
 
        }
410
 
}
411
 
 
412
 
void Tray::createDeviceTrayComponent(Device* dev)
413
 
{
414
 
        bool trayExists = false;
415
 
 
416
 
        if (!dev) return;
417
 
 
418
 
        // check if we have already a trayicon for this device
419
 
        for (QValueList<TrayComponent*>::Iterator it = d->trayComponents.begin(); it != d->trayComponents.end(); ++it)
420
 
        {       
421
 
                DeviceTrayComponent* dev_comp = dynamic_cast<DeviceTrayComponent*> (*it);
422
 
                if (dev_comp)
423
 
                        if (dev_comp->device() == dev)
424
 
                        {
425
 
                                trayExists = true;
426
 
                                break;
427
 
                        }
428
 
        }
429
 
 
430
 
        // create the appropriate device tray icon
431
 
        if (!trayExists)
432
 
        {
433
 
                DeviceTrayComponent* devTray = 0;
434
 
                // different tray icons for different device types!
435
 
                switch (dev->getDeviceType())
436
 
                {
437
 
                        case DEVICE_TYPE_802_3_ETHERNET:
438
 
                devTray = new WiredDeviceTray(dynamic_cast<WiredDevice*>(dev), this, "wired_device_tray");
439
 
                                break;
440
 
                        case DEVICE_TYPE_802_11_WIRELESS:
441
 
                devTray = new WirelessDeviceTray(static_cast<WirelessDevice*>(dev), this, "wireless_device_tray");
442
 
                                break;
443
 
                        case DEVICE_TYPE_GSM:
444
 
                        case DEVICE_TYPE_CDMA:
445
 
                devTray = new CellularDeviceTray(static_cast<CellularDevice*>(dev), this, "cellular_device_tray");
446
 
                                break;
447
 
                        default:
448
 
                                kdWarning() << k_funcinfo << "UDI: " << dev->getUdi() << " has unknown devicetype: " << dev->getDeviceType() << endl;
449
 
                }
450
 
                if(devTray)
451
 
                {
452
 
                        connect( devTray, SIGNAL(needsCenterStage(TrayComponent*,bool)),
453
 
                                        SLOT(trayComponentNeedsCenterStage(TrayComponent*,bool)));
454
 
                        connect( devTray, SIGNAL(uiUpdated()), SLOT(trayUiChanged()));
455
 
                        d->trayComponents.append(devTray);
456
 
            //WILLTODO: sort
457
 
                }
458
 
        }
459
 
}
460
 
 
461
 
void Tray::createVPNTrayComponent()
462
 
{
463
 
        bool trayExists = false;
464
 
 
465
 
        // check if we have already a trayicon for this device
466
 
        for (QValueList<TrayComponent*>::Iterator it = d->trayComponents.begin(); it != d->trayComponents.end(); ++it)
467
 
        {       
468
 
                VPNTrayComponent* vpn_comp = dynamic_cast<VPNTrayComponent*> (*it);
469
 
                if (vpn_comp)
470
 
                {
471
 
                        trayExists = true;
472
 
                        break;
473
 
                }
474
 
        }
475
 
 
476
 
        // create the appropriate device tray icon
477
 
        if (!trayExists)
478
 
        {
479
 
                TrayComponent* devTray = new VPNTrayComponent(this, "vpn_device_tray");
480
 
                if(devTray)
481
 
                {
482
 
                        d->trayComponents.append(devTray);
483
 
            //WILLTODO: sort
484
 
                }
485
 
        }
486
 
}
487
 
 
488
 
void Tray::updateDeviceTrays()
489
 
{
490
 
        // create one tray-icon for each device
491
 
        DeviceStore* store = DeviceStore::getInstance();        
492
 
        QValueList<Device*> devices = store->getDevices();
493
 
 
494
 
        // check for newly added devices
495
 
        for (QValueList<Device*>::iterator it = devices.begin(); it != devices.end(); ++it)
496
 
        {
497
 
                Device* dev = (*it);
498
 
                if (dev)
499
 
                        createDeviceTrayComponent(dev);
500
 
                else
501
 
                        kdWarning() << k_funcinfo << "got a NULL-Device" << endl;
502
 
        }
503
 
 
504
 
        // add the VPN componenet as it is not associated with a device
505
 
        createVPNTrayComponent();
506
 
}
507
 
 
508
 
void Tray::mousePressEvent( QMouseEvent *e )
509
 
{
510
 
    if ( !rect().contains( e->pos() ) ) {
511
 
        return;
512
 
    }
513
 
    switch ( e->button() ) {
514
 
        case LeftButton:
515
 
            contextMenuAboutToShow(contextMenu());
516
 
            contextMenu()->popup(e->globalPos());
517
 
            break;
518
 
        default:
519
 
            KSystemTray::mousePressEvent( e );
520
 
            break;
521
 
    }
522
 
}
523
 
 
524
 
void Tray::slotDeactivateConnection(int index)
525
 
{
526
 
        ConnectionSettings::Connection* conn = d->act_conn_map[index].first;
527
 
        Device* dev = d->act_conn_map[index].second;
528
 
        NMProxy* nm = NMProxy::getInstance();
529
 
 
530
 
        if (conn)
531
 
                nm->deactivateConnection(conn, dev);
532
 
}
533
 
 
534
 
void Tray::trayComponentNeedsCenterStage(TrayComponent *component, bool needsIt)
535
 
{
536
 
        DeviceTrayComponent * dtc = dynamic_cast<DeviceTrayComponent*>(component);
537
 
        if (dtc) {
538
 
                kdDebug() << k_funcinfo << dtc->device()->getInterface() << " : " << needsIt << endl;
539
 
                Device * device = dtc->device();
540
 
                if (needsIt) {
541
 
                        if (d->foregroundTrayComponent) {
542
 
                                disconnect(d->foregroundTrayComponent->device(), SIGNAL(StateChanged(NMDeviceState)), this, 0 );
543
 
                        }
544
 
                        d->foregroundTrayComponent = dtc;
545
 
                        connect(device, SIGNAL(StateChanged(NMDeviceState)),
546
 
                                        SLOT(slotUpdateDeviceState(NMDeviceState)));
547
 
                } else {
548
 
                        disconnect(device, SIGNAL(StateChanged(NMDeviceState)), this, 0 );
549
 
                        //use active default
550
 
                        NMProxy* nm = NMProxy::getInstance();
551
 
                        device = nm->getDefaultDevice();
552
 
                        if ( device ) {
553
 
                                // identify the new foreground
554
 
                                for (QValueList<TrayComponent*>::Iterator it = d->trayComponents.begin(); it != d->trayComponents.end(); ++it)
555
 
                                {       
556
 
                                        DeviceTrayComponent* newDtc = dynamic_cast<DeviceTrayComponent*> (*it);
557
 
                                        if ( newDtc && newDtc->device() == device ) {
558
 
                                                d->foregroundTrayComponent = newDtc;
559
 
                                                break;
560
 
                                        }
561
 
                                }
562
 
                                kdDebug() << "  Device " << dtc->device()->getInterface() << " background, new foreground device: " << device->getInterface() << endl;
563
 
                                connect(device, SIGNAL(StateChanged(NMDeviceState)),
564
 
                                                SLOT(slotUpdateDeviceState(NMDeviceState)));
565
 
                                slotUpdateDeviceState(device->getState());
566
 
                        }
567
 
                }
568
 
        }
569
 
}
570
 
 
571
 
void Tray::slotUpdateDeviceState(NMDeviceState state)
572
 
{
573
 
        updateTrayIcon(state);
574
 
        updateActiveConnection(state);
575
 
}
576
 
 
577
 
void Tray::trayUiChanged()
578
 
{
579
 
        DeviceTrayComponent * dtc = d->foregroundTrayComponent;
580
 
        if (dtc) {
581
 
                updateTrayIcon(dtc->device()->getState());
582
 
        }
583
 
}
584
 
void Tray::updateTrayIcon(NMDeviceState state)
585
 
{
586
 
        // stop the old movie to avoid unnecessary wakups
587
 
        DeviceTrayComponent * dtc = d->foregroundTrayComponent;
588
 
 
589
 
        if (movie())
590
 
                movie()->pause();
591
 
 
592
 
        if (dtc) {
593
 
 
594
 
                if (!dtc->movieForState(state).isNull())
595
 
                {
596
 
                        // animation desired
597
 
                        int frame = -1;
598
 
                        if (movie())
599
 
                                frame = movie()->frameNumber();
600
 
 
601
 
                        // set the movie
602
 
                        setMovie(dtc->movieForState(state));
603
 
 
604
 
                        // start at the same frame as the movie before
605
 
                        if (frame > 0)
606
 
                                movie()->step(frame);
607
 
 
608
 
                        // start the animation
609
 
                        movie()->unpause();
610
 
                }
611
 
                else if (!dtc->pixmapForState(state).isNull())
612
 
                        setPixmap(dtc->pixmapForState(state));
613
 
                else
614
 
                        setPixmap(loadIcon("knetworkmanager"));
615
 
        }
616
 
        else
617
 
                setPixmap(loadIcon("knetworkmanager"));
618
 
}
619
 
 
620
 
void Tray::updateActiveConnection(NMDeviceState state)
621
 
{
622
 
        if (state != NM_DEVICE_STATE_ACTIVATED)
623
 
                return;
624
 
 
625
 
        NMProxy* nm = NMProxy::getInstance();
626
 
        if (d->foregroundTrayComponent) {
627
 
                Connection* active_conn = nm->getActiveConnection(d->foregroundTrayComponent->device());
628
 
                if (active_conn)
629
 
                {
630
 
                        Info* info = dynamic_cast<Info*>(active_conn->getSetting(NM_SETTING_CONNECTION_SETTING_NAME));
631
 
                        if (info)
632
 
                                info->setTimestamp(QDateTime::currentDateTime());
633
 
                }
634
 
        }
635
 
}
636
 
 
637
 
void Tray::slotDeviceAddedNotify(Device* dev)
638
 
{
639
 
        printf("Tray::slotDeviceAddedNotify\n");
640
 
        KNotifyClient::event( winId(), "knm-nm-device-added", i18n("New network device %1 found").arg(dev->getInterface()) );
641
 
}
642
 
 
643
 
void Tray::slotDeviceRemovedNotify(Device* dev)
644
 
{
645
 
        printf("Tray::slotDeviceRemovedNotify\n");
646
 
        KNotifyClient::event( winId(), "knm-nm-device-removed", i18n("Network device %1 removed").arg(dev->getInterface()) );
647
 
}
648
 
 
649
 
void Tray::slotStateChangedNotify(Q_UINT32 state)
650
 
{
651
 
        NMState nm_state = (NMState) state;
652
 
        // change tray icon according to NM's state
653
 
        switch(nm_state)
654
 
        {
655
 
                case NM_STATE_CONNECTING:
656
 
                        KNotifyClient::event( winId(), "knm-nm-connecting", i18n("NetworkManager is connecting") );
657
 
                        break;
658
 
                case NM_STATE_DISCONNECTED:
659
 
                        KNotifyClient::event( winId(), "knm-nm-disconnected", i18n("NetworkManager is now disconnected") );
660
 
                        break;
661
 
                case NM_STATE_CONNECTED:
662
 
                        KNotifyClient::event( winId(), "knm-nm-connected", i18n("NetworkManager is now connected") );
663
 
                        break;
664
 
                case NM_STATE_ASLEEP:
665
 
                        KNotifyClient::event( winId(), "knm-nm-sleeping", i18n("KNetworkManager Offline") );
666
 
                        break;
667
 
                case NM_STATE_UNKNOWN:
668
 
 
669
 
                default:
670
 
                        break;
671
 
        }
672
 
}
673
 
 
674
 
void Tray::slotEditNotifications()
675
 
{
676
 
        KNotifyDialog::configure(this);
677
 
}
678
 
 
679
 
Tray::Tray () : KSystemTray ()
680
 
{
681
 
        d = new TrayPrivate(this);
682
 
 
683
 
        connect(&d->signalMapper, SIGNAL(mapped(int)), this, SLOT(slotDeactivateConnection(int)));
684
 
 
685
 
        setPixmap (loadIcon ("knetworkmanager"));
686
 
        setMouseTracking (true);
687
 
 
688
 
        // Actions used for plugging into the menu
689
 
        new KAction (i18n ("Switch to offline mode"),
690
 
                                             SmallIcon ("no",  QIconSet::Automatic), 0,
691
 
                                             this, SLOT (slotOfflineMode()), actionCollection (), "offline_mode");
692
 
 
693
 
        new KAction (i18n ("Switch to online mode"),
694
 
                                             SmallIcon ("ok",  QIconSet::Automatic), 0,
695
 
                                             this, SLOT (slotOnlineMode()), actionCollection (), "online_mode");
696
 
 
697
 
        new KAction (i18n ("Disable Wireless"),
698
 
                                             SmallIcon ("wireless_off",  QIconSet::Automatic), 0,
699
 
                                             this, SLOT (slotDisableWireless()), actionCollection (), "disable_wireless");
700
 
 
701
 
        new KAction (i18n ("Enable Wireless"),
702
 
                                             SmallIcon ("wireless",  QIconSet::Automatic), 0,
703
 
                                             this, SLOT (slotEnableWireless()), actionCollection (), "enable_wireless");
704
 
 
705
 
        new KAction (i18n ("Edit Connections"),
706
 
                                             SmallIcon ("edit",  QIconSet::Automatic), 0,
707
 
                                             this, SLOT (slotEditConnections()), actionCollection (), "edit_connections");
708
 
 
709
 
        new KAction (i18n ("Configure Notifications"),
710
 
                                             SmallIcon ("knotify",  QIconSet::Automatic), 0,
711
 
                                             this, SLOT (slotEditNotifications()), actionCollection (), "configure_notifications");
712
 
 
713
 
        // this action is only connected when the menu is shown, hence the 0 receiver
714
 
        new KAction (i18n ("New connection ..."),
715
 
                                             SmallIcon ("filenew",  QIconSet::Automatic), 0,
716
 
                                             this, 0, actionCollection (), "new_connection");
717
 
 
718
 
        new KActionMenu (i18n ("New connection ..."),
719
 
                                             SmallIcon ("filenew",  QIconSet::Automatic),
720
 
                                             actionCollection(), "new_connection_menu");
721
 
 
722
 
        new KActionMenu (i18n ("Deactivate connection..."),
723
 
                        SmallIcon ("no",  QIconSet::Automatic),
724
 
                        actionCollection (), "deactivate_menu");
725
 
 
726
 
        // get notified when NM's state changes
727
 
        NMProxy* nm = NMProxy::getInstance();
728
 
        connect(nm, SIGNAL(StateChange(Q_UINT32)), this, SLOT(slotStateChanged(Q_UINT32)));
729
 
 
730
 
        // get notifier when NM requests new secrets
731
 
        ConnectionStore* cstore = ConnectionStore::getInstance();
732
 
        connect(cstore, SIGNAL(SecretsNeeded(ConnectionSettings::Connection*, ConnectionSettings::ConnectionSetting*, const QStringList&, bool)), this, SLOT(slotSecretsNeeded(ConnectionSettings::Connection*, ConnectionSettings::ConnectionSetting*, const QStringList&, bool)));
733
 
 
734
 
        // get notified about new/removed devices
735
 
        DeviceStore* store = DeviceStore::getInstance();
736
 
        connect(store, SIGNAL(DeviceStoreChanged()), this, SLOT(updateDeviceTrays()));  
737
 
        connect(store, SIGNAL(DeviceAdded(Device*)), this, SLOT(slotAddDeviceTrayComponent(Device*)));  
738
 
        connect(store, SIGNAL(DeviceRemoved(Device*)), this, SLOT(slotRemoveDeviceTrayComponent(Device*)));     
739
 
 
740
 
        // Notifications
741
 
        connect(store, SIGNAL(DeviceAdded(Device*)), this, SLOT(slotDeviceAddedNotify(Device*)));       
742
 
        connect(store, SIGNAL(DeviceRemoved(Device*)), this, SLOT(slotDeviceRemovedNotify(Device*)));   
743
 
        connect(nm, SIGNAL(StateChange(Q_UINT32)), this, SLOT(slotStateChangedNotify(Q_UINT32)));
744
 
 
745
 
 
746
 
        // initial setup of the device-trays
747
 
        updateDeviceTrays();
748
 
 
749
 
        QDBusError err;
750
 
        slotStateChanged(nm->getState(err));
751
 
}
752
 
 
753
 
Tray::~Tray ()
754
 
{
755
 
        delete d;
756
 
}
757
 
 
758
 
#include "knetworkmanager-tray.moc"
759