You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
488 lines
16 KiB
488 lines
16 KiB
/* This file is part of KNemo
|
|
Copyright (C) 2004, 2006 Percy Leonhardt <percy@eris23.de>
|
|
|
|
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 <tqtimer.h>
|
|
#include <tqpixmap.h>
|
|
|
|
#include <twin.h>
|
|
#include <kdebug.h>
|
|
#include <klocale.h>
|
|
#include <twinmodule.h>
|
|
#include <kiconloader.h>
|
|
|
|
#include "interface.h"
|
|
#include "signalplotter.h"
|
|
#include "interfacestatistics.h"
|
|
#include "interfacestatusdialog.h"
|
|
#include "interfacestatisticsdialog.h"
|
|
|
|
Interface::Interface( TQString ifname,
|
|
const GeneralData& generalData,
|
|
const PlotterSettings& plotterSettings )
|
|
: TQObject(),
|
|
mType( UNKNOWN_TYPE ),
|
|
mState( UNKNOWN_STATE ),
|
|
mOutgoingPos( 0 ),
|
|
mIncomingPos( 0 ),
|
|
mName( ifname ),
|
|
mPlotterTimer( 0 ),
|
|
mIcon( this ),
|
|
mStatistics( 0 ),
|
|
mStatusDialog( 0 ),
|
|
mStatisticsDialog( 0 ),
|
|
mPlotter( 0 ),
|
|
mVisibleBeams( NONE ),
|
|
mGeneralData( generalData ),
|
|
mPlotterSettings( plotterSettings )
|
|
{
|
|
connect( &mMonitor, TQT_SIGNAL( statusChanged( int ) ),
|
|
&mIcon, TQT_SLOT( updateStatus( int ) ) );
|
|
connect( &mMonitor, TQT_SIGNAL( available( int ) ),
|
|
&mIcon, TQT_SLOT( updateTrayStatus( int ) ) );
|
|
connect( &mMonitor, TQT_SIGNAL( notAvailable( int ) ),
|
|
&mIcon, TQT_SLOT( updateTrayStatus( int ) ) );
|
|
connect( &mMonitor, TQT_SIGNAL( notExisting( int ) ),
|
|
&mIcon, TQT_SLOT( updateTrayStatus( int ) ) );
|
|
connect( &mMonitor, TQT_SIGNAL( available( int ) ),
|
|
this, TQT_SLOT( setStartTime( int ) ) );
|
|
connect( &mMonitor, TQT_SIGNAL( statusChanged( int ) ),
|
|
this, TQT_SLOT( resetData( int ) ) );
|
|
connect( &mIcon, TQT_SIGNAL( statisticsSelected() ),
|
|
this, TQT_SLOT( showStatisticsDialog() ) );
|
|
}
|
|
|
|
Interface::~Interface()
|
|
{
|
|
if ( mStatusDialog != 0 )
|
|
{
|
|
delete mStatusDialog;
|
|
}
|
|
if ( mPlotter != 0 )
|
|
{
|
|
delete mPlotter;
|
|
}
|
|
if ( mPlotterTimer != 0 )
|
|
{
|
|
mPlotterTimer->stop();
|
|
delete mPlotterTimer;
|
|
}
|
|
if ( mStatistics != 0 )
|
|
{
|
|
// this will also delete a possibly open statistics dialog
|
|
stopStatistics();
|
|
}
|
|
}
|
|
|
|
void Interface::configChanged()
|
|
{
|
|
// UNKNOWN_STATE to avoid notification
|
|
mIcon.updateTrayStatus( UNKNOWN_STATE );
|
|
// handle changed iconset by user
|
|
mIcon.updateStatus( mState );
|
|
mIcon.updateToolTip();
|
|
mIcon.updateMenu();
|
|
|
|
if ( mPlotter != 0L )
|
|
{
|
|
configurePlotter();
|
|
}
|
|
|
|
if ( mStatistics != 0 )
|
|
{
|
|
mStatistics->configChanged();
|
|
}
|
|
|
|
if ( mSettings.activateStatistics && mStatistics == 0 )
|
|
{
|
|
// user turned on statistics
|
|
startStatistics();
|
|
}
|
|
else if ( !mSettings.activateStatistics && mStatistics != 0 )
|
|
{
|
|
// user turned off statistics
|
|
stopStatistics();
|
|
}
|
|
|
|
if ( mStatusDialog )
|
|
{
|
|
mStatusDialog->setStatisticsGroupEnabled( mSettings.activateStatistics );
|
|
}
|
|
}
|
|
|
|
void Interface::activateMonitor()
|
|
{
|
|
mMonitor.checkStatus( this );
|
|
}
|
|
|
|
void Interface::setStartTime( int )
|
|
{
|
|
mStartTime.setDate( TQDate::currentDate() );
|
|
mStartTime.setTime( TQTime::currentTime() );
|
|
}
|
|
|
|
void Interface::showStatusDialog()
|
|
{
|
|
// Toggle the status dialog.
|
|
// First click will show the status dialog, second will hide it.
|
|
if ( mStatusDialog == 0L )
|
|
{
|
|
mStatusDialog = new InterfaceStatusDialog( this );
|
|
connect( &mMonitor, TQT_SIGNAL( available( int ) ),
|
|
mStatusDialog, TQT_SLOT( enableNetworkGroups( int ) ) );
|
|
connect( &mMonitor, TQT_SIGNAL( notAvailable( int ) ),
|
|
mStatusDialog, TQT_SLOT( disableNetworkGroups( int ) ) );
|
|
connect( &mMonitor, TQT_SIGNAL( notExisting( int ) ),
|
|
mStatusDialog, TQT_SLOT( disableNetworkGroups( int ) ) );
|
|
if ( mStatistics != 0 )
|
|
{
|
|
connect( mStatistics, TQT_SIGNAL( currentEntryChanged() ),
|
|
mStatusDialog, TQT_SLOT( statisticsChanged() ) );
|
|
mStatusDialog->statisticsChanged();
|
|
}
|
|
activateOrHide( mStatusDialog, true );
|
|
}
|
|
else
|
|
{
|
|
// Toggle the status dialog.
|
|
activateOrHide( mStatusDialog );
|
|
}
|
|
}
|
|
|
|
void Interface::showSignalPlotter( bool wasMiddleButton )
|
|
{
|
|
// No plotter, create it.
|
|
if ( mPlotter == 0L )
|
|
{
|
|
mPlotter = new SignalPlotter( 0L, mName.local8Bit() );
|
|
mPlotter->setIcon( SmallIcon( "knemo" ) );
|
|
mPlotter->setCaption( mName + " " + i18n( "Traffic" ) );
|
|
mPlotter->setTitle( mName );
|
|
configurePlotter();
|
|
activateOrHide( mPlotter, true );
|
|
|
|
mPlotterTimer = new TQTimer();
|
|
connect( mPlotterTimer, TQT_SIGNAL( timeout() ),
|
|
this, TQT_SLOT( updatePlotter() ) );
|
|
mPlotterTimer->start( 1000 );
|
|
}
|
|
else
|
|
{
|
|
if ( wasMiddleButton )
|
|
{
|
|
// Toggle the signal plotter.
|
|
activateOrHide( mPlotter );
|
|
}
|
|
else
|
|
{
|
|
// Called from the context menu, show the dialog.
|
|
activateOrHide( mPlotter, true );
|
|
}
|
|
}
|
|
}
|
|
|
|
void Interface::showStatisticsDialog()
|
|
{
|
|
if ( mStatisticsDialog == 0 )
|
|
{
|
|
mStatisticsDialog = new InterfaceStatisticsDialog( this );
|
|
if ( mStatistics == 0 )
|
|
{
|
|
// should never happen but you never know...
|
|
startStatistics();
|
|
}
|
|
connect( mStatistics, TQT_SIGNAL( dayStatisticsChanged() ),
|
|
mStatisticsDialog, TQT_SLOT( updateDays() ) );
|
|
connect( mStatistics, TQT_SIGNAL( monthStatisticsChanged() ),
|
|
mStatisticsDialog, TQT_SLOT( updateMonths() ) );
|
|
connect( mStatistics, TQT_SIGNAL( yearStatisticsChanged() ),
|
|
mStatisticsDialog, TQT_SLOT( updateYears() ) );
|
|
connect( mStatistics, TQT_SIGNAL( currentEntryChanged() ),
|
|
mStatisticsDialog, TQT_SLOT( updateCurrentEntry() ) );
|
|
connect( mStatisticsDialog, TQT_SIGNAL( clearDailyStatisticsClicked() ),
|
|
mStatistics, TQT_SLOT( clearDayStatistics() ) );
|
|
connect( mStatisticsDialog, TQT_SIGNAL( clearMonthlyStatisticsClicked() ),
|
|
mStatistics, TQT_SLOT( clearMonthStatistics() ) );
|
|
connect( mStatisticsDialog, TQT_SIGNAL( clearYearlyStatisticsClicked() ),
|
|
mStatistics, TQT_SLOT( clearYearStatistics() ) );
|
|
|
|
mStatisticsDialog->updateDays();
|
|
mStatisticsDialog->updateMonths();
|
|
mStatisticsDialog->updateYears();
|
|
}
|
|
mStatisticsDialog->show();
|
|
}
|
|
|
|
void Interface::resetData( int state )
|
|
{
|
|
// For PPP interfaces we will reset all data to zero when the
|
|
// interface gets disconnected. If the driver also resets its data
|
|
// (like PPP seems to do) we will start from zero for every new
|
|
// connection.
|
|
if ( mType == PPP &&
|
|
( state == NOT_AVAILABLE ||
|
|
state == NOT_EXISTING ) )
|
|
{
|
|
mData.prevTxBytes = mData.txBytes = 0;
|
|
mData.prevRxBytes = mData.rxBytes = 0;
|
|
mData.prevTxPackets = mData.txPackets = 0;
|
|
mData.prevRxPackets = mData.rxPackets = 0;
|
|
}
|
|
}
|
|
|
|
void Interface::updatePlotter()
|
|
{
|
|
if ( mPlotter )
|
|
{
|
|
double outgoingBytes = mData.outgoingBytes / 1024.0 / (double) mGeneralData.pollInterval;
|
|
double incomingBytes = mData.incomingBytes / 1024.0 / (double) mGeneralData.pollInterval;
|
|
|
|
TQValueList<double> trafficList;
|
|
switch ( mVisibleBeams )
|
|
{
|
|
case BOTH:
|
|
if ( mIncomingPos == 1 )
|
|
{
|
|
trafficList.append( outgoingBytes );
|
|
trafficList.append( incomingBytes );
|
|
}
|
|
else
|
|
{
|
|
trafficList.append( incomingBytes );
|
|
trafficList.append( outgoingBytes );
|
|
}
|
|
mPlotter->addSample( trafficList );
|
|
break;
|
|
case INCOMING_TRAFFIC:
|
|
trafficList.append( incomingBytes );
|
|
mPlotter->addSample( trafficList );
|
|
break;
|
|
case OUTGOING_TRAFFIC:
|
|
trafficList.append( outgoingBytes );
|
|
mPlotter->addSample( trafficList );
|
|
break;
|
|
case NONE:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Interface::configurePlotter()
|
|
{
|
|
mPlotter->setFontSize( mPlotterSettings.fontSize );
|
|
if ( !mPlotterSettings.automaticDetection )
|
|
{
|
|
mPlotter->setMinValue( mPlotterSettings.minimumValue );
|
|
mPlotter->setMaxValue( mPlotterSettings.maximumValue );
|
|
}
|
|
mPlotter->setHorizontalScale( mPlotterSettings.pixel );
|
|
mPlotter->setHorizontalLinesCount( mPlotterSettings.count );
|
|
mPlotter->setVerticalLinesDistance( mPlotterSettings.distance );
|
|
mPlotter->setShowLabels( mPlotterSettings.labels );
|
|
mPlotter->setShowTopBar( mPlotterSettings.topBar );
|
|
mPlotter->setShowVerticalLines( mPlotterSettings.verticalLines );
|
|
mPlotter->setShowHorizontalLines( mPlotterSettings.horizontalLines );
|
|
mPlotter->setUseAutoRange( mPlotterSettings.automaticDetection );
|
|
mPlotter->setVerticalLinesScroll( mPlotterSettings.verticalLinesScroll );
|
|
mPlotter->setVerticalLinesColor( mPlotterSettings.colorVLines );
|
|
mPlotter->setHorizontalLinesColor( mPlotterSettings.colorHLines );
|
|
mPlotter->setBackgroundColor( mPlotterSettings.colorBackground );
|
|
|
|
// add or remove beams according to user settings
|
|
VisibleBeams nextVisibleBeams = NONE;
|
|
if ( mPlotterSettings.showOutgoing )
|
|
nextVisibleBeams = (VisibleBeams) ( nextVisibleBeams | OUTGOING_TRAFFIC );
|
|
if ( mPlotterSettings.showIncoming )
|
|
nextVisibleBeams = (VisibleBeams) ( nextVisibleBeams | INCOMING_TRAFFIC );
|
|
|
|
TQValueList<TQColor>& colors = mPlotter->beamColors();
|
|
switch( mVisibleBeams )
|
|
{
|
|
case NONE:
|
|
if ( nextVisibleBeams == BOTH )
|
|
{
|
|
mOutgoingPos = 0;
|
|
mPlotter->addBeam( mPlotterSettings.colorOutgoing );
|
|
mIncomingPos = 1;
|
|
mPlotter->addBeam( mPlotterSettings.colorIncoming );
|
|
}
|
|
else if ( nextVisibleBeams == OUTGOING_TRAFFIC )
|
|
{
|
|
mOutgoingPos = 0;
|
|
mPlotter->addBeam( mPlotterSettings.colorOutgoing );
|
|
}
|
|
else if ( nextVisibleBeams == INCOMING_TRAFFIC )
|
|
{
|
|
mIncomingPos = 0;
|
|
mPlotter->addBeam( mPlotterSettings.colorIncoming );
|
|
}
|
|
break;
|
|
case INCOMING_TRAFFIC:
|
|
if ( nextVisibleBeams == BOTH )
|
|
{
|
|
mOutgoingPos = 1;
|
|
mPlotter->addBeam( mPlotterSettings.colorOutgoing );
|
|
}
|
|
else if ( nextVisibleBeams == OUTGOING_TRAFFIC )
|
|
{
|
|
mPlotter->removeBeam( mIncomingPos );
|
|
mOutgoingPos = 0;
|
|
mPlotter->addBeam( mPlotterSettings.colorOutgoing );
|
|
}
|
|
else if ( nextVisibleBeams == INCOMING_TRAFFIC )
|
|
{
|
|
colors[mIncomingPos] = ( mPlotterSettings.colorIncoming );
|
|
}
|
|
else if ( nextVisibleBeams == NONE )
|
|
{
|
|
mPlotter->removeBeam( mIncomingPos );
|
|
}
|
|
break;
|
|
case OUTGOING_TRAFFIC:
|
|
if ( nextVisibleBeams == BOTH )
|
|
{
|
|
mIncomingPos = 1;
|
|
mPlotter->addBeam( mPlotterSettings.colorIncoming );
|
|
}
|
|
else if ( nextVisibleBeams == INCOMING_TRAFFIC )
|
|
{
|
|
mPlotter->removeBeam( mOutgoingPos );
|
|
mIncomingPos = 0;
|
|
mPlotter->addBeam( mPlotterSettings.colorIncoming );
|
|
}
|
|
else if ( nextVisibleBeams == OUTGOING_TRAFFIC )
|
|
{
|
|
colors[mOutgoingPos] = ( mPlotterSettings.colorOutgoing );
|
|
}
|
|
else if ( nextVisibleBeams == NONE )
|
|
{
|
|
mPlotter->removeBeam( mOutgoingPos );
|
|
}
|
|
break;
|
|
case BOTH:
|
|
if ( nextVisibleBeams == BOTH )
|
|
{
|
|
colors[mIncomingPos] = ( mPlotterSettings.colorIncoming );
|
|
colors[mOutgoingPos] = ( mPlotterSettings.colorOutgoing );
|
|
}
|
|
else if ( nextVisibleBeams == OUTGOING_TRAFFIC )
|
|
{
|
|
mOutgoingPos = 0;
|
|
mPlotter->removeBeam( mIncomingPos );
|
|
}
|
|
else if ( nextVisibleBeams == INCOMING_TRAFFIC )
|
|
{
|
|
mIncomingPos = 0;
|
|
mPlotter->removeBeam( mOutgoingPos );
|
|
}
|
|
else if ( nextVisibleBeams == NONE )
|
|
{
|
|
mPlotter->removeBeam( 0 );
|
|
mPlotter->removeBeam( 0 );
|
|
}
|
|
break;
|
|
}
|
|
mVisibleBeams = nextVisibleBeams;
|
|
mPlotter->repaint();
|
|
}
|
|
|
|
void Interface::startStatistics()
|
|
{
|
|
mStatistics = new InterfaceStatistics( this );
|
|
connect( &mMonitor, TQT_SIGNAL( incomingData( unsigned long ) ),
|
|
mStatistics, TQT_SLOT( addIncomingData( unsigned long ) ) );
|
|
connect( &mMonitor, TQT_SIGNAL( outgoingData( unsigned long ) ),
|
|
mStatistics, TQT_SLOT( addOutgoingData( unsigned long ) ) );
|
|
if ( mStatusDialog != 0 )
|
|
{
|
|
connect( mStatistics, TQT_SIGNAL( currentEntryChanged() ),
|
|
mStatusDialog, TQT_SLOT( statisticsChanged() ) );
|
|
mStatusDialog->statisticsChanged();
|
|
}
|
|
|
|
mStatistics->loadStatistics();
|
|
}
|
|
|
|
void Interface::stopStatistics()
|
|
{
|
|
if ( mStatisticsDialog != 0 )
|
|
{
|
|
// this will close an open statistics dialog
|
|
delete mStatisticsDialog;
|
|
mStatisticsDialog = 0;
|
|
}
|
|
|
|
mStatistics->saveStatistics();
|
|
|
|
delete mStatistics;
|
|
mStatistics = 0;
|
|
}
|
|
|
|
// taken from ksystemtray.cpp
|
|
void Interface::activateOrHide( TQWidget* widget, bool onlyActivate )
|
|
{
|
|
if ( !widget )
|
|
return;
|
|
|
|
KWin::WindowInfo info1 = KWin::windowInfo( 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 )
|
|
{
|
|
KWin::setOnDesktop( widget->winId(), KWin::currentDesktop() );
|
|
widget->show();
|
|
widget->raise();
|
|
KWin::activateWindow( widget->winId() );
|
|
}
|
|
else
|
|
{
|
|
KWinModule module;
|
|
for( TQValueList< WId >::ConstIterator it = module.stackingOrder().fromLast();
|
|
it != module.stackingOrder().end() && (*it) != widget->winId();
|
|
--it )
|
|
{
|
|
KWin::WindowInfo info2 = KWin::windowInfo( *it, (unsigned long)
|
|
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();
|
|
KWin::activateWindow( widget->winId());
|
|
return;
|
|
}
|
|
if ( !onlyActivate )
|
|
{
|
|
widget->hide();
|
|
}
|
|
}
|
|
}
|
|
|
|
#include "interface.moc"
|