diff --git a/src/common/data.h b/src/common/data.h index 7fe9fec..a1e3c0e 100644 --- a/src/common/data.h +++ b/src/common/data.h @@ -1,462 +1,461 @@ /* This file is part of KNemo Copyright (C) 2004 Percy Leonhardt Copyright (C) 2009, 2010 John Stamp KNemo is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. KNemo 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef DATA_H #define DATA_H #include #include #include #include #include #include #include #include -#include #include #include class KCalendarSystem; /** * This file contains data structures used to store information about * an interface. It is shared between the daemon and the control center * module. * * @short Shared data structures * @author Percy Leonhardt */ namespace KNemoIface { enum Type { UnknownType, Ethernet, PPP }; enum IfaceState { UnknownState = 0, Unavailable = 1, Available = 2, Up = 4, Connected = 8, RxTraffic = 16, TxTraffic = 32 }; } namespace KNemoStats { enum TrafficUnits { UnitB = 0, UnitK, UnitM, UnitG }; enum TrafficDirection { TrafficIn = 0, TrafficOut, TrafficTotal }; enum WarnType { Peak = 0, Offpeak, PeakOffpeak }; enum PeriodUnits { Hour = 0, Day, Week, Month, BillPeriod, Year, HourArchive }; // Powers of 2 enum TrafficType { AllTraffic = 0, OffpeakTraffic = 1 }; }; static const char NETLOAD_THEME[] = "netloadtheme"; static const char TEXT_THEME[] = "texttheme"; static const char SYSTEM_THEME[] = "systemtheme"; static const char ICON_ERROR[] = "error"; static const char ICON_OFFLINE[] = "offline"; static const char ICON_IDLE[] = "idle"; static const char ICON_RX[] = "receive"; static const char ICON_TX[] = "transmit"; static const char ICON_RX_TX[] = "transmit-receive"; // config groups static const char confg_general[] = "General"; static const char confg_interface[] = "Interface_"; static const char confg_plotter[] = "Plotter_"; static const char confg_statsRule[] = "StatsRule_"; static const char confg_warnRule[] = "WarnRule_"; static const char conf_firstStart[] = "FirstStart"; static const char conf_autoStart[] = "AutoStart"; static const char conf_interfaces[] = "Interfaces"; // interface static const char conf_alias[] = "Alias"; // interface icon static const char conf_hideWhenNotAvail[] = "HideWhenNotAvailable"; static const char conf_hideWhenNotExist[] = "HideWhenNotExisting"; static const char conf_trafficThreshold[] = "TrafficThreshold"; static const char conf_iconTheme[] = "IconSet"; static const char conf_colorIncoming[] = "ColorIncoming"; static const char conf_colorOutgoing[] = "ColorOutgoing"; static const char conf_colorDisabled[] = "ColorDisabled"; static const char conf_colorUnavailable[] = "ColorUnavailable"; static const char conf_dynamicColor[] = "DynamicColor"; static const char conf_colorIncomingMax[] = "ColorIncomingMax"; static const char conf_colorOutgoingMax[] = "ColorOutgoingMax"; static const char conf_barScale[] = "BarScale"; static const char conf_inMaxRate[] = "InMaxRate"; static const char conf_outMaxRate[] = "OutMaxRate"; static const char conf_iconFont[] = "IconFont"; // interface statistics static const char conf_activateStatistics[] = "ActivateStatistics"; static const char conf_calendar[] = "Calendar"; static const char conf_calendarSystem[] = "CalendarSystem"; static const char conf_statsRules[] = "StatsRules"; static const char conf_warnRules[] = "WarnRules"; // interface billing static const char conf_statsStartDate[] = "StartDate"; static const char conf_statsPeriodUnits[] = "PeriodUnits"; static const char conf_statsPeriodCount[] = "PeriodCount"; static const char conf_logOffpeak[] = "LogOffpeak"; static const char conf_offpeakStartTime[] = "OffpeakStartTime"; static const char conf_offpeakEndTime[] = "OffpeakEndTime"; static const char conf_weekendIsOffpeak[] = "WeekendIsOffpeak"; static const char conf_weekendDayStart[] = "WeekendDayStart"; static const char conf_weekendDayEnd[] = "WeekendDayEnd"; static const char conf_weekendTimeStart[] = "WeekendTimeStart"; static const char conf_weekendTimeEnd[] = "WeekendTimeEnd"; // warning static const char conf_warnPeriodUnits[] = "PeriodUnits"; static const char conf_warnPeriodCount[] = "PeriodCount"; static const char conf_warnTrafficType[] = "TrafficType"; static const char conf_warnTrafficDirection[] = "TrafficDirection"; static const char conf_warnTrafficUnits[] = "TrafficUnits"; static const char conf_warnThreshold[] = "Threshold"; static const char conf_warnCustomText[] = "CustomText"; // interface context menu static const char conf_numCommands[] = "NumCommands"; static const char conf_runAsRoot[] = "RunAsRoot"; static const char conf_command[] = "Command"; static const char conf_menuText[] = "MenuText"; // tooltip static const char conf_toolTipContent[] = "ToolTipContent"; // general static const char conf_pollInterval[] = "PollInterval"; static const char conf_saveInterval[] = "SaveInterval"; static const char conf_statisticsDir[] = "StatisticsDir"; static const char conf_useBitrate[] = "UseBitrate"; static const char conf_plotterPos[] = "PlotterPos"; static const char conf_plotterSize[] = "PlotterSize"; static const char conf_statisticsPos[] = "StatisticsPos"; static const char conf_statisticsSize[] = "StatisticsSize"; static const char conf_statusPos[] = "StatusPos"; static const char conf_statusSize[] = "StatusSize"; static const char conf_hourState[] = "HourState"; static const char conf_dayState[] = "DayState"; static const char conf_weekState[] = "WeekState"; static const char conf_monthState[] = "MonthState"; static const char conf_billingState[] = "BillingState"; static const char conf_yearState[] = "YearState"; enum ToolTipEnums { INTERFACE = 0x00000001, ALIAS = 0x00000002, STATUS = 0x00000004, UPTIME = 0x00000008, IP_ADDRESS = 0x00000010, SCOPE = 0x00000020, HW_ADDRESS = 0x00000040, PTP_ADDRESS = 0x00000080, RX_PACKETS = 0x00000100, TX_PACKETS = 0x00000200, RX_BYTES = 0x00000400, TX_BYTES = 0x00000800, ESSID = 0x00001000, MODE = 0x00002000, FREQUENCY = 0x00004000, BIT_RATE = 0x00008000, ACCESS_POINT = 0x00010000, LINK_QUALITY = 0x00020000, BCAST_ADDRESS = 0x00040000, GATEWAY = 0x00080000, DOWNLOAD_SPEED = 0x00100000, UPLOAD_SPEED = 0x00200000, NICK_NAME = 0x00400000, ENCRYPTION = 0x00800000 }; static const int defaultTip = STATUS | IP_ADDRESS | RX_BYTES | TX_BYTES | ESSID | LINK_QUALITY | DOWNLOAD_SPEED | UPLOAD_SPEED | ENCRYPTION; struct KNemoTheme { QString name; QString comment; QString internalName; }; struct AddrData { int afType; QString broadcastAddress; int scope; QString ipv6Flags; QString label; bool hasPeer; }; struct BackendData { BackendData() : status( KNemoIface::UnknownState ), index( -1 ), interfaceType( KNemoIface::UnknownType ), isWireless( false ), prevRxPackets( 0L ), prevTxPackets( 0L ), rxPackets( 0L ), txPackets( 0L ), prevRxBytes( 0L ), prevTxBytes( 0L ), incomingBytes( 0L ), outgoingBytes( 0L ), rxBytes( 0L ), txBytes( 0L ), isEncrypted( false ) {} int status; int index; KNemoIface::Type interfaceType; bool isWireless; unsigned long prevRxPackets; unsigned long prevTxPackets; unsigned long rxPackets; unsigned long txPackets; unsigned long prevRxBytes; unsigned long prevTxBytes; unsigned long incomingBytes; unsigned long outgoingBytes; QMap addrData; QString hwAddress; QString ip4DefaultGateway; QString ip6DefaultGateway; QString rxString; QString txString; quint64 rxBytes; quint64 txBytes; QString essid; QString mode; QString frequency; QString channel; QString bitRate; QString linkQuality; QString accessPoint; QString prevAccessPoint; QString nickName; bool isEncrypted; }; struct InterfaceCommand { bool runAsRoot; QString command; QString menuText; }; struct GeneralSettings { GeneralSettings() : toolTipContent( defaultTip ), pollInterval( 1.0 ), saveInterval( 60 ), useBitrate( false ), statisticsDir( QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/knemo" ) {} int toolTipContent; double pollInterval; int saveInterval; bool useBitrate; QUrl statisticsDir; }; class StatsRule { public: StatsRule() : periodCount( 1 ), periodUnits( KNemoStats::Month ), logOffpeak( false ), offpeakStartTime( QTime( 23, 0) ), offpeakEndTime( QTime( 7, 0) ), weekendIsOffpeak( false ), weekendDayStart( 5 ), weekendDayEnd( 1 ), weekendTimeStart( QTime( 23, 0) ), weekendTimeEnd( QTime( 7, 0) ) { } bool operator==( StatsRule &r ); bool isValid( KCalendarSystem *cal ); QDate startDate; int periodCount; int periodUnits; bool logOffpeak; QTime offpeakStartTime; QTime offpeakEndTime; bool weekendIsOffpeak; int weekendDayStart; int weekendDayEnd; QTime weekendTimeStart; QTime weekendTimeEnd; }; struct WarnRule { WarnRule() : periodUnits( KNemoStats::Month ), periodCount( 1 ), trafficType( KNemoStats::PeakOffpeak ), trafficDirection( KNemoStats::TrafficIn ), trafficUnits( KNemoStats::UnitG ), threshold( 5.0 ), warnDone( false ) { } bool operator==( WarnRule &r ) { if ( periodUnits == r.periodUnits && periodCount == r.periodCount && trafficType == r.trafficType && trafficDirection == r.trafficDirection && trafficUnits == r.trafficUnits && threshold == r.threshold ) return true; else return false; } int periodUnits; uint periodCount; int trafficType; int trafficDirection; int trafficUnits; double threshold; QString customText; bool warnDone; }; struct InterfaceSettings { InterfaceSettings() : iconTheme( "monitor" ), colorIncoming( 0x1889FF ), colorOutgoing( 0xFF7F08 ), colorDisabled( 0x888786 ), colorUnavailable( 0x888786 ), colorBackground( 0x888786 ), dynamicColor( false ), colorIncomingMax( 0x96FFFF ), colorOutgoingMax( 0xFFC868 ), barScale( false ), inMaxRate( 4 ), outMaxRate( 4 ), iconFont( QFontDatabase::systemFont( QFontDatabase::GeneralFont ) ), numCommands( 0 ), trafficThreshold( 0 ), hideWhenUnavailable( false ), hideWhenDisconnected( false ), activateStatistics( false ), calendarSystem( KLocale::QDateCalendar ) {} QString iconTheme; QColor colorIncoming; QColor colorOutgoing; QColor colorDisabled; QColor colorUnavailable; QColor colorBackground; bool dynamicColor; QColor colorIncomingMax; QColor colorOutgoingMax; bool barScale; unsigned int inMaxRate; unsigned int outMaxRate; QFont iconFont; int numCommands; unsigned int trafficThreshold; bool hideWhenUnavailable; bool hideWhenDisconnected; bool activateStatistics; QList statsRules; QList warnRules; KLocale::CalendarSystem calendarSystem; QString alias; QList commands; }; #ifndef __linux__ enum rt_scope_t { RT_SCOPE_UNIVERSE=0, RT_SCOPE_SITE=200, RT_SCOPE_LINK=253, RT_SCOPE_HOST=254, RT_SCOPE_NOWHERE=255 }; #endif static const double pollIntervals[] = { 0.1, 0.2, 0.25, 0.5, 1.0, 2.0 }; #endif // DATA_H diff --git a/src/knemod/backends/netlinkbackend.cpp b/src/knemod/backends/netlinkbackend.cpp index 43e74a7..a53418b 100644 --- a/src/knemod/backends/netlinkbackend.cpp +++ b/src/knemod/backends/netlinkbackend.cpp @@ -1,247 +1,247 @@ /* This file is part of KNemo Copyright (C) 2009 John Stamp KNemo is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. KNemo 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include -#include +#include #include #include "config-knemo.h" #include "utils.h" #include "netlinkbackend.h" #ifndef IFF_LOWER_UP #define IFF_LOWER_UP 0x10000 #endif NetlinkBackend::NetlinkBackend() : rtsock( NULL ), addrCache( NULL ), linkCache( NULL ), routeCache( NULL ) { rtsock = nl_socket_alloc(); int c = nl_connect(rtsock, NETLINK_ROUTE); if ( c >= 0 ) { rtnl_addr_alloc_cache( rtsock, &addrCache ); rtnl_link_alloc_cache( rtsock, AF_UNSPEC, &linkCache ); rtnl_route_alloc_cache( rtsock, AF_UNSPEC, 0, &routeCache ); } #ifdef HAVE_LIBIW wireless.openSocket(); #endif } NetlinkBackend::~NetlinkBackend() { nl_cache_free( addrCache ); nl_cache_free( linkCache ); nl_cache_free( routeCache ); nl_close( rtsock ); nl_socket_free( rtsock ); #ifdef HAVE_LIBIW wireless.closeSocket(); #endif } QStringList NetlinkBackend::ifaceList() { QStringList ifaces; struct rtnl_link * rtlink; for ( rtlink = reinterpret_cast(nl_cache_get_first( linkCache )); rtlink != NULL; rtlink = reinterpret_cast(nl_cache_get_next( reinterpret_cast(rtlink) )) ) { QString ifname( rtnl_link_get_name( rtlink ) ); ifaces << ifname; } return ifaces; } void NetlinkBackend::update() { nl_cache_refill( rtsock, addrCache ); nl_cache_refill( rtsock, linkCache ); nl_cache_refill( rtsock, routeCache ); getDefaultRoute( AF_INET, &ip4DefGw, routeCache ); getDefaultRoute( AF_INET6, &ip6DefGw, routeCache ); foreach ( QString key, mInterfaces.keys() ) { BackendData *interface = mInterfaces.value( key ); updateIfaceData( key, interface ); #ifdef HAVE_LIBIW wireless.update( key, interface ); #endif } emit updateComplete(); } QString NetlinkBackend::defaultRouteIface( int afInet ) { return getDefaultRoute( afInet, NULL, routeCache ); } BackendBase* NetlinkBackend::createInstance() { return new NetlinkBackend(); } void NetlinkBackend::updateAddresses( BackendData *data ) { struct rtnl_addr * rtaddr; for ( rtaddr = reinterpret_cast(nl_cache_get_first( addrCache )); rtaddr != NULL; rtaddr = reinterpret_cast(nl_cache_get_next( reinterpret_cast(rtaddr) )) ) { if ( data->index != rtnl_addr_get_ifindex( rtaddr ) ) continue; struct nl_addr * addr = rtnl_addr_get_local( rtaddr ); char buf[ 128 ]; QString addrKey; AddrData addrVal; addrVal.afType = rtnl_addr_get_family( rtaddr ); addrVal.label = rtnl_addr_get_label( rtaddr ); addrVal.scope = rtnl_addr_get_scope( rtaddr ); nl_addr2str( addr, buf, sizeof( buf ) ); addrKey = buf; QString strFlags; int flags = rtnl_addr_get_flags( rtaddr ); if (flags & IFA_F_SECONDARY ) strFlags += i18n( " secondary" ); if ( flags & IFA_F_NODAD ) strFlags += i18n( " nodad" ); if ( flags & IFA_F_OPTIMISTIC ) strFlags += i18n( " optimistic" ); if ( flags & IFA_F_HOMEADDRESS ) strFlags += i18nc( "mobile ipv6 home address flag", " homeaddress" ); if ( flags & IFA_F_DEPRECATED ) strFlags += i18n( " deprecated" ); if ( flags & IFA_F_TENTATIVE ) strFlags += i18n( " tentative" ); if ( ! (flags & IFA_F_PERMANENT) ) strFlags += i18n( " dynamic" ); addrVal.ipv6Flags = strFlags; addrVal.hasPeer = false; addr = rtnl_addr_get_peer( rtaddr ); if ( addr ) { nl_addr2str( addr, buf, sizeof( buf ) ); addrVal.hasPeer = true; addrVal.broadcastAddress = buf; int prefixlen = rtnl_addr_get_prefixlen( rtaddr ); if ( prefixlen >= 0 && !addrVal.broadcastAddress.contains( '/' ) ) addrVal.broadcastAddress = addrVal.broadcastAddress + "/" + QString::number( prefixlen ); } else { addr = rtnl_addr_get_broadcast( rtaddr ); if ( addr ) { nl_addr2str( addr, buf, sizeof( buf ) ); addrVal.broadcastAddress = buf; } int prefixlen = rtnl_addr_get_prefixlen( rtaddr ); if ( prefixlen >= 0 && !addrKey.contains( '/' ) ) addrKey = addrKey + "/" + QString::number( prefixlen ); } data->addrData.insert( addrKey, addrVal ); } } void NetlinkBackend::updateIfaceData( const QString& ifName, BackendData* data ) { if ( !linkCache || !addrCache ) return; data->status = KNemoIface::UnknownState; data->incomingBytes = 0; data->outgoingBytes = 0; data->prevRxPackets = data->rxPackets; data->prevTxPackets = data->txPackets; data->addrData.clear(); data->ip4DefaultGateway = ip4DefGw; data->ip6DefaultGateway = ip6DefGw; struct rtnl_link * link = rtnl_link_get_by_name( linkCache, ifName.toLocal8Bit().data() ); if ( link ) { data->index = rtnl_link_get_ifindex( link ); unsigned long rx_bytes = 0, tx_bytes = 0; char mac[ 20 ]; memset( mac, 0, sizeof( mac ) ); unsigned int flags = rtnl_link_get_flags( link ); if ( flags & IFF_POINTOPOINT ) data->interfaceType = KNemoIface::PPP; else data->interfaceType = KNemoIface::Ethernet; // hw address struct nl_addr * addr = rtnl_link_get_addr( link ); if ( addr && nl_addr_get_len( addr ) ) nl_addr2str( addr, mac, sizeof( mac ) ); data->hwAddress = mac; // traffic statistics data->rxPackets = rtnl_link_get_stat( link, RTNL_LINK_RX_PACKETS ); data->txPackets = rtnl_link_get_stat( link, RTNL_LINK_TX_PACKETS ); rx_bytes = rtnl_link_get_stat( link, RTNL_LINK_RX_BYTES ); tx_bytes = rtnl_link_get_stat( link, RTNL_LINK_TX_BYTES ); incBytes( data->interfaceType, rx_bytes, data->incomingBytes, data->prevRxBytes, data->rxBytes ); incBytes( data->interfaceType, tx_bytes, data->outgoingBytes, data->prevTxBytes, data->txBytes ); data->rxString = KIO::convertSize( data->rxBytes ); data->txString = KIO::convertSize( data->txBytes ); updateAddresses( data ); data->status = KNemoIface::Available; if ( flags & IFF_UP ) { data->status |= KNemoIface::Up; if ( rtnl_link_get_flags( link ) & IFF_LOWER_UP ) { if ( !(flags & IFF_POINTOPOINT) || data->addrData.size() ) data->status |= KNemoIface::Connected; } } rtnl_link_put( link ); } else data->status = KNemoIface::Unavailable; } #include "moc_netlinkbackend.cpp" diff --git a/src/knemod/global.cpp b/src/knemod/global.cpp index 8a5c811..5c09683 100644 --- a/src/knemod/global.cpp +++ b/src/knemod/global.cpp @@ -1,61 +1,62 @@ /* This file is part of KNemo Copyright (C) 2010 John Stamp KNemo is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. KNemo 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include -#include +#include #include #include "global.h" QString formattedRate( quint64 data, bool useBits ) { if ( !useBits ) return KIO::convertSize( data ) + i18n( "/s" ); QString fmtString; double bits = data; // bit/s typically uses SI notation int units = 0; while ( bits >= 1000.0 && units < 3 ) { bits /= 1000.0; units++; } int precision = 0; if ( units ) precision = 1; - QString formattedNum = KGlobal::locale()->formatNumber( bits, precision ); + QLocale locale; + QString formattedNum = locale.toString( bits, 'g', precision ); switch (units) { case 0: fmtString = QString( "%1 bit/s" ).arg( formattedNum ); break; case 1: fmtString = QString( "%1 kbit/s" ).arg( formattedNum ); break; case 2: fmtString = QString( "%1 Mbit/s" ).arg( formattedNum ); break; case 3: fmtString = QString( "%1 Gbit/s" ).arg( formattedNum ); break; } return fmtString; } diff --git a/src/knemod/interfaceicon.cpp b/src/knemod/interfaceicon.cpp index c441cf2..48cd528 100644 --- a/src/knemod/interfaceicon.cpp +++ b/src/knemod/interfaceicon.cpp @@ -1,606 +1,606 @@ /* This file is part of KNemo Copyright (C) 2004, 2005 Percy Leonhardt Copyright (C) 2009, 2010 John Stamp KNemo is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. KNemo 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include #include #include #include -#include +#include #include #include #include #include "global.h" #include "utils.h" #include "interface.h" #include "knemodaemon.h" #include "interfaceicon.h" #include "interfacetray.h" #define SHRINK_MAX 0.75 #define HISTSIZE_STORE 0.5 Q_DECLARE_METATYPE(InterfaceCommand) InterfaceIcon::InterfaceIcon( Interface* interface ) : QObject(), mInterface( interface ), mTray( 0L ), barIncoming( 0 ), barOutgoing( 0 ) { commandActions = new KActionCollection( this ); statusAction = new QAction( i18n( "Show &Status Dialog" ), this ); plotterAction = new QAction( QIcon::fromTheme( "utilities-system-monitor" ), i18n( "Show &Traffic Plotter" ), this ); statisticsAction = new QAction( QIcon::fromTheme( "view-statistics" ), i18n( "Show St&atistics" ), this ); configAction = new QAction( QIcon::fromTheme( "configure" ), i18n( "&Configure KNemo..." ), this ); connect( statusAction, SIGNAL( triggered() ), this, SLOT( showStatus() ) ); connect( plotterAction, SIGNAL( triggered() ), this, SLOT( showGraph() ) ); connect( statisticsAction, SIGNAL( triggered() ), this, SLOT( showStatistics() ) ); connect( configAction, SIGNAL( triggered() ), this, SLOT( showConfigDialog() ) ); } InterfaceIcon::~InterfaceIcon() { // Prevent the "Destroyed while process is still running" message foreach( KProcess* process, processList ) { process->kill(); process->waitForFinished( 2000 ); } delete mTray; } void InterfaceIcon::configChanged() { KConfigGroup cg( KSharedConfig::openConfig(), "System Tray" ); iconWidth = cg.readEntry( "systrayIconWidth", 22 ); barWidth = iconWidth/3; int margins = iconWidth - (barWidth*2); midMargin = margins/3; int rightMargin = (margins - midMargin)/2; leftMargin = margins-midMargin - rightMargin; midMargin = leftMargin + barWidth+ midMargin; histSize = HISTSIZE_STORE/generalSettings->pollInterval; if ( histSize < 2 ) histSize = 2; for ( int i=0; i < histSize; i++ ) { inHist.append( 0 ); outHist.append( 0 ); } inMaxRate = mInterface->settings().inMaxRate; outMaxRate = mInterface->settings().outMaxRate; updateTrayStatus(); if ( mTray != 0L ) { updateMenu(); if ( mInterface->settings().iconTheme == TEXT_THEME ) updateIconText( true ); else if ( mInterface->settings().iconTheme == NETLOAD_THEME ) updateBars( true ); } } void InterfaceIcon::updateIconImage( int status ) { if ( mTray == 0L || mInterface->settings().iconTheme == TEXT_THEME ) return; QString iconName; if ( mInterface->settings().iconTheme == SYSTEM_THEME ) iconName = "network-"; else iconName = "knemo-" + mInterface->settings().iconTheme + "-"; // Now set the correct icon depending on the status of the interface. if ( ( status & KNemoIface::RxTraffic ) && ( status & KNemoIface::TxTraffic ) ) { iconName += ICON_RX_TX; } else if ( status & KNemoIface::RxTraffic ) { iconName += ICON_RX; } else if ( status & KNemoIface::TxTraffic ) { iconName += ICON_TX; } else if ( status & KNemoIface::Connected ) { iconName += ICON_IDLE; } else if ( status & KNemoIface::Available ) { iconName += ICON_OFFLINE; } else { iconName += ICON_ERROR; } mTray->setIconByName( iconName ); } int InterfaceIcon::calcHeight( QList& hist, unsigned int& net_max ) { unsigned long histcalculate = 0; unsigned long rate = 0; foreach( unsigned long j, hist ) { histcalculate += j; } rate = histcalculate / histSize; /* update maximum */ if ( !mInterface->settings().barScale ) { QListsortedMax( hist ); qSort( sortedMax ); unsigned long max = sortedMax.last(); int multiplier = 1024; if ( generalSettings->useBitrate ) multiplier = 1000; if( rate > net_max ) { net_max = rate; } else if( max < net_max * SHRINK_MAX && net_max * SHRINK_MAX >= multiplier ) { net_max *= SHRINK_MAX; } } qreal ratio = static_cast(rate)/net_max; if ( ratio > 1.0 ) ratio = 1.0; return ratio*iconWidth; } QColor InterfaceIcon::calcColor( QList& hist, const QColor& low, const QColor& high, int hival ) { const BackendData * data = mInterface->backendData(); if ( data->status & KNemoIface::Connected ) { if ( ! mInterface->settings().dynamicColor ) return low; } else if ( data->status & KNemoIface::Available ) return mInterface->settings().colorDisabled; else if ( data->status & KNemoIface::Unavailable ) return mInterface->settings().colorUnavailable; unsigned long histcalculate = 0; unsigned long rate = 0; if ( mInterface->settings().iconTheme == NETLOAD_THEME ) { foreach( unsigned long j, hist ) { histcalculate += j; } rate = histcalculate / histSize; } else rate = hist[0]; int lowH, lowS, lowV; int hiH, hiS, hiV; int difH, difS, difV; low.getHsv( &lowH, &lowS, &lowV ); high.getHsv( &hiH, &hiS, &hiV ); difH = hiH - lowH; difS = hiS - lowS; difV = hiV - lowV; qreal percentage = static_cast(rate)/hival; if ( percentage > 1.0 ) percentage = 1.0; QColor retcolor; retcolor.setHsv( lowH + ( percentage*difH ), lowS + ( percentage*difS), lowV + (percentage*difV ) ); return retcolor; } void InterfaceIcon::updateBars( bool doUpdate ) { // Has color changed? QColor rxColor = calcColor( inHist, mInterface->settings().colorIncoming, mInterface->settings().colorIncomingMax, mInterface->settings().inMaxRate ); QColor txColor = calcColor( outHist, mInterface->settings().colorOutgoing, mInterface->settings().colorOutgoingMax, mInterface->settings().outMaxRate ); if ( rxColor != colorIncoming ) { doUpdate = true; colorIncoming = rxColor; } if ( txColor != colorOutgoing ) { doUpdate = true; colorOutgoing = txColor; } // Has height changed? int rateIn = calcHeight( inHist, inMaxRate ); int rateOut = calcHeight( outHist, outMaxRate ); if ( rateIn != barIncoming ) { doUpdate = true; barIncoming = rateIn; } if ( rateOut != barOutgoing ) { doUpdate = true; barOutgoing = rateOut; } if ( !doUpdate ) return; QPixmap barIcon(iconWidth, iconWidth); QLinearGradient inGrad( midMargin, 0, midMargin+barWidth, 0 ); QLinearGradient topInGrad( midMargin, 0, midMargin+barWidth, 0 ); QLinearGradient outGrad( leftMargin, 0, leftMargin+barWidth, 0 ); QLinearGradient topOutGrad( leftMargin, 0, leftMargin+barWidth, 0 ); int top = iconWidth - barOutgoing; QRect topLeftRect( leftMargin, 0, barWidth, top ); QRect leftRect( leftMargin, top, barWidth, iconWidth ); top = iconWidth - barIncoming; QRect topRightRect( midMargin, 0, barWidth, top ); QRect rightRect( midMargin, top, barWidth, iconWidth ); barIcon.fill( Qt::transparent ); QPainter p( &barIcon ); p.setOpacity( 1.0 ); const BackendData * data = mInterface->backendData(); QColor topColor; if ( data->status & KNemoIface::Connected ) { topColor = mInterface->settings().colorBackground; } else if ( data->status & KNemoIface::Available ) { topColor = mInterface->settings().colorDisabled; } else { topColor = mInterface->settings().colorUnavailable; } QColor topColorD = topColor.darker(); topColor.setAlpha( 128 ); topColorD.setAlpha( 128 ); topInGrad.setColorAt(0, topColorD); topInGrad.setColorAt(1, topColor ); topOutGrad.setColorAt(0, topColorD); topOutGrad.setColorAt(1, topColor ); inGrad.setColorAt(0, rxColor ); inGrad.setColorAt(1, rxColor.darker() ); outGrad.setColorAt(0, txColor ); outGrad.setColorAt(1, txColor.darker() ); QBrush brush( inGrad ); p.setBrush( brush ); p.fillRect( rightRect, inGrad ); brush = QBrush( topInGrad ); p.fillRect( topRightRect, topInGrad ); brush = QBrush( outGrad ); p.fillRect( leftRect, outGrad ); brush = QBrush( topOutGrad ); p.fillRect( topLeftRect, topOutGrad ); mTray->setIconByPixmap( barIcon ); QPixmapCache::clear(); } QString InterfaceIcon::compactTrayText(unsigned long data ) { QString dataString; // Space is tight, so no space between number and units, and the complete // string should be no more than 4 chars. /* Visually confusing to display bytes if ( bytes < 922 ) // 922B = 0.9K byteString = i18n( "%1B", bytes ); */ double multiplier = 1024; if ( generalSettings->useBitrate ) multiplier = 1000; int precision = 0; if ( data < multiplier*9.95 ) // < 9.95K { precision = 1; } if ( data < multiplier*999.5 ) // < 999.5K { if ( generalSettings->useBitrate ) dataString = i18n( "%1k", QString::number( data/multiplier, 'f', precision ) ); else dataString = i18n( "%1K", QString::number( data/multiplier, 'f', precision ) ); return dataString; } if ( data < pow(multiplier, 2)*9.95 ) // < 9.95M precision = 1; if ( data < pow(multiplier, 2)*999.5 ) // < 999.5M { dataString = i18n( "%1M", QString::number( data/pow(multiplier, 2), 'f', precision ) ); return dataString; } if ( data < pow(multiplier, 3)*9.95 ) // < 9.95G precision = 1; // xgettext: no-c-format dataString = i18n( "%1G", QString::number( data/pow(multiplier, 3), 'f', precision) ); return dataString; } void InterfaceIcon::updateIconText( bool doUpdate ) { // Has color changed? QColor rxColor = calcColor( inHist, mInterface->settings().colorIncoming, mInterface->settings().colorIncomingMax, mInterface->settings().inMaxRate ); QColor txColor = calcColor( outHist, mInterface->settings().colorOutgoing, mInterface->settings().colorOutgoingMax, mInterface->settings().outMaxRate ); if ( rxColor != colorIncoming ) { doUpdate = true; colorIncoming = rxColor; } if ( rxColor != colorOutgoing ) { doUpdate = true; colorOutgoing = txColor; } // Has text changed? QString byteText = compactTrayText( mInterface->rxRate() ); if ( byteText != textIncoming ) { doUpdate = true; textIncoming = byteText; } byteText = compactTrayText( mInterface->txRate() ); if ( byteText != textOutgoing ) { doUpdate = true; textOutgoing = byteText; } if ( !doUpdate ) return; QPixmap textIcon(iconWidth, iconWidth); QRect topRect( 0, 0, iconWidth, iconWidth/2 ); QRect bottomRect( 0, iconWidth/2, iconWidth, iconWidth/2 ); textIcon.fill( Qt::transparent ); QPainter p( &textIcon ); p.setBrush( Qt::NoBrush ); p.setOpacity( 1.0 ); KColorScheme scheme(QPalette::Active, KColorScheme::View); // rxFont and txFont should be the same size per poll period QFont rxFont = setIconFont( textIncoming, mInterface->settings().iconFont, iconWidth ); QFont txFont = setIconFont( textOutgoing, mInterface->settings().iconFont, iconWidth ); if ( rxFont.pointSizeF() > txFont.pointSizeF() ) rxFont.setPointSizeF( txFont.pointSizeF() ); p.setFont( rxFont ); p.setPen( rxColor ); p.drawText( topRect, Qt::AlignCenter | Qt::AlignRight, textIncoming ); p.setFont( rxFont ); p.setPen( txColor ); p.drawText( bottomRect, Qt::AlignCenter | Qt::AlignRight, textOutgoing ); mTray->setIconByPixmap( textIcon ); QPixmapCache::clear(); } void InterfaceIcon::updateToolTip() { if ( mTray == 0L ) return; inHist.prepend( mInterface->rxRate() ); outHist.prepend( mInterface->txRate() ); while ( inHist.count() > histSize ) { inHist.removeLast(); outHist.removeLast(); } if ( mInterface->settings().iconTheme == TEXT_THEME ) updateIconText(); else if ( mInterface->settings().iconTheme == NETLOAD_THEME ) updateBars(); mTray->updateToolTip(); } void InterfaceIcon::updateMenu() { // Remove all old entries. QMenu* menu = mTray->contextMenu(); QList actions = menu->actions(); foreach ( QAction* action, commandActions->actions() ) menu->removeAction( action ); commandActions->clear(); InterfaceSettings& settings = mInterface->settings(); // If the user wants custom commands, add them. if ( settings.commands.size() > 0 ) { int i = 0; foreach ( InterfaceCommand command, settings.commands ) { QAction *action = new QAction( command.menuText, this ); action->setData( QVariant::fromValue( command ) ); commandActions->addAction( QString( "command%1" ).arg( i ), action ); ++i; } QAction* sep = menu->addSeparator(); commandActions->addAction( "sep", sep ); menu->insertActions( statusAction, commandActions->actions() ); } if ( settings.activateStatistics ) menu->insertAction( configAction, statisticsAction ); else menu->removeAction( statisticsAction ); } void InterfaceIcon::updateTrayStatus() { const QString ifaceName( mInterface->ifaceName() ); const BackendData * data = mInterface->backendData(); int currentStatus = data->status; bool hideWhenUnavailable = mInterface->settings().hideWhenUnavailable; bool hideWhenDisconnected = mInterface->settings().hideWhenDisconnected; QString title = mInterface->settings().alias; if ( title.isEmpty() ) title = ifaceName; /* Remove the icon if * - the interface is not available and the option to hide it is selected * - the interface does not exist, the option to hide it is selected * and the other option is not selected */ if ( mTray != 0L && ( ( (currentStatus < KNemoIface::Connected ) && hideWhenDisconnected ) || ( (currentStatus < KNemoIface::Available ) && hideWhenUnavailable && !hideWhenDisconnected ) ) ) { delete mTray; mTray = 0L; } /* Create the icon if * - the interface is available * - the interface is not available and the option to hide it is not * selected and the interface does exist * - the interface does not exist and the option to hide it is not selected * and the other option is not selected */ else if ( mTray == 0L && ( currentStatus & KNemoIface::Connected || ( currentStatus & KNemoIface::Available && !hideWhenDisconnected ) || ( !hideWhenUnavailable && !hideWhenDisconnected ) ) ) { mTray = new InterfaceTray( mInterface, ifaceName ); QMenu* menu = mTray->contextMenu(); menu->removeAction( menu->actions().at( 0 ) ); // FIXME: title for QMenu? //menu->addTitle( QIcon::fromTheme( "knemo" ), i18n( "KNemo - %1", title ) ); menu->addAction( statusAction ); menu->addAction( plotterAction ); menu->addAction( configAction ); KHelpMenu* helpMenu( new KHelpMenu( menu, KAboutData::applicationData(), false ) ); menu->addMenu( helpMenu->menu() )->setIcon( QIcon::fromTheme( "help-contents" ) ); connect( menu, SIGNAL( triggered( QAction * ) ), this, SLOT( menuTriggered( QAction * ) ) ); if ( mInterface->settings().iconTheme == TEXT_THEME ) updateIconText(); else if ( mInterface->settings().iconTheme == NETLOAD_THEME ) updateBars(); else updateIconImage( mInterface->ifaceState() ); updateMenu(); } else if ( mTray != 0L ) { if ( mInterface->settings().iconTheme != TEXT_THEME && mInterface->settings().iconTheme != NETLOAD_THEME ) updateIconImage( mInterface->ifaceState() ); } } void InterfaceIcon::showConfigDialog() { KNemoDaemon::sSelectedInterface = mInterface->ifaceName(); KProcess process; process << "kcmshell4" << "kcm_knemo"; process.startDetached(); } void InterfaceIcon::menuTriggered( QAction *action ) { if ( !action->data().canConvert() ) return; InterfaceCommand command = action->data().value(); KProcess *process = new KProcess( this ); if ( command.runAsRoot ) *process << QStandardPaths::findExecutable("kdesu") << command.command; else process->setShellCommand( command.command ); processList << process; connect( process, SIGNAL( finished( int, QProcess::ExitStatus ) ), this, SLOT( processFinished() ) ); process->start(); } void InterfaceIcon::processFinished() { processList.removeAll( static_cast(sender()) ); static_cast(sender())->deleteLater(); } void InterfaceIcon::showStatistics() { emit statisticsSelected(); } void InterfaceIcon::showStatus() { mInterface->showStatusDialog( true ); } void InterfaceIcon::showGraph() { mInterface->showSignalPlotter( true ); } #include "moc_interfaceicon.cpp" diff --git a/src/knemod/interfacetray.cpp b/src/knemod/interfacetray.cpp index db848f8..0287e84 100644 --- a/src/knemod/interfacetray.cpp +++ b/src/knemod/interfacetray.cpp @@ -1,255 +1,255 @@ /* This file is part of KNemo Copyright (C) 2004, 2005 Percy Leonhardt Copyright (C) 2009, 2010 John Stamp KNemo is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. KNemo 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "global.h" #include "interfacetray.h" #ifdef __linux__ #include #endif #include #include #include #include #include #include -#include +#include #include #include #include #include InterfaceTray::InterfaceTray( Interface* interface, const QString &id, QWidget* parent ) : KStatusNotifierItem( id, parent ) { mInterface = interface; setToolTipIconByName( "knemo" ); setCategory(Hardware); setStatus(Active); connect(this, SIGNAL(secondaryActivateRequested(QPoint)), this, SLOT(togglePlotter())); setupMappings(); QAction *quitAction = new QAction(this); quitAction->setText(KStatusNotifierItem::tr("Quit")); quitAction->setIcon(QIcon::fromTheme("application-exit")); QObject::connect(quitAction, SIGNAL(triggered()), this, SLOT(slotQuit())); // Replace the standard quit action addAction("quit", quitAction); } InterfaceTray::~InterfaceTray() { } void InterfaceTray::updateToolTip() { QString currentTip; QString title = mInterface->settings().alias; if ( title.isEmpty() ) title = mInterface->ifaceName(); title = i18n( "KNemo - %1", title ); if ( toolTipTitle() != title ) setToolTipTitle( title ); currentTip = toolTipData(); if ( currentTip != toolTipSubTitle() ) setToolTipSubTitle( currentTip ); } void InterfaceTray::slotQuit() { int autoStart = KMessageBox::questionYesNoCancel(0, i18n("Should KNemo start automatically when you login?"), i18n("Automatically Start KNemo?"), KGuiItem(i18n("Start")), KGuiItem(i18n("Do Not Start")), KStandardGuiItem::cancel(), "StartAutomatically"); KSharedConfigPtr config = KSharedConfig::openConfig(); KConfigGroup generalGroup( config, confg_general ); if ( autoStart == KMessageBox::Yes ) { generalGroup.writeEntry( conf_autoStart, true ); } else if ( autoStart == KMessageBox::No) { generalGroup.writeEntry( conf_autoStart, false ); } else // cancel chosen; don't quit return; config->sync(); qApp->quit(); } void InterfaceTray::activate(const QPoint&) { mInterface->showStatusDialog( false ); } void InterfaceTray::togglePlotter() { mInterface->showSignalPlotter( false ); } QString InterfaceTray::toolTipData() { QString tipData; int toolTipContent = generalSettings->toolTipContent; const BackendData * data = mInterface->backendData(); if ( !data ) return QString(); QString leftTags = ""; QString centerTags = ""; QString rightTags = ""; tipData = ""; if ( toolTipContent & INTERFACE ) tipData += leftTags + i18n( "Interface" ) + centerTags + mInterface->ifaceName() + rightTags; if ( toolTipContent & STATUS ) { tipData += leftTags + i18n( "Status" ) + centerTags; if ( data->status & KNemoIface::Connected ) tipData += i18n( "Connected" ); else if ( data->status & KNemoIface::Up ) tipData += i18n( "Disconnected" ); else if ( data->status & KNemoIface::Available ) tipData += i18n( "Down" ); else tipData += i18n( "Unavailable" ); tipData += rightTags; } if ( data->status & KNemoIface::Connected && toolTipContent & UPTIME ) { tipData += leftTags + i18n( "Connection time" ) + centerTags + mInterface->uptimeString() + rightTags ; } if ( data->status & KNemoIface::Up ) { QStringList keys = data->addrData.keys(); QString ip4Tip; QString ip6Tip; QString ptpaddress = i18n( "PtP Address" ); QString scope = i18n( "Scope & Flags" ); foreach ( QString key, keys ) { AddrData addrData = data->addrData.value( key ); if ( addrData.afType == AF_INET ) { if ( toolTipContent & IP_ADDRESS ) ip4Tip += leftTags + i18n( "IPv4 Address" ) + centerTags + key + rightTags; if ( toolTipContent & SCOPE ) ip4Tip += leftTags + scope + centerTags + mScope.value( addrData.scope ) + addrData.ipv6Flags + rightTags; if ( toolTipContent & BCAST_ADDRESS && !addrData.hasPeer ) ip4Tip += leftTags + i18n( "Broadcast Address" ) + centerTags + addrData.broadcastAddress + rightTags; else if ( toolTipContent & PTP_ADDRESS && addrData.hasPeer ) ip4Tip += leftTags + ptpaddress + centerTags + addrData.broadcastAddress + rightTags; } else { if ( toolTipContent & IP_ADDRESS ) ip6Tip += leftTags + i18n( "IPv6 Address" ) + centerTags + key + rightTags; if ( toolTipContent & SCOPE ) ip6Tip += leftTags + scope + centerTags + mScope.value( addrData.scope ) + rightTags; if ( toolTipContent & PTP_ADDRESS && addrData.hasPeer ) ip6Tip += leftTags + ptpaddress + centerTags + addrData.broadcastAddress + rightTags; } } tipData += ip4Tip + ip6Tip; if ( KNemoIface::Ethernet == data->interfaceType ) { if ( toolTipContent & GATEWAY ) { if ( !data->ip4DefaultGateway.isEmpty() ) tipData += leftTags + i18n( "IPv4 Default Gateway" ) + centerTags + data->ip4DefaultGateway + rightTags; if ( !data->ip6DefaultGateway.isEmpty() ) tipData += leftTags + i18n( "IPv6 Default Gateway" ) + centerTags + data->ip6DefaultGateway + rightTags; } } } if ( data->status & KNemoIface::Available ) { if ( toolTipContent & HW_ADDRESS ) tipData += leftTags + i18n( "MAC Address" ) + centerTags + data->hwAddress + rightTags; if ( toolTipContent & RX_PACKETS ) tipData += leftTags + i18n( "Packets Received" ) + centerTags + QString::number( data->rxPackets ) + rightTags; if ( toolTipContent & TX_PACKETS ) tipData += leftTags + i18n( "Packets Sent" ) + centerTags + QString::number( data->txPackets ) + rightTags; if ( toolTipContent & RX_BYTES ) tipData += leftTags + i18n( "Bytes Received" ) + centerTags + data->rxString + rightTags; if ( toolTipContent & TX_BYTES ) tipData += leftTags + i18n( "Bytes Sent" ) + centerTags + data->txString + rightTags; } if ( data->status & KNemoIface::Connected ) { if ( toolTipContent & DOWNLOAD_SPEED ) tipData += leftTags + i18n( "Download Speed" ) + centerTags + mInterface->rxRateStr() + rightTags; if ( toolTipContent & UPLOAD_SPEED ) tipData += leftTags + i18n( "Upload Speed" ) + centerTags + mInterface->txRateStr() + rightTags; } if ( data->status & KNemoIface::Connected && data->isWireless ) { if ( toolTipContent & ESSID ) tipData += leftTags + i18n( "ESSID" ) + centerTags + data->essid + rightTags; if ( toolTipContent & MODE ) tipData += leftTags + i18n( "Mode" ) + centerTags + data->mode + rightTags; if ( toolTipContent & FREQUENCY ) tipData += leftTags + i18n( "Frequency" ) + centerTags + data->frequency + rightTags; if ( toolTipContent & BIT_RATE ) tipData += leftTags + i18n( "Bit Rate" ) + centerTags + data->bitRate + rightTags; if ( toolTipContent & ACCESS_POINT ) tipData += leftTags + i18n( "Access Point" ) + centerTags + data->accessPoint + rightTags; if ( toolTipContent & LINK_QUALITY ) tipData += leftTags + i18n( "Link Quality" ) + centerTags + data->linkQuality + rightTags; #ifdef __linux__ if ( toolTipContent & NICK_NAME ) tipData += leftTags + i18n( "Nickname" ) + centerTags + data->nickName + rightTags; #endif if ( toolTipContent & ENCRYPTION ) { QString encryption = i18n( "Encryption" ); if ( data->isEncrypted == true ) { tipData += leftTags + encryption + centerTags + i18n( "active" ) + rightTags; } else { tipData += leftTags + encryption + centerTags + i18n( "off" ) + rightTags; } } } tipData += "
"; return tipData; } void InterfaceTray::setupMappings() { // Cannot make this data static as the i18n macro doesn't seem // to work when called to early i.e. before setting the catalogue. mScope.insert( RT_SCOPE_NOWHERE, i18nc( "ipv6 address scope", "none" ) ); mScope.insert( RT_SCOPE_HOST, i18nc( "ipv6 address scope", "host" ) ); mScope.insert( RT_SCOPE_LINK, i18nc( "ipv6 address scope", "link" ) ); mScope.insert( RT_SCOPE_SITE, i18nc( "ipv6 address scope", "site" ) ); mScope.insert( RT_SCOPE_UNIVERSE, i18nc( "ipv6 address scope", "global" ) ); } #include "moc_interfacetray.cpp" diff --git a/src/knemod/knemodaemon.cpp b/src/knemod/knemodaemon.cpp index be67e91..6a2078e 100644 --- a/src/knemod/knemodaemon.cpp +++ b/src/knemod/knemodaemon.cpp @@ -1,215 +1,215 @@ /* This file is part of KNemo Copyright (C) 2004, 2006 Percy Leonhardt Copyright (C) 2009, 2010 John Stamp KNemo is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. KNemo 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include -#include +#include #include #include "global.h" #include "knemodaemon.h" #include "interface.h" #include "backends/backendfactory.h" #include "utils.h" QString KNemoDaemon::sSelectedInterface = QString::null; BackendBase *backend = NULL; GeneralSettings *generalSettings = NULL; KNemoDaemon::KNemoDaemon() : QObject(), mConfig( KSharedConfig::openConfig() ), mHaveInterfaces( false ) { generalSettings = new GeneralSettings(); backend = BackendFactory::backend(); QDBusConnection::sessionBus().registerObject("/knemo", this, QDBusConnection::ExportScriptableSlots); mPollTimer = new QTimer(); connect( mPollTimer, SIGNAL( timeout() ), this, SLOT( updateInterfaces() ) ); KActionCollection* ac = new KActionCollection( this ); QAction* action = new QAction( i18n( "Toggle Traffic Plotters" ), this ); ac->addAction( "toggleTrafficPlotters", action ); connect( action, SIGNAL( triggered() ), SLOT( togglePlotters() ) ); KGlobalAccel::setGlobalShortcut( action, QKeySequence() ); readConfig(); } KNemoDaemon::~KNemoDaemon() { mPollTimer->stop(); delete mPollTimer; foreach ( QString key, mInterfaceHash.keys() ) { Interface *interface = mInterfaceHash.take( key ); delete interface; } delete generalSettings; } void KNemoDaemon::readConfig() { mPollTimer->stop(); KConfig *config = mConfig.data(); // For when reparseConfiguration() is called config->reparseConfiguration(); // General GeneralSettings g; KConfigGroup generalGroup( config, confg_general ); generalSettings->pollInterval = clamp(generalGroup.readEntry( conf_pollInterval, g.pollInterval ), 0.1, 2.0 ); generalSettings->pollInterval = validatePoll( generalSettings->pollInterval ); generalSettings->useBitrate = generalGroup.readEntry( conf_useBitrate, g.useBitrate ); generalSettings->saveInterval = clamp(generalGroup.readEntry( conf_saveInterval, g.saveInterval ), 0, 300 ); generalSettings->statisticsDir = generalGroup.readEntry( conf_statisticsDir, g.statisticsDir ); generalSettings->toolTipContent = generalGroup.readEntry( conf_toolTipContent, g.toolTipContent ); // If we already have an Interfaces key--even if its empty--then we // shouldn't try to set up a default interface if ( generalGroup.hasKey( conf_interfaces ) ) mHaveInterfaces = true; QStringList interfaceList = generalGroup.readEntry( conf_interfaces, QStringList() ); // Remove interfaces that are no longer monitored foreach ( QString key, mInterfaceHash.keys() ) { if ( !interfaceList.contains( key ) ) { Interface *interface = mInterfaceHash.take( key ); delete interface; backend->removeIface( key ); // If knemo is running while config removes an interface to monitor, // it will keep the interface and plotter groups. Delete them here. KConfigGroup interfaceGroup( config, QString( confg_interface + key ) ); KConfigGroup plotterGroup( config, QString( confg_plotter + key ) ); interfaceGroup.deleteGroup(); plotterGroup.deleteGroup(); config->sync(); } } if ( !mHaveInterfaces ) { QString ifaceName = backend->defaultRouteIface( AF_INET ); if ( ifaceName.isEmpty() ) ifaceName = backend->defaultRouteIface( AF_INET6 ); if ( !ifaceName.isEmpty() ) { interfaceList << ifaceName; mHaveInterfaces = true; } } // Add/update those that do need to be monitored QStringList newIfaces; foreach ( QString key, interfaceList ) { if ( !mInterfaceHash.contains( key ) ) { const BackendData * data = backend->addIface( key ); Interface *iface = new Interface( key, data ); mInterfaceHash.insert( key, iface ); newIfaces << key; } } // Now (re)config interfaces, but new interfaces need extra work so // they don't show bogus icon traffic states on startup. updateInterfaces(); foreach( QString key, interfaceList ) { Interface *iface = mInterfaceHash.value( key ); iface->configChanged(); if ( newIfaces.contains( key ) ) { backend->updatePackets( key ); iface->processUpdate(); connect( backend, SIGNAL( updateComplete() ), iface, SLOT( processUpdate() ) ); } } bool statsActivated = false; foreach ( Interface *iface, mInterfaceHash ) { if ( iface->settings().activateStatistics ) statsActivated = true; } if ( statsActivated ) { QStringList drivers = QSqlDatabase::drivers(); if ( !drivers.contains( "QSQLITE" ) ) { KMessageBox::sorry( 0, i18n( "The Qt4 SQLite database plugin is not available.\n" "Please install it to store traffic statistics." ) ); } } mPollTimer->start( generalSettings->pollInterval * 1000 ); } void KNemoDaemon::reparseConfiguration() { readConfig(); } QString KNemoDaemon::getSelectedInterface() { // Reset the variable to avoid preselecting an interface when // the user opens the control center module from the control // center afterwards. QString tmp = sSelectedInterface; sSelectedInterface = QString::null; return tmp; } void KNemoDaemon::updateInterfaces() { backend->update(); } void KNemoDaemon::togglePlotters() { bool showPlotters = false; foreach ( QString key, mInterfaceHash.keys() ) { // If only some of the plotters are visible, show them all if ( !mInterfaceHash.value( key )->plotterVisible() ) showPlotters = true; } foreach ( QString key, mInterfaceHash.keys() ) { mInterfaceHash.value( key )->toggleSignalPlotter( showPlotters ); } } #include "moc_knemodaemon.cpp" diff --git a/src/knemod/statisticsmodel.cpp b/src/knemod/statisticsmodel.cpp index db0ce75..9e3cb9a 100644 --- a/src/knemod/statisticsmodel.cpp +++ b/src/knemod/statisticsmodel.cpp @@ -1,342 +1,342 @@ /* This file is part of KNemo Copyright (C) 2010 John Stamp KNemo is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. KNemo 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "statisticsmodel.h" #include "global.h" #include -#include +#include #include #include StatisticsModel::StatisticsModel( enum KNemoStats::PeriodUnits t, QObject *parent ) : QStandardItemModel( parent ), mPeriodType( t ), mCalendar( 0 ) { QStringList headerList; headerList << i18n( "Date" ) << i18n( "Sent" ) << i18n( "Received" ) << i18n( "Total" ); setHorizontalHeaderLabels( headerList ); setSortRole( DataRole ); } StatisticsModel::~StatisticsModel() { } void StatisticsModel::addBytes( enum StatsColumn column, KNemoStats::TrafficType trafficType, quint64 bytes, int row ) { if ( !bytes || !rowCount() ) return; if ( row < 0 ) row = rowCount() - 1; int role = DataRole + trafficType; quint64 b = item( row, column )->data( role ).toULongLong() + bytes; item( row, column )->setData( b, role ); if ( trafficType == KNemoStats::AllTraffic ) updateText( item( row, column ) ); } quint64 StatisticsModel::bytes( enum StatsColumn column, int role, int row ) const { if ( row < 0 ) row = rowCount() - 1; if ( rowCount() && rowCount() > row ) return item( row, column )->data( role ).toULongLong(); else return 0; } QString StatisticsModel::text( StatsColumn column, int row ) const { if ( row < 0 ) row = rowCount() - 1; if ( rowCount() && rowCount() > row ) return item( row, column )->data( Qt::DisplayRole ).toString(); else return QString(); } void StatisticsModel::updateText( QStandardItem * i ) { quint64 all = i->data( DataRole ).toULongLong(); i->setData( KIO::convertSize( all ), Qt::DisplayRole ); } int StatisticsModel::createEntry( const QDateTime &dateTime, int entryId, int days ) { QList entry; QStandardItem * dateItem = new QStandardItem(); QStandardItem * txItem = new QStandardItem(); QStandardItem * rxItem = new QStandardItem(); QStandardItem * totalItem = new QStandardItem(); dateItem->setData( dateTime, DataRole ); if ( entryId < 0 ) { entryId = rowCount(); } dateItem->setData( entryId, IdRole ); if ( days > 0 ) { dateItem->setData( days, SpanRole ); } entry << dateItem << txItem << rxItem << totalItem; appendRow( entry ); setTraffic( rowCount() - 1, 0, 0 ); updateDateText( rowCount() - 1 ); return entryId; } void StatisticsModel::updateDateText( int row ) { if ( row < 0 || !rowCount() || !mCalendar ) return; QLocale locale; QString dateStr; QDateTime dt = dateTime( row ); int dy = days( row ); switch ( mPeriodType ) { case KNemoStats::Hour: dateStr = locale.toString( dt.time(), QLocale::ShortFormat ); if ( dt.date() == QDate::currentDate() ) { dateStr += " " + i18n("Today"); } else { dateStr += " " + i18n("Yesterday"); } break; case KNemoStats::Month: dateStr = QString( "%1 %2" ) .arg( mCalendar->monthName( dt.date(), KCalendarSystem::ShortName ) ) .arg( mCalendar->year( dt.date() ) ); break; case KNemoStats::Year: dateStr = QString::number( mCalendar->year( dt.date() ) ); break; case KNemoStats::BillPeriod: // Format for simple period // Starts on the first of the month, lasts exactly one month if ( mCalendar->day( dt.date() ) == 1 && dy == mCalendar->daysInMonth( dt.date() ) ) dateStr = QString( "%1 %2" ) .arg( mCalendar->monthName( dt.date(), KCalendarSystem::ShortName ) ) .arg( mCalendar->year( dt.date() ) ); // Format for complex period else { QDate endDate = dt.date().addDays( dy - 1 ); dateStr = QString( "%1 %2 - %4 %5 %6" ) .arg( mCalendar->day( dt.date() ) ) .arg( mCalendar->monthName( dt.date(), KCalendarSystem::ShortName ) ) .arg( mCalendar->day( endDate ) ) .arg( mCalendar->monthName( endDate, KCalendarSystem::ShortName ) ) .arg( mCalendar->year( endDate ) ); } break; default: dateStr = mCalendar->formatDate( dt.date(), KLocale::ShortDate ); } item( row, Date )->setData( dateStr, Qt::DisplayRole ); } void StatisticsModel::setId( int id, int row ) { if ( !rowCount() ) return; if ( row < 0 ) row = rowCount() - 1; item( row, Date )->setData(id, IdRole ); } int StatisticsModel::id( int row ) const { if ( row < 0 ) row = rowCount() - 1; if ( !rowCount() || rowCount() <= row ) return -1; return item( row, Date )->data( IdRole ).toInt(); } QDateTime StatisticsModel::dateTime( int row ) const { if ( row < 0 ) row = rowCount() - 1; if ( rowCount() && rowCount() > row ) return item( row, Date )->data( DataRole ).toDateTime(); else return QDateTime(); } QDate StatisticsModel::date( int row ) const { return dateTime( row ).date(); } int StatisticsModel::days( int row ) const { if ( row < 0 ) row = rowCount() - 1; if ( rowCount() && rowCount() > row ) { if ( mPeriodType != KNemoStats::BillPeriod ) { QDate dateTime = item( row, Date )->data( DataRole ).toDateTime().date(); switch ( mPeriodType ) { case KNemoStats::Day: return 1; break; case KNemoStats::Week: return mCalendar->daysInWeek( dateTime ); break; case KNemoStats::Month: return mCalendar->daysInMonth( dateTime ); break; case KNemoStats::Year: return mCalendar->daysInYear( dateTime ); break; default: return 0; } } else { return item( row, Date )->data( SpanRole ).toInt(); } } else return 0; } void StatisticsModel::addTrafficType( int trafficType, int row ) { if ( row < 0 ) row = rowCount() - 1; if ( rowCount() && rowCount() > row ) { int types = item( row, Date )->data( TrafficTypeRole ).toInt(); item( row, Date )->setData( types | trafficType, TrafficTypeRole ); } } void StatisticsModel::resetTrafficTypes( int row ) { if ( row < 0 ) row = rowCount() - 1; if ( rowCount() && rowCount() > row ) item( row, Date )->setData( KNemoStats::AllTraffic, TrafficTypeRole ); } QList StatisticsModel::trafficTypes( int row ) const { if ( row < 0 ) row = rowCount() - 1; QList typeList; typeList << KNemoStats::AllTraffic; if ( rowCount() && rowCount() > row ) { int types = item( row, Date )->data( TrafficTypeRole ).toInt(); if ( types & KNemoStats::OffpeakTraffic ) typeList << KNemoStats::OffpeakTraffic; } return typeList; } quint64 StatisticsModel::rxBytes( int row, KNemoStats::TrafficType trafficType ) const { return bytes( RxBytes, DataRole+trafficType, row ); } quint64 StatisticsModel::txBytes( int row, KNemoStats::TrafficType trafficType ) const { return bytes( TxBytes, DataRole+trafficType, row ); } quint64 StatisticsModel::totalBytes( int row, KNemoStats::TrafficType trafficType ) const { return bytes( TotalBytes, DataRole+trafficType, row ); } QString StatisticsModel::txText( int row ) const { return text( TxBytes, row ); } QString StatisticsModel::rxText( int row ) const { return text( RxBytes, row ); } QString StatisticsModel::totalText( int row ) const { return text( TotalBytes, row ); } void StatisticsModel::addRxBytes( quint64 bytes, KNemoStats::TrafficType trafficType, int row ) { addBytes( RxBytes, trafficType, bytes, row ); addBytes( TotalBytes, trafficType, bytes, row ); } void StatisticsModel::addTxBytes( quint64 bytes, KNemoStats::TrafficType trafficType, int row ) { addBytes( TxBytes, trafficType, bytes, row ); addBytes( TotalBytes, trafficType, bytes, row ); } int StatisticsModel::indexOfId( int id ) const { int index = 0; while ( index < rowCount() ) { if ( item( index, Date )->data( IdRole ).toInt() == id ) return index; index++; } return -1; } void StatisticsModel::setTraffic( int row, quint64 rx, quint64 tx, KNemoStats::TrafficType trafficType ) { if ( row < 0 || row >= rowCount() ) return; item( row, RxBytes )->setData( rx, DataRole + trafficType ); item( row, TxBytes )->setData( tx, DataRole + trafficType ); item( row, TotalBytes )->setData( rx+tx, DataRole + trafficType ); if ( trafficType == KNemoStats::AllTraffic ) { updateText( item( row, RxBytes ) ); updateText( item( row, TxBytes ) ); updateText( item( row, TotalBytes ) ); } } #include "moc_statisticsmodel.cpp"