diff --git a/src/common/data.h b/src/common/data.h index 058492f..ee4e562 100644 --- a/src/common/data.h +++ b/src/common/data.h @@ -1,443 +1,446 @@ /* This file is part of KNemo Copyright (C) 2004 Percy Leonhardt Copyright (C) 2009, 2010 John Stamp KNemo is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. KNemo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef DATA_H #define DATA_H #include #include #include #include #include #include #include #include #include #include class KCalendarSystem; /** * This file contains data structures used to store information about * an interface. It is shared between the daemon and the control center * module. * * @short Shared data structures * @author Percy Leonhardt */ namespace KNemoIface { enum Type { UnknownType, Ethernet, PPP }; enum IfaceState { UnknownState = 0, Unavailable = 1, Available = 2, Up = 4, Connected = 8, RxTraffic = 16, TxTraffic = 32 }; } namespace KNemoStats { enum TrafficUnits { UnitB = 0, UnitK, UnitM, UnitG }; enum TrafficDirection { TrafficIn = 0, TrafficOut, TrafficTotal }; enum WarnType { Peak = 0, Offpeak, PeakOffpeak }; enum PeriodUnits { Hour = 0, Day, Week, Month, BillPeriod, Year, HourArchive }; // Powers of 2 enum TrafficType { AllTraffic = 0, OffpeakTraffic = 1 }; }; static const 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_hideWhenNotAvail("HideWhenNotAvailable"); static const QLatin1String conf_hideWhenNotExist("HideWhenNotExisting"); +static const QLatin1String conf_hideAlways("HideAlways"); static const QLatin1String conf_trafficThreshold("TrafficThreshold"); static const QLatin1String conf_iconTheme("IconSet"); static const QLatin1String conf_colorIncoming("ColorIncoming"); static const QLatin1String conf_colorOutgoing("ColorOutgoing"); static const QLatin1String conf_colorDisabled("ColorDisabled"); static const QLatin1String conf_colorUnavailable("ColorUnavailable"); static const QLatin1String conf_dynamicColor("DynamicColor"); static const QLatin1String conf_colorIncomingMax("ColorIncomingMax"); static const QLatin1String conf_colorOutgoingMax("ColorOutgoingMax"); static const QLatin1String conf_barScale("BarScale"); static const QLatin1String conf_inMaxRate("InMaxRate"); static const QLatin1String conf_outMaxRate("OutMaxRate"); static const QLatin1String conf_iconFont("IconFont"); // 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() : iconTheme( QLatin1String("monitor") ), colorIncoming( 0x1889FF ), colorOutgoing( 0xFF7F08 ), colorDisabled( 0x888786 ), colorUnavailable( 0x888786 ), colorBackground( 0x888786 ), dynamicColor( false ), colorIncomingMax( 0x96FFFF ), colorOutgoingMax( 0xFFC868 ), barScale( false ), inMaxRate( 4 ), outMaxRate( 4 ), iconFont( QFontDatabase::systemFont( QFontDatabase::GeneralFont ) ), trafficThreshold( 0 ), hideWhenUnavailable( false ), hideWhenDisconnected( false ), + hideAlways( false ), activateStatistics( false ), calendarSystem( KLocale::QDateCalendar ) {} QString iconTheme; QColor colorIncoming; QColor colorOutgoing; QColor colorDisabled; QColor colorUnavailable; QColor colorBackground; bool dynamicColor; QColor colorIncomingMax; QColor colorOutgoingMax; bool barScale; unsigned int inMaxRate; unsigned int outMaxRate; QFont iconFont; unsigned int trafficThreshold; bool hideWhenUnavailable; bool hideWhenDisconnected; + bool hideAlways; 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 0b8eec7..6b2bca1 100644 --- a/src/kcm/configdialog.cpp +++ b/src/kcm/configdialog.cpp @@ -1,1554 +1,1571 @@ /* 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 "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") ) ); mDlg->themeColorBox->setEnabled( false ); 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->colorIncoming, SIGNAL( changed( const QColor& ) ), this, SLOT( colorButtonChanged() ) ); connect( mDlg->colorOutgoing, SIGNAL( changed( const QColor& ) ), this, SLOT( colorButtonChanged() ) ); connect( mDlg->colorDisabled, SIGNAL( changed( const QColor& ) ), this, SLOT( colorButtonChanged() ) ); connect( mDlg->colorUnavailable, SIGNAL( changed( const QColor& ) ), this, SLOT( colorButtonChanged() ) ); connect( mDlg->iconFont, SIGNAL( currentFontChanged( const QFont& ) ), this, SLOT( iconFontChanged( const QFont& ) ) ); 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->hideWhenDisconnected = interfaceGroup.readEntry( conf_hideWhenNotAvail, s.hideWhenDisconnected ); settings->hideWhenUnavailable = interfaceGroup.readEntry( conf_hideWhenNotExist, s.hideWhenUnavailable ); + settings->hideAlways = interfaceGroup.readEntry( conf_hideAlways, s.hideAlways ); settings->trafficThreshold = clamp(interfaceGroup.readEntry( conf_trafficThreshold, s.trafficThreshold ), 0, 1000 ); settings->iconTheme = interfaceGroup.readEntry( conf_iconTheme, s.iconTheme ); settings->colorIncoming = interfaceGroup.readEntry( conf_colorIncoming, s.colorIncoming ); settings->colorOutgoing = interfaceGroup.readEntry( conf_colorOutgoing, s.colorOutgoing ); KColorScheme scheme(QPalette::Active, KColorScheme::View); settings->colorDisabled = interfaceGroup.readEntry( conf_colorDisabled, scheme.foreground( KColorScheme::InactiveText ).color() ); settings->colorUnavailable = interfaceGroup.readEntry( conf_colorUnavailable, scheme.foreground( KColorScheme::InactiveText ).color() ); settings->colorBackground = scheme.foreground( KColorScheme::InactiveText ).color(); settings->iconFont = interfaceGroup.readEntry( conf_iconFont, s.iconFont ); settings->dynamicColor = interfaceGroup.readEntry( conf_dynamicColor, s.dynamicColor ); settings->colorIncomingMax = interfaceGroup.readEntry( conf_colorIncomingMax, s.colorIncomingMax ); settings->colorOutgoingMax = interfaceGroup.readEntry( conf_colorOutgoingMax, s.colorOutgoingMax ); 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->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_hideWhenNotAvail, settings->hideWhenDisconnected ); - interfaceGroup.writeEntry( conf_hideWhenNotExist, settings->hideWhenUnavailable ); + if ( settings->hideAlways ) + { + interfaceGroup.writeEntry( conf_hideAlways, settings->hideAlways ); + } else { + interfaceGroup.writeEntry( conf_hideWhenNotAvail, settings->hideWhenDisconnected ); + interfaceGroup.writeEntry( conf_hideWhenNotExist, settings->hideWhenUnavailable ); + } + interfaceGroup.writeEntry( conf_hideAlways, settings->hideAlways ); interfaceGroup.writeEntry( conf_trafficThreshold, settings->trafficThreshold ); interfaceGroup.writeEntry( conf_iconTheme, settings->iconTheme ); if ( settings->iconTheme == TEXT_THEME || settings->iconTheme == NETLOAD_THEME ) { interfaceGroup.writeEntry( conf_colorIncoming, settings->colorIncoming ); interfaceGroup.writeEntry( conf_colorOutgoing, settings->colorOutgoing ); interfaceGroup.writeEntry( conf_colorDisabled, settings->colorDisabled ); interfaceGroup.writeEntry( conf_colorUnavailable, settings->colorUnavailable ); interfaceGroup.writeEntry( conf_dynamicColor, settings->dynamicColor ); if ( settings->dynamicColor ) { interfaceGroup.writeEntry( conf_colorIncomingMax, settings->colorIncomingMax ); interfaceGroup.writeEntry( conf_colorOutgoingMax, settings->colorOutgoingMax ); } if ( settings->iconTheme == NETLOAD_THEME ) { interfaceGroup.writeEntry( conf_barScale, settings->barScale ); } if ( settings->iconTheme == TEXT_THEME && settings->iconFont != QFontDatabase::systemFont( QFontDatabase::GeneralFont ) ) { interfaceGroup.writeEntry( conf_iconFont, settings->iconFont ); } if ( settings->dynamicColor || ( settings->iconTheme == NETLOAD_THEME && settings->barScale ) ) { interfaceGroup.writeEntry( conf_inMaxRate, settings->inMaxRate ); interfaceGroup.writeEntry( conf_outMaxRate, settings->outMaxRate ); } } 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, NL_AUTO_PROVIDE, 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(); KColorScheme scheme(QPalette::Active, KColorScheme::View); settings->colorDisabled = scheme.foreground( KColorScheme::InactiveText ).color(); settings->colorUnavailable = scheme.foreground( KColorScheme::InactiveText ).color(); settings->colorBackground = scheme.foreground( KColorScheme::InactiveText ).color(); settings->iconFont = QFontDatabase::systemFont( QFontDatabase::GeneralFont ); 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 ); mDlg->colorIncoming->setColor( settings->colorIncoming ); mDlg->colorOutgoing->setColor( settings->colorOutgoing ); mDlg->colorDisabled->setColor( settings->colorDisabled ); mDlg->colorUnavailable->setColor( settings->colorUnavailable ); mDlg->iconFont->setCurrentFont( settings->iconFont ); iconThemeChanged( index ); - if ( settings->hideWhenDisconnected ) + if ( settings->hideAlways ) + index = 3; + else if ( settings->hideWhenDisconnected ) index = 1; else if ( settings->hideWhenUnavailable ) index = 2; else 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); settings->colorDisabled = scheme.foreground( KColorScheme::InactiveText ).color(); settings->colorUnavailable = scheme.foreground( KColorScheme::InactiveText ).color(); settings->colorBackground = scheme.foreground( KColorScheme::InactiveText ).color(); settings->iconFont = QFontDatabase::systemFont( QFontDatabase::GeneralFont ); 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(); settings->colorDisabled = scheme.foreground( KColorScheme::InactiveText ).color(); settings->colorUnavailable = scheme.foreground( KColorScheme::InactiveText ).color(); settings->colorBackground = scheme.foreground( KColorScheme::InactiveText ).color(); settings->iconFont = QFontDatabase::systemFont( QFontDatabase::GeneralFont ); 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 ) { QPixmap sampleIcon( 22, 22 ); sampleIcon.fill( Qt::transparent ); QRect topRect( 0, 0, 22, 11 ); QRect bottomRect( 0, 11, 22, 11 ); QPainter p( &sampleIcon ); p.setBrush( Qt::NoBrush ); p.setOpacity( 1.0 ); QFont rxFont = setIconFont( incomingText, mDlg->iconFont->currentFont(), 22 ); QFont txFont = setIconFont( outgoingText, mDlg->iconFont->currentFont(), 22 ); if ( rxFont.pointSizeF() > txFont.pointSizeF() ) rxFont.setPointSizeF( txFont.pointSizeF() ); p.setFont( rxFont ); if ( status >= KNemoIface::Connected ) p.setPen( mDlg->colorIncoming->color() ); else if ( status == KNemoIface::Available ) p.setPen( mDlg->colorDisabled->color() ); else p.setPen( mDlg->colorUnavailable->color() ); p.drawText( topRect, Qt::AlignCenter | Qt::AlignRight, incomingText ); p.setFont( rxFont ); if ( status >= KNemoIface::Connected ) p.setPen( mDlg->colorOutgoing->color() ); p.drawText( bottomRect, Qt::AlignCenter | Qt::AlignRight, outgoingText ); return sampleIcon; } QPixmap ConfigDialog::barIcon( int status ) { int barIncoming = 0; int barOutgoing = 0; QPixmap barIcon( 22, 22 ); barIcon.fill( Qt::transparent ); QPainter p( &barIcon ); QLinearGradient inGrad( 12, 0, 19, 0 ); QLinearGradient topInGrad( 12, 0, 19, 0 ); QLinearGradient outGrad( 3, 0, 10, 0 ); QLinearGradient topOutGrad( 3, 0, 10, 0 ); QColor topColor = getItemSettings()->colorBackground; QColor topColorD = getItemSettings()->colorBackground.darker(); topColor.setAlpha( 128 ); topColorD.setAlpha( 128 ); topInGrad.setColorAt(0, topColorD); topInGrad.setColorAt(1, topColor ); topOutGrad.setColorAt(0, topColorD); topOutGrad.setColorAt(1, topColor ); if ( status & KNemoIface::Connected ) { inGrad.setColorAt(0, mDlg->colorIncoming->color() ); inGrad.setColorAt(1, mDlg->colorIncoming->color().darker() ); outGrad.setColorAt(0, mDlg->colorOutgoing->color() ); outGrad.setColorAt(1, mDlg->colorOutgoing->color().darker() ); } else if ( status & KNemoIface::Available ) { inGrad.setColorAt(0, mDlg->colorDisabled->color()); inGrad.setColorAt(1, mDlg->colorDisabled->color().darker() ); outGrad.setColorAt(0, mDlg->colorDisabled->color() ); outGrad.setColorAt(1, mDlg->colorDisabled->color().darker() ); } else { inGrad.setColorAt(0, mDlg->colorUnavailable->color() ); inGrad.setColorAt(1, mDlg->colorUnavailable->color().darker() ); outGrad.setColorAt(0, mDlg->colorUnavailable->color() ); outGrad.setColorAt(1, mDlg->colorUnavailable->color().darker() ); } if ( status & KNemoIface::Available || status & KNemoIface::Unavailable ) { barIncoming = 22; barOutgoing = 22; } if ( status & KNemoIface::RxTraffic ) barIncoming = 17; if ( status & KNemoIface::TxTraffic ) barOutgoing = 17; int top = 22 - barOutgoing; QRect topLeftRect( 3, 0, 7, top ); QRect leftRect( 3, top, 7, 22 ); top = 22 - barIncoming; QRect topRightRect( 12, 0, 7, top ); QRect rightRect( 12, top, 7, 22 ); QBrush brush( inGrad ); p.setBrush( brush ); p.fillRect( rightRect, inGrad ); brush = QBrush( topInGrad ); p.fillRect( topRightRect, topInGrad ); brush = QBrush( outGrad ); p.fillRect( leftRect, outGrad ); brush = QBrush( topOutGrad ); p.fillRect( topLeftRect, topOutGrad ); return barIcon; } void ConfigDialog::comboHidingChanged( int val ) { InterfaceSettings* settings = getItemSettings(); if ( !settings ) return; switch ( val ) { case 0: settings->hideWhenDisconnected = false; settings->hideWhenUnavailable = false; + settings->hideAlways = false; break; case 1: settings->hideWhenDisconnected = true; settings->hideWhenUnavailable = true; + settings->hideAlways = false; break; case 2: settings->hideWhenDisconnected = false; settings->hideWhenUnavailable = true; + settings->hideAlways = false; + break; + case 3: + settings->hideWhenDisconnected = false; + settings->hideWhenUnavailable = false; + settings->hideAlways = true; 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 ) { mDlg->iconFontLabel->setEnabled( false ); mDlg->iconFont->setEnabled( false ); } 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 ) ); mDlg->iconFontLabel->setEnabled( true ); mDlg->iconFont->setEnabled( true ); } 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->themeColorBox->setEnabled( true ); } else { settings->iconTheme = findNameFromIndex( set ); QString iconName; if ( settings->iconTheme == SYSTEM_THEME ) iconName = QLatin1String("network-"); else iconName = QLatin1String("knemo-") + settings->iconTheme + QLatin1Char('-'); mDlg->pixmapError->setPixmap( QIcon::fromTheme( iconName + ICON_ERROR ).pixmap( 22 ) ); mDlg->pixmapDisconnected->setPixmap( QIcon::fromTheme( iconName + ICON_OFFLINE ).pixmap( 22 ) ); mDlg->pixmapConnected->setPixmap( QIcon::fromTheme( iconName + ICON_IDLE ).pixmap( 22 ) ); mDlg->pixmapIncoming->setPixmap( QIcon::fromTheme( iconName + ICON_RX ).pixmap( 22 ) ); mDlg->pixmapOutgoing->setPixmap( QIcon::fromTheme( iconName + ICON_TX ).pixmap( 22 ) ); mDlg->pixmapTraffic->setPixmap( QIcon::fromTheme( iconName + ICON_RX_TX ).pixmap( 22 ) ); mDlg->themeColorBox->setEnabled( false ); } if (!mLock) changed( true ); } void ConfigDialog::colorButtonChanged() { InterfaceSettings* settings = getItemSettings(); if ( !settings ) return; if ( mDlg->colorIncoming->color().isValid() ) settings->colorIncoming = mDlg->colorIncoming->color(); if ( mDlg->colorOutgoing->color().isValid() ) settings->colorOutgoing = mDlg->colorOutgoing->color(); if ( mDlg->colorDisabled->color().isValid() ) settings->colorDisabled = mDlg->colorDisabled->color(); if ( mDlg->colorUnavailable->color().isValid() ) settings->colorUnavailable = mDlg->colorUnavailable->color(); KNemoTheme curTheme = mDlg->comboBoxIconTheme->itemData( mDlg->comboBoxIconTheme->currentIndex() ).value(); if ( curTheme.internalName == TEXT_THEME || curTheme.internalName == NETLOAD_THEME ) iconThemeChanged( mDlg->comboBoxIconTheme->currentIndex() ); if ( !mLock) changed( true ); } void ConfigDialog::iconFontChanged( const QFont &font ) { InterfaceSettings* settings = getItemSettings(); if ( !settings ) return; if ( font != settings->iconFont ) { settings->iconFont = font; iconThemeChanged( mDlg->comboBoxIconTheme->currentIndex() ); } 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->dynamicColor = s.dynamicColor; settings->colorIncomingMax = s.colorIncomingMax; settings->colorOutgoingMax = s.colorOutgoingMax; settings->barScale = s.barScale; settings->inMaxRate = s.inMaxRate; settings->outMaxRate = s.outMaxRate; 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/configdlg.ui b/src/kcm/configdlg.ui index 2abc734..95f15ef 100644 --- a/src/kcm/configdlg.ui +++ b/src/kcm/configdlg.ui @@ -1,965 +1,970 @@ ConfigDlg 0 0 0 0 Start KNemo automatically when you login 0 Interfaces This lists the interfaces that you wish to monitor. Please use the names understood by <i>ifconfig</i> ('eth0', 'wlan0', 'ppp0', etc.), or click "Add all interfaces" below to include all of the interfaces currently found on your system. true Add a new interface Add all interfaces false Delete the selected interface Qt::Vertical 0 0 false Alias: false false You can enter an alias for the interface. KNemo will use it to differentiate interfaces when it displays tooltips, dialogs, etc. false 0 0 0 Icon Appearance Icon hiding: Do not hide Hide when disconnected Hide when unavailable + + + Always hide + + Icon theme: false Unavailable false Disconnected false Connected false Incoming traffic false Outgoing traffic false Incoming and outgoing traffic false Theme Settings Incoming traffic: Outgoing traffic: Disconnected: Unavailable: false Icon Font: Qt::Horizontal QSizePolicy::Expanding 0 0 Advanced... Qt::Vertical 0 0 Statistics Activate statistics false Custom Billing Periods Log traffic statistics according to customized rules. When a custom billing period ends, it will automatically start a new billing period with the same rules. false false Add a new entry Add... Modify... Remove the selected entry Remove Qt::Vertical QSizePolicy::Expanding 0 0 false Traffic Notifications When interface traffic exceeds the limit set by a rule, KNemo will emit a notification. The notification will appear once per period. false false Add a new entry Add... Modify... Remove the selected entry Remove Qt::Vertical QSizePolicy::Expanding 0 0 Qt::Vertical 0 0 ToolTip 0 0 Available: false QAbstractItemView::ExtendedSelection Qt::Vertical QSizePolicy::Expanding 0 0 Qt::Horizontal QSizePolicy::Fixed 5 20 Add the selected entry to the tray icon's tooltip Remove the selected entry from the tray icon's tooltip Qt::Horizontal QSizePolicy::Fixed 5 20 Qt::Vertical QSizePolicy::Expanding 0 0 0 0 Active: false QAbstractItemView::ExtendedSelection Wireless specific information will only appear in the tooltips of wireless devices true General Notifications Configure Notifications... Update interval Update interface information every false Set how often KNemo polls interfaces for information. A lower value will speed up reaction to changes, but it will also increase CPU load. Qt::Horizontal QSizePolicy::Expanding 0 0 Report traffic rate in bit/s Statistics Autosave interval: false Save interface statistics every <i>n</i> seconds. If 0, KNemo will only save statistics when it closes. At shutdown sec 0 300 60 Qt::Horizontal QSizePolicy::Expanding 0 0 Qt::Vertical QSizePolicy::Expanding 0 0 KColorButton QPushButton
kcolorbutton.h
checkBoxStartKNemo tabWidgetConfiguration listBoxInterfaces pushButtonNew pushButtonAll pushButtonDelete lineEditAlias ifaceTab comboHiding comboBoxIconTheme colorIncoming colorOutgoing colorDisabled colorUnavailable iconFont advancedButton checkBoxStatistics statsView addStats modifyStats removeStats warnView addWarn modifyWarn removeWarn listBoxAvailable pushButtonAddToolTip pushButtonRemoveToolTip listBoxDisplay pushButtonNotifications comboBoxPoll useBitrate numInputSaveInterval checkBoxStatistics toggled(bool) groupBox setEnabled(bool) 429 148 496 437 checkBoxStatistics toggled(bool) groupBox_2 setEnabled(bool) 431 146 426 162
diff --git a/src/knemod/interface.cpp b/src/knemod/interface.cpp index f033a93..d544ad8 100644 --- a/src/knemod/interface.cpp +++ b/src/knemod/interface.cpp @@ -1,454 +1,455 @@ /* 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 "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 ); QStringList themeNames; QList themes = findThemes(); // Let's check that it's available foreach( KNemoTheme theme, themes ) themeNames << theme.internalName; themeNames << NETLOAD_THEME; if ( !themeNames.contains( mSettings.iconTheme ) ) mSettings.iconTheme = TEXT_THEME; mSettings.colorIncoming = interfaceGroup.readEntry( conf_colorIncoming, s.colorIncoming ); mSettings.colorOutgoing = interfaceGroup.readEntry( conf_colorOutgoing, s.colorOutgoing ); KColorScheme scheme(QPalette::Active, KColorScheme::View); mSettings.colorDisabled = interfaceGroup.readEntry( conf_colorDisabled, scheme.foreground( KColorScheme::InactiveText ).color() ); mSettings.colorUnavailable = interfaceGroup.readEntry( conf_colorUnavailable, scheme.foreground( KColorScheme::InactiveText ).color() ); mSettings.colorBackground = scheme.foreground( KColorScheme::InactiveText ).color(); mSettings.iconFont = interfaceGroup.readEntry( conf_iconFont, s.iconFont ); mSettings.dynamicColor = interfaceGroup.readEntry( conf_dynamicColor, s.dynamicColor ); mSettings.colorIncomingMax = interfaceGroup.readEntry( conf_colorIncomingMax, s.colorIncomingMax ); mSettings.colorOutgoingMax = interfaceGroup.readEntry( conf_colorOutgoingMax, s.colorOutgoingMax ); 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.hideWhenDisconnected = interfaceGroup.readEntry( conf_hideWhenNotAvail, s.hideWhenDisconnected ); mSettings.hideWhenUnavailable = interfaceGroup.readEntry( conf_hideWhenNotExist, s.hideWhenUnavailable ); + mSettings.hideAlways = interfaceGroup.readEntry( conf_hideAlways, s.hideAlways ); 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 df546b1..bb65d87 100644 --- a/src/knemod/interfaceicon.cpp +++ b/src/knemod/interfaceicon.cpp @@ -1,550 +1,552 @@ /* 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 "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() { KConfigGroup cg( KSharedConfig::openConfig(), "System Tray" ); iconWidth = cg.readEntry( "systrayIconWidth", 22 ); barWidth = iconWidth/3; int margins = iconWidth - (barWidth*2); midMargin = margins/3; int rightMargin = (margins - midMargin)/2; leftMargin = margins-midMargin - rightMargin; midMargin = leftMargin + barWidth+ midMargin; histSize = HISTSIZE_STORE/generalSettings->pollInterval; if ( histSize < 2 ) histSize = 2; for ( int i=0; i < histSize; i++ ) { inHist.append( 0 ); outHist.append( 0 ); } inMaxRate = mInterface->settings().inMaxRate; outMaxRate = mInterface->settings().outMaxRate; updateTrayStatus(); if ( mTray != 0L ) { updateMenu(); if ( mInterface->settings().iconTheme == TEXT_THEME ) updateIconText( true ); else if ( mInterface->settings().iconTheme == NETLOAD_THEME ) updateBars( true ); } } void InterfaceIcon::updateIconImage( int status ) { if ( mTray == 0L || mInterface->settings().iconTheme == TEXT_THEME ) return; QString iconName; if ( mInterface->settings().iconTheme == SYSTEM_THEME ) iconName = 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( QList& hist, unsigned int& net_max ) { unsigned long histcalculate = 0; unsigned long rate = 0; foreach( unsigned long j, hist ) { histcalculate += j; } rate = histcalculate / histSize; /* update maximum */ if ( !mInterface->settings().barScale ) { QListsortedMax( hist ); qSort( sortedMax ); unsigned long max = sortedMax.last(); int multiplier = 1024; if ( generalSettings->useBitrate ) multiplier = 1000; if( rate > net_max ) { net_max = rate; } else if( max < net_max * SHRINK_MAX && net_max * SHRINK_MAX >= multiplier ) { net_max *= SHRINK_MAX; } } qreal ratio = static_cast(rate)/net_max; if ( ratio > 1.0 ) ratio = 1.0; return ratio*iconWidth; } QColor InterfaceIcon::calcColor( QList& hist, const QColor& low, const QColor& high, int hival ) { const BackendData * data = mInterface->backendData(); if ( data->status & KNemoIface::Connected ) { if ( ! mInterface->settings().dynamicColor ) return low; } else if ( data->status & KNemoIface::Available ) return mInterface->settings().colorDisabled; else if ( data->status & KNemoIface::Unavailable ) return mInterface->settings().colorUnavailable; unsigned long histcalculate = 0; unsigned long rate = 0; if ( mInterface->settings().iconTheme == NETLOAD_THEME ) { foreach( unsigned long j, hist ) { histcalculate += j; } rate = histcalculate / histSize; } else rate = hist[0]; int lowH, lowS, lowV; int hiH, hiS, hiV; int difH, difS, difV; low.getHsv( &lowH, &lowS, &lowV ); high.getHsv( &hiH, &hiS, &hiV ); difH = hiH - lowH; difS = hiS - lowS; difV = hiV - lowV; qreal percentage = static_cast(rate)/hival; if ( percentage > 1.0 ) percentage = 1.0; QColor retcolor; retcolor.setHsv( lowH + ( percentage*difH ), lowS + ( percentage*difS), lowV + (percentage*difV ) ); return retcolor; } void InterfaceIcon::updateBars( bool doUpdate ) { // Has color changed? QColor rxColor = calcColor( inHist, mInterface->settings().colorIncoming, mInterface->settings().colorIncomingMax, mInterface->settings().inMaxRate ); QColor txColor = calcColor( outHist, mInterface->settings().colorOutgoing, mInterface->settings().colorOutgoingMax, mInterface->settings().outMaxRate ); if ( rxColor != colorIncoming ) { doUpdate = true; colorIncoming = rxColor; } if ( txColor != colorOutgoing ) { doUpdate = true; colorOutgoing = txColor; } // Has height changed? int rateIn = calcHeight( inHist, inMaxRate ); int rateOut = calcHeight( outHist, outMaxRate ); if ( rateIn != barIncoming ) { doUpdate = true; barIncoming = rateIn; } if ( rateOut != barOutgoing ) { doUpdate = true; barOutgoing = rateOut; } if ( !doUpdate ) return; QPixmap barIcon(iconWidth, iconWidth); QLinearGradient inGrad( midMargin, 0, midMargin+barWidth, 0 ); QLinearGradient topInGrad( midMargin, 0, midMargin+barWidth, 0 ); QLinearGradient outGrad( leftMargin, 0, leftMargin+barWidth, 0 ); QLinearGradient topOutGrad( leftMargin, 0, leftMargin+barWidth, 0 ); int top = iconWidth - barOutgoing; QRect topLeftRect( leftMargin, 0, barWidth, top ); QRect leftRect( leftMargin, top, barWidth, iconWidth ); top = iconWidth - barIncoming; QRect topRightRect( midMargin, 0, barWidth, top ); QRect rightRect( midMargin, top, barWidth, iconWidth ); barIcon.fill( Qt::transparent ); QPainter p( &barIcon ); p.setOpacity( 1.0 ); const BackendData * data = mInterface->backendData(); QColor topColor; if ( data->status & KNemoIface::Connected ) { topColor = mInterface->settings().colorBackground; } else if ( data->status & KNemoIface::Available ) { topColor = mInterface->settings().colorDisabled; } else { topColor = mInterface->settings().colorUnavailable; } QColor topColorD = topColor.darker(); topColor.setAlpha( 128 ); topColorD.setAlpha( 128 ); topInGrad.setColorAt(0, topColorD); topInGrad.setColorAt(1, topColor ); topOutGrad.setColorAt(0, topColorD); topOutGrad.setColorAt(1, topColor ); inGrad.setColorAt(0, rxColor ); inGrad.setColorAt(1, rxColor.darker() ); outGrad.setColorAt(0, txColor ); outGrad.setColorAt(1, txColor.darker() ); QBrush brush( inGrad ); p.setBrush( brush ); p.fillRect( rightRect, inGrad ); brush = QBrush( topInGrad ); p.fillRect( topRightRect, topInGrad ); brush = QBrush( outGrad ); p.fillRect( leftRect, outGrad ); brush = QBrush( topOutGrad ); p.fillRect( topLeftRect, topOutGrad ); mTray->setIconByPixmap( barIcon ); QPixmapCache::clear(); } QString InterfaceIcon::compactTrayText(unsigned long data ) { QString dataString; // Space is tight, so no space between number and units, and the complete // string should be no more than 4 chars. /* Visually confusing to display bytes if ( bytes < 922 ) // 922B = 0.9K byteString = i18n( "%1B", bytes ); */ double multiplier = 1024; if ( generalSettings->useBitrate ) multiplier = 1000; int precision = 0; if ( data < multiplier*9.95 ) // < 9.95K { precision = 1; } if ( data < multiplier*999.5 ) // < 999.5K { if ( generalSettings->useBitrate ) dataString = i18n( "%1k", QString::number( data/multiplier, 'f', precision ) ); else dataString = i18n( "%1K", QString::number( data/multiplier, 'f', precision ) ); return dataString; } if ( data < pow(multiplier, 2)*9.95 ) // < 9.95M precision = 1; if ( data < pow(multiplier, 2)*999.5 ) // < 999.5M { dataString = i18n( "%1M", QString::number( data/pow(multiplier, 2), 'f', precision ) ); return dataString; } if ( data < pow(multiplier, 3)*9.95 ) // < 9.95G precision = 1; // xgettext: no-c-format dataString = i18n( "%1G", QString::number( data/pow(multiplier, 3), 'f', precision) ); return dataString; } void InterfaceIcon::updateIconText( bool doUpdate ) { // Has color changed? QColor rxColor = calcColor( inHist, mInterface->settings().colorIncoming, mInterface->settings().colorIncomingMax, mInterface->settings().inMaxRate ); QColor txColor = calcColor( outHist, mInterface->settings().colorOutgoing, mInterface->settings().colorOutgoingMax, mInterface->settings().outMaxRate ); if ( rxColor != colorIncoming ) { doUpdate = true; colorIncoming = rxColor; } if ( rxColor != colorOutgoing ) { doUpdate = true; colorOutgoing = txColor; } // Has text changed? QString byteText = compactTrayText( mInterface->rxRate() ); if ( byteText != textIncoming ) { doUpdate = true; textIncoming = byteText; } byteText = compactTrayText( mInterface->txRate() ); if ( byteText != textOutgoing ) { doUpdate = true; textOutgoing = byteText; } if ( !doUpdate ) return; QPixmap textIcon(iconWidth, iconWidth); QRect topRect( 0, 0, iconWidth, iconWidth/2 ); QRect bottomRect( 0, iconWidth/2, iconWidth, iconWidth/2 ); textIcon.fill( Qt::transparent ); QPainter p( &textIcon ); p.setBrush( Qt::NoBrush ); p.setOpacity( 1.0 ); KColorScheme scheme(QPalette::Active, KColorScheme::View); // rxFont and txFont should be the same size per poll period QFont rxFont = setIconFont( textIncoming, mInterface->settings().iconFont, iconWidth ); QFont txFont = setIconFont( textOutgoing, mInterface->settings().iconFont, iconWidth ); if ( rxFont.pointSizeF() > txFont.pointSizeF() ) rxFont.setPointSizeF( txFont.pointSizeF() ); p.setFont( rxFont ); p.setPen( rxColor ); p.drawText( topRect, Qt::AlignCenter | Qt::AlignRight, textIncoming ); p.setFont( rxFont ); p.setPen( txColor ); p.drawText( bottomRect, Qt::AlignCenter | Qt::AlignRight, textOutgoing ); mTray->setIconByPixmap( textIcon ); QPixmapCache::clear(); } void InterfaceIcon::updateToolTip() { if ( mTray == 0L ) return; inHist.prepend( mInterface->rxRate() ); outHist.prepend( mInterface->txRate() ); while ( inHist.count() > histSize ) { inHist.removeLast(); outHist.removeLast(); } if ( mInterface->settings().iconTheme == TEXT_THEME ) updateIconText(); else if ( mInterface->settings().iconTheme == NETLOAD_THEME ) updateBars(); mTray->updateToolTip(); } void InterfaceIcon::updateMenu() { 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; bool hideWhenUnavailable = mInterface->settings().hideWhenUnavailable; bool hideWhenDisconnected = mInterface->settings().hideWhenDisconnected; + bool hideAlways = mInterface->settings().hideAlways; QString title = mInterface->settings().alias; if ( title.isEmpty() ) title = ifaceName; /* Remove the icon if * - the interface is not available and the option to hide it is selected * - the interface does not exist, the option to hide it is selected * and the other option is not selected */ if ( mTray != 0L && - ( ( (currentStatus < KNemoIface::Connected ) && hideWhenDisconnected ) || + ( ( hideAlways ) || + ( (currentStatus < KNemoIface::Connected ) && hideWhenDisconnected ) || ( (currentStatus < KNemoIface::Available ) && hideWhenUnavailable && !hideWhenDisconnected ) ) ) { delete mTray; mTray = 0L; } /* Create the icon if * - the interface is available * - the interface is not available and the option to hide it is not * selected and the interface does exist * - the interface does not exist and the option to hide it is not selected * and the other option is not selected */ else if ( mTray == 0L && ( currentStatus & KNemoIface::Connected || ( currentStatus & KNemoIface::Available && !hideWhenDisconnected ) || ( !hideWhenUnavailable && !hideWhenDisconnected ) ) ) { mTray = new InterfaceTray( mInterface, ifaceName ); QMenu* menu = mTray->contextMenu(); menu->removeAction( menu->actions().at( 0 ) ); // FIXME: title for QMenu? //menu->addTitle( QIcon::fromTheme( 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/knemodaemon.cpp b/src/knemod/knemodaemon.cpp index d9ac8c0..26aeec2 100644 --- a/src/knemod/knemodaemon.cpp +++ b/src/knemod/knemodaemon.cpp @@ -1,217 +1,211 @@ /* This file is part of KNemo Copyright (C) 2004, 2006 Percy Leonhardt Copyright (C) 2009, 2010 John Stamp KNemo is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. KNemo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "knemodaemon.h" #include "interface.h" #include "backends/backendfactory.h" #include "utils.h" QString KNemoDaemon::sSelectedInterface = QString::null; BackendBase *backend = NULL; GeneralSettings *generalSettings = NULL; KNemoDaemon::KNemoDaemon() - : QObject(), - mHaveInterfaces( false ) + : QObject() { migrateKde4Conf(); generalSettings = new GeneralSettings(); backend = BackendFactory::backend(); QDBusConnection::sessionBus().registerObject(QLatin1String("/knemo"), this, QDBusConnection::ExportScriptableSlots); mPollTimer = new QTimer(); connect( mPollTimer, SIGNAL( timeout() ), this, SLOT( updateInterfaces() ) ); KActionCollection* ac = new KActionCollection( this ); QAction* action = new QAction( i18n( "Toggle Traffic Plotters" ), this ); ac->addAction( QLatin1String("toggleTrafficPlotters"), action ); connect( action, SIGNAL( triggered() ), SLOT( togglePlotters() ) ); KGlobalAccel::setGlobalShortcut( action, QKeySequence() ); readConfig(); } KNemoDaemon::~KNemoDaemon() { mPollTimer->stop(); delete mPollTimer; foreach ( QString key, mInterfaceHash.keys() ) { Interface *interface = mInterfaceHash.take( key ); delete interface; } delete generalSettings; } void KNemoDaemon::readConfig() { mPollTimer->stop(); KSharedConfig::Ptr config = KSharedConfig::openConfig(); // For when reparseConfiguration() is called config->reparseConfiguration(); // General GeneralSettings g; KConfigGroup generalGroup( config, confg_general ); generalSettings->pollInterval = clamp(generalGroup.readEntry( conf_pollInterval, g.pollInterval ), 0.1, 2.0 ); generalSettings->pollInterval = validatePoll( generalSettings->pollInterval ); generalSettings->useBitrate = generalGroup.readEntry( conf_useBitrate, g.useBitrate ); generalSettings->saveInterval = clamp(generalGroup.readEntry( conf_saveInterval, g.saveInterval ), 0, 300 ); generalSettings->statisticsDir = g.statisticsDir; generalSettings->toolTipContent = generalGroup.readEntry( conf_toolTipContent, g.toolTipContent ); - // If we already have an Interfaces key--even if its empty--then we - // shouldn't try to set up a default interface - if ( generalGroup.hasKey( conf_interfaces ) ) - mHaveInterfaces = true; QStringList interfaceList = generalGroup.readEntry( conf_interfaces, QStringList() ); // Remove interfaces that are no longer monitored foreach ( QString key, mInterfaceHash.keys() ) { if ( !interfaceList.contains( key ) ) { Interface *interface = mInterfaceHash.take( key ); delete interface; backend->removeIface( key ); // If knemo is running while config removes an interface to monitor, // it will keep the interface and plotter groups. Delete them here. KConfigGroup interfaceGroup( config, QString( confg_interface + key ) ); KConfigGroup plotterGroup( config, QString( confg_plotter + key ) ); interfaceGroup.deleteGroup(); plotterGroup.deleteGroup(); config->sync(); } } - if ( !mHaveInterfaces ) + // If an interface has the default route, add it even if it's not + // explicitly configured. It will just use the default settings. + // This should minimize user confusion. + QString ifaceName = backend->defaultRouteIface( AF_INET ); + if ( ifaceName.isEmpty() ) + ifaceName = backend->defaultRouteIface( AF_INET6 ); + if ( !ifaceName.isEmpty() ) { - QString ifaceName = backend->defaultRouteIface( AF_INET ); - if ( ifaceName.isEmpty() ) - ifaceName = backend->defaultRouteIface( AF_INET6 ); - if ( !ifaceName.isEmpty() ) - { - interfaceList << ifaceName; - mHaveInterfaces = true; - } + interfaceList << ifaceName; } // Add/update those that do need to be monitored QStringList newIfaces; foreach ( QString key, interfaceList ) { if ( !mInterfaceHash.contains( key ) ) { const BackendData * data = backend->addIface( key ); Interface *iface = new Interface( key, data ); mInterfaceHash.insert( key, iface ); newIfaces << key; } } // Now (re)config interfaces, but new interfaces need extra work so // they don't show bogus icon traffic states on startup. updateInterfaces(); foreach( QString key, interfaceList ) { Interface *iface = mInterfaceHash.value( key ); iface->configChanged(); if ( newIfaces.contains( key ) ) { backend->updatePackets( key ); iface->processUpdate(); connect( backend, SIGNAL( updateComplete() ), iface, SLOT( processUpdate() ) ); } } bool statsActivated = false; foreach ( Interface *iface, mInterfaceHash ) { if ( iface->settings().activateStatistics ) statsActivated = true; } if ( statsActivated ) { QStringList drivers = QSqlDatabase::drivers(); if ( !drivers.contains( QLatin1String("QSQLITE") ) ) { KMessageBox::sorry( 0, i18n( "The Qt4 SQLite database plugin is not available.\n" "Please install it to store traffic statistics." ) ); } } mPollTimer->start( generalSettings->pollInterval * 1000 ); } void KNemoDaemon::reparseConfiguration() { readConfig(); } QString KNemoDaemon::getSelectedInterface() { // Reset the variable to avoid preselecting an interface when // the user opens the control center module from the control // center afterwards. QString tmp = sSelectedInterface; sSelectedInterface = QString::null; return tmp; } void KNemoDaemon::updateInterfaces() { backend->update(); } void KNemoDaemon::togglePlotters() { bool showPlotters = false; foreach ( QString key, mInterfaceHash.keys() ) { // If only some of the plotters are visible, show them all if ( !mInterfaceHash.value( key )->plotterVisible() ) showPlotters = true; } foreach ( QString key, mInterfaceHash.keys() ) { mInterfaceHash.value( key )->toggleSignalPlotter( showPlotters ); } } #include "moc_knemodaemon.cpp" diff --git a/src/knemod/knemodaemon.h b/src/knemod/knemodaemon.h index 3dec208..58822b6 100644 --- a/src/knemod/knemodaemon.h +++ b/src/knemod/knemodaemon.h @@ -1,101 +1,99 @@ /* 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. */ #ifndef KNEMODAEMON_H #define KNEMODAEMON_H #include #include class QTimer; class Interface; class BackendBase; /** * This class is the main entry point of KNemo. It reads the configuration, * creates the logical interfaces and starts an interface updater. It also * takes care of configuration changes by the user. * * @short KNemos main entry point * @author Percy Leonhardt */ //class KNemoDaemon : public KDEDModule class KNemoDaemon : public QObject { Q_OBJECT Q_CLASSINFO( "D-Bus Interface", "org.kde.knemo" ) public: /** * Default Constructor */ KNemoDaemon(); /** * Default Destructor */ virtual ~KNemoDaemon(); // tell the control center module which interface the user selected static QString sSelectedInterface; public Q_SLOTS: /* * Called from the control center module when the user changed * the settings. It updates the internal list of interfaces * that should be monitored. */ Q_SCRIPTABLE void reparseConfiguration(); /* When the user selects 'Configure KNemo...' from the context * menus this functions gets called from the control center * module. This way the module knows for which interface the * user opened the dialog and can preselect the appropriate * interface in the list. */ Q_SCRIPTABLE QString getSelectedInterface(); private: /* * Read the configuration on startup */ void readConfig(); private Q_SLOTS: /** * trigger the backend to update the interface informations */ void updateInterfaces(); void togglePlotters(); private: - bool mHaveInterfaces; - // every time this timer expires we will // gather new informations from the backend QTimer* mPollTimer; // the name of backend we currently use QString mBackendName; // a list of all interfaces the user wants to monitor QHash mInterfaceHash; }; #endif // KNEMODAEMON_H