diff options
Diffstat (limited to 'knetworkmanager-0.9/src/knetworkmanager-wireless_device_tray.cpp')
-rw-r--r-- | knetworkmanager-0.9/src/knetworkmanager-wireless_device_tray.cpp | 391 |
1 files changed, 391 insertions, 0 deletions
diff --git a/knetworkmanager-0.9/src/knetworkmanager-wireless_device_tray.cpp b/knetworkmanager-0.9/src/knetworkmanager-wireless_device_tray.cpp new file mode 100644 index 0000000..9bf44ed --- /dev/null +++ b/knetworkmanager-0.9/src/knetworkmanager-wireless_device_tray.cpp @@ -0,0 +1,391 @@ +/*************************************************************************** + * + * knetworkmanager-wireless_device_tray.cpp - A NetworkManager frontend for KDE + * + * Copyright (C) 2005, 2006 Novell, Inc. + * + * Author: Helmut Schaa <[email protected]>, <[email protected]> + * + * 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 + * + **************************************************************************/ + +// TQt includes +#include <tqevent.h> +#include <tqvbox.h> +#include <tqlayout.h> +#include <tqpushbutton.h> +#include <tqbitmap.h> +#include <tqimage.h> +#include <tqpixmap.h> +#include <tqpixmapcache.h> +#include <tqpainter.h> +#include <tqstyle.h> +#include <tqstring.h> +#include <tqguardedptr.h> + +// KDE includes +#include <kdebug.h> +#include <kiconloader.h> +#include <klocale.h> +#include <knotifyclient.h> + +// QT DBus +#include <tqdbuserror.h> +#include <tqdbusobjectpath.h> + +// KNM includes +#include "knetworkmanager-wireless_device_tray.h" +#include "knetworkmanager-wireless_device.h" +#include "knetworkmanager-wireless_menuitem.h" +#include "knetworkmanager-wireless_network.h" +#include "knetworkmanager-accesspoint.h" +#include "knetworkmanager-menu_subhead.h" +#include "knetworkmanager-connection_store.h" +#include "knetworkmanager-wireless_connection.h" +#include "knetworkmanager-connection_setting_info.h" +#include "knetworkmanager-connection_setting_wireless.h" +#include "knetworkmanager-connection_setting_wireless_security.h" +#include "knetworkmanager-nm_proxy.h" +#include "knetworkmanager-wireless_manager.h" +#include "knetworkmanager-connection_settings_dialog.h" + +using namespace ConnectionSettings; + +extern char use_new_wireless_essid; +extern TQByteArray new_wireless_essid; + +class WirelessDeviceTrayPrivate +{ + public: + WirelessDeviceTrayPrivate() :dev(0), activeAccessPoint(0) { } + ~WirelessDeviceTrayPrivate() {} + + WirelessDevice* dev; + TQGuardedPtr<AccessPoint> activeAccessPoint; +}; + +TQStringList WirelessDeviceTray::getToolTipText() +{ + TQStringList tooltip = DeviceTrayComponent::getToolTipText(); + + AccessPoint * ap = d->dev->getActiveAccessPoint(); + if (ap) + tooltip.append(i18n("Network: %1").tqarg(ap->getDisplaySsid())); + + return tooltip; +} + +void WirelessDeviceTray::newConnection() +{ + // create a new wireless connection + Connection* conn = new WirelessConnection(); + + // open a dialog for editing the connection + use_new_wireless_essid = 0; // deactivate autofill for now + ConnectionSettingsDialogImpl* dlg = new ConnectionSettingsDialogImpl(conn, true, NULL, tray(), "connect_something", false, TQt::WDestructiveClose); + dlg->show(); +} + +bool WirelessDeviceTray::findMatchingNetwork(const WirelessConnection* conn, const TQValueList<WirelessNetwork>& nets, WirelessNetwork& net) +{ + Wireless* wireless = conn->getWirelessSetting(); + WirelessSecurity* security = conn->getWirelessSecuritySetting(); + + if (!wireless && !security) + return false; + + for (TQValueList<WirelessNetwork>::ConstIterator it = nets.begin(); it != nets.end(); ++it) + { + if (wireless->getEssid() == (*it).getSsid()) + { + net = *it; + return true; + } + } + return false; +} + +WirelessConnection* WirelessDeviceTray::findMatchingConnection(const WirelessNetwork& net, const TQValueList<WirelessConnection*>& connections) +{ + // try to find a connection matching this network + for (TQValueList<WirelessConnection*>::ConstIterator it = connections.begin(); it != connections.end(); ++it) + { + Wireless* wireless = (*it)->getWirelessSetting(); + WirelessSecurity* security = (*it)->getWirelessSecuritySetting(); + + // should not happen but its ever better to check + if (!wireless || !security) + continue; + + if (wireless->getEssid() == net.getSsid()) + { + return *it; + } + } + + return NULL; +} + +void WirelessDeviceTray::addWirelessNetworks(KPopupMenu* menu) +{ + printf("Updating wireless network list\n\r"); + + // get all wireless networks + TQValueList<WirelessNetwork> nets = WirelessManager::getWirelessNetworks(d->dev); + + // get all wireless connections + TQValueList<WirelessConnection*> conns = WirelessManager::getWirelessConnections(); + + // get the currently active connection + NMProxy* nm = NMProxy::getInstance(); + Connection* active_conn = nm->getActiveConnection(d->dev); + if (active_conn) + kdDebug() << active_conn->getObjectPath().data() << endl; + + // add all wireless connections in range + // (we may have more then one connection per network) + for (TQValueList<WirelessConnection*>::iterator it = conns.begin(); it != conns.end(); ++it) + { + WirelessNetworkItem* wirelessNetworkItem; + WirelessNetwork net; + + // only show connections which are in range + if ( !findMatchingNetwork(*it, nets, net) ) + continue; + + wirelessNetworkItem = new WirelessNetworkItem (menu, + d->dev, + net, + *it, + false); + int id = menu->insertItem (wirelessNetworkItem, -1, -1); + menu->setItemChecked(id, ((Connection*)(*it) == active_conn)); + menu->connectItem(id, wirelessNetworkItem, TQT_SLOT(slotActivate())); + } + + // now add all connections which are not in range to a submenu + TQPopupMenu* popup = new TQPopupMenu(menu); + + uint networkItemsAdded = 0; + for (TQValueList<WirelessConnection*>::iterator it = conns.begin(); it != conns.end(); ++it) + { + WirelessNetworkItem* wirelessNetworkItem; + WirelessNetwork net; + + // only show connections which are out of range + if ( findMatchingNetwork(*it, nets, net) ) + continue; + + Info* info = (*it)->getInfoSetting(); + Wireless* wireless = (*it)->getWirelessSetting(); + + if (!info || !wireless) + continue; + + wirelessNetworkItem = new WirelessNetworkItem (menu, + d->dev, + net, + *it, + false); + + int id = popup->insertItem (wirelessNetworkItem, -1, -1); + popup->connectItem(id, wirelessNetworkItem, TQT_SLOT(slotActivate())); + networkItemsAdded += 1; + } + + if (networkItemsAdded) { + menu->insertSeparator(); + menu->insertItem(i18n("Connect to saved network"), popup); + } + +// // List available unsaved networks + TQPopupMenu* newpopup = new TQPopupMenu(menu); + WirelessConnection* newconn; + uint newnetworkItemsAdded = 0; + TQValueList<WirelessNetwork> newnets = WirelessManager::getWirelessNetworks(0, WirelessNetwork::MATCH_SSID); + + for (TQValueList<WirelessNetwork>::Iterator it = newnets.begin(); it != newnets.end(); ++it) + { + // Only display networks with no existing connnection + if ( findMatchingConnection(*it, conns) != NULL) + continue; + + WirelessNetworkItem* wirelessNetworkItem; + wirelessNetworkItem = new WirelessNetworkItem (menu, + d->dev, + *it, + NULL, + false); + + int id = newpopup->insertItem (wirelessNetworkItem, -1, -1); + newpopup->connectItem(id, this, TQT_SLOT(newConnection())); + + newnetworkItemsAdded += 1; + } + + if (newnetworkItemsAdded) { + menu->insertSeparator(); + menu->insertItem(i18n("Connect to new network"), newpopup); + } + // Signal done with wireless menu + //menu->insertSeparator(); +} + +void WirelessDeviceTray::addMenuItems(KPopupMenu* menu) +{ + NMProxy* nm = NMProxy::getInstance(); + TQT_DBusError err; + + // device title + Subhead* subhead = new Subhead (menu, "subhead", TQString("Wireless Connection (%1)").tqarg(d->dev->getInterface()), SmallIcon("wireless", TQIconSet::Automatic)); + menu->insertItem (subhead, -1, -1); + + // bolding subhead instead + //menu->insertSeparator(); + + if (!nm->getWirelessEnabled(err)) + { + // wireless disabled -> do not show any connections + subhead = new Subhead(menu, "subhead2", i18n("Wireless disabled"), SmallIcon("no", TQIconSet::Automatic)); + menu->insertItem(subhead, -1, -1); + } + else if (!nm->getWirelessHardwareEnabled(err)) + { + // wireless disabled -> do not show any connections + subhead = new Subhead(menu, "subhead2", i18n("Wireless disabled by Killswitch"), SmallIcon("no", TQIconSet::Automatic)); + menu->insertItem(subhead, -1, -1); + } + else + { + // networks + addWirelessNetworks(menu); + + // bring the device down + KAction* deactivate = tray()->actionCollection()->action("deactivate_device"); + if (deactivate) + deactivate->plug(menu); + } + menu->insertSeparator(); +} + +void WirelessDeviceTray::slotUpdateDeviceState(NMDeviceState state) +{ + slotCheckActiveAccessPoint(); + if (state == NM_DEVICE_STATE_ACTIVATED) + { + // trigger an update of the connections seen bssids property + + AccessPoint * ap = d->dev->getActiveAccessPoint(); + if (ap) { + int strength = ap->getStrength(); + + if (strength > 80) + setPixmapForState((NMDeviceState)state, "nm_signal_100"); + else if (strength > 55) + setPixmapForState((NMDeviceState)state, "nm_signal_75"); + else if (strength > 30) + setPixmapForState((NMDeviceState)state, "nm_signal_50"); + else if (strength > 5) + setPixmapForState((NMDeviceState)state, "nm_signal_25"); + else + setPixmapForState((NMDeviceState)state, "nm_signal_00"); + } + } +} + +void WirelessDeviceTray::slotCheckActiveAccessPoint() +{ + // the active AP changed, if a connection is already active we have roamed + // thus add the bssid to the list of seen bssids + NMProxy* nm = NMProxy::getInstance(); + if (!nm) + return; + + WirelessConnection* active_conn = dynamic_cast<WirelessConnection*>(nm->getActiveConnection(d->dev)); + if (active_conn && d->dev->getState() == NM_DEVICE_STATE_ACTIVATED) + { + if ( d->dev->getActiveAccessPoint() != d->activeAccessPoint) { + if (!d->activeAccessPoint.isNull()) + disconnect( d->activeAccessPoint, TQT_SIGNAL(strengthChanged(TQ_UINT8)), this, TQT_SLOT(apStrengthChanged(TQ_UINT8))); + + d->activeAccessPoint = d->dev->getActiveAccessPoint(); + if ( d->activeAccessPoint ) { + connect( d->activeAccessPoint, TQT_SIGNAL(strengthChanged(TQ_UINT8)), this, TQT_SLOT(apStrengthChanged(TQ_UINT8))); + ConnectionSettings::Wireless* wireless = active_conn->getWirelessSetting(); + wireless->addSeenBssid(d->activeAccessPoint->getHwAddress()); + } + } + } +} + +void WirelessDeviceTray::apStrengthChanged(TQ_UINT8 strength) +{ + kdDebug() << k_funcinfo << (uint)strength << endl; + NMDeviceState state = device()->getState(); + if (strength > 80) + setPixmapForState(state, "nm_signal_100"); + else if (strength > 55) + setPixmapForState(state, "nm_signal_75"); + else if (strength > 30) + setPixmapForState(state, "nm_signal_50"); + else if (strength > 5) + setPixmapForState(state, "nm_signal_25"); + else + setPixmapForState(state, "nm_signal_00"); + emit uiUpdated(); +} + +void WirelessDeviceTray::slotAccessPointAdded(AccessPoint* ap) +{ + KNotifyClient::event( tray()->winId(), "knm-nm-network-found", i18n("KNetworkManager New Wireless Network Found") ); +} + +void WirelessDeviceTray::slotAccessPointRemoved(const TQString&) +{ + KNotifyClient::event( tray()->winId(), "knm-nm-network-gone", i18n("KNetworkManager Wireless Network Disappeared") ); +} + +WirelessDeviceTray::WirelessDeviceTray (WirelessDevice* dev, KSystemTray * parent, const char * name) + : DeviceTrayComponent (dev, parent, name) +{ + d = new WirelessDeviceTrayPrivate(); + d->dev = dev; + + // we want other icons for wireless devices + setPixmapForState(NM_DEVICE_STATE_UNKNOWN, "wireless_off"); + setPixmapForState(NM_DEVICE_STATE_UNAVAILABLE, "wireless_off"); + setPixmapForState(NM_DEVICE_STATE_UNMANAGED, "wireless_off"); + setPixmapForState(NM_DEVICE_STATE_DISCONNECTED, "wireless"); + setPixmapForState(NM_DEVICE_STATE_ACTIVATED, "nm_signal_50"); + + // get notified when the device state changes + connect(dev, TQT_SIGNAL(StateChanged(NMDeviceState)), this, TQT_SLOT(slotUpdateDeviceState(NMDeviceState))); + + // if the active access point changed but not the connection we roamed to a new AP + connect(dev, TQT_SIGNAL(propertiesChanged()), this, TQT_SLOT(slotCheckActiveAccessPoint())); + + // get notified of all AP changes + connect(dev, TQT_SIGNAL(accessPointAdded(AccessPoint*)), this, TQT_SLOT(slotAccessPointAdded(AccessPoint*))); + connect(dev, TQT_SIGNAL(accessPointRemoved(const TQString&)), this, TQT_SLOT(slotAccessPointRemoved(const TQString&))); +} + +WirelessDeviceTray::~WirelessDeviceTray () +{ + delete d; +} + + +#include "knetworkmanager-wireless_device_tray.moc" |