/*************************************************************************** * * knetworkmanager-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 * **************************************************************************/ class WirelessDialog; #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 #include #include #include #include "xmlmarshaller.h" #include "vpn_tray_component.h" #include "devicetraycomponent.h" #include "knetworkmanager-cellular_device_tray.h" #include "knetworkmanager-cellular_device.h" #include "knetworkmanager-device.h" #include "knetworkmanager-devicestore.h" #include "knetworkmanager-tray.h" #include "knetworkmanager-menu_subhead.h" #include "knetworkmanager-nm_proxy.h" #include "knetworkmanager-connection.h" #include "knetworkmanager-connection_setting_info.h" #include "knetworkmanager-connection_settings_dialog.h" #include "knetworkmanager-connection_store.h" #include "knetworkmanager-vpn_connection.h" #include "knetworkmanager-connection.h" #include "knetworkmanager-storage.h" #include "knetworkmanager-connection_editor.h" #include "knetworkmanager-vpnauthenticationdialog.h" #include "knetworkmanager-wired_device.h" #include "knetworkmanager-wired_device_tray.h" #include "knetworkmanager-wireless_device_tray.h" #include "knetworkmanager-wireless_device.h" #include #define KDED_NETWORK_NAME "NMNetwork" #if !defined(NM_CHECK_VERSION) #define NM_CHECK_VERSION(x,y,z) 0 #endif extern unsigned int current_vpn_state; NMDeviceState nm_device_state_global; extern unsigned char vpn_new_credentials_needed; NewSecretsDialog::NewSecretsDialog(ConnectionSettings::Connection *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, NULL, Tray::getInstance(), "Edit connection"); dlg->show(); close(); } void NewSecretsDialog::reject() { _connection->slotSecretsError(); TQDialog::reject(); } void NewSecretsDialog::init() { ConnectionSettings::GenericConnection* conn = dynamic_cast(_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 ").tqarg(conn->getInfoSetting()->getName()), 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() { NMProxy* nm = NMProxy::getInstance(); TQT_DBusError err; if (!nm) return; nm->setWirelessEnabled(true, err); } void Tray::slotDisableWireless() { NMProxy* nm = NMProxy::getInstance(); TQT_DBusError err; if (!nm) return; nm->setWirelessEnabled(false, err); } void Tray::slotOfflineMode() { NMProxy* nm = NMProxy::getInstance(); TQT_DBusError err; if (!nm) return; nm->Sleep(true, err); } void Tray::slotOnlineMode() { NMProxy* nm = NMProxy::getInstance(); TQT_DBusError err; if (!nm) return; nm->Sleep(false, err); } void Tray::slotNewVPNConnection() { printf("Creating new VPN connection\n\r"); // create a new VPN connection Connection* conn = new VPNConnection(); // edit the new connection ConnectionSettingsDialogImpl* dlg = new ConnectionSettingsDialogImpl(conn, true, NULL, this, "connect_something", false, TQt::WDestructiveClose); dlg->show(); } void Tray::contextMenuAboutToShow (KPopupMenu* menu) { TQT_DBusError err; NMProxy* nm = NMProxy::getInstance(); // clear menu menu->clear(); if (nm->isNMRunning()) { // 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("knetworkmanager_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").tqarg(dev_comp->device()->getInterface()); TQString menuCaption = TQString("%1").tqarg(dev_comp->device()->getInterface()); 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); } } // New VPN connection option ++it; KAction * deviceNewConnAction = 0; TQString menuCaption = "VPN Connection"; TQString actionName = TQString("new_connection_%1").tqarg("vpn"); deviceNewConnAction = new KAction (menuCaption, 0, TQT_TQOBJECT(this), TQT_SLOT(slotNewVPNConnection()), 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(); TQValueList > map = nm->getActiveConnectionsMap(); d->act_conn_map.clear(); for (TQValueList >::Iterator it = map.begin(); it != map.end(); ++it) { ConnectionSettings::GenericConnection* conn = dynamic_cast((*it).first); Device* dev = (*it).second; if (!conn) continue; TQString actionName = TQString("disable_connection_%1_%2").tqarg(conn->getID()).tqarg(dev ? dev->getInterface() : ""); KAction * deviceNewConnAction = actionCollection ()->action (actionName); TQString actionText = conn->getInfoSetting()->getName(); if (dev) actionText += TQString(" (%1)").tqarg(dev->getInterface()); 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, TQPair (conn, dev)); d->current_idx++; disableStuffActionMenu->insert(deviceNewConnAction); } // disable wireless if (nm->getWirelessHardwareEnabled(err)) { KAction* wireless = NULL; if (nm->getWirelessEnabled(err)) { wireless = actionCollection ()->action ("disable_wireless"); } else { wireless = actionCollection ()->action ("enable_wireless"); } disableStuffActionMenu->insert(wireless); } // offline vs. online mode KAction* switch_mode = NULL; if (nm->getState(err) != NM_STATE_ASLEEP) { 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(TQ_UINT32 state) { NMState nm_state = (NMState) state; // change tray icon according to NM's state switch(nm_state) { case NM_STATE_UNKNOWN: case NM_STATE_ASLEEP: case NM_STATE_CONNECTING: case NM_STATE_DISCONNECTED: setPixmap (loadIcon ("knetworkmanager_disabled")); break; case NM_STATE_CONNECTED: setPixmap (loadIcon ("knetworkmanager")); break; } 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::slotVPNSecretsNeeded(ConnectionSettings::Connection* connection, ConnectionSettings::ConnectionSetting* setting, const TQStringList& hints, bool request_new) { #warning Implement Tray::slotVPNSecretsNeeded to handle parms properly Q_UNUSED(hints); Storage* storage = Storage::getInstance(); bool hasSecretsStored = storage->hasSecretsStored(connection, setting); printf("Tray::slotVPNSecretsNeeded\n\r"); kdDebug() << "Tray::slotVPNSecretsNeeded" << endl; // default secrets handling for all other connection types // 1) if we have secrets stored, restore them and send them back to NM // 2) if NM requests new secrets we should allow the user to retry the // connection or to edit it //if (hasSecretsStored && (!request_new)) if (hasSecretsStored) { printf("Tray::slotVPNSecretsNeeded: Restoring saved secrets\n\r"); // We have secrets stored, restore them // if (storage->restoreVPNSecrets(connection, setting)) // { int number_of_secrets_found = 0; ConnectionSettings::VPNConnection* conn = dynamic_cast(connection); TQString id = connection->getID(); TQString type = setting->getType(); printf("restoreVPNSecrets\n\r"); // ID is necessary if (id.isEmpty()) { printf("VPN connection ID is empty!\n\r"); } else { // Get a group for this setting TQString setting_grp = TQString("ConnectionSecrets_%1_%2").tqarg(id).tqarg(type); // Restore the settings printf("Restoring VPN secret: %s\n\r", setting_grp.ascii()); KConfigGroup secrets_grp(KGlobal::config(), setting_grp); TQMap config_map = KGlobal::config()->entryMap(setting_grp); TQString typetwo = secrets_grp.readEntry("Type"); // // get the appropriate setting from the connection // ConnectionSetting* setting = conn->getSetting(typetwo); // if (!setting) // { // printf("Secrets cannot be restored!\n\r"); // } // Read the SettingsMap from kconfig // This loop reads the secrets information map only TQMap map; for(TQMap::ConstIterator it = config_map.begin(); it != config_map.end(); ++it) { if (!it.key().startsWith("Value_")) continue; TQString key = it.key(); // Get the original key name key.replace("Value_", ""); TQString xmldata = it.data(); // Remove the annoying XML stuff xmldata.replace("", ""); xmldata.replace("", ""); //printf("Got %s with value %s\n\r", key.ascii(), xmldata.ascii()); map.insert(key, xmldata); number_of_secrets_found++; } if (number_of_secrets_found > 0) { printf("Got secrets from file, continuing...\n\r"); // Good, we have new secrets now, update the settings //map = _vpnAuthWidget->getPasswords(); ConnectionSetting* propcore = conn->getVPNSettingConnectionCore(); SettingsMap othersettingsmap = propcore->toMap(); // Pull the username and gateway out of map to stuff in the NM standard settings matrix othersettingsmap.insert("user", TQT_DBusData::fromString(map["user"])); map.erase("user"); othersettingsmap.insert("domain", TQT_DBusData::fromString(map["domain"])); map.erase("domain"); if (!request_new) { propcore->fromMap(othersettingsmap); VPN* prop = dynamic_cast(propcore); prop->setSecrets(map); conn->slotSecretsProvided(prop); } else { printf("Tray::slotVPNSecretsNeeded: New secrets requested\n\r"); // OK, NM requests new secrets...do something! ConnectionSettings::VPNConnection* conn = dynamic_cast(connection); VPNAuthenticationDialog* auth = new VPNAuthenticationDialog(conn, this, "vpnauth"); // Prefill the password dialog with cached credentials TQString passdata; for(TQMap::ConstIterator it = map.begin(); it != map.end(); ++it) { passdata = it.data(); // Remove any non-typable characters from the string! passdata.remove("\r"); passdata.remove("\n"); passdata.remove("\t"); //printf("Trying to set %s to value %s\n\r", it.key().ascii(), passdata.ascii()); auth->setPasswords(it.key(), passdata); } auth->show(); } //connection->slotSecretsProvided(setting); } else { printf("Tray::slotVPNSecretsNeeded: New secrets needed\n\r"); // OK, NM needs new secrets...do something! ConnectionSettings::VPNConnection* conn = dynamic_cast(connection); VPNAuthenticationDialog* auth = new VPNAuthenticationDialog(conn, this, "vpnauth"); auth->show(); } } // } } else { printf("Tray::slotVPNSecretsNeeded: New secrets needed\n\r"); // OK, NM needs new secrets...do something! ConnectionSettings::VPNConnection* conn = dynamic_cast(connection); VPNAuthenticationDialog* auth = new VPNAuthenticationDialog(conn, this, "vpnauth"); auth->show(); } } void Tray::slotSecretsNeeded(ConnectionSettings::Connection* connection, ConnectionSettings::ConnectionSetting* setting, const TQStringList& hints, bool request_new) { Storage* storage = Storage::getInstance(); bool hasSecretsStored = storage->hasSecretsStored(connection, setting); // FIXME ugly secrets handling for VPN if (connection->getType() == NM_SETTING_VPN_SETTING_NAME) { if (vpn_new_credentials_needed == 1) { printf("VPN connection failed with bad credentials\n\r"); vpn_new_credentials_needed = 0; request_new = 1; } slotVPNSecretsNeeded(connection, setting, hints, request_new); return; } // default secrets handling for all other connection types // 1) if we have secrets stored, restore them and send them back to NM // 2) if NM requests new secrets we should allow the user to retry the // connection or to edit it if (hasSecretsStored && !request_new) { // We have secrets stored, restore them if (storage->restoreSecrets(connection, setting)) { connection->slotSecretsProvided(setting); } } else { // ok, NM requests new secrets, let's ask the user if he wants to retry // or edit the connection NewSecretsDialog* dlg = new NewSecretsDialog(connection, this, "knetworkmanager"); dlg->show(); } } void Tray::slotAddDeviceTrayComponent(Device* dev) { if (dev) createDeviceTrayComponent(dev); } void Tray::slotRemoveDeviceTrayComponent(Device* 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").tqarg(dev_comp->device()->getInterface()); 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(Device* 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; // different tray icons for different device types! switch (dev->getDeviceType()) { #if NM_CHECK_VERSION(0,8,992) case NM_DEVICE_TYPE_ETHERNET: #else case DEVICE_TYPE_802_3_ETHERNET: #endif devTray = new WiredDeviceTray(dynamic_cast(dev), this, "wired_device_tray"); break; #if NM_CHECK_VERSION(0,8,992) case NM_DEVICE_TYPE_WIFI: #else case DEVICE_TYPE_802_11_WIRELESS: #endif devTray = new WirelessDeviceTray(static_cast(dev), this, "wireless_device_tray"); break; #if NM_CHECK_VERSION(0,8,992) case NM_DEVICE_TYPE_MODEM: #else case DEVICE_TYPE_GSM: case DEVICE_TYPE_CDMA: #endif devTray = new CellularDeviceTray(static_cast(dev), this, "cellular_device_tray"); break; default: kdWarning() << k_funcinfo << "UDI: " << dev->getUdi() << " has unknown devicetype: " << dev->getDeviceType() << 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::createVPNTrayComponent() { bool trayExists = false; // check if we have already a trayicon for this device for (TQValueList::Iterator it = d->trayComponents.begin(); it != d->trayComponents.end(); ++it) { VPNTrayComponent* vpn_comp = dynamic_cast (*it); if (vpn_comp) { trayExists = true; break; } } // create the appropriate device tray icon if (!trayExists) { TrayComponent* devTray = new VPNTrayComponent(this, "vpn_device_tray"); if(devTray) { d->trayComponents.append(devTray); //WILLTODO: sort } } } void Tray::updateDeviceTrays() { // create one tray-icon for each device DeviceStore* store = DeviceStore::getInstance(); TQValueList devices = store->getDevices(); // check for newly added devices for (TQValueList::iterator it = devices.begin(); it != devices.end(); ++it) { Device* dev = (*it); if (dev) createDeviceTrayComponent(dev); else kdWarning() << k_funcinfo << "got a NULL-Device" << endl; } // add the VPN componenet as it is not associated with a device createVPNTrayComponent(); } 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) { ConnectionSettings::Connection* conn = d->act_conn_map[index].first; Device* dev = d->act_conn_map[index].second; NMProxy* nm = NMProxy::getInstance(); if (conn) { TQString actionText = conn->getObjectPath().data(); nm->deactivateConnection(conn, dev); } } void Tray::trayComponentNeedsCenterStage(TrayComponent *component, bool needsIt) { DeviceTrayComponent * dtc = dynamic_cast(component); if (dtc) { kdDebug() << k_funcinfo << dtc->device()->getInterface() << " : " << needsIt << endl; Device * 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 NMProxy* nm = NMProxy::getInstance(); 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()->getInterface() << " background, new foreground device: " << device->getInterface() << endl; connect(device, TQT_SIGNAL(StateChanged(NMDeviceState)), TQT_SLOT(slotUpdateDeviceState(NMDeviceState))); slotUpdateDeviceState(device->getState()); } } } } void Tray::slotUpdateDeviceState() { // FIXME } void Tray::slotUpdateDeviceState(NMDeviceState state) { updateTrayIcon(state); updateActiveConnection(state); } void Tray::trayUiChanged() { DeviceTrayComponent * dtc = d->foregroundTrayComponent; if (dtc) { updateTrayIcon(dtc->device()->getState()); } } void Tray::updateTrayIcon(NMDeviceState state) { // Get all active connections char active_vpn=0; char found_any_active_connection=0; ConnectionStore* connectionStore = ConnectionStore::getInstance(); NMProxy* nm = NMProxy::getInstance(); TQValueList > map = nm->getActiveConnectionsMap(); // get all available VPN Connections TQValueList connections = connectionStore->getConnections(NM_SETTING_VPN_SETTING_NAME); if (!connections.empty()) { for (TQValueList::iterator it = connections.begin(); it != connections.end(); ++it) { VPNConnection* vpnconn = dynamic_cast(*it); if (vpnconn) { // VPN connection found :) Info* info = vpnconn->getInfoSetting(); // lets create a nice name for this connection if (info) { TQString title = info->getName(); for (TQValueList >::Iterator it = map.begin(); it != map.end(); ++it) { ConnectionSettings::GenericConnection* conn = dynamic_cast((*it).first); if (conn) { if (strcmp(info->getName(), conn->getInfoSetting()->getName()) == 0) { active_vpn = 1; } } } } } } } found_any_active_connection = 0; // Get all active connections TQValueList > allconnmap = nm->getActiveConnectionsMap(); for (TQValueList >::Iterator it = allconnmap.begin(); it != allconnmap.end(); ++it) { ConnectionSettings::GenericConnection* conn = dynamic_cast((*it).first); if (!conn) continue; // Found an active connection found_any_active_connection = 1; } // if (found_any_active_connection == 1) { // printf("Active connection found\n\r"); // } if ((current_vpn_state == NM_VPN_CONNECTION_STATE_FAILED) || (current_vpn_state == NM_VPN_CONNECTION_STATE_DISCONNECTED)) { active_vpn = 0; } if (active_vpn == 0) { // 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("knetworkmanager")); } else { setPixmap(loadIcon("knetworkmanager")); } } else { printf("VPN state: %d\n\r", current_vpn_state); //printf("Activated is: %d\n\r", NM_VPN_CONNECTION_STATE_ACTIVATED); // stop the old movie to avoid unnecessary wakups DeviceTrayComponent * dtc = d->foregroundTrayComponent; if (movie()) movie()->pause(); if (dtc) { if (current_vpn_state == NM_VPN_CONNECTION_STATE_ACTIVATED) { setPixmap(loadIcon("nm_device_vpn")); } if ((current_vpn_state == NM_VPN_CONNECTION_STATE_PREPARE) || (current_vpn_state == NM_VPN_CONNECTION_STATE_NEED_AUTH) || (current_vpn_state == NM_VPN_CONNECTION_STATE_CONNECT) || (current_vpn_state == NM_VPN_CONNECTION_STATE_IP_CONFIG_GET)) { int frame = -1; if (movie()) frame = movie()->frameNumber(); // set the movie if ((current_vpn_state == NM_VPN_CONNECTION_STATE_PREPARE) || (current_vpn_state == NM_VPN_CONNECTION_STATE_NEED_AUTH)) { setMovie(TQMovie(KGlobal::iconLoader()->moviePath("nm_stage02_connecting_vpn", KIcon::Panel))); } if ((current_vpn_state == NM_VPN_CONNECTION_STATE_CONNECT) || (current_vpn_state == NM_VPN_CONNECTION_STATE_IP_CONFIG_GET)) { setMovie(TQMovie(KGlobal::iconLoader()->moviePath("nm_stage03_connecting_vpn", KIcon::Panel))); } // start at the same frame as the movie before if (frame > 0) movie()->step(frame); // start the animation movie()->unpause(); } } } nm_device_state_global = state; //printf("Device state: %d\n\r", nm_device_state_global); } void Tray::updateActiveConnection(NMDeviceState state) { if (state != NM_DEVICE_STATE_ACTIVATED) return; NMProxy* nm = NMProxy::getInstance(); if (d->foregroundTrayComponent) { Connection* active_conn = nm->getActiveConnection(d->foregroundTrayComponent->device()); if (active_conn) { Info* info = dynamic_cast(active_conn->getSetting(NM_SETTING_CONNECTION_SETTING_NAME)); if (info) info->setTimestamp(TQDateTime::tqcurrentDateTime()); } } } void Tray::slotDeviceAddedNotify(Device* dev) { kdDebug() << "Tray::slotDeviceAddedNotify" << endl; KNotifyClient::event( winId(), "knm-nm-device-added", i18n("New network device %1 found").tqarg(dev->getInterface()) ); } void Tray::slotDeviceRemovedNotify(Device* dev) { kdDebug() << "Tray::slotDeviceRemovedNotify" << endl; KNotifyClient::event( winId(), "knm-nm-device-removed", i18n("Network device %1 removed").tqarg(dev->getInterface()) ); } void Tray::slotVPNBannerShow(const TQString& vpnbanner) { printf("VPN banner: %s\n\r", vpnbanner.ascii()); KNotifyClient::event(winId(), "knm-nm-vpn-banner", vpnbanner); } void Tray::slotStateChangedNotify(TQ_UINT32 state) { NMState nm_state = (NMState) state; // change tray icon according to NM's state switch(nm_state) { case NM_STATE_CONNECTING: KNotifyClient::event( winId(), "knm-nm-connecting", i18n("NetworkManager is connecting") ); break; case NM_STATE_DISCONNECTED: KNotifyClient::event( winId(), "knm-nm-disconnected", i18n("NetworkManager is now disconnected") ); break; case NM_STATE_CONNECTED: KNotifyClient::event( winId(), "knm-nm-connected", i18n("NetworkManager is now connected") ); break; case NM_STATE_ASLEEP: KNotifyClient::event( winId(), "knm-nm-sleeping", i18n("KNetworkManager Offline") ); break; case NM_STATE_UNKNOWN: default: break; } } 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 ("knetworkmanager")); 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 NMProxy* nm = NMProxy::getInstance(); connect(nm, TQT_SIGNAL(StateChange(TQ_UINT32)), this, TQT_SLOT(slotStateChanged(TQ_UINT32))); // get notifier when NM requests new secrets ConnectionStore* cstore = ConnectionStore::getInstance(); connect(cstore, TQT_SIGNAL(SecretsNeeded(ConnectionSettings::Connection*, ConnectionSettings::ConnectionSetting*, const TQStringList&, bool)), this, TQT_SLOT(slotSecretsNeeded(ConnectionSettings::Connection*, ConnectionSettings::ConnectionSetting*, const TQStringList&, bool))); // get notified about new/removed devices DeviceStore* store = DeviceStore::getInstance(); connect(store, TQT_SIGNAL(DeviceStoreChanged()), this, TQT_SLOT(updateDeviceTrays())); connect(store, TQT_SIGNAL(DeviceAdded(Device*)), this, TQT_SLOT(slotAddDeviceTrayComponent(Device*))); connect(store, TQT_SIGNAL(DeviceRemoved(Device*)), this, TQT_SLOT(slotRemoveDeviceTrayComponent(Device*))); // Notifications connect(store, TQT_SIGNAL(DeviceAdded(Device*)), this, TQT_SLOT(slotDeviceAddedNotify(Device*))); connect(store, TQT_SIGNAL(DeviceRemoved(Device*)), this, TQT_SLOT(slotDeviceRemovedNotify(Device*))); connect(nm, TQT_SIGNAL(StateChange(TQ_UINT32)), this, TQT_SLOT(slotStateChangedNotify(TQ_UINT32))); // initial setup of the device-trays updateDeviceTrays(); TQT_DBusError err; slotStateChanged(nm->getState(err)); } Tray::~Tray () { delete d; } #include "knetworkmanager-tray.moc"