/***************************************************************************
*
* tdenetman - wireless_device_tray . cpp - A NetworkManager frontend for TDE
*
* Copyright ( C ) 2012 Timothy Pearson < kb9vqf @ pearsoncomputing . net >
* Copyright ( C ) 2005 , 2006 Novell , Inc .
*
* Author : Helmut Schaa < hschaa @ suse . de > , < helmut . schaa @ gmx . de >
*
* 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>
// TDE includes
# include <kdebug.h>
# include <kiconloader.h>
# include <tdelocale.h>
# include <knotifyclient.h>
// TDENM includes
# include "tdenetman-wireless_device_tray.h"
# include "tdenetman-wireless_menuitem.h"
# include "tdenetman-wireless_network.h"
# include "tdenetman-menu_subhead.h"
# include "tdenetman-wireless_manager.h"
# include "tdenetman-connection_settings_dialog.h"
using namespace ConnectionSettings ;
class WirelessDeviceTrayPrivate
{
public :
WirelessDeviceTrayPrivate ( ) : dev ( 0 ) , activeAccessPoint ( 0 ) { }
~ WirelessDeviceTrayPrivate ( ) { }
TQString dev ;
TDENetworkWiFiAPInfo * activeAccessPoint ;
} ;
TQStringList WirelessDeviceTray : : getToolTipText ( )
{
TDENetworkDevice * dev = dynamic_cast < TDENetworkDevice * > ( hwdevices - > findByUniqueID ( d - > dev ) ) ;
TQStringList tooltip = DeviceTrayComponent : : getToolTipText ( ) ;
TDENetworkConnectionManager * deviceConnMan = dev - > connectionManager ( ) ;
TDENetworkWiFiAPInfo * ap = deviceConnMan - > findAccessPointByBSSID ( deviceConnMan - > deviceInformation ( ) . wiFiInfo . activeAccessPointBSSID ) ;
if ( ap ) {
tooltip . append ( i18n ( " Network: %1 " ) . arg ( ap - > friendlySSID ( ) ) ) ;
int strength = ( ap - > signalQuality * 100.0 ) ;
tooltip . append ( i18n ( " Signal Strength: %1% " ) . arg ( strength ) ) ;
}
return tooltip ;
}
void WirelessDeviceTray : : newConnection ( )
{
newConnection ( 0 ) ;
}
void WirelessDeviceTray : : newConnection ( int id )
{
TDEGlobalNetworkManager * nm = TDEGlobal : : networkManager ( ) ;
// create a new wireless connection
TDENetworkConnection * conn = new TDEWiFiConnection ( ) ;
nm - > loadConnectionAllowedValues ( conn ) ;
// open a dialog for editing the connection
char use_new_wireless_essid = 0 ;
if ( ( id < 0 ) & & newWirelessPopupSSIDMap . contains ( id ) ) {
use_new_wireless_essid = 1 ;
}
ConnectionSettingsDialogImpl * dlg = new ConnectionSettingsDialogImpl ( conn , true , ( use_new_wireless_essid ) ? newWirelessPopupSSIDMap [ id ] : TQByteArray ( ) , tray ( ) , " connect_something " , false , TQt : : WDestructiveClose ) ;
dlg - > show ( ) ;
}
bool WirelessDeviceTray : : findMatchingNetwork ( const TDEWiFiConnection * conn , const TQValueList < WirelessNetwork > & nets , WirelessNetwork & net )
{
const TDEWiFiConnection * wireless = dynamic_cast < const TDEWiFiConnection * > ( conn ) ;
if ( ! wireless ) {
return false ;
}
for ( TQValueList < WirelessNetwork > : : ConstIterator it = nets . begin ( ) ; it ! = nets . end ( ) ; + + it ) {
if ( wireless - > SSID = = ( * it ) . getSsid ( ) ) {
net = * it ;
return true ;
}
}
return false ;
}
TDEWiFiConnection * WirelessDeviceTray : : findMatchingConnection ( const WirelessNetwork & net , const TQValueList < TDEWiFiConnection * > & connections )
{
// try to find a connection matching this network
for ( TQValueList < TDEWiFiConnection * > : : ConstIterator it = connections . begin ( ) ; it ! = connections . end ( ) ; + + it ) {
const TDEWiFiConnection * wireless = dynamic_cast < const TDEWiFiConnection * > ( * it ) ;
if ( ! wireless ) {
continue ;
}
if ( wireless - > SSID = = net . getSsid ( ) )
{
return * it ;
}
}
return NULL ;
}
void WirelessDeviceTray : : addWirelessNetworks ( TDEPopupMenu * menu )
{
TDEGlobalNetworkManager * nm = TDEGlobal : : networkManager ( ) ;
TDENetworkDevice * dev = dynamic_cast < TDENetworkDevice * > ( hwdevices - > findByUniqueID ( d - > dev ) ) ;
# ifdef DEBUG_STATE
printf ( " Updating wireless network list \n " ) ;
# endif // DEBUG_STATE
// get all wireless networks
TQValueList < WirelessNetwork > nets = WirelessManager : : getWirelessNetworks ( dev ) ;
// get all wireless connections
TQValueList < TDEWiFiConnection * > conns = WirelessManager : : getWirelessConnections ( ) ;
// get the currently active connection
TDENetworkConnectionManager * deviceConnMan = dev - > connectionManager ( ) ;
TDENetworkConnection * active_conn = NULL ;
TDENetworkDeviceInformation devInfo = deviceConnMan - > deviceStatus ( ) ;
if ( ( ! ( devInfo . statusFlags & TDENetworkConnectionStatus : : Disconnected ) )
& & ( ! ( devInfo . statusFlags & TDENetworkConnectionStatus : : Invalid ) ) ) {
active_conn = nm - > findConnectionByUUID ( devInfo . activeConnectionUUID ) ;
}
// add all wireless connections in range
// (we may have more then one connection per network)
for ( TQValueList < TDEWiFiConnection * > : : 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 ) - > UUID ,
false ) ;
int id = menu - > insertItem ( wirelessNetworkItem , - 1 , - 1 ) ;
menu - > setItemChecked ( id , ( ( TDENetworkConnection * ) ( * 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 < TDEWiFiConnection * > : : 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 ;
}
TDEWiFiConnection * wireless = dynamic_cast < const TDEWiFiConnection * > ( * it ) ;
if ( ! wireless ) {
continue ;
}
wirelessNetworkItem = new WirelessNetworkItem ( popup ,
d - > dev ,
net ,
( * it ) - > UUID ,
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 ) ;
uint newnetworkItemsAdded = 0 ;
TQValueList < WirelessNetwork > newnets = WirelessManager : : getWirelessNetworks ( 0 , WirelessNetwork : : MATCH_SSID ) ;
newWirelessPopupSSIDMap . clear ( ) ;
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 ( newpopup ,
d - > dev ,
* it ,
NULL ,
false ) ;
int id = newpopup - > insertItem ( wirelessNetworkItem , - 1 , - 1 ) ;
newWirelessPopupSSIDMap [ id ] = ( * it ) . getSsid ( ) ;
newpopup - > connectItem ( id , this , TQT_SLOT ( newConnection ( int ) ) ) ;
newnetworkItemsAdded + = 1 ;
}
if ( newnetworkItemsAdded ) {
menu - > insertSeparator ( ) ;
menu - > insertItem ( i18n ( " Connect to new network " ) , newpopup ) ;
}
// Signal done with wireless menu
//menu->insertSeparator();
}
void WirelessDeviceTray : : addMenuItems ( TDEPopupMenu * menu )
{
TDENetworkDevice * dev = dynamic_cast < TDENetworkDevice * > ( hwdevices - > findByUniqueID ( d - > dev ) ) ;
// get the currently active connection
TDEGlobalNetworkManager * nm = TDEGlobal : : networkManager ( ) ;
// device title
Subhead * subhead = new Subhead ( menu , " subhead " , TQString ( " Wireless Connection (%1) " ) . arg ( dev - > deviceNode ( ) ) , SmallIcon ( " wireless " , TQIconSet : : Automatic ) ) ;
menu - > insertItem ( subhead , - 1 , - 1 ) ;
// bolding subhead instead
//menu->insertSeparator();
if ( ! nm - > wiFiEnabled ( ) )
{
// 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 - > wiFiHardwareEnabled ( ) )
{
// 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
TDEAction * deactivate = tray ( ) - > actionCollection ( ) - > action ( " deactivate_device " ) ;
if ( deactivate ) {
deactivate - > plug ( menu ) ;
}
}
menu - > insertSeparator ( ) ;
}
void WirelessDeviceTray : : setPixmapForStates ( TDENetworkConnectionStatus : : TDENetworkConnectionStatus states , TQString pixmap ) {
TDENetworkConnectionStatus : : TDENetworkConnectionStatus flag = ( TDENetworkConnectionStatus : : TDENetworkConnectionStatus ) 0x80000000 ;
while ( ( TQ_UINT32 ) flag > 0 ) {
if ( states & flag ) {
setPixmapForState ( flag , pixmap ) ;
}
flag = ( TDENetworkConnectionStatus : : TDENetworkConnectionStatus ) ( ( TQ_UINT32 ) flag > > 1 ) ;
}
}
void WirelessDeviceTray : : slotUpdateDeviceState ( TDENetworkConnectionStatus : : TDENetworkConnectionStatus newState , TDENetworkConnectionStatus : : TDENetworkConnectionStatus prevState , TQString hwAddress )
{
TDENetworkDevice * dev = dynamic_cast < TDENetworkDevice * > ( hwdevices - > findByUniqueID ( d - > dev ) ) ;
if ( dev - > macAddress ( ) ! = hwAddress ) {
kdDebug ( ) < < k_funcinfo < < " WARNING: Got networkDeviceStateChanged signal for HW address ' " < < hwAddress < < " ', but my HW address is ' " < < dev - > macAddress ( ) < < " '! Ignoring... " ;
return ;
}
# ifdef DEBUG_STATE
printf ( " Wireless state: 0x%08x \n " , newState ) ;
# endif // DEBUG_STATE
slotCheckActiveAccessPoint ( ) ;
if ( newState = = TDENetworkConnectionStatus : : Connected ) {
// trigger an update of the connections seen bssids property
TDENetworkConnectionManager * deviceConnMan = dev - > connectionManager ( ) ;
TDENetworkWiFiAPInfo * ap = deviceConnMan - > findAccessPointByBSSID ( deviceConnMan - > deviceInformation ( ) . wiFiInfo . activeAccessPointBSSID ) ;
if ( ap ) {
int strength = ( ap - > signalQuality * 100.0 ) ;
if ( strength > 80 ) {
setPixmapForStates ( newState , " nm_signal_100 " ) ;
}
else if ( strength > 55 ) {
setPixmapForStates ( newState , " nm_signal_75 " ) ;
}
else if ( strength > 30 ) {
setPixmapForStates ( newState , " nm_signal_50 " ) ;
}
else if ( strength > 5 ) {
setPixmapForStates ( newState , " nm_signal_25 " ) ;
}
else {
setPixmapForStates ( newState , " nm_signal_00 " ) ;
}
}
}
// Update tray icon
TQTimer : : singleShot ( 0 , this , TQT_SLOT ( sendUpdateUI ( ) ) ) ;
}
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
TDENetworkDevice * dev = dynamic_cast < TDENetworkDevice * > ( hwdevices - > findByUniqueID ( d - > dev ) ) ;
// get the currently active connection
TDEGlobalNetworkManager * nm = TDEGlobal : : networkManager ( ) ;
TDENetworkConnectionManager * deviceConnMan = dev - > connectionManager ( ) ;
TDENetworkConnection * active_conn = NULL ;
TDENetworkDeviceInformation devInfo = deviceConnMan - > deviceStatus ( ) ;
if ( ( ! ( devInfo . statusFlags & TDENetworkConnectionStatus : : Disconnected ) )
& & ( ! ( devInfo . statusFlags & TDENetworkConnectionStatus : : Invalid ) ) ) {
active_conn = nm - > findConnectionByUUID ( devInfo . activeConnectionUUID ) ;
}
if ( active_conn & & devInfo . statusFlags = = TDENetworkConnectionStatus : : Connected ) {
TDENetworkDeviceInformation devInfo = deviceConnMan - > deviceInformation ( ) ;
TDENetworkWiFiAPInfo * activeap = deviceConnMan - > findAccessPointByBSSID ( devInfo . wiFiInfo . activeAccessPointBSSID ) ;
if ( activeap ! = d - > activeAccessPoint ) {
d - > activeAccessPoint = activeap ;
if ( d - > activeAccessPoint ) {
TDEWiFiConnection * wireless = dynamic_cast < TDEWiFiConnection * > ( active_conn ) ;
if ( wireless ) {
if ( ! ( wireless - > heardBSSIDs . contains ( d - > activeAccessPoint - > BSSID ) ) ) {
wireless - > heardBSSIDs . append ( d - > activeAccessPoint - > BSSID ) ;
}
}
}
}
}
}
void WirelessDeviceTray : : apPropertyChanged ( TDEMACAddress BSSID , TDENetworkAPEventType : : TDENetworkAPEventType event )
{
TDENetworkDevice * dev = dynamic_cast < TDENetworkDevice * > ( hwdevices - > findByUniqueID ( d - > dev ) ) ;
if ( event = = TDENetworkAPEventType : : SignalStrengthChanged ) {
TDENetworkConnectionManager * deviceConnMan = dev - > connectionManager ( ) ;
TDENetworkWiFiAPInfo * ap = deviceConnMan - > findAccessPointByBSSID ( BSSID ) ;
if ( ap ) {
TQ_UINT32 strength = ( ap - > signalQuality * 100.0 ) ;
kdDebug ( ) < < k_funcinfo < < strength < < endl ;
TDENetworkConnectionStatus : : TDENetworkConnectionStatus state = deviceConnMan - > deviceInformation ( ) . statusFlags ;
if ( strength > 80 ) {
setPixmapForStates ( state , " nm_signal_100 " ) ;
}
else if ( strength > 55 ) {
setPixmapForStates ( state , " nm_signal_75 " ) ;
}
else if ( strength > 30 ) {
setPixmapForStates ( state , " nm_signal_50 " ) ;
}
else if ( strength > 5 ) {
setPixmapForStates ( state , " nm_signal_25 " ) ;
}
else {
setPixmapForStates ( state , " nm_signal_00 " ) ;
}
TQTimer : : singleShot ( 0 , this , TQT_SLOT ( sendUpdateUI ( ) ) ) ;
}
}
}
void WirelessDeviceTray : : slotAccessPointAdded ( TDENetworkWiFiAPInfo * ap )
{
KNotifyClient : : event ( tray ( ) - > winId ( ) , " tdenm-nm-network-found " , i18n ( " TDENetworkManager New Wireless Network Found " ) ) ;
}
void WirelessDeviceTray : : slotAccessPointRemoved ( TDEMACAddress )
{
KNotifyClient : : event ( tray ( ) - > winId ( ) , " tdenm-nm-network-gone " , i18n ( " TDENetworkManager Wireless Network Disappeared " ) ) ;
}
void WirelessDeviceTray : : tdeHardwareEventHandler ( TDEHardwareEvent : : TDEHardwareEvent event , TQString )
{
if ( event = = TDEHardwareEvent : : HardwareListModified ) {
TDENetworkDevice * dev = dynamic_cast < TDENetworkDevice * > ( hwdevices - > findByUniqueID ( d - > dev ) ) ;
TDENetworkConnectionManager * deviceConnMan = ( dev ) ? dev - > connectionManager ( ) : NULL ;
// get notified when the device state changes
connect ( deviceConnMan , TQT_SIGNAL ( networkDeviceStateChanged ( TDENetworkConnectionStatus : : TDENetworkConnectionStatus , TDENetworkConnectionStatus : : TDENetworkConnectionStatus , TQString ) ) , this , TQT_SLOT ( slotUpdateDeviceState ( TDENetworkConnectionStatus : : TDENetworkConnectionStatus , TDENetworkConnectionStatus : : TDENetworkConnectionStatus , TQString ) ) ) ;
// get notified of all AP changes
connect ( deviceConnMan , TQT_SIGNAL ( accessPointStatusChanged ( TDEMACAddress , TDENetworkAPEventType : : TDENetworkAPEventType ) ) , this , TQT_SLOT ( tdeAccessPointStatusChangedHandler ( TDEMACAddress , TDENetworkAPEventType : : TDENetworkAPEventType ) ) ) ;
// force status update to ensure correct icon is shown on startup
if ( ( dev ) & & ( deviceConnMan ) ) {
slotUpdateDeviceState ( deviceConnMan - > deviceInformation ( ) . statusFlags , TDENetworkConnectionStatus : : Invalid , dev - > macAddress ( ) ) ;
}
}
}
void WirelessDeviceTray : : tdeAccessPointStatusChangedHandler ( TDEMACAddress BSSID , TDENetworkAPEventType : : TDENetworkAPEventType event ) {
TDENetworkDevice * dev = dynamic_cast < TDENetworkDevice * > ( hwdevices - > findByUniqueID ( d - > dev ) ) ;
TDENetworkConnectionManager * deviceConnMan = dev - > connectionManager ( ) ;
if ( event = = TDENetworkAPEventType : : Discovered ) {
TDENetworkWiFiAPInfo * apinfo = deviceConnMan - > findAccessPointByBSSID ( BSSID ) ;
slotAccessPointAdded ( apinfo ) ;
}
else if ( event = = TDENetworkAPEventType : : Lost ) {
slotAccessPointRemoved ( BSSID ) ;
}
else if ( event = = TDENetworkAPEventType : : SignalStrengthChanged ) {
if ( deviceConnMan - > deviceInformation ( ) . wiFiInfo . activeAccessPointBSSID = = BSSID ) {
apPropertyChanged ( BSSID , event ) ;
}
}
else if ( event = = TDENetworkAPEventType : : AccessPointChanged ) {
slotCheckActiveAccessPoint ( ) ;
}
}
void WirelessDeviceTray : : sendUpdateUI ( )
{
emit uiUpdated ( ) ;
}
WirelessDeviceTray : : WirelessDeviceTray ( TQString dev , KSystemTray * parent , const char * name )
: DeviceTrayComponent ( dev , parent , name )
{
hwdevices = TDEGlobal : : hardwareDevices ( ) ;
d = new WirelessDeviceTrayPrivate ( ) ;
d - > dev = dev ;
// we want other icons for wireless devices
setPixmapForState ( TDENetworkConnectionStatus : : Invalid , " wireless_off " ) ;
setPixmapForState ( TDENetworkConnectionStatus : : LinkUnavailable , " wireless_off " ) ;
setPixmapForState ( TDENetworkConnectionStatus : : UnManaged , " wireless_off " ) ;
setPixmapForState ( TDENetworkConnectionStatus : : Disconnected , " wireless " ) ;
setPixmapForState ( TDENetworkConnectionStatus : : Connected , " nm_signal_50 " ) ;
// Listen for hardware change events
connect ( hwdevices , TQT_SIGNAL ( hardwareEvent ( TDEHardwareEvent : : TDEHardwareEvent , TQString ) ) , this , TQT_SLOT ( tdeHardwareEventHandler ( TDEHardwareEvent : : TDEHardwareEvent , TQString ) ) ) ;
// Trigger an initial hardware information update
tdeHardwareEventHandler ( TDEHardwareEvent : : HardwareListModified , TQString : : null ) ;
}
WirelessDeviceTray : : ~ WirelessDeviceTray ( )
{
delete d ;
}
# include "tdenetman-wireless_device_tray.moc"