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

« back to all changes in this revision

Viewing changes to knetworkmanager-0.7/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