diff --git a/src/common/data.h b/src/common/data.h index 038f165..0e9a760 100644 --- a/src/common/data.h +++ b/src/common/data.h @@ -1,411 +1,408 @@ /* 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 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, MaxState = 256 }; } 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 QLatin1String NETLOAD_THEME("netloadtheme"); static const QLatin1String TEXT_THEME("texttheme"); static const QLatin1String SYSTEM_THEME("systemtheme"); static const QLatin1String ICON_ERROR("error"); static const QLatin1String ICON_OFFLINE("offline"); static const QLatin1String ICON_IDLE("idle"); static const QLatin1String ICON_RX("receive"); static const QLatin1String ICON_TX("transmit"); static const QLatin1String ICON_RX_TX("transmit-receive"); // config groups static const QLatin1String confg_general("General"); static const QLatin1String confg_interface("Interface_"); static const QLatin1String confg_plotter("Plotter_"); static const QLatin1String confg_statsRule("StatsRule_"); static const QLatin1String confg_warnRule("WarnRule_"); static const QLatin1String conf_firstStart("FirstStart"); static const QLatin1String conf_autoStart("AutoStart"); static const QLatin1String conf_interfaces("Interfaces"); // interface static const QLatin1String conf_alias("Alias"); // interface icon static const QLatin1String conf_minVisibleState("MinVisibleState"); static const QLatin1String conf_trafficThreshold("TrafficThreshold"); static const QLatin1String conf_iconTheme("IconSet"); static const QLatin1String conf_barScale("BarScale"); -static const QLatin1String conf_inMaxRate("InMaxRate"); -static const QLatin1String conf_outMaxRate("OutMaxRate"); +static const QLatin1String conf_maxRate("MaxRate"); // interface statistics static const QLatin1String conf_activateStatistics("ActivateStatistics"); static const QLatin1String conf_calendarSystem("CalendarSystem"); static const QLatin1String conf_statsRules("StatsRules"); static const QLatin1String conf_warnRules("WarnRules"); // interface billing static const QLatin1String conf_statsStartDate("StartDate"); static const QLatin1String conf_statsPeriodUnits("PeriodUnits"); static const QLatin1String conf_statsPeriodCount("PeriodCount"); static const QLatin1String conf_logOffpeak("LogOffpeak"); static const QLatin1String conf_offpeakStartTime("OffpeakStartTime"); static const QLatin1String conf_offpeakEndTime("OffpeakEndTime"); static const QLatin1String conf_weekendIsOffpeak("WeekendIsOffpeak"); static const QLatin1String conf_weekendDayStart("WeekendDayStart"); static const QLatin1String conf_weekendDayEnd("WeekendDayEnd"); static const QLatin1String conf_weekendTimeStart("WeekendTimeStart"); static const QLatin1String conf_weekendTimeEnd("WeekendTimeEnd"); // warning static const QLatin1String conf_warnPeriodUnits("PeriodUnits"); static const QLatin1String conf_warnPeriodCount("PeriodCount"); static const QLatin1String conf_warnTrafficType("TrafficType"); static const QLatin1String conf_warnTrafficDirection("TrafficDirection"); static const QLatin1String conf_warnTrafficUnits("TrafficUnits"); static const QLatin1String conf_warnThreshold("Threshold"); static const QLatin1String conf_warnCustomText("CustomText"); // tooltip static const QLatin1String conf_toolTipContent("ToolTipContent"); // general static const QLatin1String conf_pollInterval("PollInterval"); static const QLatin1String conf_saveInterval("SaveInterval"); static const QLatin1String conf_useBitrate("UseBitrate"); static const QLatin1String conf_plotterPos("PlotterPos"); static const QLatin1String conf_plotterSize("PlotterSize"); static const QLatin1String conf_statisticsPos("StatisticsPos"); static const QLatin1String conf_statisticsSize("StatisticsSize"); static const QLatin1String conf_statusPos("StatusPos"); static const QLatin1String conf_statusSize("StatusSize"); static const QLatin1String conf_hourState("HourState"); static const QLatin1String conf_dayState("DayState"); static const QLatin1String conf_weekState("WeekState"); static const QLatin1String conf_monthState("MonthState"); static const QLatin1String conf_billingState("BillingState"); static const QLatin1String 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 GeneralSettings { GeneralSettings() : toolTipContent( defaultTip ), pollInterval( 1.0 ), saveInterval( 60 ), useBitrate( false ), statisticsDir( QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1String("/knemo") ) {} int toolTipContent; double pollInterval; int saveInterval; bool useBitrate; QDir 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() : barScale( false ), - inMaxRate( 4 ), - outMaxRate( 4 ), + maxRate( 4 ), trafficThreshold( 0 ), minVisibleState( KNemoIface::UnknownState ), activateStatistics( false ), calendarSystem( KLocale::QDateCalendar ) {} QString iconTheme; bool barScale; - unsigned int inMaxRate; - unsigned int outMaxRate; + unsigned int maxRate; unsigned int trafficThreshold; int minVisibleState; bool activateStatistics; QList statsRules; QList warnRules; KLocale::CalendarSystem calendarSystem; QString alias; }; #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/kcm/configdialog.cpp b/src/kcm/configdialog.cpp index fad2d15..371b3c9 100644 --- a/src/kcm/configdialog.cpp +++ b/src/kcm/configdialog.cpp @@ -1,1452 +1,1449 @@ /* 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 #include #include #include #include #include "ui_configdlg.h" #include "config-knemo.h" #include "configdialog.h" #include "statsconfig.h" #include "warnconfig.h" #include "themeconfig.h" #include "utils.h" #include #include #include #include #ifdef __linux__ #include #include #include #endif K_PLUGIN_FACTORY(KNemoFactory, registerPlugin(QLatin1String("knemo"));) K_EXPORT_PLUGIN(KNemoFactory("kcm_knemo")) Q_DECLARE_METATYPE( KNemoTheme ) Q_DECLARE_METATYPE( StatsRule ) Q_DECLARE_METATYPE( WarnRule ) static bool themesLessThan( const KNemoTheme& s1, const KNemoTheme& s2 ) { if ( s1.name < s2.name ) return true; else return false; } static QString periodText( int c, int u ) { QString units; switch ( u ) { case KNemoStats::Hour: units = i18np( "%1 hour", "%1 hours", c ); break; case KNemoStats::Day: units = i18np( "%1 day", "%1 days", c ); break; case KNemoStats::Week: units = i18np( "%1 week", "%1 weeks", c ); break; case KNemoStats::Month: units = i18np( "%1 month", "%1 months", c ); break; case KNemoStats::BillPeriod: units = i18np( "%1 billing period", "%1 billing periods", c ); break; case KNemoStats::Year: units = i18np( "%1 year", "%1 years", c ); break; default: units = i18n( "Invalid period" ); ;; } return units; } void StatsRuleModel::setCalendar( const KCalendarSystem *cal ) { mCalendar = cal; } QString StatsRuleModel::dateText( const StatsRule &s ) { QString dateStr = mCalendar->formatDate( s.startDate, KLocale::LongDate ); if ( !mCalendar->isValid( s.startDate ) ) dateStr = i18n( "Invalid Date" ); return dateStr; } QList StatsRuleModel::getRules() { QList statsRules; for ( int i = 0; i < rowCount(); ++i ) { statsRules << item( i, 0 )->data( Qt::UserRole ).value(); } return statsRules; } QModelIndex StatsRuleModel::addRule( const StatsRule &s ) { QList items; QStandardItem *item = new QStandardItem( dateText( s ) ); QVariant v; v.setValue( s ); item->setData( v, Qt::UserRole ); item->setData( s.startDate, Qt::UserRole + 1 ); items << item; item = new QStandardItem( periodText( s.periodCount, s.periodUnits ) ); items << item; appendRow( items ); return indexFromItem (items[0] ); } void StatsRuleModel::modifyRule( const QModelIndex &index, const StatsRule &s ) { QVariant v; v.setValue( s ); item( index.row(), 0 )->setData( v, Qt::UserRole ); item( index.row(), 0 )->setData( s.startDate, Qt::UserRole + 1 ); item( index.row(), 0 )->setData( dateText( s ), Qt::DisplayRole ); item( index.row(), 1 )->setData( periodText( s.periodCount, s.periodUnits ), Qt::DisplayRole ); } QString WarnModel::ruleText( const WarnRule &warn ) { QString warnText; quint64 siz = warn.threshold * pow( 1024, warn.trafficUnits ); switch ( warn.trafficDirection ) { case KNemoStats::TrafficIn: if ( warn.trafficType == KNemoStats::Peak ) warnText = i18n( "peak incoming traffic > %1" ).arg( KIO::convertSize( siz ) ); else if ( warn.trafficType == KNemoStats::Offpeak ) warnText = i18n( "off-peak incoming traffic > %1" ).arg( KIO::convertSize( siz ) ); else warnText = i18n( "incoming traffic > %1" ).arg( KIO::convertSize( siz ) ); break; case KNemoStats::TrafficOut: if ( warn.trafficType == KNemoStats::Peak ) warnText = i18n( "peak outgoing traffic > %1" ).arg( KIO::convertSize( siz ) ); else if ( warn.trafficType == KNemoStats::Offpeak ) warnText = i18n( "off-peak outgoing traffic > %1" ).arg( KIO::convertSize( siz ) ); else warnText = i18n( "outgoing traffic > %1" ).arg( KIO::convertSize( siz ) ); break; case KNemoStats::TrafficTotal: if ( warn.trafficType == KNemoStats::Peak ) warnText = i18n( "peak incoming and outgoing traffic > %1" ).arg( KIO::convertSize( siz ) ); else if ( warn.trafficType == KNemoStats::Offpeak ) warnText = i18n( "off-peak incoming and outgoing traffic > %1" ).arg( KIO::convertSize( siz ) ); else warnText = i18n( "incoming and outgoing traffic > %1" ).arg( KIO::convertSize( siz ) ); } return warnText; } QList WarnModel::getRules() { QList warnRules; for ( int i = 0; i < rowCount(); ++i ) { warnRules << item( i, 0 )->data( Qt::UserRole ).value(); } return warnRules; } QModelIndex WarnModel::addWarn( const WarnRule &warn ) { QList items; QStandardItem *item = new QStandardItem( ruleText( warn ) ); QVariant v; v.setValue( warn ); item->setData( v, Qt::UserRole ); items << item; item = new QStandardItem( periodText( warn.periodCount, warn.periodUnits ) ); items << item; appendRow( items ); return indexFromItem( items[0] ); } void WarnModel::modifyWarn( const QModelIndex &index, const WarnRule &warn ) { QVariant v; v.setValue( warn ); item( index.row(), 0 )->setData( v, Qt::UserRole ); item( index.row(), 0 )->setData( ruleText( warn ), Qt::DisplayRole ); item( index.row(), 1 )->setData( periodText( warn.periodCount, warn.periodUnits ), Qt::DisplayRole ); } ConfigDialog::ConfigDialog( QWidget *parent, const QVariantList &args ) : KCModule( parent, args ), mLock( false ), mDlg( new Ui::ConfigDlg() ), mCalendar( 0 ) { migrateKde4Conf(); setupToolTipMap(); QWidget *main = new QWidget( this ); QVBoxLayout* top = new QVBoxLayout( this ); mDlg->setupUi( main ); top->addWidget( main ); statsModel = new StatsRuleModel( this ); QStringList l; l << i18n( "Start Date" ) << i18n( "Period" ); statsModel->setHorizontalHeaderLabels( l ); QSortFilterProxyModel *proxy = new QSortFilterProxyModel( mDlg->statsView ); proxy->setSourceModel( statsModel ); proxy->setSortRole( Qt::UserRole + 1 ); mDlg->statsView->setModel( proxy ); mDlg->statsView->sortByColumn( 0, Qt::AscendingOrder ); warnModel = new WarnModel( this ); l.clear(); l << i18n( "Alert" ) << i18n( "Period" ); warnModel->setHorizontalHeaderLabels( l ); mDlg->warnView->setModel( warnModel ); QList themes = findThemes(); qSort( themes.begin(), themes.end(), themesLessThan ); foreach ( KNemoTheme theme, themes ) mDlg->comboBoxIconTheme->addItem( theme.name, QVariant::fromValue( theme ) ); // We want these hardcoded and at the bottom of the list KNemoTheme systemTheme; systemTheme.name = i18n( "System Theme" ); systemTheme.comment = i18n( "Use the current icon theme's network status icons" ); systemTheme.internalName = SYSTEM_THEME; KNemoTheme textTheme; textTheme.name = i18n( "Text" ); textTheme.comment = i18n( "KNemo theme that shows the upload/download speed as text" ); textTheme.internalName = TEXT_THEME; KNemoTheme netloadTheme; netloadTheme.name = i18n( "Netload" ); netloadTheme.comment = i18n( "KNemo theme that shows the upload/download speed as bar graphs" ); netloadTheme.internalName = NETLOAD_THEME; // Leave this out for now. Looks like none of the KDE icon themes provide // status/network-* icons. //mDlg->comboBoxIconTheme->addItem( systemTheme.name, QVariant::fromValue( systemTheme ) ); mDlg->comboBoxIconTheme->addItem( netloadTheme.name, QVariant::fromValue( netloadTheme ) ); mDlg->comboBoxIconTheme->addItem( textTheme.name, QVariant::fromValue( textTheme ) ); InterfaceSettings s; int index = findIndexFromName( s.iconTheme ); if ( index < 0 ) index = findIndexFromName( TEXT_THEME ); mDlg->comboBoxIconTheme->setCurrentIndex( index ); for ( size_t i = 0; i < sizeof(pollIntervals)/sizeof(double); i++ ) mDlg->comboBoxPoll->addItem( i18n( "%1 sec", pollIntervals[i] ), pollIntervals[i] ); mDlg->pushButtonNew->setIcon( QIcon::fromTheme( QLatin1String("list-add") ) ); mDlg->pushButtonAll->setIcon( QIcon::fromTheme( QLatin1String("document-new") ) ); mDlg->pushButtonDelete->setIcon( QIcon::fromTheme( QLatin1String("list-remove") ) ); mDlg->pushButtonAddToolTip->setIcon( QIcon::fromTheme( QLatin1String("arrow-right") ) ); mDlg->pushButtonRemoveToolTip->setIcon( QIcon::fromTheme( QLatin1String("arrow-left") ) ); setButtons( KCModule::Default | KCModule::Apply ); connect( mDlg->checkBoxStartKNemo, SIGNAL( toggled( bool ) ), this, SLOT( checkBoxStartKNemoToggled( bool ) ) ); // Interface connect( mDlg->listBoxInterfaces, SIGNAL( currentRowChanged( int ) ), this, SLOT( interfaceSelected( int ) ) ); connect( mDlg->pushButtonNew, SIGNAL( clicked() ), this, SLOT( buttonNewSelected() ) ); connect( mDlg->pushButtonAll, SIGNAL( clicked() ), this, SLOT( buttonAllSelected() ) ); connect( mDlg->pushButtonDelete, SIGNAL( clicked() ), this, SLOT( buttonDeleteSelected() ) ); connect( mDlg->lineEditAlias, SIGNAL( textChanged( const QString& ) ), this, SLOT( aliasChanged( const QString& ) ) ); // Interface - Icon Appearance connect( mDlg->comboHiding, SIGNAL( activated( int ) ), this, SLOT( comboHidingChanged( int ) ) ); connect( mDlg->comboBoxIconTheme, SIGNAL( activated( int ) ), this, SLOT( iconThemeChanged( int ) ) ); connect( mDlg->advancedButton, SIGNAL( clicked() ), this, SLOT( advancedButtonClicked() ) ); // Interface - Statistics connect( mDlg->checkBoxStatistics, SIGNAL( toggled( bool ) ), this, SLOT( checkBoxStatisticsToggled ( bool ) ) ); connect( mDlg->addStats, SIGNAL( clicked() ), this, SLOT( addStatsClicked() ) ); connect( mDlg->modifyStats, SIGNAL( clicked() ), this, SLOT( modifyStatsClicked() ) ); connect( mDlg->removeStats, SIGNAL( clicked() ), this, SLOT( removeStatsClicked() ) ); connect( mDlg->addWarn, SIGNAL( clicked() ), this, SLOT( addWarnClicked() ) ); connect( mDlg->modifyWarn, SIGNAL( clicked() ), this, SLOT( modifyWarnClicked() ) ); connect( mDlg->removeWarn, SIGNAL( clicked() ), this, SLOT( removeWarnClicked() ) ); // ToolTip connect( mDlg->pushButtonAddToolTip, SIGNAL( clicked() ), this, SLOT( buttonAddToolTipSelected() ) ); connect( mDlg->pushButtonRemoveToolTip, SIGNAL( clicked() ), this, SLOT( buttonRemoveToolTipSelected() ) ); // General connect( mDlg->pushButtonNotifications, SIGNAL( clicked() ), this, SLOT( buttonNotificationsSelected() ) ); connect( mDlg->comboBoxPoll, SIGNAL( currentIndexChanged( int ) ), this, SLOT( changed() ) ); connect( mDlg->numInputSaveInterval, SIGNAL( valueChanged( int ) ), this, SLOT( changed() ) ); connect( mDlg->useBitrate, SIGNAL( toggled( bool ) ), this, SLOT( changed() ) ); } ConfigDialog::~ConfigDialog() { delete mDlg; } void ConfigDialog::load() { mSettingsMap.clear(); mDlg->listBoxInterfaces->clear(); KSharedConfig::Ptr config = KSharedConfig::openConfig( QLatin1String("knemorc") ); KConfigGroup generalGroup( config, confg_general ); bool startKNemo = generalGroup.readEntry( conf_autoStart, true ); mDlg->checkBoxStartKNemo->setChecked( startKNemo ); GeneralSettings g; double pollVal = clamp(generalGroup.readEntry( conf_pollInterval, g.pollInterval ), 0.1, 2.0 ); pollVal = validatePoll( pollVal ); int index = mDlg->comboBoxPoll->findData( pollVal ); if ( index >= 0 ) mDlg->comboBoxPoll->setCurrentIndex( index ); mDlg->numInputSaveInterval->setValue( clamp(generalGroup.readEntry( conf_saveInterval, g.saveInterval ), 0, 300 ) ); mDlg->useBitrate->setChecked( generalGroup.readEntry( conf_useBitrate, g.useBitrate ) ); mToolTipContent = generalGroup.readEntry( conf_toolTipContent, g.toolTipContent ); QStringList list = generalGroup.readEntry( conf_interfaces, QStringList() ); // Get defaults from the struct InterfaceSettings s; foreach ( QString interface, list ) { QString group( confg_interface ); group += interface; InterfaceSettings* settings = new InterfaceSettings(); if ( config->hasGroup( group ) ) { KConfigGroup interfaceGroup( config, group ); settings->alias = interfaceGroup.readEntry( conf_alias ).trimmed(); settings->minVisibleState = interfaceGroup.readEntry( conf_minVisibleState, s.minVisibleState ); settings->trafficThreshold = clamp(interfaceGroup.readEntry( conf_trafficThreshold, s.trafficThreshold ), 0, 1000 ); settings->iconTheme = interfaceGroup.readEntry( conf_iconTheme, s.iconTheme ); KColorScheme scheme(QPalette::Active, KColorScheme::View); settings->barScale = interfaceGroup.readEntry( conf_barScale, s.barScale ); - settings->inMaxRate = interfaceGroup.readEntry( conf_inMaxRate, s.inMaxRate ); - settings->outMaxRate = interfaceGroup.readEntry( conf_outMaxRate, s.outMaxRate ); + settings->maxRate = interfaceGroup.readEntry( conf_maxRate, s.maxRate ); settings->calendarSystem = static_cast(interfaceGroup.readEntry( conf_calendarSystem, static_cast(KLocale::QDateCalendar) )); settings->activateStatistics = interfaceGroup.readEntry( conf_activateStatistics, s.activateStatistics ); int statsRuleCount = interfaceGroup.readEntry( conf_statsRules, 0 ); for ( int i = 0; i < statsRuleCount; ++i ) { group = QString::fromLatin1( "%1%2 #%3" ).arg( confg_statsRule ).arg( interface ).arg( i ); if ( config->hasGroup( group ) ) { KConfigGroup statsGroup( config, group ); StatsRule stats; stats.startDate = statsGroup.readEntry( conf_statsStartDate, QDate() ); stats.periodUnits = clamp(statsGroup.readEntry( conf_statsPeriodUnits, stats.periodUnits ), KNemoStats::Day, KNemoStats::Year ); stats.periodCount = clamp(statsGroup.readEntry( conf_statsPeriodCount, stats.periodCount ), 1, 1000 ); stats.logOffpeak = statsGroup.readEntry( conf_logOffpeak,stats.logOffpeak ); stats.offpeakStartTime = QTime::fromString( statsGroup.readEntry( conf_offpeakStartTime, stats.offpeakStartTime.toString( Qt::ISODate ) ), Qt::ISODate ); stats.offpeakEndTime = QTime::fromString( statsGroup.readEntry( conf_offpeakEndTime, stats.offpeakEndTime.toString( Qt::ISODate ) ), Qt::ISODate ); stats.weekendIsOffpeak = statsGroup.readEntry( conf_weekendIsOffpeak, stats.weekendIsOffpeak ); stats.weekendDayStart = statsGroup.readEntry( conf_weekendDayStart, stats.weekendDayStart ); stats.weekendDayEnd = statsGroup.readEntry( conf_weekendDayEnd, stats.weekendDayEnd ); stats.weekendTimeStart = QTime::fromString( statsGroup.readEntry( conf_weekendTimeStart, stats.weekendTimeStart.toString( Qt::ISODate ) ), Qt::ISODate ); stats.weekendTimeEnd = QTime::fromString( statsGroup.readEntry( conf_weekendTimeEnd, stats.weekendTimeEnd.toString( Qt::ISODate ) ), Qt::ISODate ); settings->statsRules << stats; } } int warnRuleCount = interfaceGroup.readEntry( conf_warnRules, 0 ); for ( int i = 0; i < warnRuleCount; ++i ) { group = QString::fromLatin1( "%1%2 #%3" ).arg( confg_warnRule ).arg( interface ).arg( i ); if ( config->hasGroup( group ) ) { KConfigGroup warnGroup( config, group ); WarnRule warn; warn.periodUnits = clamp(warnGroup.readEntry( conf_warnPeriodUnits, warn.periodUnits ), KNemoStats::Hour, KNemoStats::Year ); warn.periodCount = clamp(warnGroup.readEntry( conf_warnPeriodCount, warn.periodCount ), 1, 1000 ); warn.trafficType = clamp(warnGroup.readEntry( conf_warnTrafficType, warn.trafficType ), KNemoStats::Peak, KNemoStats::PeakOffpeak ); warn.trafficDirection = clamp(warnGroup.readEntry( conf_warnTrafficDirection, warn.trafficDirection ), KNemoStats::TrafficIn, KNemoStats::TrafficTotal ); warn.trafficUnits = clamp(warnGroup.readEntry( conf_warnTrafficUnits, warn.trafficUnits ), KNemoStats::UnitB, KNemoStats::UnitG ); warn.threshold = clamp(warnGroup.readEntry( conf_warnThreshold, warn.threshold ), 0.0, 9999.0 ); warn.customText = warnGroup.readEntry( conf_warnCustomText, warn.customText ).trimmed(); settings->warnRules << warn; } } } mSettingsMap.insert( interface, settings ); mDlg->listBoxInterfaces->addItem( interface ); mDlg->pushButtonDelete->setEnabled( true ); mDlg->ifaceTab->setEnabled( true ); } // These things need to be here so that 'Reset' from the control // center is handled correctly. setupToolTipTab(); // In case the user opened the control center via the context menu // this call to the daemon will deliver the interface the menu // belongs to. This way we can preselect the appropriate entry in the list. QString selectedInterface = QString::null; QDBusMessage reply = QDBusInterface(QLatin1String("org.kde.knemo"), QLatin1String("/knemo"), QLatin1String("org.kde.knemo")).call(QLatin1String("getSelectedInterface")); if ( reply.arguments().count() ) { selectedInterface = reply.arguments().first().toString(); } if ( selectedInterface != QString::null ) { // Try to preselect the interface. int i; for ( i = 0; i < mDlg->listBoxInterfaces->count(); i++ ) { if ( mDlg->listBoxInterfaces->item( i )->text() == selectedInterface ) { // Found it. mDlg->listBoxInterfaces->setCurrentRow( i ); break; } } if ( i == mDlg->listBoxInterfaces->count() ) { // Not found. Select first entry in list. mDlg->listBoxInterfaces->setCurrentRow( 0 ); } } else if ( mDlg->listBoxInterfaces->count() ) { // No interface from KNemo. Select first entry in list. mDlg->listBoxInterfaces->setCurrentRow( 0 ); } } void ConfigDialog::save() { KSharedConfig::Ptr config = KSharedConfig::openConfig( QLatin1String("knemorc") ); QStringList list; // Remove interfaces from the config that were deleted during this session foreach ( QString delIface, mDeletedIfaces ) { if ( !mSettingsMap.contains( delIface ) ) { config->deleteGroup( confg_interface + delIface ); config->deleteGroup( confg_plotter + delIface ); } } QStringList groupList = config->groupList(); foreach ( QString tempDel, groupList ) { if ( tempDel.contains( confg_statsRule ) || tempDel.contains( confg_warnRule ) ) config->deleteGroup( tempDel ); } foreach ( QString it, mSettingsMap.keys() ) { list.append( it ); InterfaceSettings* settings = mSettingsMap.value( it ); KConfigGroup interfaceGroup( config, confg_interface + it ); // Preserve settings set by the app before delete QPoint plotterPos = interfaceGroup.readEntry( conf_plotterPos, QPoint() ); QSize plotterSize = interfaceGroup.readEntry( conf_plotterSize, QSize() ); QPoint statisticsPos = interfaceGroup.readEntry( conf_statisticsPos, QPoint() ); QSize statisticsSize = interfaceGroup.readEntry( conf_statisticsSize, QSize() ); QPoint statusPos = interfaceGroup.readEntry( conf_statusPos, QPoint() ); QSize statusSize = interfaceGroup.readEntry( conf_statusSize, QSize() ); QByteArray hourState = interfaceGroup.readEntry( conf_hourState, QByteArray() ); QByteArray dayState = interfaceGroup.readEntry( conf_dayState, QByteArray() ); QByteArray weekState = interfaceGroup.readEntry( conf_weekState, QByteArray() ); QByteArray monthState = interfaceGroup.readEntry( conf_monthState, QByteArray() ); QByteArray billingState = interfaceGroup.readEntry( conf_billingState, QByteArray() ); QByteArray yearState = interfaceGroup.readEntry( conf_yearState, QByteArray() ); // Make sure we don't get crufty commands left over interfaceGroup.deleteGroup(); if ( !plotterPos.isNull() ) interfaceGroup.writeEntry( conf_plotterPos, plotterPos ); if ( !plotterSize.isEmpty() ) interfaceGroup.writeEntry( conf_plotterSize, plotterSize ); if ( !statisticsPos.isNull() ) interfaceGroup.writeEntry( conf_statisticsPos, statisticsPos ); if ( !statisticsSize.isEmpty() ) interfaceGroup.writeEntry( conf_statisticsSize, statisticsSize ); if ( !statusPos.isNull() ) interfaceGroup.writeEntry( conf_statusPos, statusPos ); if ( !statusSize.isEmpty() ) interfaceGroup.writeEntry( conf_statusSize, statusSize ); if ( !settings->alias.trimmed().isEmpty() ) interfaceGroup.writeEntry( conf_alias, settings->alias ); if ( !hourState.isNull() ) interfaceGroup.writeEntry( conf_hourState, hourState ); if ( !dayState.isNull() ) interfaceGroup.writeEntry( conf_dayState, dayState ); if ( !weekState.isNull() ) interfaceGroup.writeEntry( conf_weekState, weekState ); if ( !monthState.isNull() ) interfaceGroup.writeEntry( conf_monthState, monthState ); if ( !billingState.isNull() ) interfaceGroup.writeEntry( conf_billingState, billingState ); if ( !yearState.isNull() ) interfaceGroup.writeEntry( conf_yearState, yearState ); interfaceGroup.writeEntry( conf_minVisibleState, settings->minVisibleState ); interfaceGroup.writeEntry( conf_trafficThreshold, settings->trafficThreshold ); interfaceGroup.writeEntry( conf_iconTheme, settings->iconTheme ); if ( settings->iconTheme == TEXT_THEME || settings->iconTheme == NETLOAD_THEME ) { if ( settings->iconTheme == NETLOAD_THEME ) { interfaceGroup.writeEntry( conf_barScale, settings->barScale ); } if ( settings->iconTheme == NETLOAD_THEME && settings->barScale ) { - interfaceGroup.writeEntry( conf_inMaxRate, settings->inMaxRate ); - interfaceGroup.writeEntry( conf_outMaxRate, settings->outMaxRate ); + interfaceGroup.writeEntry( conf_maxRate, settings->maxRate ); } } interfaceGroup.writeEntry( conf_activateStatistics, settings->activateStatistics ); interfaceGroup.writeEntry( conf_calendarSystem, static_cast(settings->calendarSystem) ); interfaceGroup.writeEntry( conf_statsRules, settings->statsRules.count() ); for ( int i = 0; i < settings->statsRules.count(); i++ ) { QString group = QString::fromLatin1( "%1%2 #%3" ).arg( confg_statsRule ).arg( it ).arg( i ); KConfigGroup statsGroup( config, group ); statsGroup.writeEntry( conf_statsStartDate, settings->statsRules[i].startDate ); statsGroup.writeEntry( conf_statsPeriodUnits, settings->statsRules[i].periodUnits ); statsGroup.writeEntry( conf_statsPeriodCount, settings->statsRules[i].periodCount ); statsGroup.writeEntry( conf_logOffpeak, settings->statsRules[i].logOffpeak ); if ( settings->statsRules[i].logOffpeak ) { statsGroup.writeEntry( conf_offpeakStartTime, settings->statsRules[i].offpeakStartTime.toString( Qt::ISODate ) ); statsGroup.writeEntry( conf_offpeakEndTime, settings->statsRules[i].offpeakEndTime.toString( Qt::ISODate ) ); statsGroup.writeEntry( conf_weekendIsOffpeak, settings->statsRules[i].weekendIsOffpeak ); if ( settings->statsRules[i].weekendIsOffpeak ) { statsGroup.writeEntry( conf_weekendDayStart, settings->statsRules[i].weekendDayStart ); statsGroup.writeEntry( conf_weekendDayEnd, settings->statsRules[i].weekendDayEnd ); statsGroup.writeEntry( conf_weekendTimeStart, settings->statsRules[i].weekendTimeStart.toString( Qt::ISODate ) ); statsGroup.writeEntry( conf_weekendTimeEnd, settings->statsRules[i].weekendTimeEnd.toString( Qt::ISODate ) ); } } } interfaceGroup.writeEntry( conf_warnRules, settings->warnRules.count() ); for ( int i = 0; i < settings->warnRules.count(); i++ ) { QString group = QString::fromLatin1( "%1%2 #%3" ).arg( confg_warnRule ).arg( it ).arg( i ); KConfigGroup warnGroup( config, group ); if ( settings->statsRules.count() == 0 && settings->warnRules[i].periodUnits == KNemoStats::BillPeriod ) { warnGroup.writeEntry( conf_warnPeriodUnits, static_cast(KNemoStats::Month) ); } else { warnGroup.writeEntry( conf_warnPeriodUnits, settings->warnRules[i].periodUnits ); } warnGroup.writeEntry( conf_warnPeriodCount, settings->warnRules[i].periodCount ); warnGroup.writeEntry( conf_warnTrafficType, settings->warnRules[i].trafficType ); warnGroup.writeEntry( conf_warnTrafficDirection, settings->warnRules[i].trafficDirection ); warnGroup.writeEntry( conf_warnTrafficUnits, settings->warnRules[i].trafficUnits ); warnGroup.writeEntry( conf_warnThreshold, settings->warnRules[i].threshold ); warnGroup.writeEntry( conf_warnCustomText, settings->warnRules[i].customText.trimmed() ); } } KConfigGroup generalGroup( config, confg_general ); generalGroup.writeEntry( conf_firstStart, false ); generalGroup.writeEntry( conf_autoStart, mDlg->checkBoxStartKNemo->isChecked() ); generalGroup.writeEntry( conf_pollInterval, mDlg->comboBoxPoll->itemData( mDlg->comboBoxPoll->currentIndex() ).value() ); generalGroup.writeEntry( conf_saveInterval, mDlg->numInputSaveInterval->value() ); generalGroup.writeEntry( conf_useBitrate, mDlg->useBitrate->isChecked() ); generalGroup.writeEntry( conf_toolTipContent, mToolTipContent ); generalGroup.writeEntry( conf_interfaces, list ); config->sync(); QDBusMessage reply = QDBusInterface(QLatin1String("org.kde.knemo"), QLatin1String("/knemo"), QLatin1String("org.kde.knemo")).call(QLatin1String("reparseConfiguration")); } void ConfigDialog::defaults() { // Set these values before we check for default interfaces mSettingsMap.clear(); mDlg->listBoxInterfaces->clear(); mDlg->pushButtonDelete->setEnabled( false ); InterfaceSettings emptySettings; updateControls( &emptySettings ); // Default interface void *cache = NULL; #ifdef __linux__ struct nl_sock *rtsock = nl_socket_alloc(); int c = nl_connect(rtsock, NETLINK_ROUTE); if ( c >= 0 ) { rtnl_route_alloc_cache( rtsock, AF_UNSPEC, 0, reinterpret_cast(&cache) ); } #endif QString interface = getDefaultRoute( AF_INET, NULL, cache ); if ( interface.isEmpty() ) interface = getDefaultRoute( AF_INET6, NULL, cache ); #ifdef __linux__ nl_cache_free( static_cast(cache) ); nl_close( rtsock ); nl_socket_free( rtsock ); #endif if ( interface.isEmpty() ) { mDlg->aliasLabel->setEnabled( false ); mDlg->lineEditAlias->setEnabled( false ); mDlg->ifaceTab->setEnabled( false ); mDlg->pixmapError->clear(); mDlg->pixmapDisconnected->clear(); mDlg->pixmapConnected->clear(); mDlg->pixmapIncoming->clear(); mDlg->pixmapOutgoing->clear(); mDlg->pixmapTraffic->clear(); } else { InterfaceSettings* settings = new InterfaceSettings(); mSettingsMap.insert( interface, settings ); mDlg->listBoxInterfaces->addItem( interface ); mDlg->listBoxInterfaces->setCurrentRow( 0 ); mDlg->pushButtonDelete->setEnabled( true ); mDlg->aliasLabel->setEnabled( true ); mDlg->lineEditAlias->setEnabled( true ); mDlg->ifaceTab->setEnabled( true ); } // Default general settings GeneralSettings g; int index = mDlg->comboBoxPoll->findData( g.pollInterval ); if ( index >= 0 ) mDlg->comboBoxPoll->setCurrentIndex( index ); mDlg->numInputSaveInterval->setValue( g.saveInterval ); mDlg->useBitrate->setChecked( g.useBitrate ); // Default tool tips mToolTipContent = g.toolTipContent; setupToolTipTab(); changed( true ); } void ConfigDialog::checkBoxStartKNemoToggled( bool on ) { if ( on ) { KSharedConfig::Ptr config = KSharedConfig::openConfig( QLatin1String("knemorc") ); KConfigGroup generalGroup( config, confg_general ); if ( generalGroup.readEntry( conf_firstStart, true ) ) { // Populate the dialog with some default values if the user starts // KNemo for the very first time. defaults(); } } if (!mLock) changed( true ); } /****************************************** * * * Interface tab * * * ******************************************/ InterfaceSettings * ConfigDialog::getItemSettings() { if ( !mDlg->listBoxInterfaces->currentItem() ) return NULL; QListWidgetItem* selected = mDlg->listBoxInterfaces->currentItem(); return mSettingsMap[selected->text()]; } QString ConfigDialog::findNameFromIndex( int index ) { KNemoTheme theme = mDlg->comboBoxIconTheme->itemData( index ).value(); return theme.internalName; } int ConfigDialog::findIndexFromName( const QString& internalName ) { for( int i = 0; i < mDlg->comboBoxIconTheme->count(); i++ ) { KNemoTheme theme = mDlg->comboBoxIconTheme->itemData( i ).value(); if ( theme.internalName == internalName ) return i; } return -1; } void ConfigDialog::updateWarnText( int oldCount ) { // If the billing periods go away, the warn period will change to months // This only changes the text displayed in the model, so it can change // back if a billing period reappears. if ( ! statsModel->rowCount() ) { QList warnRules = warnModel->getRules(); for ( int i = 0; i < warnRules.count(); ++i ) { if ( warnRules[i].periodUnits == KNemoStats::BillPeriod ) { warnModel->item( i, 1 )->setData( periodText( warnRules[i].periodCount, KNemoStats::Month ), Qt::DisplayRole ); } } } else if ( oldCount == 0 ) { QList warnRules = warnModel->getRules(); for ( int i = 0; i < warnRules.count(); ++i ) { if ( warnRules[i].periodUnits == KNemoStats::BillPeriod ) warnModel->item( i, 1 )->setData( periodText( warnRules[i].periodCount, warnRules[i].periodUnits ), Qt::DisplayRole ); } } } void ConfigDialog::updateControls( InterfaceSettings *settings ) { mLock = true; mDlg->lineEditAlias->setText( settings->alias ); int index = findIndexFromName( settings->iconTheme ); if ( index < 0 ) index = findIndexFromName( TEXT_THEME ); mDlg->comboBoxIconTheme->setCurrentIndex( index ); iconThemeChanged( index ); switch ( settings->minVisibleState ) { case KNemoIface::Connected: index = 1; break; case KNemoIface::Available: index = 2; break; case KNemoIface::MaxState: index = 3; break; default: index = 0; } mDlg->comboHiding->setCurrentIndex( index ); comboHidingChanged( index ); mDlg->checkBoxStatistics->setChecked( settings->activateStatistics ); if ( !mCalendar || mCalendar->calendarSystem() != settings->calendarSystem ) mCalendar = KCalendarSystem::create( settings->calendarSystem ); statsModel->removeRows(0, statsModel->rowCount() ); statsModel->setCalendar( mCalendar ); foreach( StatsRule s, settings->statsRules ) { statsModel->addRule( s ); } if ( statsModel->rowCount() ) { QSortFilterProxyModel* proxy = static_cast(mDlg->statsView->model()); QModelIndex index = statsModel->indexFromItem( statsModel->item( 0, 0 ) ); mDlg->statsView->setCurrentIndex( proxy->mapFromSource( index ) ); } mDlg->modifyStats->setEnabled( statsModel->rowCount() ); mDlg->removeStats->setEnabled( statsModel->rowCount() ); warnModel->removeRows(0, warnModel->rowCount() ); foreach( WarnRule warn, settings->warnRules ) { warnModel->addWarn( warn ); } updateWarnText( statsModel->rowCount() ); mDlg->modifyWarn->setEnabled( warnModel->rowCount() ); mDlg->removeWarn->setEnabled( warnModel->rowCount() ); if ( warnModel->rowCount() ) { mDlg->warnView->setCurrentIndex( warnModel->indexFromItem ( warnModel->item( 0, 0 ) ) ); } mLock = false; } void ConfigDialog::interfaceSelected( int row ) { if ( row < 0 ) return; QString interface = mDlg->listBoxInterfaces->item( row )->text(); InterfaceSettings* settings = mSettingsMap[interface]; mDlg->ifaceTab->setEnabled( true ); mDlg->aliasLabel->setEnabled( true ); mDlg->lineEditAlias->setEnabled( true ); updateControls( settings ); } void ConfigDialog::buttonNewSelected() { bool ok = false; QString ifname = QInputDialog::getText( this, i18n( "Add new interface" ), i18n( "Please enter the name of the interface to be monitored.\nIt should be something like 'eth1', 'wlan2' or 'ppp0'." ), QLineEdit::Normal, QString::null, &ok ); if ( ok ) { QListWidgetItem *item = new QListWidgetItem( ifname ); mDlg->listBoxInterfaces->addItem( item ); InterfaceSettings *settings = new InterfaceSettings(); KColorScheme scheme(QPalette::Active, KColorScheme::View); mSettingsMap.insert( ifname, settings ); mDlg->listBoxInterfaces->setCurrentRow( mDlg->listBoxInterfaces->row( item ) ); mDlg->pushButtonDelete->setEnabled( true ); changed( true ); } } void ConfigDialog::buttonAllSelected() { QStringList ifaces; #ifdef __linux__ nl_cache * linkCache = NULL; nl_sock *rtsock = nl_socket_alloc(); int c = nl_connect(rtsock, NETLINK_ROUTE); if ( c >= 0 ) { rtnl_link_alloc_cache( rtsock, AF_UNSPEC, &linkCache ); 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( QLatin1String(rtnl_link_get_name( rtlink )) ); ifaces << ifname; } } nl_cache_free( linkCache ); nl_close( rtsock ); nl_socket_free( rtsock ); #else struct ifaddrs *ifaddr; struct ifaddrs *ifa; getifaddrs( &ifaddr ); for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { QString ifname( ifa->ifa_name ); ifaces << ifname; } freeifaddrs( ifaddr ); #endif ifaces.removeAll( QLatin1String("lo") ); ifaces.removeAll( QLatin1String("lo0") ); const KColorScheme scheme(QPalette::Active, KColorScheme::View); foreach ( QString ifname, ifaces ) { if ( mSettingsMap.contains( ifname ) ) continue; InterfaceSettings* settings = new InterfaceSettings(); mSettingsMap.insert( ifname, settings ); mDlg->listBoxInterfaces->addItem( ifname ); } if ( mDlg->listBoxInterfaces->count() > 0 ) { mDlg->listBoxInterfaces->setCurrentRow( 0 ); mDlg->pushButtonDelete->setEnabled( true ); mDlg->ifaceTab->setEnabled( true ); QString iface = mDlg->listBoxInterfaces->item( 0 )->text(); } changed( true ); } void ConfigDialog::buttonDeleteSelected() { if ( !mDlg->listBoxInterfaces->currentItem() ) return; QListWidgetItem* selected = mDlg->listBoxInterfaces->currentItem(); // To prevent bloat when we save if ( !mDeletedIfaces.contains( selected->text() ) ) mDeletedIfaces << selected->text(); mSettingsMap.remove( selected->text() ); QListWidgetItem *taken = mDlg->listBoxInterfaces->takeItem( mDlg->listBoxInterfaces->row( selected ) ); delete taken; if ( mDlg->listBoxInterfaces->count() < 1 ) { InterfaceSettings emptySettings; updateControls( &emptySettings ); mDlg->pushButtonDelete->setEnabled( false ); mDlg->aliasLabel->setEnabled( false ); mDlg->lineEditAlias->setEnabled( false ); mDlg->ifaceTab->setEnabled( false ); mDlg->pixmapError->clear(); mDlg->pixmapDisconnected->clear(); mDlg->pixmapConnected->clear(); mDlg->pixmapIncoming->clear(); mDlg->pixmapOutgoing->clear(); mDlg->pixmapTraffic->clear(); } changed( true ); } void ConfigDialog::aliasChanged( const QString& text ) { InterfaceSettings* settings = getItemSettings(); if ( !settings ) return; settings->alias = text; if (!mLock) changed( true ); } /****************************************** * * * Interface tab - Icon Appearance * * * ******************************************/ QPixmap ConfigDialog::textIcon( QString incomingText, QString outgoingText, int status ) { QSize iconSize = getIconSize(); QPixmap sampleIcon( iconSize ); sampleIcon.fill( Qt::transparent ); QRect topRect( 0, 0, iconSize.width(), iconSize.height()/2 ); QRect bottomRect( 0, iconSize.width()/2, iconSize.width(), iconSize.height()/2 ); QPainter p( &sampleIcon ); p.setBrush( Qt::NoBrush ); p.setOpacity( 1.0 ); Plasma::Theme theme; QFont rxFont = setIconFont( incomingText, theme.smallestFont(), iconSize.height() ); QFont txFont = setIconFont( outgoingText, theme.smallestFont(), iconSize.height() ); if ( rxFont.pointSizeF() > txFont.pointSizeF() ) rxFont.setPointSizeF( txFont.pointSizeF() ); p.setFont( rxFont ); if ( status >= KNemoIface::Connected ) p.setPen( KColorScheme(QPalette::Active).foreground(KColorScheme::ActiveText).color() ); else if ( status == KNemoIface::Available ) p.setPen( KColorScheme(QPalette::Active).foreground(KColorScheme::InactiveText).color() ); else p.setPen( KColorScheme(QPalette::Active).foreground(KColorScheme::NegativeText).color() ); p.drawText( topRect, Qt::AlignCenter | Qt::AlignRight, incomingText ); p.setFont( rxFont ); if ( status >= KNemoIface::Connected ) p.setPen( KColorScheme(QPalette::Active).foreground(KColorScheme::NeutralText).color() ); p.drawText( bottomRect, Qt::AlignCenter | Qt::AlignRight, outgoingText ); return sampleIcon; } QPixmap ConfigDialog::barIcon( int status ) { int barIncoming = 0; int barOutgoing = 0; QSize iconSize = getIconSize(); int barWidth = static_cast(round(iconSize.width()/3.0) + 0.5); int margins = iconSize.width() - (barWidth*2); int midMargin = static_cast(round(margins/3.0) + 0.5); int outerMargin = static_cast(round((margins - midMargin)/2.0) + 0.5); midMargin = outerMargin + barWidth + midMargin; QPixmap barIcon( iconSize ); barIcon.fill( Qt::transparent ); QPainter p( &barIcon ); QColor rxColor; QColor txColor; QColor bgColor = KColorScheme(QPalette::Active, KColorScheme::Window).foreground(KColorScheme::InactiveText).color(); bgColor.setAlpha( 77 ); if ( status & KNemoIface::Connected ) { rxColor = KColorScheme(QPalette::Active, KColorScheme::Window).foreground(KColorScheme::ActiveText).color(); txColor = KColorScheme(QPalette::Active, KColorScheme::Window).foreground(KColorScheme::NeutralText).color(); } else if ( status & KNemoIface::Available ) { rxColor = KColorScheme(QPalette::Active, KColorScheme::Window).foreground(KColorScheme::InactiveText).color(); rxColor.setAlpha( 153 ); txColor = rxColor; } else { rxColor = KColorScheme(QPalette::Active, KColorScheme::Window).foreground(KColorScheme::NegativeText).color(); txColor = rxColor; } if ( status & KNemoIface::Available || status & KNemoIface::Unavailable ) { barIncoming = iconSize.height(); barOutgoing = iconSize.height(); } if ( status & KNemoIface::RxTraffic ) barIncoming = static_cast(round(iconSize.height()*.75) + 0.5); if ( status & KNemoIface::TxTraffic ) barOutgoing = static_cast(round(iconSize.height()*.75) + 0.5); int top = iconSize.height() - barOutgoing; QRect topLeftRect( outerMargin, 0, barWidth, top ); QRect leftRect( outerMargin, top, barWidth, iconSize.height() ); top = iconSize.height() - barIncoming; QRect topRightRect( midMargin, 0, barWidth, top ); QRect rightRect( midMargin, top, barWidth, iconSize.height() ); p.fillRect( rightRect, rxColor ); p.fillRect( leftRect, txColor ); p.fillRect( topRightRect, bgColor ); p.fillRect( topLeftRect, bgColor ); return barIcon; } void ConfigDialog::comboHidingChanged( int val ) { InterfaceSettings* settings = getItemSettings(); if ( !settings ) return; switch ( val ) { case 0: // Do not hide settings->minVisibleState = KNemoIface::UnknownState; break; case 1: // Hide when disconnected settings->minVisibleState = KNemoIface::Connected; break; case 2: // Hide when unavailable settings->minVisibleState = KNemoIface::Available; break; case 3: // Always hide settings->minVisibleState = KNemoIface::MaxState; break; } if (!mLock) changed( true ); } void ConfigDialog::iconThemeChanged( int set ) { InterfaceSettings* settings = getItemSettings(); if ( !settings ) return; KNemoTheme curTheme = mDlg->comboBoxIconTheme->itemData( mDlg->comboBoxIconTheme->currentIndex() ).value(); if ( curTheme.internalName == TEXT_THEME || curTheme.internalName == NETLOAD_THEME ) { if ( curTheme.internalName == TEXT_THEME ) { QString f1 = QStringLiteral("0.0K"); QString f2 = QStringLiteral("123K"); QString f3 = QStringLiteral("12K"); settings->iconTheme = TEXT_THEME; mDlg->pixmapError->setPixmap( textIcon( f1, f1, KNemoIface::Unavailable ) ); mDlg->pixmapDisconnected->setPixmap( textIcon( f1, f1, KNemoIface::Available ) ); mDlg->pixmapConnected->setPixmap( textIcon( f1, f1, KNemoIface::Connected ) ); mDlg->pixmapIncoming->setPixmap( textIcon( f2, f1, KNemoIface::Connected ) ); mDlg->pixmapOutgoing->setPixmap( textIcon( f1, f3, KNemoIface::Connected ) ); mDlg->pixmapTraffic->setPixmap( textIcon( f2, f3, KNemoIface::Connected ) ); } else { settings->iconTheme = NETLOAD_THEME; mDlg->pixmapError->setPixmap( barIcon( KNemoIface::Unavailable ) ); mDlg->pixmapDisconnected->setPixmap( barIcon( KNemoIface::Available ) ); mDlg->pixmapConnected->setPixmap( barIcon( KNemoIface::Connected ) ); mDlg->pixmapIncoming->setPixmap( barIcon( KNemoIface::Connected | KNemoIface::RxTraffic ) ); mDlg->pixmapOutgoing->setPixmap( barIcon( KNemoIface::Connected | KNemoIface::TxTraffic ) ); mDlg->pixmapTraffic->setPixmap( barIcon( KNemoIface::Connected | KNemoIface::RxTraffic | KNemoIface::TxTraffic ) ); mDlg->pixmapError->setMinimumHeight(getIconSize().height()); } } else { settings->iconTheme = findNameFromIndex( set ); QString iconName; if ( settings->iconTheme == SYSTEM_THEME ) iconName = QLatin1String("network-"); else iconName = QLatin1String("knemo-") + settings->iconTheme + QLatin1Char('-'); QSize iconSize = getIconSize(); mDlg->pixmapError->setPixmap( QIcon::fromTheme( iconName + ICON_ERROR ).pixmap( iconSize ) ); mDlg->pixmapDisconnected->setPixmap( QIcon::fromTheme( iconName + ICON_OFFLINE ).pixmap( iconSize ) ); mDlg->pixmapConnected->setPixmap( QIcon::fromTheme( iconName + ICON_IDLE ).pixmap( iconSize ) ); mDlg->pixmapIncoming->setPixmap( QIcon::fromTheme( iconName + ICON_RX ).pixmap( iconSize ) ); mDlg->pixmapOutgoing->setPixmap( QIcon::fromTheme( iconName + ICON_TX ).pixmap( iconSize ) ); mDlg->pixmapTraffic->setPixmap( QIcon::fromTheme( iconName + ICON_RX_TX ).pixmap( iconSize ) ); } if (!mLock) changed( true ); } void ConfigDialog::advancedButtonClicked() { InterfaceSettings* settings = getItemSettings(); if ( !settings ) return; ThemeConfig dlg( *settings ); if ( dlg.exec() ) { InterfaceSettings s = dlg.settings(); settings->trafficThreshold = s.trafficThreshold; settings->barScale = s.barScale; - settings->inMaxRate = s.inMaxRate; - settings->outMaxRate = s.outMaxRate; + settings->maxRate = s.maxRate; changed( true ); } } void ConfigDialog::addStatsClicked() { InterfaceSettings* settings = getItemSettings(); if ( !settings ) return; StatsRule rule; int oldRuleCount = statsModel->rowCount(); StatsConfig dlg( settings, mCalendar, rule, true ); if ( dlg.exec() ) { rule = dlg.settings(); QSortFilterProxyModel* proxy = static_cast(mDlg->statsView->model()); QModelIndex index = statsModel->addRule( rule ); mDlg->statsView->setCurrentIndex( proxy->mapFromSource( index ) ); settings->statsRules = statsModel->getRules(); mDlg->modifyStats->setEnabled( true ); mDlg->removeStats->setEnabled( true ); updateWarnText( oldRuleCount ); changed( true ); } } void ConfigDialog::modifyStatsClicked() { InterfaceSettings* settings = getItemSettings(); if ( !settings || mDlg->statsView->model()->rowCount() < 1 ) return; QModelIndex index = mDlg->statsView->selectionModel()->currentIndex(); if ( !index.isValid() ) return; QSortFilterProxyModel* proxy = static_cast(mDlg->statsView->model()); index = proxy->mapToSource( index ); StatsRule s = statsModel->item( index.row(), 0 )->data( Qt::UserRole ).value(); StatsConfig dlg( settings, mCalendar, s, false ); if ( dlg.exec() ) { s = dlg.settings(); statsModel->modifyRule( index, s ); settings->statsRules = statsModel->getRules(); changed( true ); } } void ConfigDialog::removeStatsClicked() { InterfaceSettings* settings = getItemSettings(); if ( !settings || mDlg->statsView->model()->rowCount() < 1 ) return; QModelIndex index = mDlg->statsView->selectionModel()->currentIndex(); if ( !index.isValid() ) return; QSortFilterProxyModel* proxy = static_cast(mDlg->statsView->model()); index = proxy->mapToSource( index ); statsModel->removeRow( index.row() ); settings->statsRules = statsModel->getRules(); mDlg->modifyStats->setEnabled( statsModel->rowCount() ); mDlg->removeStats->setEnabled( statsModel->rowCount() ); updateWarnText( statsModel->rowCount() ); changed( true ); } void ConfigDialog::addWarnClicked() { InterfaceSettings* settings = getItemSettings(); if ( !settings ) return; WarnRule warn; WarnConfig dlg( settings, warn, true ); if ( dlg.exec() ) { warn = dlg.settings(); QModelIndex index = warnModel->addWarn( warn ); mDlg->warnView->setCurrentIndex( index ); settings->warnRules = warnModel->getRules(); changed( true ); mDlg->modifyWarn->setEnabled( true ); mDlg->removeWarn->setEnabled( true ); } } void ConfigDialog::modifyWarnClicked() { InterfaceSettings* settings = getItemSettings(); if ( !settings || mDlg->warnView->model()->rowCount() < 1 ) return; const QModelIndex index = mDlg->warnView->selectionModel()->currentIndex(); if ( !index.isValid() ) return; WarnRule warn = mDlg->warnView->model()->data( index.sibling( index.row(), 0 ), Qt::UserRole ).value(); WarnConfig dlg( settings, warn, false ); if ( dlg.exec() ) { warn = dlg.settings(); warnModel->modifyWarn( index, warn ); settings->warnRules = warnModel->getRules(); changed( true ); } } void ConfigDialog::removeWarnClicked() { InterfaceSettings* settings = getItemSettings(); if ( !settings || mDlg->warnView->model()->rowCount() < 1 ) return; const QModelIndex index = mDlg->warnView->selectionModel()->currentIndex(); if ( !index.isValid() ) return; warnModel->removeRow( index.row() ); settings->warnRules = warnModel->getRules(); mDlg->modifyWarn->setEnabled( warnModel->rowCount() ); mDlg->removeWarn->setEnabled( warnModel->rowCount() ); changed( true ); } /****************************************** * * * Interface tab - Statistics * * * ******************************************/ void ConfigDialog::checkBoxStatisticsToggled( bool on ) { InterfaceSettings* settings = getItemSettings(); if ( !settings ) return; settings->activateStatistics = on; if (!mLock) changed( true ); } /****************************************** * * * ToolTip tab * * * ******************************************/ void ConfigDialog::setupToolTipMap() { // Cannot make this data static as the i18n macro doesn't seem // to work when called to early i.e. before setting the catalogue. mToolTips.insert( INTERFACE, i18n( "Interface" ) ); mToolTips.insert( STATUS, i18n( "Status" ) ); mToolTips.insert( UPTIME, i18n( "Connection Time" ) ); mToolTips.insert( IP_ADDRESS, i18n( "IP Address" ) ); mToolTips.insert( SCOPE, i18n( "Scope & Flags" ) ); mToolTips.insert( HW_ADDRESS, i18n( "MAC Address" ) ); mToolTips.insert( BCAST_ADDRESS, i18n( "Broadcast Address" ) ); mToolTips.insert( GATEWAY, i18n( "Default Gateway" ) ); mToolTips.insert( PTP_ADDRESS, i18n( "PtP Address" ) ); mToolTips.insert( RX_PACKETS, i18n( "Packets Received" ) ); mToolTips.insert( TX_PACKETS, i18n( "Packets Sent" ) ); mToolTips.insert( RX_BYTES, i18n( "Bytes Received" ) ); mToolTips.insert( TX_BYTES, i18n( "Bytes Sent" ) ); mToolTips.insert( DOWNLOAD_SPEED, i18n( "Download Speed" ) ); mToolTips.insert( UPLOAD_SPEED, i18n( "Upload Speed" ) ); mToolTips.insert( ESSID, i18n( "ESSID" ) ); mToolTips.insert( MODE, i18n( "Mode" ) ); mToolTips.insert( FREQUENCY, i18n( "Frequency" ) ); mToolTips.insert( BIT_RATE, i18n( "Bit Rate" ) ); mToolTips.insert( ACCESS_POINT, i18n( "Access Point" ) ); mToolTips.insert( LINK_QUALITY, i18n( "Link Quality" ) ); #ifndef __linux__ mToolTips.insert( NICK_NAME, i18n( "Nickname" ) ); #endif mToolTips.insert( ENCRYPTION, i18n( "Encryption" ) ); } void ConfigDialog::setupToolTipTab() { mDlg->listBoxDisplay->clear(); mDlg->listBoxAvailable->clear(); foreach ( QString tip, mToolTips ) { if ( mToolTipContent & mToolTips.key( tip ) ) mDlg->listBoxDisplay->addItem( tip ); else mDlg->listBoxAvailable->addItem( tip ); } if ( mDlg->listBoxDisplay->count() > 0 ) mDlg->listBoxDisplay->item( 0 )->setSelected( true ); if ( mDlg->listBoxAvailable->count() > 0 ) mDlg->listBoxAvailable->item( 0 )->setSelected( true ); mDlg->pushButtonRemoveToolTip->setEnabled( (mDlg->listBoxDisplay->count() > 0) ); mDlg->pushButtonAddToolTip->setEnabled( (mDlg->listBoxAvailable->count() > 0) ); } void ConfigDialog::moveTips( QListWidget *from, QListWidget* to ) { QList selectedItems = from->selectedItems(); foreach ( QListWidgetItem *selected, selectedItems ) { quint32 key = mToolTips.key( selected->text() ); int newIndex = -1; int count = to->count(); for ( int i = 0; i < count; i++ ) { QListWidgetItem *item = to->item( i ); if ( mToolTips.key( item->text() ) > key ) { newIndex = i; break; } } if ( newIndex < 0 ) newIndex = count; selected->setSelected( false ); from->takeItem( from->row( selected ) ); to->insertItem( newIndex, selected ); mDlg->pushButtonAddToolTip->setEnabled( (mDlg->listBoxAvailable->count() > 0) ); mDlg->pushButtonRemoveToolTip->setEnabled( (mDlg->listBoxDisplay->count() > 0) ); changed( true ); } mToolTipContent = 0; for ( int i = 0; i < mDlg->listBoxDisplay->count(); i++ ) mToolTipContent += mToolTips.key( mDlg->listBoxDisplay->item( i )->text() ); } void ConfigDialog::buttonAddToolTipSelected() { // Support extended selection if ( mDlg->listBoxAvailable->count() == 0 ) return; moveTips( mDlg->listBoxAvailable, mDlg->listBoxDisplay ); } void ConfigDialog::buttonRemoveToolTipSelected() { // Support extended selection if ( mDlg->listBoxDisplay->count() == 0 ) return; moveTips( mDlg->listBoxDisplay, mDlg->listBoxAvailable ); } /****************************************** * * * General tab * * * ******************************************/ void ConfigDialog::buttonNotificationsSelected() { KNotifyConfigWidget::configure( this, QLatin1String("knemo") ); } #include "configdialog.moc" diff --git a/src/kcm/themecfg.ui b/src/kcm/themecfg.ui index ed8555e..402d808 100644 --- a/src/kcm/themecfg.ui +++ b/src/kcm/themecfg.ui @@ -1,172 +1,168 @@ ThemeCfg 0 0 0 0 Traffic Traffic activity threshold: If you are on a network with a lot of low-level traffic, you can increase this value so the tray icon does not constantly report activity. packets/sec 1000 Traffic Rate Visualization If this is checked, the Netload bar graphs will use a constant scale based on the maximum rates below. If unchecked, the bar graphs will change scale according to recent traffic rates. Always scale bar graphs to max visual rate - - - - - - - false - - - Max Visual Rate - - - - - Incoming traffic: - - - - - - - <p>The maximum incoming rate for this connection.</p><p>This does <b>not</b> affect the actual traffic rate, only how KNemo displays it.</p> - - - KiB/sec + + + false - - 1 - - - 1048576 - - - 4 - - - - - - - - - - Outgoing traffic: + Max visual rate: - + + + false + - <p>The maximum outgoing rate for this connection.</p><p>This does <b>not</b> affect the actual traffic rate, only how KNemo displays it.</p> + <p>The maximum rate for this connection.</p><p>This does <b>not</b> affect the actual traffic rate, only how KNemo displays it.</p> KiB/sec 1 1048576 4 Qt::Vertical 0 0 QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults spinBoxTrafficThreshold checkBarScale - rxMaxRate - txMaxRate + maxRate - + + + checkBarScale + toggled(bool) + maxText + setEnabled(bool) + + + 87 + 124 + + + 81 + 155 + + + + + checkBarScale + toggled(bool) + maxRate + setEnabled(bool) + + + 258 + 127 + + + 262 + 155 + + + + diff --git a/src/kcm/themeconfig.cpp b/src/kcm/themeconfig.cpp index bcd9d7f..97a14a1 100644 --- a/src/kcm/themeconfig.cpp +++ b/src/kcm/themeconfig.cpp @@ -1,87 +1,70 @@ /* This file is part of KNemo 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 "themeconfig.h" #include ThemeConfig::ThemeConfig( const InterfaceSettings s ) : QDialog(), mSettings( s ) { mDlg.setupUi( this ); if ( mSettings.iconTheme != NETLOAD_THEME ) - mDlg.checkBarScale->hide(); - if ( mSettings.iconTheme != NETLOAD_THEME && - mSettings.iconTheme != TEXT_THEME ) { + mDlg.checkBarScale->hide(); mDlg.rateGroup->hide(); - mDlg.maxRateGroup->hide(); } mDlg.spinBoxTrafficThreshold->setValue( mSettings.trafficThreshold ); - mDlg.txMaxRate->setValue( mSettings.outMaxRate ); - mDlg.rxMaxRate->setValue( mSettings.inMaxRate ); + mDlg.maxRate->setValue( mSettings.maxRate ); mDlg.checkBarScale->setChecked( mSettings.barScale ); - updateRateGroup(); connect( mDlg.buttonBox, SIGNAL( accepted() ), SLOT( accept() ) ); connect( mDlg.buttonBox, SIGNAL( rejected() ), SLOT( reject() ) ); connect( mDlg.buttonBox, SIGNAL( clicked( QAbstractButton* ) ), SLOT( setDefaults( QAbstractButton* ) ) ); - connect( mDlg.checkBarScale, SIGNAL( toggled( bool ) ), SLOT( updateRateGroup() ) ); } void ThemeConfig::setDefaults( QAbstractButton* button ) { if (static_cast(button) == mDlg.buttonBox->button(QDialogButtonBox::RestoreDefaults) ) { InterfaceSettings s; mDlg.spinBoxTrafficThreshold->setValue( s.trafficThreshold ); - mDlg.txMaxRate->setValue( s.outMaxRate ); - mDlg.rxMaxRate->setValue( s.inMaxRate ); + mDlg.maxRate->setValue( s.maxRate ); mDlg.checkBarScale->setChecked( s.barScale ); } } -void ThemeConfig::updateRateGroup() -{ - if ( mDlg.checkBarScale->isChecked() ) - mDlg.maxRateGroup->setEnabled( true ); - else - mDlg.maxRateGroup->setEnabled( false ); -} - - InterfaceSettings ThemeConfig::settings() { mSettings.trafficThreshold = mDlg.spinBoxTrafficThreshold->value(); - mSettings.outMaxRate = mDlg.txMaxRate->value(); - mSettings.inMaxRate = mDlg.rxMaxRate->value(); + mSettings.maxRate = mDlg.maxRate->value(); mSettings.barScale = mDlg.checkBarScale->isChecked(); return mSettings; } #include "moc_themeconfig.cpp" diff --git a/src/kcm/themeconfig.h b/src/kcm/themeconfig.h index b7f288b..4098967 100644 --- a/src/kcm/themeconfig.h +++ b/src/kcm/themeconfig.h @@ -1,41 +1,40 @@ /* This file is part of KNemo 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 THEMECONFIG_H #define THEMECONFIG_H #include #include "data.h" #include "ui_themecfg.h" class ThemeConfig : public QDialog { Q_OBJECT public: ThemeConfig( const InterfaceSettings s ); InterfaceSettings settings(); private Q_SLOTS: void setDefaults( QAbstractButton* ); - void updateRateGroup(); private: Ui::ThemeCfg mDlg; InterfaceSettings mSettings; }; #endif diff --git a/src/knemod/interface.cpp b/src/knemod/interface.cpp index b7512ce..f6ad39e 100644 --- a/src/knemod/interface.cpp +++ b/src/knemod/interface.cpp @@ -1,455 +1,454 @@ /* 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 "backends/backendbase.h" #include "global.h" #include "utils.h" #include "interface.h" #include "interfaceplotterdialog.h" #include "interfacestatistics.h" #include "interfacestatusdialog.h" #include "interfacestatisticsdialog.h" Interface::Interface( const QString &ifname, const BackendData* data ) : QObject(), mIfaceState( KNemoIface::UnknownState ), mPreviousIfaceState( KNemoIface::UnknownState ), mIfaceName( ifname ), mRealSec( 0.0 ), mUptime( 0 ), mUptimeString( QStringLiteral("00:00:00") ), mRxRate( 0 ), mTxRate( 0 ), mIcon( this ), mIfaceStatistics( 0 ), mStatusDialog( 0 ), mStatisticsDialog( 0 ), mPlotterDialog( 0 ), mBackendData( data ) { mPlotterDialog = new InterfacePlotterDialog( mIfaceName ); connect( &mIcon, SIGNAL( statisticsSelected() ), this, SLOT( showStatisticsDialog() ) ); } Interface::~Interface() { delete mStatusDialog; delete mPlotterDialog; delete mStatisticsDialog; delete mIfaceStatistics; } void Interface::configChanged() { KSharedConfig::Ptr config = KSharedConfig::openConfig(); QString group( confg_interface ); group += mIfaceName; KConfigGroup interfaceGroup( config, group ); InterfaceSettings s; mSettings.alias = interfaceGroup.readEntry( conf_alias ).trimmed(); mSettings.iconTheme = interfaceGroup.readEntry( conf_iconTheme, s.iconTheme ); // If the theme is not configured, use a sensible default if (mSettings.iconTheme.isEmpty()) { if ( mBackendData->isWireless ) { mSettings.iconTheme = QLatin1String("wireless"); } else { mSettings.iconTheme = QLatin1String("network"); } } // Let's check that the theme is available QStringList themeNames; QList themes = findThemes(); foreach( KNemoTheme theme, themes ) themeNames << theme.internalName; themeNames << NETLOAD_THEME; // If that's not available, default to the text theme if ( !themeNames.contains( mSettings.iconTheme ) ) mSettings.iconTheme = TEXT_THEME; mSettings.barScale = interfaceGroup.readEntry( conf_barScale, s.barScale ); - mSettings.inMaxRate = interfaceGroup.readEntry( conf_inMaxRate, s.inMaxRate )*1024; - mSettings.outMaxRate = interfaceGroup.readEntry( conf_outMaxRate, s.outMaxRate )*1024; + mSettings.maxRate = interfaceGroup.readEntry( conf_maxRate, s.maxRate )*1024; mSettings.minVisibleState = interfaceGroup.readEntry( conf_minVisibleState, s.minVisibleState ); mSettings.activateStatistics = interfaceGroup.readEntry( conf_activateStatistics, s.activateStatistics ); mSettings.trafficThreshold = clamp(interfaceGroup.readEntry( conf_trafficThreshold, s.trafficThreshold ), 0, 1000 ); mSettings.warnRules.clear(); int warnRuleCount = interfaceGroup.readEntry( conf_warnRules, 0 ); for ( int i = 0; i < warnRuleCount; ++i ) { group = QString::fromLatin1( "%1%2 #%3" ).arg( confg_warnRule ).arg( mIfaceName ).arg( i ); if ( config->hasGroup( group ) ) { KConfigGroup warnGroup( config, group ); WarnRule warn; warn.periodUnits = clamp(warnGroup.readEntry( conf_warnPeriodUnits, warn.periodUnits ), KNemoStats::Hour, KNemoStats::Year ); warn.periodCount = clamp(warnGroup.readEntry( conf_warnPeriodCount, warn.periodUnits ), 1, 1000 ); warn.trafficType = clamp(warnGroup.readEntry( conf_warnTrafficType, warn.trafficType ), KNemoStats::Peak, KNemoStats::PeakOffpeak ); warn.trafficDirection = clamp(warnGroup.readEntry( conf_warnTrafficDirection, warn.trafficDirection ), KNemoStats::TrafficIn, KNemoStats::TrafficTotal ); warn.trafficUnits = clamp(warnGroup.readEntry( conf_warnTrafficUnits, warn.trafficUnits ), KNemoStats::UnitB, KNemoStats::UnitG ); warn.threshold = clamp(warnGroup.readEntry( conf_warnThreshold, warn.threshold ), 0.0, 9999.0 ); warn.customText = warnGroup.readEntry( conf_warnCustomText, warn.customText ).trimmed(); mSettings.warnRules << warn; } } mSettings.calendarSystem = static_cast(interfaceGroup.readEntry( conf_calendarSystem, static_cast(KLocale::QDateCalendar) )); mSettings.statsRules.clear(); int statsRuleCount = interfaceGroup.readEntry( conf_statsRules, 0 ); KCalendarSystem *testCal = KCalendarSystem::create( mSettings.calendarSystem ); for ( int i = 0; i < statsRuleCount; ++i ) { group = QString::fromLatin1( "%1%2 #%3" ).arg( confg_statsRule ).arg( mIfaceName ).arg( i ); if ( config->hasGroup( group ) ) { KConfigGroup statsGroup( config, group ); StatsRule rule; rule.startDate = statsGroup.readEntry( conf_statsStartDate, QDate() ); rule.periodUnits = clamp(statsGroup.readEntry( conf_statsPeriodUnits, rule.periodUnits ), KNemoStats::Day, KNemoStats::Year ); rule.periodCount = clamp(statsGroup.readEntry( conf_statsPeriodCount, rule.periodCount ), 1, 1000 ); rule.logOffpeak = statsGroup.readEntry( conf_logOffpeak,rule.logOffpeak ); rule.offpeakStartTime = QTime::fromString( statsGroup.readEntry( conf_offpeakStartTime, rule.offpeakStartTime.toString( Qt::ISODate ) ), Qt::ISODate ); rule.offpeakEndTime = QTime::fromString( statsGroup.readEntry( conf_offpeakEndTime, rule.offpeakEndTime.toString( Qt::ISODate ) ), Qt::ISODate ); rule.weekendIsOffpeak = statsGroup.readEntry( conf_weekendIsOffpeak, rule.weekendIsOffpeak ); rule.weekendDayStart = clamp(statsGroup.readEntry( conf_weekendDayStart, rule.weekendDayStart ), 1, testCal->daysInWeek( QDate::currentDate() ) ); rule.weekendDayEnd = clamp(statsGroup.readEntry( conf_weekendDayEnd, rule.weekendDayEnd ), 1, testCal->daysInWeek( QDate::currentDate() ) ); rule.weekendTimeStart = QTime::fromString( statsGroup.readEntry( conf_weekendTimeStart, rule.weekendTimeStart.toString( Qt::ISODate ) ), Qt::ISODate ); rule.weekendTimeEnd = QTime::fromString( statsGroup.readEntry( conf_weekendTimeEnd, rule.weekendTimeEnd.toString( Qt::ISODate ) ), Qt::ISODate ); if ( rule.isValid( testCal ) ) { mSettings.statsRules << rule; } } } // This prevents needless regeneration of icon when first shown in tray if ( mIfaceState == KNemoIface::UnknownState ) { mIfaceState = mBackendData->status; mPreviousIfaceState = mIfaceState; } mIcon.configChanged(); if ( mIfaceStatistics ) { mIfaceStatistics->configChanged(); if ( !mSettings.activateStatistics ) stopStatistics(); } else if ( mSettings.activateStatistics ) { startStatistics(); } if ( mStatusDialog ) mStatusDialog->configChanged(); if ( mStatisticsDialog != 0 ) mStatisticsDialog->configChanged(); if ( mPlotterDialog ) mPlotterDialog->useBitrate( generalSettings->useBitrate ); } void Interface::processUpdate() { mPreviousIfaceState = mIfaceState; unsigned int trafficThreshold = mSettings.trafficThreshold; mIfaceState = mBackendData->status; int units = 1; if ( generalSettings->useBitrate ) units = 8; mRxRate = mBackendData->incomingBytes * units / generalSettings->pollInterval; mTxRate = mBackendData->outgoingBytes * units / generalSettings->pollInterval; mRxRateStr = formattedRate( mRxRate, generalSettings->useBitrate ); mTxRateStr = formattedRate( mTxRate, generalSettings->useBitrate ); QString title = mSettings.alias; if ( title.isEmpty() ) title = mIfaceName; if ( mIfaceState & KNemoIface::Connected ) { // the interface is connected, look for traffic if ( ( mBackendData->rxPackets - mBackendData->prevRxPackets ) > trafficThreshold ) mIfaceState |= KNemoIface::RxTraffic; if ( ( mBackendData->txPackets - mBackendData->prevTxPackets ) > trafficThreshold ) mIfaceState |= KNemoIface::TxTraffic; if ( mIfaceStatistics ) { // We only check once an hour if we need to create a new stats entry. // However, the timer will be out of sync if we're resuming from suspend, // so we just check if we need to readjust when an interface becomes connected. if ( mPreviousIfaceState < KNemoIface::Connected ) mIfaceStatistics->checkValidEntry(); mIfaceStatistics->addRxBytes( mBackendData->incomingBytes ); mIfaceStatistics->addTxBytes( mBackendData->outgoingBytes ); } updateTime(); if ( mPreviousIfaceState < KNemoIface::Connected ) { QString connectedStr; if ( mBackendData->isWireless ) connectedStr = i18n( "%1 is connected to %2", title, mBackendData->essid ); else connectedStr = i18n( "%1 is connected", title ); if ( mPreviousIfaceState != KNemoIface::UnknownState ) KNotification::event( QLatin1String("connected"), connectedStr ); } } else if ( mIfaceState & KNemoIface::Available ) { if ( mPreviousIfaceState & KNemoIface::Connected ) { KNotification::event( QLatin1String("disconnected"), i18n( "%1 has disconnected", title ) ); if ( mBackendData->interfaceType == KNemoIface::PPP ) backend->clearTraffic( mIfaceName ); resetUptime(); } else if ( mPreviousIfaceState < KNemoIface::Available ) { if ( mPreviousIfaceState != KNemoIface::UnknownState ) KNotification::event( QLatin1String("available"), i18n( "%1 is available", title ) ); } } else if ( mIfaceState == KNemoIface::Unavailable && mPreviousIfaceState > KNemoIface::Unavailable ) { KNotification::event( QLatin1String("unavailable"), i18n( "%1 is unavailable", title ) ); backend->clearTraffic( mIfaceName ); resetUptime(); } if ( mPreviousIfaceState != mIfaceState ) mIcon.updateTrayStatus(); if ( mPlotterDialog ) mPlotterDialog->updatePlotter( mRxRate, mTxRate ); mIcon.updateToolTip(); if ( mStatusDialog ) mStatusDialog->updateDialog(); } void Interface::resetUptime() { mUptime = 0; mRealSec = 0.0; mUptimeString = QStringLiteral("00:00:00"); mRxRate = 0; mTxRate = 0; mRxRateStr = formattedRate( mRxRate, generalSettings->useBitrate ); mTxRateStr = formattedRate( mTxRate, generalSettings->useBitrate ); } void Interface::showStatusDialog( bool fromContextMenu ) { // Toggle the status dialog. // First click will show the status dialog, second will hide it. if ( mStatusDialog == 0L ) { mStatusDialog = new InterfaceStatusDialog( this ); if ( mIfaceStatistics != 0 ) { connect( mIfaceStatistics, SIGNAL( currentEntryChanged() ), mStatusDialog, SLOT( statisticsChanged() ) ); mStatusDialog->statisticsChanged(); } } activateOrHide( mStatusDialog, fromContextMenu ); } void Interface::showSignalPlotter( bool fromContextMenu ) { // Toggle the signal plotter. activateOrHide( mPlotterDialog, fromContextMenu ); } void Interface::showStatisticsDialog() { if ( mStatisticsDialog == 0 ) { mStatisticsDialog = new InterfaceStatisticsDialog( this ); if ( mIfaceStatistics == 0 ) { // should never happen but you never know... startStatistics(); } connect( mStatisticsDialog, SIGNAL( clearStatistics() ), mIfaceStatistics, SLOT( clearStatistics() ) ); } mStatisticsDialog->show(); } void Interface::updateTime() { mRealSec += generalSettings->pollInterval; if ( mRealSec < 1.0 ) return; mUptime += trunc( mRealSec ); mRealSec -= trunc( mRealSec ); time_t updays = mUptime / 86400; mUptimeString = i18np("1 day, ","%1 days, ",updays); mUptime -= 86400 * updays; // we only want the seconds of today int hrs = mUptime / 3600; int mins = ( mUptime - hrs * 3600 ) / 60; int secs = mUptime - hrs * 3600 - mins * 60; QString time; time.sprintf( "%02d:%02d:%02d", hrs, mins, secs ); mUptimeString += time; } void Interface::startStatistics() { mIfaceStatistics = new InterfaceStatistics( this ); connect( mIfaceStatistics, SIGNAL( warnTraffic( QString, quint64, quint64 ) ), this, SLOT( warnTraffic( QString, quint64, quint64 ) ) ); if ( mStatusDialog != 0 ) { connect( mIfaceStatistics, SIGNAL( currentEntryChanged() ), mStatusDialog, SLOT( statisticsChanged() ) ); mStatusDialog->statisticsChanged(); } } void Interface::stopStatistics() { // this will close an open statistics dialog delete mStatisticsDialog; mStatisticsDialog = 0; delete mIfaceStatistics; mIfaceStatistics = 0; } void Interface::warnTraffic( QString warnText, quint64 threshold, quint64 current ) { if ( !warnText.isEmpty() ) { warnText = warnText.replace( QRegExp(QLatin1String("%i")), mIfaceName ); warnText = warnText.replace( QRegExp(QLatin1String("%a")), mSettings.alias ); warnText = warnText.replace( QRegExp(QLatin1String("%t")), KIO::convertSize( threshold ) ); warnText = warnText.replace( QRegExp(QLatin1String("%c")), KIO::convertSize( threshold ) ); } else { warnText = i18n( "" "
%1:Exceeded traffic limit of %2\n" "(currently %3)
", mIfaceName, KIO::convertSize( threshold ), KIO::convertSize( current ) ); } KNotification::event( QLatin1String("exceededTraffic"), warnText ); } void Interface::toggleSignalPlotter( bool show ) { if ( !mPlotterDialog ) return; if ( show ) mPlotterDialog->show(); else mPlotterDialog->hide(); } bool Interface::plotterVisible() { if ( !mPlotterDialog || !mPlotterDialog->isVisible() ) return false; return true; } // taken from ksystemtray.cpp void Interface::activateOrHide( QWidget* widget, bool onlyActivate ) { if ( !widget ) return; KWindowInfo info1 = KWindowInfo( widget->winId(), NET::XAWMState | NET::WMState ); // mapped = visible (but possibly obscured) bool mapped = (info1.mappingState() == NET::Visible) && !info1.isMinimized(); // - not mapped -> show, raise, focus // - mapped // - obscured -> raise, focus // - not obscured -> hide if( !mapped ) { KWindowSystem::setOnDesktop( widget->winId(), KWindowSystem::currentDesktop() ); widget->show(); widget->raise(); } else { QListIterator< WId > it (KWindowSystem::stackingOrder()); it.toBack(); while( it.hasPrevious() ) { WId id = it.previous(); if( id == widget->winId() ) break; KWindowInfo info2 = KWindowInfo( id, NET::WMGeometry | NET::XAWMState | NET::WMState | NET::WMWindowType ); if( info2.mappingState() != NET::Visible ) continue; // not visible on current desktop -> ignore if( !info2.geometry().intersects( widget->geometry())) continue; // not obscuring the window -> ignore if( !info1.hasState( NET::KeepAbove ) && info2.hasState( NET::KeepAbove )) continue; // obscured by window kept above -> ignore NET::WindowType type = info2.windowType( NET::NormalMask | NET::DesktopMask | NET::DockMask | NET::ToolbarMask | NET::MenuMask | NET::DialogMask | NET::OverrideMask | NET::TopMenuMask | NET::UtilityMask | NET::SplashMask ); if( type == NET::Dock || type == NET::TopMenu ) continue; // obscured by dock or topmenu -> ignore widget->raise(); KWindowSystem::activateWindow( widget->winId()); return; } if ( !onlyActivate ) { widget->hide(); } } } #include "moc_interface.cpp" diff --git a/src/knemod/interfaceicon.cpp b/src/knemod/interfaceicon.cpp index 26ed8fc..49ad3b6 100644 --- a/src/knemod/interfaceicon.cpp +++ b/src/knemod/interfaceicon.cpp @@ -1,463 +1,463 @@ /* 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 InterfaceIcon::InterfaceIcon( Interface* interface ) : QObject(), mInterface( interface ), mTray( 0L ), barIncoming( 0 ), barOutgoing( 0 ) { statusAction = new QAction( i18n( "Show &Status Dialog" ), this ); plotterAction = new QAction( QIcon::fromTheme( QLatin1String("utilities-system-monitor") ), i18n( "Show &Traffic Plotter" ), this ); statisticsAction = new QAction( QIcon::fromTheme( QLatin1String("view-statistics") ), i18n( "Show St&atistics" ), this ); configAction = new QAction( QIcon::fromTheme( QLatin1String("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() { delete mTray; } void InterfaceIcon::configChanged() { 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; + maxRate = mInterface->settings().maxRate; 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 = QStringLiteral("network-"); else iconName = QLatin1String("knemo-") + mInterface->settings().iconTheme + QLatin1Char('-'); // 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( int iconHeight, 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*iconHeight; } QColor InterfaceIcon::calcColor( const QColor& low ) { const BackendData * data = mInterface->backendData(); if ( data->status & KNemoIface::Connected ) return low; else if ( data->status & KNemoIface::Available ) return KColorScheme(QPalette::Active).foreground(KColorScheme::InactiveText).color(); else return KColorScheme(QPalette::Active).foreground(KColorScheme::NegativeText).color(); } void InterfaceIcon::updateBars( bool doUpdate ) { // Has color changed? QColor rxColor = calcColor( KColorScheme(QPalette::Active, KColorScheme::Window).foreground(KColorScheme::ActiveText).color() ); QColor txColor = calcColor( KColorScheme(QPalette::Active, KColorScheme::Window).foreground(KColorScheme::NeutralText).color() ); if ( rxColor != colorIncoming ) { doUpdate = true; colorIncoming = rxColor; } QSize iconSize = getIconSize(); // Has height changed? - int rateIn = calcHeight( iconSize.height(), inHist, inMaxRate ); - int rateOut = calcHeight( iconSize.height(), outHist, outMaxRate ); + // FIXME: they should have same scale!! + int rateIn = calcHeight( iconSize.height(), inHist, maxRate ); + int rateOut = calcHeight( iconSize.height(), outHist, maxRate ); if ( rateIn != barIncoming ) { doUpdate = true; barIncoming = rateIn; } if ( rateOut != barOutgoing ) { doUpdate = true; barOutgoing = rateOut; } if ( !doUpdate ) return; int barWidth = static_cast(round(iconSize.width()/3.0) + 0.5); int margins = iconSize.width() - (barWidth*2); int midMargin = static_cast(round(margins/3.0) + 0.5); int outerMargin = static_cast(round((margins - midMargin)/2.0) + 0.5); midMargin = outerMargin + barWidth + midMargin; QPixmap barIcon(iconSize); barIcon.fill( Qt::transparent ); int top = iconSize.height() - barOutgoing; QRect topLeftRect( outerMargin, 0, barWidth, top ); QRect leftRect( outerMargin, top, barWidth, iconSize.height() ); top = iconSize.height() - barIncoming; QRect topRightRect( midMargin, 0, barWidth, top ); QRect rightRect( midMargin, top, barWidth, iconSize.height() ); const BackendData * data = mInterface->backendData(); QColor bgColor; if ( data->status & KNemoIface::Connected ) { bgColor = KColorScheme(QPalette::Active, KColorScheme::Window).foreground(KColorScheme::InactiveText).color(); bgColor.setAlpha( 77 ); } else if ( data->status & KNemoIface::Available ) { bgColor = KColorScheme(QPalette::Active, KColorScheme::Window).foreground(KColorScheme::InactiveText).color(); rxColor.setAlpha( 153 ); } else { bgColor = KColorScheme(QPalette::Active, KColorScheme::Window).foreground(KColorScheme::NegativeText).color(); } QPainter p( &barIcon ); p.fillRect( leftRect, txColor ); p.fillRect( rightRect, rxColor ); p.fillRect( topLeftRect, bgColor ); p.fillRect( topRightRect, bgColor ); 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( KColorScheme(QPalette::Active).foreground(KColorScheme::ActiveText).color() ); QColor txColor = calcColor( KColorScheme(QPalette::Active).foreground(KColorScheme::NeutralText).color() ); if ( rxColor != colorIncoming ) { doUpdate = true; colorIncoming = rxColor; } // 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; QSize iconSize = getIconSize(); QPixmap textIcon(iconSize); QRect topRect( 0, 0, iconSize.width(), iconSize.height()/2 ); QRect bottomRect( 0, iconSize.width()/2, iconSize.width(), iconSize.height()/2 ); textIcon.fill( Qt::transparent ); QPainter p( &textIcon ); p.setBrush( Qt::NoBrush ); p.setOpacity( 1.0 ); // rxFont and txFont should be the same size per poll period QFont rxFont = setIconFont( textIncoming, plasmaTheme->smallestFont(), iconSize.height() ); QFont txFont = setIconFont( textOutgoing, plasmaTheme->smallestFont(), iconSize.height() ); 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() { QMenu* menu = mTray->contextMenu(); InterfaceSettings& settings = mInterface->settings(); 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; int minVisibleState = mInterface->settings().minVisibleState; QString title = mInterface->settings().alias; if ( title.isEmpty() ) title = ifaceName; if ( mTray != 0L && currentStatus < minVisibleState ) { delete mTray; mTray = 0L; } else if ( mTray == 0L && currentStatus >= minVisibleState ) { mTray = new InterfaceTray( mInterface, ifaceName ); QMenu* menu = mTray->contextMenu(); menu->removeAction( menu->actions().at( 0 ) ); // FIXME: title for QMenu? //menu->addTitle( QIcon::fromTheme( QLatin1String("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( QLatin1String("help-contents") ) ); 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 << QLatin1String("kcmshell5") << QLatin1String("kcm_knemo"); process.startDetached(); } 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/interfaceicon.h b/src/knemod/interfaceicon.h index a4165b7..2fff571 100644 --- a/src/knemod/interfaceicon.h +++ b/src/knemod/interfaceicon.h @@ -1,127 +1,126 @@ /* 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. */ #ifndef INTERFACEICON_H #define INTERFACEICON_H #include class Interface; class InterfaceTray; class KActionCollection; class QAction; /** * This is the logical representation of the systemtray icon. It handles * creation and deletion of the real icon, setting the tooltip, setting * the correct icon image and displaying of the settings dialog. * * @short Logical representation of the systemtray icon * @author Percy Leonhardt */ class InterfaceIcon : public QObject { Q_OBJECT public: /** * Default Constructor */ InterfaceIcon( Interface* interface ); /** * Default Destructor */ virtual ~InterfaceIcon(); Q_SIGNALS: void statisticsSelected(); public Q_SLOTS: /* * Creates or deletes the tray icon */ void updateTrayStatus(); /* * Change the tooltip according to the alias of the interface */ void updateToolTip(); /* * Fill the context menu with entries if the user configured * start and stop command */ void updateMenu(); void configChanged(); private Q_SLOTS: /* * Called when the user selects 'Configure KNemo' from the context menu */ void showConfigDialog(); /* * Returns a string with a compact transfer rate * This should not be more than 4 chars, including the units */ QString compactTrayText( unsigned long ); void showStatus(); void showGraph(); void showStatistics(); private: /* * Changes the icon displayed in the tray */ void updateIconImage( int status ); QColor calcColor( const QColor& low ); int calcHeight( int iconHeight, QList& hist, unsigned int& net_max ); void updateBars( bool doUpdate = false ); void updateIconText( bool doUpdate = false ); // the interface this icon belongs to Interface* mInterface; // the real tray icon InterfaceTray* mTray; KActionCollection* commandActions; QAction* statusAction; QAction* plotterAction; QAction* statisticsAction; QAction* configAction; QString textIncoming; QString textOutgoing; QColor colorIncoming; int iconWidth; int histSize; int barIncoming; int barOutgoing; int barWidth; int leftMargin; int midMargin; QListinHist; QListoutHist; - unsigned int inMaxRate; - unsigned int outMaxRate; + unsigned int maxRate; }; #endif // INTERFACEICON_H