/*************************************************************************** * * tdenetman-tray.cpp - A NetworkManager frontend for KDE * * Copyright (C) 2005, 2006 Novell, Inc. * * Author: Timo Hoenig , * Will Stephenson , * Valentine Sinitsyn * Helmut Schaa , * Alexander Naumov , * Author: Timothy Pearson * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * **************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "devicetraycomponent.h" #include "tdenetman-tray.h" #include "tdenetman-connection_settings_dialog.h" #include "tdenetman-connection_editor.h" #include "tdenetman-menu_subhead.h" #include "tdenetman-wired_device_tray.h" #include "tdenetman-wireless_device_tray.h" #include "tdenetman-cellular_device_tray.h" #include TDENetworkConnectionStatus::TDENetworkConnectionStatus nm_device_state_global; NewSecretsDialog::NewSecretsDialog(TDENetworkConnection *connection, TQWidget * parent, const char * name, bool modal, TQt::WFlags f) : TQDialog(parent, name, modal, f) { _connection = connection; init(); } NewSecretsDialog::~NewSecretsDialog () { } void NewSecretsDialog::slotDialogEdit() { ConnectionSettingsDialogImpl* dlg = new ConnectionSettingsDialogImpl(_connection, false, Tray::getInstance(), "Edit connection"); dlg->show(); close(); } void NewSecretsDialog::reject() { TQDialog::reject(); } void NewSecretsDialog::init() { TDENetworkConnection* conn = _connection; // if we do not have a connection bail out if (!conn) { reject(); return; } // show a message to the user that the connection failed // and allow edit or cancel TQLabel* label = new TQLabel(tqtr(" The connection %1 could not be established ").arg(conn->friendlyName), this); TQPushButton* buttonEdit = new TQPushButton(tr("&Edit"), this); TQPushButton* buttonCancel = new TQPushButton(tr("&Cancel"), this); TQHBoxLayout *topLeftLayout = new TQHBoxLayout(); topLeftLayout->addWidget(buttonEdit); topLeftLayout->addWidget(buttonCancel); TQVBoxLayout *mainLayout = new TQVBoxLayout(this); mainLayout->setMargin(15); mainLayout->setSpacing(10); mainLayout->addWidget(label); mainLayout->addLayout(topLeftLayout); connect(buttonEdit, TQT_SIGNAL(clicked()), TQT_SLOT(slotDialogEdit())); connect(buttonCancel, TQT_SIGNAL(clicked()), this, TQT_SLOT(close())); } class TrayPrivate { public: TrayPrivate(TQObject* parent) : foregroundTrayComponent(0) , signalMapper(parent, "signal_mapper") , current_idx(0) {} ~TrayPrivate() {} static Tray* tray; TQValueList trayComponents; DeviceTrayComponent * foregroundTrayComponent; TQSignalMapper signalMapper; TQMap act_conn_map; int current_idx; }; Tray* TrayPrivate::tray = NULL; Tray* Tray::getInstance() { if (TrayPrivate::tray) return TrayPrivate::tray; else return (TrayPrivate::tray = new Tray()); } void Tray::slotEditConnections() { ConnectionEditorImpl* dlg = new ConnectionEditorImpl(this); dlg->show(); } void Tray::slotEnableWireless() { TDEGlobalNetworkManager* nm = KGlobal::networkManager(); if (!nm) return; nm->enableWiFi(true); } void Tray::slotDisableWireless() { TDEGlobalNetworkManager* nm = KGlobal::networkManager(); if (!nm) return; nm->enableWiFi(false); } void Tray::slotOfflineMode() { TDEGlobalNetworkManager* nm = KGlobal::networkManager(); if (!nm) return; nm->enableNetworking(false); } void Tray::slotOnlineMode() { TDEGlobalNetworkManager* nm = KGlobal::networkManager(); if (!nm) return; nm->enableNetworking(true); } void Tray::contextMenuAboutToShow (KPopupMenu* menu) { TDEGlobalNetworkManager* nm = KGlobal::networkManager(); // clear menu menu->clear(); if (!(nm->backendStatus() & TDENetworkGlobalManagerFlags::BackendUnavailable)) { // actions for each Device for (TQValueList::Iterator it = d->trayComponents.begin(); it != d->trayComponents.end(); ++it) { (*it)->addMenuItems(menu); } // Submenu title Subhead* subhead = new Subhead (menu, "subhead", TQString("Connection Management"), SmallIcon("tdenetworkmanager_disabled", TQIconSet::Automatic)); menu->insertItem (subhead, -1, -1); // New connection KAction * newConnAction = 0; int devices = d->trayComponents.count(); if ( devices > 1 ) { newConnAction = actionCollection ()->action ("new_connection_menu"); KActionMenu* newConnActionMenu = static_cast(newConnAction); newConnActionMenu->popupMenu()->clear(); TQValueList::Iterator it; for (it = d->trayComponents.begin(); it != d->trayComponents.end(); ++it) { DeviceTrayComponent* dev_comp = dynamic_cast (*it); KAction * deviceNewConnAction = 0; if (dev_comp) { TQString actionName = TQString("new_connection_%1").arg(dev_comp->device()->deviceNode()); TQString menuCaption = TQString("%1").arg(dev_comp->device()->deviceNode()); if (menuCaption.contains("eth", FALSE) > 0) { menuCaption = menuCaption.insert(0, "Wired Connection ("); } else if (menuCaption.contains("wlan", FALSE) > 0) { menuCaption = menuCaption.insert(0, "Wireless Connection ("); } else if (menuCaption.contains("pan", FALSE) > 0) { menuCaption = menuCaption.insert(0, "Private Area Connection ("); } else { menuCaption = menuCaption.insert(0, "Unknown Connection ("); } menuCaption = menuCaption.append(")"); deviceNewConnAction = actionCollection ()->action (actionName); if (!deviceNewConnAction) { deviceNewConnAction = new KAction (menuCaption, 0, (*it), TQT_SLOT(newConnection()), actionCollection(), actionName); } newConnActionMenu->insert(deviceNewConnAction); } } } else if ( devices == 1 ) { newConnAction = actionCollection ()->action ("new_connection"); TQT_BASE_OBJECT_NAME::disconnect( newConnAction, TQT_SIGNAL(activated()) ); TQT_BASE_OBJECT_NAME::connect( newConnAction, TQT_SIGNAL(activated()), d->trayComponents[0], TQT_SLOT(newConnection())); } if (newConnAction) { newConnAction->plug(menu); } // turn things off if (nm) { KActionMenu* disableStuffActionMenu = static_cast(actionCollection ()->action ("deactivate_menu") ); disableStuffActionMenu->popupMenu()->clear(); TDENetworkConnectionList* map = nm->connections(); d->act_conn_map.clear(); for (TDENetworkConnectionList::Iterator it = map->begin(); it != map->end(); ++it) { TDENetworkConnection* conn = (*it); if (!conn) { continue; } if ((nm->checkConnectionStatus(conn->UUID) & TDENetworkConnectionStatus::Disconnected) || (nm->checkConnectionStatus(conn->UUID) & TDENetworkConnectionStatus::Invalid)) { continue; } TQString actionName = TQString("disable_connection_%1").arg(conn->UUID); KAction * deviceNewConnAction = actionCollection ()->action (actionName); TQString actionText = conn->friendlyName; if (!deviceNewConnAction) { deviceNewConnAction = new KAction (actionText, 0, &d->signalMapper, TQT_SLOT(map()), actionCollection(), actionName); } d->signalMapper.setMapping(deviceNewConnAction, d->current_idx); d->act_conn_map.insert(d->current_idx, conn); d->current_idx++; disableStuffActionMenu->insert(deviceNewConnAction); } // disable wireless if (nm->wiFiHardwareEnabled()) { KAction* wireless = NULL; if (nm->wiFiEnabled()) { wireless = actionCollection ()->action ("disable_wireless"); } else { wireless = actionCollection ()->action ("enable_wireless"); } disableStuffActionMenu->insert(wireless); } // offline vs. online mode KAction* switch_mode = NULL; if (nm->backendStatus() != TDENetworkGlobalManagerFlags::Sleeping) { switch_mode = actionCollection ()->action ("offline_mode"); } else { switch_mode = actionCollection ()->action ("online_mode"); } disableStuffActionMenu->insert(switch_mode); disableStuffActionMenu->plug(menu); } } else { Subhead* subhead = new Subhead (menu, "subhead", i18n("NetworkManager is not running"), SmallIcon("stop", TQIconSet::Automatic)); menu->insertItem (subhead, -1, -1); } // Notifications KAction* notif = actionCollection()->action("configure_notifications"); notif->plug(menu); // Connection Editor KAction* edit = actionCollection ()->action ("edit_connections"); edit->plug(menu); // quit menu->insertSeparator (); KAction* quitAction = actionCollection ()->action (KStdAction::name (KStdAction::Quit)); if (quitAction) { quitAction->plug (menu); } } void Tray::slotStateChanged(TDENetworkGlobalManagerFlags::TDENetworkGlobalManagerFlags newState, TDENetworkGlobalManagerFlags::TDENetworkGlobalManagerFlags prevState) { TDENetworkGlobalManagerFlags::TDENetworkGlobalManagerFlags nm_state = newState; // change tray icon according to NM's state if ((nm_state & TDENetworkGlobalManagerFlags::Unknown) || (nm_state & TDENetworkGlobalManagerFlags::Sleeping) || (nm_state & TDENetworkGlobalManagerFlags::EstablishingLink) || (nm_state & TDENetworkGlobalManagerFlags::Disconnected) || (nm_state & TDENetworkGlobalManagerFlags::BackendUnavailable)) { setPixmap (loadIcon ("tdenetworkmanager_disabled")); } else if (nm_state & TDENetworkGlobalManagerFlags::Connected) { setPixmap (loadIcon ("tdenetworkmanager")); } printf("NM state: %d\n\r", nm_state); } void Tray::enterEvent (TQEvent* /*e*/) { // show tooltip TQToolTip::remove (this); TQString tooltip = ""; // build up the tooltip from all tray components for (TQValueList::Iterator it = d->trayComponents.begin(); it != d->trayComponents.end(); ++it) { TrayComponent* comp = *it; if (comp->getToolTipText().isEmpty()) continue; if (!tooltip.isEmpty()) tooltip += "\n\n"; tooltip += comp->getToolTipText().join("\n"); } if (!tooltip.isEmpty()) TQToolTip::add (this, tooltip); } void Tray::slotSecretsNeeded(TDENetworkConnection* connection, const TQStringList& hints, bool request_new) { // For now assume secrets are already in NM... } void Tray::slotAddDeviceTrayComponent(TDENetworkDevice* dev) { if (dev) { createDeviceTrayComponent(dev); } } void Tray::slotRemoveDeviceTrayComponent(TDENetworkDevice* dev) { for (TQValueList::Iterator it = d->trayComponents.begin(); it != d->trayComponents.end(); ++it) { DeviceTrayComponent* dev_comp = dynamic_cast(*it); if (!dev_comp) continue; if (dev_comp->device() == dev) { if (d->foregroundTrayComponent && dev_comp->device() == d->foregroundTrayComponent->device() ) { d->foregroundTrayComponent = 0; } // remove the appropriate action TQString actionName = TQString("new_connection_%1").arg(dev_comp->device()->deviceNode()); KAction * deviceNewConnAction = actionCollection ()->action (actionName); if (!deviceNewConnAction) { delete deviceNewConnAction; deviceNewConnAction = NULL; } // remove device_tray and delete it d->trayComponents.remove(it); delete dev_comp; if (contextMenu()->isVisible()) { contextMenu()->hide(); } break; } } } void Tray::createDeviceTrayComponent(TDENetworkDevice* dev) { bool trayExists = false; if (!dev) return; // check if we have already a trayicon for this device for (TQValueList::Iterator it = d->trayComponents.begin(); it != d->trayComponents.end(); ++it) { DeviceTrayComponent* dev_comp = dynamic_cast (*it); if (dev_comp) if (dev_comp->device() == dev) { trayExists = true; break; } } // create the appropriate device tray icon if (!trayExists) { DeviceTrayComponent* devTray = 0; TDENetworkConnectionManager* deviceConnMan = dev->connectionManager(); // different tray icons for different device types! switch (deviceConnMan->deviceType()) { case TDENetworkDeviceType::WiredEthernet: devTray = new WiredDeviceTray(dev, this, "wired_device_tray"); break; case TDENetworkDeviceType::WiFi: devTray = new WirelessDeviceTray(dev, this, "wireless_device_tray"); break; case TDENetworkDeviceType::Modem: devTray = new CellularDeviceTray(dev, this, "cellular_device_tray"); break; default: kdWarning() << k_funcinfo << "UDI: " << dev->uniqueID() << " has unknown devicetype: " << deviceConnMan->deviceType() << endl; } if(devTray) { connect( devTray, TQT_SIGNAL(needsCenterStage(TrayComponent*,bool)), TQT_SLOT(trayComponentNeedsCenterStage(TrayComponent*,bool))); connect( devTray, TQT_SIGNAL(uiUpdated()), TQT_SLOT(trayUiChanged())); d->trayComponents.append(devTray); //WILLTODO: sort } } } void Tray::updateDeviceTrays() { TDEHardwareDevices *hwdevices = KGlobal::hardwareDevices(); if (!hwdevices) return; // create one tray-icon for each device TDEGenericHardwareList devices = hwdevices->listByDeviceClass(TDEGenericDeviceType::Network); // check for newly added devices for (TDEGenericHardwareList::iterator it = devices.begin(); it != devices.end(); ++it) { TDENetworkDevice* dev = dynamic_cast(*it); if (dev) { createDeviceTrayComponent(dev); } else { kdWarning() << k_funcinfo << "got a NULL-Device" << endl; } } } void Tray::mousePressEvent( TQMouseEvent *e ) { if ( !TQT_TQRECT_OBJECT(rect()).contains( e->pos() ) ) { return; } switch ( e->button() ) { case Qt::LeftButton: contextMenuAboutToShow(contextMenu()); contextMenu()->popup(e->globalPos()); break; default: KSystemTray::mousePressEvent( e ); break; } } void Tray::slotDeactivateConnection(int index) { TDENetworkConnection* conn = d->act_conn_map[index]; TDEGlobalNetworkManager* nm = KGlobal::networkManager(); if (!nm) return; if (conn) { nm->deactivateConnection(conn->UUID); } } void Tray::trayComponentNeedsCenterStage(TrayComponent *component, bool needsIt) { DeviceTrayComponent * dtc = dynamic_cast(component); if (dtc) { kdDebug() << k_funcinfo << dtc->device()->deviceNode() << " : " << needsIt << endl; TDENetworkDevice * device = dtc->device(); if (needsIt) { if (d->foregroundTrayComponent) { disconnect(d->foregroundTrayComponent->device(), TQT_SIGNAL(StateChanged(NMDeviceState)), this, 0 ); } d->foregroundTrayComponent = dtc; connect(device, TQT_SIGNAL(StateChanged(NMDeviceState)), TQT_SLOT(slotUpdateDeviceState(NMDeviceState))); } else { disconnect(device, TQT_SIGNAL(StateChanged(NMDeviceState)), this, 0 ); // use active default #if 0 // FIXME // The TDE network backend has no concept of a default device // Should it? device = nm->getDefaultDevice(); if ( device ) { // identify the new foreground for (TQValueList::Iterator it = d->trayComponents.begin(); it != d->trayComponents.end(); ++it) { DeviceTrayComponent* newDtc = dynamic_cast (*it); if ( newDtc && newDtc->device() == device ) { d->foregroundTrayComponent = newDtc; break; } } kdDebug() << " Device " << dtc->device()->deviceNode() << " background, new foreground device: " << device->deviceNode() << endl; connect(device, TQT_SIGNAL(StateChanged(NMDeviceState)), TQT_SLOT(slotUpdateDeviceState(NMDeviceState))); slotUpdateDeviceState(device->getState()); } #endif } } } void Tray::slotUpdateDeviceState() { // FIXME } void Tray::slotUpdateDeviceState(TDENetworkConnectionStatus::TDENetworkConnectionStatus state) { updateTrayIcon(state); updateActiveConnection(state); } void Tray::trayUiChanged() { DeviceTrayComponent * dtc = d->foregroundTrayComponent; if (dtc) { TDENetworkConnectionManager* deviceConnMan = dtc->device()->connectionManager(); updateTrayIcon(deviceConnMan->deviceInformation().statusFlags); } } void Tray::updateTrayIcon(TDENetworkConnectionStatus::TDENetworkConnectionStatus state) { // Get all active connections char found_any_active_connection=0; TDEGlobalNetworkManager* nm = KGlobal::networkManager(); found_any_active_connection = 0; // Get all active connections TDENetworkConnectionList* allconmap = nm->connections(); for (TDENetworkConnectionList::Iterator it = allconmap->begin(); it != allconmap->end(); ++it) { TDENetworkConnection* conn = (*it); if (!conn) { continue; } if ((nm->checkConnectionStatus(conn->UUID) & TDENetworkConnectionStatus::Disconnected) || (nm->checkConnectionStatus(conn->UUID) & TDENetworkConnectionStatus::Invalid)) { continue; } // Found an active connection found_any_active_connection = 1; } // if (found_any_active_connection == 1) { // printf("Active connection found\n\r"); // } // stop the old movie to avoid unnecessary wakups DeviceTrayComponent * dtc = d->foregroundTrayComponent; if (movie()) movie()->pause(); if ((dtc) && (found_any_active_connection == 1)) { if (!dtc->movieForState(state).isNull()) { // animation desired int frame = -1; if (movie()) frame = movie()->frameNumber(); // set the movie setMovie(dtc->movieForState(state)); // start at the same frame as the movie before if (frame > 0) movie()->step(frame); // start the animation movie()->unpause(); } else if (!dtc->pixmapForState(state).isNull()) setPixmap(dtc->pixmapForState(state)); else setPixmap(loadIcon("tdenetworkmanager")); } else { setPixmap(loadIcon("tdenetworkmanager")); } nm_device_state_global = state; //printf("Device state: %d\n\r", nm_device_state_global); } void Tray::updateActiveConnection(TDENetworkConnectionStatus::TDENetworkConnectionStatus state) { if (state != TDENetworkConnectionStatus::Connected) { return; } } void Tray::slotDeviceAddedNotify(TDENetworkDevice* dev) { kdDebug() << "Tray::slotDeviceAddedNotify" << endl; KNotifyClient::event( winId(), "knm-nm-device-added", i18n("New network device %1 found").arg(dev->deviceNode()) ); } void Tray::slotDeviceRemovedNotify(TDENetworkDevice* dev) { kdDebug() << "Tray::slotDeviceRemovedNotify" << endl; KNotifyClient::event( winId(), "knm-nm-device-removed", i18n("Network device %1 removed").arg(dev->deviceNode()) ); } void Tray::slotStateChangedNotify(TDENetworkGlobalManagerFlags::TDENetworkGlobalManagerFlags newState, TDENetworkGlobalManagerFlags::TDENetworkGlobalManagerFlags prevState) { TDENetworkGlobalManagerFlags::TDENetworkGlobalManagerFlags nm_state = newState; // change tray icon according to NM's state if (nm_state & TDENetworkGlobalManagerFlags::EstablishingLink) { KNotifyClient::event( winId(), "knm-nm-connecting", i18n("NetworkManager is connecting") ); } else if (nm_state & TDENetworkGlobalManagerFlags::Disconnected) { KNotifyClient::event( winId(), "knm-nm-disconnected", i18n("NetworkManager is now disconnected") ); } else if (nm_state & TDENetworkGlobalManagerFlags::Connected) { KNotifyClient::event( winId(), "knm-nm-connected", i18n("NetworkManager is now connected") ); } else if (nm_state & TDENetworkGlobalManagerFlags::Sleeping) { KNotifyClient::event( winId(), "knm-nm-sleeping", i18n("KNetworkManager Offline") ); } else if (nm_state & TDENetworkGlobalManagerFlags::Unknown) { // } } void Tray::slotEditNotifications() { KNotifyDialog::configure(this); } Tray::Tray () : KSystemTray () { d = new TrayPrivate(TQT_TQOBJECT(this)); connect(&d->signalMapper, TQT_SIGNAL(mapped(int)), this, TQT_SLOT(slotDeactivateConnection(int))); setPixmap (loadIcon ("tdenetworkmanager")); setMouseTracking (true); // Actions used for plugging into the menu new KAction (i18n ("Switch to offline mode"), SmallIcon ("no", TQIconSet::Automatic), 0, TQT_TQOBJECT(this), TQT_SLOT (slotOfflineMode()), actionCollection (), "offline_mode"); new KAction (i18n ("Switch to online mode"), SmallIcon ("ok", TQIconSet::Automatic), 0, TQT_TQOBJECT(this), TQT_SLOT (slotOnlineMode()), actionCollection (), "online_mode"); new KAction (i18n ("Disable Wireless"), SmallIcon ("wireless_off", TQIconSet::Automatic), 0, TQT_TQOBJECT(this), TQT_SLOT (slotDisableWireless()), actionCollection (), "disable_wireless"); new KAction (i18n ("Enable Wireless"), SmallIcon ("wireless", TQIconSet::Automatic), 0, TQT_TQOBJECT(this), TQT_SLOT (slotEnableWireless()), actionCollection (), "enable_wireless"); new KAction (i18n ("Edit Connections"), SmallIcon ("edit", TQIconSet::Automatic), 0, TQT_TQOBJECT(this), TQT_SLOT (slotEditConnections()), actionCollection (), "edit_connections"); new KAction (i18n ("Configure Notifications"), SmallIcon ("knotify", TQIconSet::Automatic), 0, TQT_TQOBJECT(this), TQT_SLOT (slotEditNotifications()), actionCollection (), "configure_notifications"); // this action is only connected when the menu is shown, hence the 0 receiver new KAction (i18n ("New connection ..."), SmallIcon ("filenew", TQIconSet::Automatic), 0, TQT_TQOBJECT(this), 0, actionCollection (), "new_connection"); new KActionMenu (i18n ("New connection ..."), SmallIcon ("filenew", TQIconSet::Automatic), actionCollection(), "new_connection_menu"); new KActionMenu (i18n ("Deactivate connection..."), SmallIcon ("no", TQIconSet::Automatic), actionCollection (), "deactivate_menu"); // get notified when NM's state changes connect(KGlobal::networkManager(), TQT_SIGNAL(networkConnectionStateChanged(TDENetworkGlobalManagerFlags::TDENetworkGlobalManagerFlags, TDENetworkGlobalManagerFlags::TDENetworkGlobalManagerFlags)), this, TQT_SLOT(slotStateChanged(TDENetworkGlobalManagerFlags::TDENetworkGlobalManagerFlags, TDENetworkGlobalManagerFlags::TDENetworkGlobalManagerFlags))); // get notified about new/removed devices // FIXME // DeviceStore* store = DeviceStore::getInstance(); // connect(store, TQT_SIGNAL(DeviceStoreChanged()), this, TQT_SLOT(updateDeviceTrays())); // connect(store, TQT_SIGNAL(DeviceAdded(TDENetworkDevice*)), this, TQT_SLOT(slotAddDeviceTrayComponent(TDENetworkDevice*))); // connect(store, TQT_SIGNAL(DeviceRemoved(TDENetworkDevice*)), this, TQT_SLOT(slotRemoveDeviceTrayComponent(TDENetworkDevice*))); // Notifications connect(KGlobal::networkManager(), TQT_SIGNAL(networkConnectionStateChanged(TDENetworkGlobalManagerFlags::TDENetworkGlobalManagerFlags, TDENetworkGlobalManagerFlags::TDENetworkGlobalManagerFlags)), this, TQT_SLOT(slotStateChangedNotify(TDENetworkGlobalManagerFlags::TDENetworkGlobalManagerFlags, TDENetworkGlobalManagerFlags::TDENetworkGlobalManagerFlags))); // connect(store, TQT_SIGNAL(DeviceAdded(TDENetworkDevice*)), this, TQT_SLOT(slotDeviceAddedNotify(TDENetworkDevice*))); // connect(store, TQT_SIGNAL(DeviceRemoved(TDENetworkDevice*)), this, TQT_SLOT(slotDeviceRemovedNotify(TDENetworkDevice*))); // initial setup of the device-trays updateDeviceTrays(); slotStateChanged(KGlobal::networkManager()->backendStatus(), TDENetworkGlobalManagerFlags::Unknown); } Tray::~Tray () { delete d; } #include "tdenetman-tray.moc"