summaryrefslogtreecommitdiffstats
path: root/knetworkmanager-0.8/src/knetworkmanager-tray.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'knetworkmanager-0.8/src/knetworkmanager-tray.cpp')
-rw-r--r--knetworkmanager-0.8/src/knetworkmanager-tray.cpp1127
1 files changed, 1127 insertions, 0 deletions
diff --git a/knetworkmanager-0.8/src/knetworkmanager-tray.cpp b/knetworkmanager-0.8/src/knetworkmanager-tray.cpp
new file mode 100644
index 0000000..24a91a9
--- /dev/null
+++ b/knetworkmanager-0.8/src/knetworkmanager-tray.cpp
@@ -0,0 +1,1127 @@
+/***************************************************************************
+ *
+ * knetworkmanager-tray.cpp - A NetworkManager frontend for KDE
+ *
+ * Copyright (C) 2005, 2006 Novell, Inc.
+ *
+ * Author: Timo Hoenig <thoenig@suse.de>, <thoenig@nouse.net>
+ * Will Stephenson <wstephenson@suse.de>, <wstephenson@kde.org>
+ * Valentine Sinitsyn <e_val@inbox.ru>
+ * Helmut Schaa <hschaa@suse.de>, <helmut.schaa@gmx.de>
+ * Alexander Naumov <anaumov@suse.de>, <posix.ru@gmail.com>
+ * Author: Timothy Pearson <kb9vqf@pearsoncomputing.net>
+ *
+ * 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 <tqsignalmapper.h>
+#include <tqevent.h>
+#include <tqvbox.h>
+#include <tqlayout.h>
+#include <tqpushbutton.h>
+#include <tqpixmap.h>
+#include <tqpixmapcache.h>
+#include <tqpainter.h>
+#include <tqstyle.h>
+#include <tqvaluelist.h>
+#include <dcopclient.h>
+#include <tqdbusobjectpath.h>
+#include <kdebug.h>
+#include <kdialogbase.h>
+#include <knotifyclient.h>
+#include <knotifydialog.h>
+#include <klocale.h>
+#include <kstdguiitem.h>
+#include <khelpmenu.h>
+#include <kprocess.h>
+#include <kiconloader.h>
+#include <kconfig.h>
+#include <kmessagebox.h>
+
+#include <tqpushbutton.h>
+#include <tqlayout.h>
+#include <tqlabel.h>
+#include <tqapplication.h>
+#include <tqdialog.h>
+
+#include <NetworkManager.h>
+#include <NetworkManagerVPN.h>
+
+#include <tqdbuserror.h>
+
+#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 <stdio.h>
+
+#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<ConnectionSettings::GenericConnection*>(_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<TrayComponent*> trayComponents;
+ DeviceTrayComponent * foregroundTrayComponent;
+ TQSignalMapper signalMapper;
+ TQMap<int, TQPair<ConnectionSettings::Connection*, Device*> > 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<TrayComponent*>::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<KActionMenu*>(newConnAction);
+ newConnActionMenu->popupMenu()->clear();
+ TQValueList<TrayComponent*>::Iterator it;
+ for (it = d->trayComponents.begin();
+ it != d->trayComponents.end();
+ ++it)
+ {
+ DeviceTrayComponent* dev_comp = dynamic_cast<DeviceTrayComponent*> (*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<KActionMenu*>(actionCollection ()->action ("deactivate_menu") );
+ disableStuffActionMenu->popupMenu()->clear();
+ TQValueList<TQPair<ConnectionSettings::Connection*, Device*> > map = nm->getActiveConnectionsMap();
+ d->act_conn_map.clear();
+
+ for (TQValueList<TQPair<ConnectionSettings::Connection*, Device*> >::Iterator it = map.begin(); it != map.end(); ++it)
+ {
+ ConnectionSettings::GenericConnection* conn = dynamic_cast<ConnectionSettings::GenericConnection*>((*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<ConnectionSettings::Connection*, Device*> (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<TrayComponent*>::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<ConnectionSettings::VPNConnection*>(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<TQString, TQString> 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<TQString, TQString> map;
+ for(TQMap<TQString, TQString>::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 <string> stuff
+ xmldata.replace("<string>", "");
+ xmldata.replace("</string>", "");
+ //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<VPN*>(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<ConnectionSettings::VPNConnection*>(connection);
+ VPNAuthenticationDialog* auth = new VPNAuthenticationDialog(conn, this, "vpnauth");
+ // Prefill the password dialog with cached credentials
+ TQString passdata;
+ for(TQMap<TQString, TQString>::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<ConnectionSettings::VPNConnection*>(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<ConnectionSettings::VPNConnection*>(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<TrayComponent*>::Iterator it = d->trayComponents.begin(); it != d->trayComponents.end(); ++it)
+ {
+ DeviceTrayComponent* dev_comp = dynamic_cast<DeviceTrayComponent*>(*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<TrayComponent*>::Iterator it = d->trayComponents.begin(); it != d->trayComponents.end(); ++it)
+ {
+ DeviceTrayComponent* dev_comp = dynamic_cast<DeviceTrayComponent*> (*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<WiredDevice*>(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<WirelessDevice*>(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<CellularDevice*>(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<TrayComponent*>::Iterator it = d->trayComponents.begin(); it != d->trayComponents.end(); ++it)
+ {
+ VPNTrayComponent* vpn_comp = dynamic_cast<VPNTrayComponent*> (*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<Device*> devices = store->getDevices();
+
+ // check for newly added devices
+ for (TQValueList<Device*>::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<DeviceTrayComponent*>(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<TrayComponent*>::Iterator it = d->trayComponents.begin(); it != d->trayComponents.end(); ++it)
+ {
+ DeviceTrayComponent* newDtc = dynamic_cast<DeviceTrayComponent*> (*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<TQPair<ConnectionSettings::Connection*, Device*> > map = nm->getActiveConnectionsMap();
+
+ // get all available VPN Connections
+ TQValueList<Connection*> connections = connectionStore->getConnections(NM_SETTING_VPN_SETTING_NAME);
+ if (!connections.empty())
+ {
+ for (TQValueList<Connection*>::iterator it = connections.begin(); it != connections.end(); ++it)
+ {
+ VPNConnection* vpnconn = dynamic_cast<VPNConnection*>(*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<TQPair<ConnectionSettings::Connection*, Device*> >::Iterator it = map.begin(); it != map.end(); ++it)
+ {
+ ConnectionSettings::GenericConnection* conn = dynamic_cast<ConnectionSettings::GenericConnection*>((*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<TQPair<ConnectionSettings::Connection*, Device*> > allconnmap = nm->getActiveConnectionsMap();
+ for (TQValueList<TQPair<ConnectionSettings::Connection*, Device*> >::Iterator it = allconnmap.begin(); it != allconnmap.end(); ++it)
+ {
+ ConnectionSettings::GenericConnection* conn = dynamic_cast<ConnectionSettings::GenericConnection*>((*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<Info*>(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"
+